diff --git a/apps/member/api/serializers.py b/apps/member/api/serializers.py index 962841ae..a956a46b 100644 --- a/apps/member/api/serializers.py +++ b/apps/member/api/serializers.py @@ -15,6 +15,7 @@ class ProfileSerializer(serializers.ModelSerializer): class Meta: model = Profile fields = '__all__' + read_only_fields = ('user', ) class ClubSerializer(serializers.ModelSerializer): diff --git a/apps/member/models.py b/apps/member/models.py index 24e58830..1a9bcee2 100644 --- a/apps/member/models.py +++ b/apps/member/models.py @@ -178,6 +178,9 @@ class RolePermissions(models.Model): 'permission.Permission' ) + def __str__(self): + return str(self.role) + # @receiver(post_save, sender=settings.AUTH_USER_MODEL) # def save_user_profile(instance, created, **_kwargs): diff --git a/apps/note/api/serializers.py b/apps/note/api/serializers.py index 36696024..91dbb62a 100644 --- a/apps/note/api/serializers.py +++ b/apps/note/api/serializers.py @@ -4,6 +4,7 @@ from rest_framework import serializers from rest_polymorphic.serializers import PolymorphicSerializer +from member.backends import PermissionBackend 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, \ @@ -76,9 +77,10 @@ class AliasSerializer(serializers.ModelSerializer): class Meta: model = Alias fields = '__all__' + read_only_fields = ('note', ) def get_note(self, alias): - if get_current_authenticated_user().has_perm("note.view_note", alias.note): + if PermissionBackend().has_perm(get_current_authenticated_user(), "note.view_note", alias.note): return NotePolymorphicSerializer().to_representation(alias.note) else: return alias.note.id diff --git a/apps/permission/admin.py b/apps/permission/admin.py index 2e6899fd..fe2e0e74 100644 --- a/apps/permission/admin.py +++ b/apps/permission/admin.py @@ -19,4 +19,4 @@ class PermissionAdmin(admin.ModelAdmin): """ Admin customisation for Permission """ - list_display = ('type', 'model', 'field', 'description') + list_display = ('type', 'model', 'field', 'mask', 'description') diff --git a/apps/permission/fixtures/initial.json b/apps/permission/fixtures/initial.json new file mode 100644 index 00000000..e1262673 --- /dev/null +++ b/apps/permission/fixtures/initial.json @@ -0,0 +1,286 @@ +[ + { + "model": "permission.permissionmask", + "pk": 1, + "fields": { + "rank": 0, + "description": "Droits basiques" + } + }, + { + "model": "permission.permissionmask", + "pk": 2, + "fields": { + "rank": 1, + "description": "Droits note seulement" + } + }, + { + "model": "permission.permissionmask", + "pk": 3, + "fields": { + "rank": 42, + "description": "Tous mes droits" + } + }, + { + "model": "permission.permission", + "pk": 1, + "fields": { + "model": 21, + "query": "{\"pk\": [\"user\", \"pk\"]}", + "type": "view", + "mask": 1, + "field": "", + "description": "View our User object" + } + }, + { + "model": "permission.permission", + "pk": 2, + "fields": { + "model": 31, + "query": "{\"user\": [\"user\"]}", + "type": "view", + "mask": 1, + "field": "", + "description": "View our profile" + } + }, + { + "model": "permission.permission", + "pk": 3, + "fields": { + "model": 35, + "query": "{\"pk\": [\"user\", \"note\", \"pk\"]}", + "type": "view", + "mask": 1, + "field": "", + "description": "View our own note" + } + }, + { + "model": "permission.permission", + "pk": 4, + "fields": { + "model": 25, + "query": "{\"user\": [\"user\"]}", + "type": "view", + "mask": 1, + "field": "", + "description": "View our API token" + } + }, + { + "model": "permission.permission", + "pk": 5, + "fields": { + "model": 37, + "query": "[\"OR\", {\"source\": [\"user\", \"note\"]}, {\"destination\": [\"user\", \"note\"]}]", + "type": "view", + "mask": 1, + "field": "", + "description": "View our own transactions" + } + }, + { + "model": "permission.permission", + "pk": 6, + "fields": { + "model": 34, + "query": "[\"OR\", {\"note__in\": [\"NoteUser\", \"objects\", [\"filter\", {\"user__membership__club__name\": \"Kfet\"}], [\"all\"]]}, {\"note__in\": [\"NoteClub\", \"objects\", [\"all\"]]}]", + "type": "view", + "mask": 1, + "field": "", + "description": "View aliases of clubs and members of Kfet club" + } + }, + { + "model": "permission.permission", + "pk": 7, + "fields": { + "model": 21, + "query": "{\"pk\": [\"user\", \"pk\"]}", + "type": "change", + "mask": 1, + "field": "last_login", + "description": "Change myself's last login" + } + }, + { + "model": "permission.permission", + "pk": 8, + "fields": { + "model": 21, + "query": "{\"pk\": [\"user\", \"pk\"]}", + "type": "change", + "mask": 1, + "field": "username", + "description": "Change myself's username" + } + }, + { + "model": "permission.permission", + "pk": 9, + "fields": { + "model": 21, + "query": "{\"pk\": [\"user\", \"pk\"]}", + "type": "change", + "mask": 1, + "field": "first_name", + "description": "Change myself's first name" + } + }, + { + "model": "permission.permission", + "pk": 10, + "fields": { + "model": 21, + "query": "{\"pk\": [\"user\", \"pk\"]}", + "type": "change", + "mask": 1, + "field": "last_name", + "description": "Change myself's last name" + } + }, + { + "model": "permission.permission", + "pk": 11, + "fields": { + "model": 21, + "query": "{\"pk\": [\"user\", \"pk\"]}", + "type": "change", + "mask": 1, + "field": "email", + "description": "Change myself's email" + } + }, + { + "model": "permission.permission", + "pk": 12, + "fields": { + "model": 25, + "query": "{\"user\": [\"user\"]}", + "type": "delete", + "mask": 1, + "field": "", + "description": "Delete API Token" + } + }, + { + "model": "permission.permission", + "pk": 13, + "fields": { + "model": 25, + "query": "{\"user\": [\"user\"]}", + "type": "add", + "mask": 1, + "field": "", + "description": "Create API Token" + } + }, + { + "model": "permission.permission", + "pk": 14, + "fields": { + "model": 34, + "query": "{\"note\": [\"user\", \"note\"]}", + "type": "delete", + "mask": 1, + "field": "", + "description": "Remove alias" + } + }, + { + "model": "permission.permission", + "pk": 15, + "fields": { + "model": 34, + "query": "{\"note\": [\"user\", \"note\"]}", + "type": "add", + "mask": 1, + "field": "", + "description": "Add alias" + } + }, + { + "model": "permission.permission", + "pk": 16, + "fields": { + "model": 35, + "query": "{\"pk\": [\"user\", \"note\", \"pk\"]}", + "type": "change", + "mask": 1, + "field": "display_image", + "description": "Change myself's display image" + } + }, + { + "model": "permission.permission", + "pk": 17, + "fields": { + "model": 37, + "query": "[\"AND\", {\"source\": [\"user\", \"note\"]}, {\"amount__lte\": [\"user\", \"note\", \"balance\"]}]", + "type": "add", + "mask": 1, + "field": "", + "description": "Transfer from myself's note" + } + }, + { + "model": "member.role", + "pk": 1, + "fields": { + "name": "Adh\u00e9rent BDE" + } + }, + { + "model": "member.role", + "pk": 2, + "fields": { + "name": "Adh\u00e9rent Kfet" + } + }, + { + "model": "member.rolepermissions", + "pk": 1, + "fields": { + "role": 1, + "permissions": [ + 1, + 2, + 7, + 8, + 9, + 10, + 11 + ] + } + }, + { + "model": "member.rolepermissions", + "pk": 2, + "fields": { + "role": 2, + "permissions": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17 + ] + } + } +] diff --git a/apps/permission/models.py b/apps/permission/models.py index 62a1d0c3..43f62ac2 100644 --- a/apps/permission/models.py +++ b/apps/permission/models.py @@ -14,18 +14,20 @@ from django.utils.translation import gettext_lazy as _ class InstancedPermission: - def __init__(self, model, query, type, field): + def __init__(self, model, query, type, field, mask): self.model = model self.query = query self.type = type self.field = field + self.mask = mask def applies(self, obj, permission_type, field_name=None): """ Returns True if the permission applies to the field `field_name` object `obj` """ - if ContentType.objects.get_for_model(obj) != self.model: + + if not isinstance(obj, self.model.model_class()): # The permission does not apply to the model return False @@ -247,7 +249,7 @@ class Permission(models.Model): """ query = json.loads(self.query) query = self._about(query, **kwargs) - return InstancedPermission(self.model, query, self.type, self.field) + return InstancedPermission(self.model, query, self.type, self.field, self.mask) def __str__(self): if self.field: diff --git a/apps/permission/signals.py b/apps/permission/signals.py index 6d4f5f19..f18f35e0 100644 --- a/apps/permission/signals.py +++ b/apps/permission/signals.py @@ -2,6 +2,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later from django.core.exceptions import PermissionDenied + +from member.backends import PermissionBackend from note_kfet.middlewares import get_current_authenticated_user @@ -14,10 +16,6 @@ EXCLUDED = [ 'contenttypes.contenttype', 'logs.changelog', 'migrations.migration', - 'note.note', - 'note.noteuser', - 'note.noteclub', - 'note.notespecial', 'sessions.session', ] @@ -41,7 +39,7 @@ def pre_save_object(sender, instance, **kwargs): model_name = model_name_full[1] if qs.exists(): - if user.has_perm(app_label + ".change_" + model_name, instance): + if PermissionBackend().has_perm(user, app_label + ".change_" + model_name, instance): return previous = qs.get() @@ -51,10 +49,10 @@ def pre_save_object(sender, instance, **kwargs): new_value = getattr(instance, field.name) if old_value == new_value: continue - if not user.has_perm(app_label + ".change_" + model_name + "_" + field_name, instance): + if not PermissionBackend().has_perm(user, app_label + ".change_" + model_name + "_" + field_name, instance): raise PermissionDenied else: - if not user.has_perm(app_label + ".add_" + model_name, instance): + if not PermissionBackend().has_perm(user, app_label + ".add_" + model_name, instance): raise PermissionDenied @@ -75,5 +73,5 @@ def pre_delete_object(sender, instance, **kwargs): app_label = model_name_full[0] model_name = model_name_full[1] - if not user.has_perm(app_label + ".delete_" + model_name, instance): + if not PermissionBackend().has_perm(user, app_label + ".delete_" + model_name, instance): raise PermissionDenied diff --git a/apps/permission/templatetags/perms.py b/apps/permission/templatetags/perms.py index f65b606e..859f1ef2 100644 --- a/apps/permission/templatetags/perms.py +++ b/apps/permission/templatetags/perms.py @@ -10,10 +10,6 @@ from django import template from member.backends import PermissionBackend -def has_perm(value): - return get_current_authenticated_user().has_perm(value) - - @stringfilter def not_empty_model_list(model_name): user = get_current_authenticated_user() @@ -41,6 +37,5 @@ def not_empty_model_change_list(model_name): register = template.Library() -register.filter('has_perm', has_perm) register.filter('not_empty_model_list', not_empty_model_list) register.filter('not_empty_model_change_list', not_empty_model_change_list) diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py index 800c798e..1ebaf2b9 100644 --- a/note_kfet/settings/base.py +++ b/note_kfet/settings/base.py @@ -130,7 +130,6 @@ PASSWORD_HASHERS = [ # Django Guardian object permissions AUTHENTICATION_BACKENDS = ( - # 'django.contrib.auth.backends.ModelBackend', # this is default 'member.backends.PermissionBackend', 'cas.backends.CASBackend', )