From f9058904902e30a9dcf52e5ed417d330c616a389 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Wed, 12 Oct 2022 10:52:43 +0200 Subject: [PATCH] wip --- src/django_rbac/backends.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/django_rbac/backends.py b/src/django_rbac/backends.py index edd7389e..5a43f062 100644 --- a/src/django_rbac/backends.py +++ b/src/django_rbac/backends.py @@ -1,9 +1,11 @@ import copy import functools +from django.apps import apps from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.core.exceptions import FieldDoesNotExist +from django.db import models from django.db.models.query import Q from . import utils @@ -20,6 +22,26 @@ def get_fk_model(model, fieldname): return field.related_model +_MODEL_INHERITANCE = None + + +def get_model_inheritance(): + global _MODEL_INHERITANCE + + if _MODEL_INHERITANCE is not None: + return _MODEL_INHERITANCE + _MODEL_INHERITANCE = {} + for app in apps.get_app_configs(): + for model in app.get_models(): + for parent in model.__bases__: + if issubclass(parent, models.Model): + _MODEL_INHERITANCE.setdefault(parent, set()).add(model) + + +def get_model_child_classes(model): + return get_model_inheritance().get(model) or () + + class DjangoRBACBackend: _DEFAULT_DJANGO_RBAC_PERMISSIONS_HIERARCHY = { 'view': ['search'], @@ -59,6 +81,7 @@ class DjangoRBACBackend: target = ContentType.objects.get_for_id(permission.target_id) app_label = target.app_label model = target.model + model_child_classes = get_model_child_classes(target.model_class) if permission.ou_id: key = 'ou.%s' % permission.ou_id else: @@ -66,9 +89,14 @@ class DjangoRBACBackend: else: app_label = target_ct.app_label model = target_ct.model + model_child_classes = get_model_child_classes(target_ct.model_class) key = '%s.%s' % (permission.target_ct_id, permission.target_id) slug = permission.operation.slug - perms = [str('%s.%s_%s' % (app_label, slug, model))] + perms = ['%s.%s_%s' % (app_label, slug, model)] + for model_child_class in model_child_classes: + perms.append( + f'{model_child_class._meta.app_label}.{slug}_{model_child_class._meta.model_name}' + ) perm_hierarchy = getattr( settings, 'DJANGO_RBAC_PERMISSIONS_HIERARCHY', @@ -77,6 +105,11 @@ class DjangoRBACBackend: if slug in perm_hierarchy: for other_perm in perm_hierarchy[slug]: perms.append(str('%s.%s_%s' % (app_label, other_perm, model))) + for model_child_class in model_child_classes: + for other_perm in perm_hierarchy[slug]: + perms.append( + f'{model_child_class._meta.app_label}.{other_perm}_{model_child_class._meta.model_name}' + ) permissions = perms_cache.setdefault(key, set()) permissions.update(perms) # optimization for has_module_perms -- 2.37.2