1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-06-21 09:58:23 +02:00

Restructurate code

This commit is contained in:
Yohann D'ANELLO
2020-03-20 14:43:35 +01:00
parent 02817c5626
commit 091c427707
15 changed files with 135 additions and 122 deletions

View File

@ -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', )

View 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"))

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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