From 57956aac65428609b9458ba77979f4edc051a2d7 Mon Sep 17 00:00:00 2001 From: Hangzhi Yu <hangzhi@protonmail.com> Date: Mon, 15 Jun 2020 16:25:29 +0200 Subject: [PATCH] Add method to inject permissions to ExtensibleModels dynamically Add method to inject permissions to ExtensibleModels dynamically --- aleksis/core/mixins.py | 9 +++++++++ aleksis/core/util/apps.py | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/aleksis/core/mixins.py b/aleksis/core/mixins.py index 8bff94086..88a01c15c 100644 --- a/aleksis/core/mixins.py +++ b/aleksis/core/mixins.py @@ -43,6 +43,8 @@ class _ExtensibleModelBase(models.base.ModelBase): # Register all non-abstract models with django-reversion mcls = reversion.register(mcls) + mcls.extra_permissions = [] + return mcls @@ -100,6 +102,8 @@ class ExtensibleModel(models.Model, metaclass=_ExtensibleModelBase): objects = CurrentSiteManager() objects_all_sites = models.Manager() + extra_permissions = [] + def get_absolute_url(self) -> str: """Get the URL o a view representing this model instance.""" pass @@ -226,6 +230,11 @@ class ExtensibleModel(models.Model, metaclass=_ExtensibleModelBase): """Collect all fields that can be synced on a model.""" return lazy(cls.syncable_fields_choices, tuple) + @classmethod + def add_permission(cls, name: str, verbose_name: str): + """Dynamically add a new permission to a model.""" + cls.extra_permissions.append((name, verbose_name)) + class Meta: abstract = True diff --git a/aleksis/core/util/apps.py b/aleksis/core/util/apps.py index d263feb9a..1d2b76881 100644 --- a/aleksis/core/util/apps.py +++ b/aleksis/core/util/apps.py @@ -189,6 +189,9 @@ class AppConfig(django.apps.AppConfig): pass def _maintain_default_data(self): + from django.contrib.auth.models import Permission + from django.contrib.contenttypes.models import ContentType + if not self.models_module: # This app does not have any models, so bail out early return @@ -197,3 +200,12 @@ class AppConfig(django.apps.AppConfig): if hasattr(model, "maintain_default_data"): # Method implemented by each model object; can be left out model.maintain_default_data() + if hasattr(model, "extra_permissions"): + ct = ContentType.objects.get_for_model(model) + for perm, verbose_name in model.extra_permissions: + Permission.objects.get_or_create( + codename=perm, + name=verbose_name, + content_type=ct + ) + -- GitLab