mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-06-21 09:58:23 +02:00
Restructurate code
This commit is contained in:
@ -3,15 +3,15 @@
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Permission, PermissionMask
|
||||
from .models import Permission, PermissionMask, RolePermissions
|
||||
|
||||
|
||||
@admin.register(PermissionMask)
|
||||
class PermissionMaskAdmin(admin.ModelAdmin):
|
||||
"""
|
||||
Admin customisation for Permission
|
||||
Admin customisation for PermissionMask
|
||||
"""
|
||||
list_display = ('rank', 'description')
|
||||
list_display = ('description', 'rank', )
|
||||
|
||||
|
||||
@admin.register(Permission)
|
||||
@ -19,4 +19,13 @@ class PermissionAdmin(admin.ModelAdmin):
|
||||
"""
|
||||
Admin customisation for Permission
|
||||
"""
|
||||
list_display = ('type', 'model', 'field', 'mask', 'description')
|
||||
list_display = ('type', 'model', 'field', 'mask', 'description', )
|
||||
|
||||
|
||||
@admin.register(RolePermissions)
|
||||
class RolePermissionsAdmin(admin.ModelAdmin):
|
||||
"""
|
||||
Admin customisation for RolePermissions
|
||||
"""
|
||||
list_display = ('role', )
|
||||
|
||||
|
96
apps/permission/backends.py
Normal file
96
apps/permission/backends.py
Normal file
@ -0,0 +1,96 @@
|
||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django.contrib.auth.backends import ModelBackend
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db.models import Q, F
|
||||
from note.models import Note, NoteUser, NoteClub, NoteSpecial
|
||||
from note_kfet.middlewares import get_current_session
|
||||
from permission.models import Permission
|
||||
|
||||
from member.models import Membership, Club
|
||||
|
||||
|
||||
class PermissionBackend(ModelBackend):
|
||||
supports_object_permissions = True
|
||||
supports_anonymous_user = False
|
||||
supports_inactive_user = False
|
||||
|
||||
@staticmethod
|
||||
def permissions(user, model, type):
|
||||
for permission in Permission.objects.annotate(club=F("rolepermissions__role__membership__club")) \
|
||||
.filter(
|
||||
rolepermissions__role__membership__user=user,
|
||||
model__app_label=model.app_label, # For polymorphic models, we don't filter on model type
|
||||
type=type,
|
||||
).all():
|
||||
club = Club.objects.get(pk=permission.club)
|
||||
permission = permission.about(
|
||||
user=user,
|
||||
club=club,
|
||||
User=User,
|
||||
Club=Club,
|
||||
Membership=Membership,
|
||||
Note=Note,
|
||||
NoteUser=NoteUser,
|
||||
NoteClub=NoteClub,
|
||||
NoteSpecial=NoteSpecial,
|
||||
F=F,
|
||||
Q=Q
|
||||
)
|
||||
if permission.mask.rank <= get_current_session().get("permission_mask", 0):
|
||||
yield permission
|
||||
|
||||
@staticmethod
|
||||
def filter_queryset(user, model, t, field=None):
|
||||
"""
|
||||
Filter a queryset by considering the permissions of a given user.
|
||||
:param user: The owner of the permissions that are fetched
|
||||
:param model: The concerned model of the queryset
|
||||
:param t: The type of modification (view, add, change, delete)
|
||||
:param field: The field of the model to test, if concerned
|
||||
:return: A query that corresponds to the filter to give to a queryset
|
||||
"""
|
||||
|
||||
if user.is_superuser and get_current_session().get("permission_mask", 0) >= 42:
|
||||
# Superusers have all rights
|
||||
return Q()
|
||||
|
||||
if not isinstance(model, ContentType):
|
||||
model = ContentType.objects.get_for_model(model)
|
||||
|
||||
# Never satisfied
|
||||
query = Q(pk=-1)
|
||||
perms = PermissionBackend.permissions(user, model, t)
|
||||
for perm in perms:
|
||||
if perm.field and field != perm.field:
|
||||
continue
|
||||
if perm.type != t or perm.model != model:
|
||||
continue
|
||||
perm.update_query()
|
||||
query = query | perm.query
|
||||
return query
|
||||
|
||||
def has_perm(self, user_obj, perm, obj=None):
|
||||
if user_obj.is_superuser and get_current_session().get("permission_mask", 0) >= 42:
|
||||
return True
|
||||
|
||||
if obj is None:
|
||||
return True
|
||||
|
||||
perm = perm.split('.')[-1].split('_', 2)
|
||||
perm_type = perm[0]
|
||||
perm_field = perm[2] if len(perm) == 3 else None
|
||||
ct = ContentType.objects.get_for_model(obj)
|
||||
if any(permission.applies(obj, perm_type, perm_field)
|
||||
for permission in self.permissions(user_obj, ct, perm_type)):
|
||||
return True
|
||||
return False
|
||||
|
||||
def has_module_perms(self, user_obj, app_label):
|
||||
return False
|
||||
|
||||
def get_all_permissions(self, user_obj, obj=None):
|
||||
ct = ContentType.objects.get_for_model(obj)
|
||||
return list(self.permissions(user_obj, ct, "view"))
|
@ -1,4 +1,60 @@
|
||||
[
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"name": "Adh\u00e9rent BDE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 2,
|
||||
"fields": {
|
||||
"name": "Adh\u00e9rent Kfet"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 3,
|
||||
"fields": {
|
||||
"name": "Pr\u00e9sident\u00b7e BDE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 4,
|
||||
"fields": {
|
||||
"name": "Tr\u00e9sorier\u00b7\u00e8re BDE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 5,
|
||||
"fields": {
|
||||
"name": "Respo info"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 6,
|
||||
"fields": {
|
||||
"name": "GC Kfet"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 7,
|
||||
"fields": {
|
||||
"name": "Pr\u00e9sident\u00b7e de club"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 8,
|
||||
"fields": {
|
||||
"name": "Tr\u00e9sorier\u00b7\u00e8re de club"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.permissionmask",
|
||||
"pk": 1,
|
||||
@ -51,7 +107,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 3,
|
||||
"fields": {
|
||||
"model": 35,
|
||||
"model": 34,
|
||||
"query": "{\"pk\": [\"user\", \"note\", \"pk\"]}",
|
||||
"type": "view",
|
||||
"mask": 1,
|
||||
@ -75,7 +131,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 5,
|
||||
"fields": {
|
||||
"model": 37,
|
||||
"model": 36,
|
||||
"query": "[\"OR\", {\"source\": [\"user\", \"note\"]}, {\"destination\": [\"user\", \"note\"]}]",
|
||||
"type": "view",
|
||||
"mask": 1,
|
||||
@ -87,7 +143,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 6,
|
||||
"fields": {
|
||||
"model": 34,
|
||||
"model": 33,
|
||||
"query": "[\"OR\", {\"note__in\": [\"NoteUser\", \"objects\", [\"filter\", {\"user__membership__club__name\": \"Kfet\"}], [\"all\"]]}, {\"note__in\": [\"NoteClub\", \"objects\", [\"all\"]]}]",
|
||||
"type": "view",
|
||||
"mask": 1,
|
||||
@ -183,7 +239,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 14,
|
||||
"fields": {
|
||||
"model": 34,
|
||||
"model": 33,
|
||||
"query": "{\"note\": [\"user\", \"note\"]}",
|
||||
"type": "delete",
|
||||
"mask": 1,
|
||||
@ -195,7 +251,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 15,
|
||||
"fields": {
|
||||
"model": 34,
|
||||
"model": 33,
|
||||
"query": "{\"note\": [\"user\", \"note\"]}",
|
||||
"type": "add",
|
||||
"mask": 1,
|
||||
@ -207,7 +263,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 16,
|
||||
"fields": {
|
||||
"model": 35,
|
||||
"model": 34,
|
||||
"query": "{\"pk\": [\"user\", \"note\", \"pk\"]}",
|
||||
"type": "change",
|
||||
"mask": 1,
|
||||
@ -219,7 +275,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 17,
|
||||
"fields": {
|
||||
"model": 37,
|
||||
"model": 36,
|
||||
"query": "[\"AND\", {\"source\": [\"user\", \"note\"]}, {\"amount__lte\": [\"user\", \"note\", \"balance\"]}]",
|
||||
"type": "add",
|
||||
"mask": 1,
|
||||
@ -231,7 +287,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 18,
|
||||
"fields": {
|
||||
"model": 35,
|
||||
"model": 34,
|
||||
"query": "{}",
|
||||
"type": "change",
|
||||
"mask": 1,
|
||||
@ -243,7 +299,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 19,
|
||||
"fields": {
|
||||
"model": 35,
|
||||
"model": 34,
|
||||
"query": "[\"OR\", {\"pk\": [\"club\", \"note\", \"pk\"]}, {\"pk__in\": [\"NoteUser\", \"objects\", [\"filter\", {\"user__membership__club\": [\"club\"]}], [\"all\"]]}]",
|
||||
"type": "view",
|
||||
"mask": 2,
|
||||
@ -255,7 +311,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 20,
|
||||
"fields": {
|
||||
"model": 37,
|
||||
"model": 36,
|
||||
"query": "[\"AND\", [\"OR\", {\"source\": [\"club\", \"note\"]}, {\"destination\": [\"club\", \"note\"]}], {\"amount__lte\": {\"F\": [\"ADD\", [\"F\", \"source__balance\"], 5000]}}]",
|
||||
"type": "add",
|
||||
"mask": 2,
|
||||
@ -267,7 +323,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 21,
|
||||
"fields": {
|
||||
"model": 44,
|
||||
"model": 42,
|
||||
"query": "[\"AND\", {\"destination\": [\"club\", \"note\"]}, {\"amount__lte\": {\"F\": [\"ADD\", [\"F\", \"source__balance\"], 50]}}]",
|
||||
"type": "add",
|
||||
"mask": 2,
|
||||
@ -291,7 +347,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 23,
|
||||
"fields": {
|
||||
"model": 37,
|
||||
"model": 36,
|
||||
"query": "{}",
|
||||
"type": "change",
|
||||
"mask": 1,
|
||||
@ -303,7 +359,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 24,
|
||||
"fields": {
|
||||
"model": 37,
|
||||
"model": 36,
|
||||
"query": "{}",
|
||||
"type": "view",
|
||||
"mask": 2,
|
||||
@ -315,7 +371,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 25,
|
||||
"fields": {
|
||||
"model": 43,
|
||||
"model": 40,
|
||||
"query": "{}",
|
||||
"type": "view",
|
||||
"mask": 2,
|
||||
@ -339,7 +395,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 27,
|
||||
"fields": {
|
||||
"model": 36,
|
||||
"model": 35,
|
||||
"query": "{}",
|
||||
"type": "view",
|
||||
"mask": 2,
|
||||
@ -351,7 +407,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 28,
|
||||
"fields": {
|
||||
"model": 36,
|
||||
"model": 35,
|
||||
"query": "{}",
|
||||
"type": "change",
|
||||
"mask": 3,
|
||||
@ -363,7 +419,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 29,
|
||||
"fields": {
|
||||
"model": 36,
|
||||
"model": 35,
|
||||
"query": "{}",
|
||||
"type": "add",
|
||||
"mask": 3,
|
||||
@ -375,7 +431,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 30,
|
||||
"fields": {
|
||||
"model": 38,
|
||||
"model": 37,
|
||||
"query": "{}",
|
||||
"type": "view",
|
||||
"mask": 2,
|
||||
@ -387,7 +443,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 31,
|
||||
"fields": {
|
||||
"model": 38,
|
||||
"model": 37,
|
||||
"query": "{}",
|
||||
"type": "add",
|
||||
"mask": 3,
|
||||
@ -399,7 +455,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 32,
|
||||
"fields": {
|
||||
"model": 38,
|
||||
"model": 37,
|
||||
"query": "{}",
|
||||
"type": "change",
|
||||
"mask": 3,
|
||||
@ -411,7 +467,7 @@
|
||||
"model": "permission.permission",
|
||||
"pk": 33,
|
||||
"fields": {
|
||||
"model": 37,
|
||||
"model": 36,
|
||||
"query": "{}",
|
||||
"type": "add",
|
||||
"mask": 2,
|
||||
@ -420,63 +476,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"name": "Adh\u00e9rent BDE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 2,
|
||||
"fields": {
|
||||
"name": "Adh\u00e9rent Kfet"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 3,
|
||||
"fields": {
|
||||
"name": "Pr\u00e9sident\u00b7e BDE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 4,
|
||||
"fields": {
|
||||
"name": "Tr\u00e9sorier\u00b7\u00e8re BDE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 5,
|
||||
"fields": {
|
||||
"name": "Respo info"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 6,
|
||||
"fields": {
|
||||
"name": "GC Kfet"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 7,
|
||||
"fields": {
|
||||
"name": "Pr\u00e9sident\u00b7e de club"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.role",
|
||||
"pk": 8,
|
||||
"fields": {
|
||||
"name": "Tr\u00e9sorier\u00b7\u00e8re de club"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.rolepermissions",
|
||||
"model": "permission.rolepermissions",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"role": 1,
|
||||
@ -492,7 +492,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.rolepermissions",
|
||||
"model": "permission.rolepermissions",
|
||||
"pk": 2,
|
||||
"fields": {
|
||||
"role": 2,
|
||||
@ -519,7 +519,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.rolepermissions",
|
||||
"model": "permission.rolepermissions",
|
||||
"pk": 3,
|
||||
"fields": {
|
||||
"role": 8,
|
||||
@ -532,7 +532,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "member.rolepermissions",
|
||||
"model": "permission.rolepermissions",
|
||||
"pk": 4,
|
||||
"fields": {
|
||||
"role": 4,
|
||||
|
@ -11,6 +11,8 @@ from django.db import models
|
||||
from django.db.models import F, Q, Model
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from member.models import Role
|
||||
|
||||
|
||||
class InstancedPermission:
|
||||
|
||||
@ -234,3 +236,21 @@ class Permission(models.Model):
|
||||
else:
|
||||
return _("Can {type} {model} in {query}").format(type=self.type, model=self.model, query=self.query)
|
||||
|
||||
|
||||
class RolePermissions(models.Model):
|
||||
"""
|
||||
Permissions associated with a Role
|
||||
"""
|
||||
role = models.ForeignKey(
|
||||
Role,
|
||||
on_delete=models.PROTECT,
|
||||
related_name='+',
|
||||
verbose_name=_('role'),
|
||||
)
|
||||
permissions = models.ManyToManyField(
|
||||
Permission,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.role)
|
||||
|
||||
|
@ -5,7 +5,7 @@ from django.core.exceptions import PermissionDenied
|
||||
from django.db.models.signals import pre_save, pre_delete, post_save, post_delete
|
||||
|
||||
from logs import signals as logs_signals
|
||||
from member.backends import PermissionBackend
|
||||
from permission.backends import PermissionBackend
|
||||
from note_kfet.middlewares import get_current_authenticated_user
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ from django.template.defaultfilters import stringfilter
|
||||
from note_kfet.middlewares import get_current_authenticated_user, get_current_session
|
||||
from django import template
|
||||
|
||||
from member.backends import PermissionBackend
|
||||
from permission.backends import PermissionBackend
|
||||
|
||||
|
||||
@stringfilter
|
||||
@ -22,7 +22,7 @@ def not_empty_model_list(model_name):
|
||||
return session.get("not_empty_model_list_" + model_name, None) == 1
|
||||
spl = model_name.split(".")
|
||||
ct = ContentType.objects.get(app_label=spl[0], model=spl[1])
|
||||
qs = ct.model_class().objects.filter(PermissionBackend.filter_queryset(user, ct, "view"))
|
||||
qs = ct.model_class().objects.filter(PermissionBackend.filter_queryset(user, ct, "view")).all()
|
||||
session["not_empty_model_list_" + model_name] = 1 if qs.exists() else 2
|
||||
return session.get("not_empty_model_list_" + model_name) == 1
|
||||
|
||||
|
Reference in New Issue
Block a user