Being superuser is not enough (must have the correct mask), add some initial fixtures

This commit is contained in:
Yohann D'ANELLO 2020-03-19 18:53:06 +01:00
parent 022997f923
commit 7794210cc8
9 changed files with 305 additions and 19 deletions

View File

@ -15,6 +15,7 @@ class ProfileSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Profile model = Profile
fields = '__all__' fields = '__all__'
read_only_fields = ('user', )
class ClubSerializer(serializers.ModelSerializer): class ClubSerializer(serializers.ModelSerializer):

View File

@ -178,6 +178,9 @@ class RolePermissions(models.Model):
'permission.Permission' 'permission.Permission'
) )
def __str__(self):
return str(self.role)
# @receiver(post_save, sender=settings.AUTH_USER_MODEL) # @receiver(post_save, sender=settings.AUTH_USER_MODEL)
# def save_user_profile(instance, created, **_kwargs): # def save_user_profile(instance, created, **_kwargs):

View File

@ -4,6 +4,7 @@
from rest_framework import serializers from rest_framework import serializers
from rest_polymorphic.serializers import PolymorphicSerializer from rest_polymorphic.serializers import PolymorphicSerializer
from member.backends import PermissionBackend
from note_kfet.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.notes import Note, NoteClub, NoteSpecial, NoteUser, Alias
from ..models.transactions import TransactionTemplate, Transaction, MembershipTransaction, TemplateCategory, \ from ..models.transactions import TransactionTemplate, Transaction, MembershipTransaction, TemplateCategory, \
@ -76,9 +77,10 @@ class AliasSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Alias model = Alias
fields = '__all__' fields = '__all__'
read_only_fields = ('note', )
def get_note(self, alias): 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) return NotePolymorphicSerializer().to_representation(alias.note)
else: else:
return alias.note.id return alias.note.id

View File

@ -19,4 +19,4 @@ class PermissionAdmin(admin.ModelAdmin):
""" """
Admin customisation for Permission Admin customisation for Permission
""" """
list_display = ('type', 'model', 'field', 'description') list_display = ('type', 'model', 'field', 'mask', 'description')

View File

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

View File

@ -14,18 +14,20 @@ from django.utils.translation import gettext_lazy as _
class InstancedPermission: class InstancedPermission:
def __init__(self, model, query, type, field): def __init__(self, model, query, type, field, mask):
self.model = model self.model = model
self.query = query self.query = query
self.type = type self.type = type
self.field = field self.field = field
self.mask = mask
def applies(self, obj, permission_type, field_name=None): def applies(self, obj, permission_type, field_name=None):
""" """
Returns True if the permission applies to Returns True if the permission applies to
the field `field_name` object `obj` 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 # The permission does not apply to the model
return False return False
@ -247,7 +249,7 @@ class Permission(models.Model):
""" """
query = json.loads(self.query) query = json.loads(self.query)
query = self._about(query, **kwargs) 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): def __str__(self):
if self.field: if self.field:

View File

@ -2,6 +2,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from member.backends import PermissionBackend
from note_kfet.middlewares import get_current_authenticated_user from note_kfet.middlewares import get_current_authenticated_user
@ -14,10 +16,6 @@ EXCLUDED = [
'contenttypes.contenttype', 'contenttypes.contenttype',
'logs.changelog', 'logs.changelog',
'migrations.migration', 'migrations.migration',
'note.note',
'note.noteuser',
'note.noteclub',
'note.notespecial',
'sessions.session', 'sessions.session',
] ]
@ -41,7 +39,7 @@ def pre_save_object(sender, instance, **kwargs):
model_name = model_name_full[1] model_name = model_name_full[1]
if qs.exists(): 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 return
previous = qs.get() previous = qs.get()
@ -51,10 +49,10 @@ def pre_save_object(sender, instance, **kwargs):
new_value = getattr(instance, field.name) new_value = getattr(instance, field.name)
if old_value == new_value: if old_value == new_value:
continue 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 raise PermissionDenied
else: 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 raise PermissionDenied
@ -75,5 +73,5 @@ def pre_delete_object(sender, instance, **kwargs):
app_label = model_name_full[0] app_label = model_name_full[0]
model_name = model_name_full[1] 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 raise PermissionDenied

View File

@ -10,10 +10,6 @@ from django import template
from member.backends import PermissionBackend from member.backends import PermissionBackend
def has_perm(value):
return get_current_authenticated_user().has_perm(value)
@stringfilter @stringfilter
def not_empty_model_list(model_name): def not_empty_model_list(model_name):
user = get_current_authenticated_user() user = get_current_authenticated_user()
@ -41,6 +37,5 @@ def not_empty_model_change_list(model_name):
register = template.Library() register = template.Library()
register.filter('has_perm', has_perm)
register.filter('not_empty_model_list', not_empty_model_list) register.filter('not_empty_model_list', not_empty_model_list)
register.filter('not_empty_model_change_list', not_empty_model_change_list) register.filter('not_empty_model_change_list', not_empty_model_change_list)

View File

@ -130,7 +130,6 @@ PASSWORD_HASHERS = [
# Django Guardian object permissions # Django Guardian object permissions
AUTHENTICATION_BACKENDS = ( AUTHENTICATION_BACKENDS = (
# 'django.contrib.auth.backends.ModelBackend', # this is default
'member.backends.PermissionBackend', 'member.backends.PermissionBackend',
'cas.backends.CASBackend', 'cas.backends.CASBackend',
) )