mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-06-20 17:41:55 +02:00
Implements permission masks
This commit is contained in:
@ -1,55 +0,0 @@
|
||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
|
||||
from threading import local
|
||||
|
||||
|
||||
USER_ATTR_NAME = getattr(settings, 'LOCAL_USER_ATTR_NAME', '_current_user')
|
||||
IP_ATTR_NAME = getattr(settings, 'LOCAL_IP_ATTR_NAME', '_current_ip')
|
||||
|
||||
_thread_locals = local()
|
||||
|
||||
|
||||
def _set_current_user_and_ip(user=None, ip=None):
|
||||
setattr(_thread_locals, USER_ATTR_NAME, user)
|
||||
setattr(_thread_locals, IP_ATTR_NAME, ip)
|
||||
|
||||
|
||||
def get_current_user():
|
||||
return getattr(_thread_locals, USER_ATTR_NAME, None)
|
||||
|
||||
|
||||
def get_current_ip():
|
||||
return getattr(_thread_locals, IP_ATTR_NAME, None)
|
||||
|
||||
|
||||
def get_current_authenticated_user():
|
||||
current_user = get_current_user()
|
||||
if isinstance(current_user, AnonymousUser):
|
||||
return None
|
||||
return current_user
|
||||
|
||||
|
||||
class LogsMiddleware(object):
|
||||
"""
|
||||
This middleware get the current user with his or her IP address on each request.
|
||||
"""
|
||||
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
user = request.user
|
||||
if 'HTTP_X_FORWARDED_FOR' in request.META:
|
||||
ip = request.META.get('HTTP_X_FORWARDED_FOR')
|
||||
else:
|
||||
ip = request.META.get('REMOTE_ADDR')
|
||||
|
||||
_set_current_user_and_ip(user, ip)
|
||||
response = self.get_response(request)
|
||||
_set_current_user_and_ip(None, None)
|
||||
|
||||
return response
|
@ -9,7 +9,7 @@ import getpass
|
||||
|
||||
from note.models import NoteUser, Alias
|
||||
|
||||
from .middlewares import get_current_authenticated_user, get_current_ip
|
||||
from note_kfet.middlewares import get_current_authenticated_user, get_current_ip
|
||||
from .models import Changelog
|
||||
|
||||
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db.models import Q, F
|
||||
|
||||
from note.models import Note, NoteUser, NoteClub, NoteSpecial
|
||||
from note_kfet.middlewares import get_current_session
|
||||
from .models import Membership, RolePermissions, Club
|
||||
from django.contrib.auth.backends import ModelBackend
|
||||
|
||||
@ -37,7 +37,8 @@ class PermissionBackend(ModelBackend):
|
||||
F=F,
|
||||
Q=Q
|
||||
)
|
||||
yield permission
|
||||
if permission.mask.rank <= get_current_session().get("permission_mask", 0):
|
||||
yield permission
|
||||
|
||||
@staticmethod
|
||||
def filter_queryset(user, model, t, field=None):
|
||||
@ -50,7 +51,7 @@ class PermissionBackend(ModelBackend):
|
||||
:return: A query that corresponds to the filter to give to a queryset
|
||||
"""
|
||||
|
||||
if user.is_superuser:
|
||||
if user.is_superuser and get_current_session().get("permission_mask", 0) >= 42:
|
||||
# Superusers have all rights
|
||||
return Q()
|
||||
|
||||
@ -68,7 +69,7 @@ class PermissionBackend(ModelBackend):
|
||||
return query
|
||||
|
||||
def has_perm(self, user_obj, perm, obj=None):
|
||||
if user_obj.is_superuser:
|
||||
if user_obj.is_superuser and get_current_session().get("permission_mask", 0) >= 42:
|
||||
return True
|
||||
|
||||
if obj is None:
|
||||
|
@ -6,12 +6,21 @@ from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Layout
|
||||
from dal import autocomplete
|
||||
from django import forms
|
||||
from django.contrib.auth.forms import UserCreationForm
|
||||
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from permission.models import PermissionMask
|
||||
from .models import Profile, Club, Membership
|
||||
|
||||
|
||||
class CustomAuthenticationForm(AuthenticationForm):
|
||||
permission_mask = forms.ModelChoiceField(
|
||||
label="Masque de permissions",
|
||||
queryset=PermissionMask.objects.order_by("rank"),
|
||||
empty_label=None,
|
||||
)
|
||||
|
||||
|
||||
class SignUpForm(UserCreationForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
@ -9,6 +9,7 @@ from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.views import LoginView
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db.models import Q
|
||||
from django.http import HttpResponseRedirect
|
||||
@ -26,11 +27,20 @@ from note.tables import HistoryTable, AliasTable
|
||||
from .backends import PermissionBackend
|
||||
|
||||
from .filters import UserFilter, UserFilterFormHelper
|
||||
from .forms import SignUpForm, ProfileForm, ClubForm, MembershipForm, MemberFormSet, FormSetHelper
|
||||
from .forms import SignUpForm, ProfileForm, ClubForm, MembershipForm, MemberFormSet, FormSetHelper, \
|
||||
CustomAuthenticationForm
|
||||
from .models import Club, Membership
|
||||
from .tables import ClubTable, UserTable
|
||||
|
||||
|
||||
class CustomLoginView(LoginView):
|
||||
form_class = CustomAuthenticationForm
|
||||
|
||||
def form_valid(self, form):
|
||||
self.request.session['permission_mask'] = form.cleaned_data['permission_mask'].rank
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class UserCreateView(CreateView):
|
||||
"""
|
||||
Une vue pour inscrire un utilisateur et lui créer un profile
|
||||
|
@ -4,7 +4,7 @@
|
||||
from rest_framework import serializers
|
||||
from rest_polymorphic.serializers import PolymorphicSerializer
|
||||
|
||||
from logs.middlewares import get_current_authenticated_user
|
||||
from note_kfet.middlewares import get_current_authenticated_user
|
||||
from ..models.notes import Note, NoteClub, NoteSpecial, NoteUser, Alias
|
||||
from ..models.transactions import TransactionTemplate, Transaction, MembershipTransaction, TemplateCategory, \
|
||||
TemplateTransaction, SpecialTransaction
|
||||
|
@ -3,7 +3,7 @@
|
||||
"model": "note.note",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"polymorphic_ctype": 40,
|
||||
"polymorphic_ctype": 41,
|
||||
"balance": 0,
|
||||
"is_active": true,
|
||||
"display_image": "",
|
||||
@ -14,7 +14,7 @@
|
||||
"model": "note.note",
|
||||
"pk": 2,
|
||||
"fields": {
|
||||
"polymorphic_ctype": 40,
|
||||
"polymorphic_ctype": 41,
|
||||
"balance": 0,
|
||||
"is_active": true,
|
||||
"display_image": "",
|
||||
@ -25,7 +25,7 @@
|
||||
"model": "note.note",
|
||||
"pk": 3,
|
||||
"fields": {
|
||||
"polymorphic_ctype": 40,
|
||||
"polymorphic_ctype": 41,
|
||||
"balance": 0,
|
||||
"is_active": true,
|
||||
"display_image": "",
|
||||
@ -36,7 +36,7 @@
|
||||
"model": "note.note",
|
||||
"pk": 4,
|
||||
"fields": {
|
||||
"polymorphic_ctype": 40,
|
||||
"polymorphic_ctype": 41,
|
||||
"balance": 0,
|
||||
"is_active": true,
|
||||
"display_image": "",
|
||||
@ -47,7 +47,7 @@
|
||||
"model": "note.note",
|
||||
"pk": 5,
|
||||
"fields": {
|
||||
"polymorphic_ctype": 39,
|
||||
"polymorphic_ctype": 40,
|
||||
"balance": 0,
|
||||
"is_active": true,
|
||||
"display_image": "",
|
||||
@ -58,7 +58,7 @@
|
||||
"model": "note.note",
|
||||
"pk": 6,
|
||||
"fields": {
|
||||
"polymorphic_ctype": 39,
|
||||
"polymorphic_ctype": 40,
|
||||
"balance": 0,
|
||||
"is_active": true,
|
||||
"display_image": "",
|
||||
|
@ -3,7 +3,15 @@
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Permission
|
||||
from .models import Permission, PermissionMask
|
||||
|
||||
|
||||
@admin.register(PermissionMask)
|
||||
class PermissionMaskAdmin(admin.ModelAdmin):
|
||||
"""
|
||||
Admin customisation for Permission
|
||||
"""
|
||||
list_display = ('rank', 'description')
|
||||
|
||||
|
||||
@admin.register(Permission)
|
||||
|
@ -50,6 +50,20 @@ class InstancedPermission:
|
||||
return self.__repr__()
|
||||
|
||||
|
||||
class PermissionMask(models.Model):
|
||||
rank = models.PositiveSmallIntegerField(
|
||||
verbose_name=_('rank'),
|
||||
)
|
||||
|
||||
description = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_('description'),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.description
|
||||
|
||||
|
||||
class Permission(models.Model):
|
||||
|
||||
PERMISSION_TYPES = [
|
||||
@ -85,6 +99,11 @@ class Permission(models.Model):
|
||||
|
||||
type = models.CharField(max_length=15, choices=PERMISSION_TYPES)
|
||||
|
||||
mask = models.ForeignKey(
|
||||
PermissionMask,
|
||||
on_delete=models.PROTECT,
|
||||
)
|
||||
|
||||
field = models.CharField(max_length=255, blank=True)
|
||||
|
||||
description = models.CharField(max_length=255, blank=True)
|
||||
|
@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from logs.middlewares import get_current_authenticated_user
|
||||
from note_kfet.middlewares import get_current_authenticated_user
|
||||
|
||||
|
||||
EXCLUDED = [
|
||||
|
@ -4,7 +4,7 @@
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.template.defaultfilters import stringfilter
|
||||
|
||||
from logs.middlewares import get_current_authenticated_user
|
||||
from note_kfet.middlewares import get_current_authenticated_user, get_current_session
|
||||
from django import template
|
||||
|
||||
from member.backends import PermissionBackend
|
||||
@ -19,7 +19,7 @@ def not_empty_model_list(model_name):
|
||||
user = get_current_authenticated_user()
|
||||
if user is None:
|
||||
return False
|
||||
elif user.is_superuser:
|
||||
elif user.is_superuser and get_current_session().get("permission_mask", 0) >= 42:
|
||||
return True
|
||||
spl = model_name.split(".")
|
||||
ct = ContentType.objects.get(app_label=spl[0], model=spl[1])
|
||||
@ -32,7 +32,7 @@ def not_empty_model_change_list(model_name):
|
||||
user = get_current_authenticated_user()
|
||||
if user is None:
|
||||
return False
|
||||
elif user.is_superuser:
|
||||
elif user.is_superuser and get_current_session().get("permission_mask", 0) >= 42:
|
||||
return True
|
||||
spl = model_name.split(".")
|
||||
ct = ContentType.objects.get(app_label=spl[0], model=spl[1])
|
||||
|
Reference in New Issue
Block a user