mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-04 09:12:11 +01:00 
			
		
		
		
	Comment code
This commit is contained in:
		@@ -9,7 +9,6 @@ class PermissionConfig(AppConfig):
 | 
			
		||||
    name = 'permission'
 | 
			
		||||
 | 
			
		||||
    def ready(self):
 | 
			
		||||
        # noinspection PyUnresolvedReferences
 | 
			
		||||
        from . import signals
 | 
			
		||||
        pre_save.connect(signals.pre_save_object)
 | 
			
		||||
        pre_delete.connect(signals.pre_delete_object)
 | 
			
		||||
 
 | 
			
		||||
@@ -13,18 +13,31 @@ from member.models import Membership, Club
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PermissionBackend(ModelBackend):
 | 
			
		||||
    """
 | 
			
		||||
    Manage permissions of users
 | 
			
		||||
    """
 | 
			
		||||
    supports_object_permissions = True
 | 
			
		||||
    supports_anonymous_user = False
 | 
			
		||||
    supports_inactive_user = False
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def permissions(user, model, type):
 | 
			
		||||
        """
 | 
			
		||||
        List all permissions of the given user that applies to a given model and a give type
 | 
			
		||||
        :param user: The owner of the permissions
 | 
			
		||||
        :param model: The model that the permissions shoud apply
 | 
			
		||||
        :param type: The type of the permissions: view, change, add or delete
 | 
			
		||||
        :return: A generator of the requested permissions
 | 
			
		||||
        """
 | 
			
		||||
        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():
 | 
			
		||||
            if not isinstance(model, permission.model.__class__):
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            club = Club.objects.get(pk=permission.club)
 | 
			
		||||
            permission = permission.about(
 | 
			
		||||
                user=user,
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,10 @@ class InstancedPermission:
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
    def update_query(self):
 | 
			
		||||
        """
 | 
			
		||||
        The query is not analysed in a first time. It is analysed at most once if needed.
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        if not self.query:
 | 
			
		||||
            # noinspection PyProtectedMember
 | 
			
		||||
            self.query = Permission._about(self.raw_query, **self.kwargs)
 | 
			
		||||
@@ -72,6 +76,10 @@ class InstancedPermission:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PermissionMask(models.Model):
 | 
			
		||||
    """
 | 
			
		||||
    Permissions that are hidden behind a mask
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    rank = models.PositiveSmallIntegerField(
 | 
			
		||||
        unique=True,
 | 
			
		||||
        verbose_name=_('rank'),
 | 
			
		||||
@@ -106,9 +114,9 @@ class Permission(models.Model):
 | 
			
		||||
    #  query -> {key: value, …}              A list of fields and values of a Q object
 | 
			
		||||
    #  key   -> string                       A field name
 | 
			
		||||
    #  value -> int | string | bool | null   Literal values
 | 
			
		||||
    #         | [parameter]                  A parameter
 | 
			
		||||
    #         | [parameter, …]               A parameter. See compute_param for more details.
 | 
			
		||||
    #         | {"F": oper}                  An F object
 | 
			
		||||
    #  oper  -> [string]                     A parameter
 | 
			
		||||
    #  oper  -> [string, …]                  A parameter. See compute_param for more details.
 | 
			
		||||
    #         | ["ADD", oper, …]             Sum multiple F objects or literal
 | 
			
		||||
    #         | ["SUB", oper, oper]          Substract two F objects or literal
 | 
			
		||||
    #         | ["MUL", oper, …]             Multiply F objects or literals
 | 
			
		||||
@@ -164,6 +172,18 @@ class Permission(models.Model):
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def compute_param(value, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        A parameter is given by a list. The first argument is the name of the parameter.
 | 
			
		||||
        The parameters are the user, the club, and some classes (Note, ...)
 | 
			
		||||
        If there are more arguments in the list, then attributes are queried.
 | 
			
		||||
        For example, ["user", "note", "balance"] will return the balance of the note of the user.
 | 
			
		||||
        If an argument is a list, then this is interpreted with a function call:
 | 
			
		||||
            First argument is the name of the function, next arguments are parameters, and if there is a dict,
 | 
			
		||||
            then the dict is given as kwargs.
 | 
			
		||||
            For example: NoteUser.objects.filter(user__memberships__club__name="Kfet").all() is translated by:
 | 
			
		||||
            ["NoteUser", "objects", ["filter", {"user__memberships__club__name": "Kfet"}], ["all"]]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        if not isinstance(value, list):
 | 
			
		||||
            return value
 | 
			
		||||
 | 
			
		||||
@@ -192,6 +212,12 @@ class Permission(models.Model):
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def _about(query, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        Translate JSON query into a Q query.
 | 
			
		||||
        :param query: The JSON query
 | 
			
		||||
        :param kwargs: Additional params
 | 
			
		||||
        :return: A Q object
 | 
			
		||||
        """
 | 
			
		||||
        if len(query) == 0:
 | 
			
		||||
            # The query is either [] or {} and
 | 
			
		||||
            # applies to all objects of the model
 | 
			
		||||
@@ -204,6 +230,8 @@ class Permission(models.Model):
 | 
			
		||||
                return functools.reduce(operator.or_, [Permission._about(query, **kwargs) for query in query[1:]])
 | 
			
		||||
            elif query[0] == 'NOT':
 | 
			
		||||
                return ~Permission._about(query[1], **kwargs)
 | 
			
		||||
            else:
 | 
			
		||||
                return Q(pk=F("pk"))
 | 
			
		||||
        elif isinstance(query, dict):
 | 
			
		||||
            q_kwargs = {}
 | 
			
		||||
            for key in query:
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,11 @@ SAFE_METHODS = ('HEAD', 'OPTIONS', )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StrongDjangoObjectPermissions(DjangoObjectPermissions):
 | 
			
		||||
    """
 | 
			
		||||
    Default DjangoObjectPermissions grant view permission to all.
 | 
			
		||||
    This is a simple patch of this class that controls view access.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    perms_map = {
 | 
			
		||||
        'GET': ['%(app_label)s.view_%(model_name)s'],
 | 
			
		||||
        'OPTIONS': [],
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,9 @@ from permission.backends import PermissionBackend
 | 
			
		||||
 | 
			
		||||
@stringfilter
 | 
			
		||||
def not_empty_model_list(model_name):
 | 
			
		||||
    """
 | 
			
		||||
    Return True if and only if the current user has right to see any object of the given model.
 | 
			
		||||
    """
 | 
			
		||||
    user = get_current_authenticated_user()
 | 
			
		||||
    session = get_current_session()
 | 
			
		||||
    if user is None:
 | 
			
		||||
@@ -29,6 +32,9 @@ def not_empty_model_list(model_name):
 | 
			
		||||
 | 
			
		||||
@stringfilter
 | 
			
		||||
def not_empty_model_change_list(model_name):
 | 
			
		||||
    """
 | 
			
		||||
    Return True if and only if the current user has right to change any object of the given model.
 | 
			
		||||
    """
 | 
			
		||||
    user = get_current_authenticated_user()
 | 
			
		||||
    session = get_current_session()
 | 
			
		||||
    if user is None:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
from django.test import TestCase
 | 
			
		||||
 | 
			
		||||
# Create your tests here.
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
from django.shortcuts import render
 | 
			
		||||
 | 
			
		||||
# Create your views here.
 | 
			
		||||
		Reference in New Issue
	
	Block a user