From 2954986dcabd79e178f58f5ae947492efda9d2af Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 13 Oct 2022 19:21:59 +0200 Subject: [PATCH 1/2] a2_rbac: add helper method to build permissions (#70152) --- src/authentic2/a2_rbac/models.py | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/authentic2/a2_rbac/models.py b/src/authentic2/a2_rbac/models.py index 7fefc0d2..72832775 100644 --- a/src/authentic2/a2_rbac/models.py +++ b/src/authentic2/a2_rbac/models.py @@ -18,6 +18,7 @@ import hashlib import os from collections import namedtuple +from django.apps import apps from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation @@ -314,6 +315,41 @@ class Permission(models.Model): "target": self.target.natural_key_json(), } + @classmethod + def from_str(cls, s, instance=None): + '''Build permission from a string of the form [ou_slug? app_label.model_operation]. + + The optional ou_slug is used to created OU scoped permissions. + An optional instance argument can be used to create a permission on an instance. + ''' + ou_slug = None + s = s.strip() + if ' ' in s: + ou_slug, permission = s.split() + else: + permission = s + app_label, operation_model = permission.split('.', 1) + operation, model = operation_model.split('_') + app = apps.get_app_config(app_label) + model_class = app.get_model(model) + + if instance is None: + permission, _ = Permission.objects.get_or_create( + operation=Operation.objects.get(slug=operation), + ou=OrganizationalUnit.objects.get(slug=ou_slug) if ou_slug else None, + target_ct=ContentType.objects.get_for_model(ContentType), + target_id=ContentType.objects.get_for_model(model_class).pk, + ) + else: + assert isinstance(instance, model_class), f'{instance} is not an instance of {model_class}' + permission, _ = Permission.objects.get_or_create( + operation=Operation.objects.get(slug=operation), + ou=OrganizationalUnit.objects.get(slug=ou_slug) if ou_slug else None, + target_ct=ContentType.objects.get_for_model(instance), + target_id=instance.pk, + ) + return permission + def __str__(self): ct = ContentType.objects.get_for_id(self.target_ct_id) ct_ct = ContentType.objects.get_for_model(ContentType) -- 2.37.2