diff --git a/Pipfile b/Pipfile index 7d06bd66c..e8b869cd6 100644 --- a/Pipfile +++ b/Pipfile @@ -35,6 +35,7 @@ service_identity = "*" signxml = "*" urllib3 = {extras = ["secure"],version = "*"} structlog = "*" +django-guardian = "*" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index e5445b4e3..596080e81 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "53d7190ea62f504dc1a36eae952a273e0b2d9f313f23031099d039c3146235b7" + "sha256": "1636ead76bcc61736245f5255a6dfafbf261c3b37b1a2b2665db50919b4cb1ea" }, "pipfile-spec": 6, "requires": { @@ -101,10 +101,10 @@ }, "cheroot": { "hashes": [ - "sha256:6168371ab9aaf574ac5f75675f244bbfebf990202bf75048065e9d675b9ae719", - "sha256:8cc7c28961db2e13d0cac6b234a589a314c1844f7bbf54e67888ac9a2e25ac59" + "sha256:709259ea832932fb4e1c040b87836a260d386155098c7e138fc317937763e7ae", + "sha256:abba64f5f0d09b3b8bddf98fa18df1176cd83728b220a995e061c1a766e20a45" ], - "version": "==7.0.0" + "version": "==8.0.0" }, "cherrypy": { "hashes": [ @@ -180,6 +180,14 @@ "index": "pypi", "version": "==0.2.1" }, + "django-guardian": { + "hashes": [ + "sha256:8cf4efd67a863eb32beafd4335a38ffb083630f8ab2045212d27f8f9c3abe5a6", + "sha256:e638c9a23eeac534bb68b133975539ed8782f733ab6f35c0b23b4c39cd06b1bb" + ], + "index": "pypi", + "version": "==2.1.0" + }, "django-ipware": { "hashes": [ "sha256:a7c7a8fd019dbdc9c357e6e582f65034e897572fc79a7e467674efa8aef9d00b" @@ -459,10 +467,10 @@ }, "pyasn1-modules": { "hashes": [ - "sha256:43c17a83c155229839cc5c6b868e8d0c6041dba149789b6d6e28801c64821722", - "sha256:e30199a9d221f1b26c885ff3d87fd08694dbbe18ed0e8e405a2a7126d30ce4c0" + "sha256:0c35a52e00b672f832e5846826f1fb7507907f7d52fba6faa9e3c4cbe874fe4b", + "sha256:b6ada4f840fe51abf5a6bd545b45bf537bea62221fa0dde2e8a553ed9f06a4e3" ], - "version": "==0.2.6" + "version": "==0.2.7" }, "pycparser": { "hashes": [ diff --git a/passbook/core/models.py b/passbook/core/models.py index ee433b7f5..301e1d878 100644 --- a/passbook/core/models.py +++ b/passbook/core/models.py @@ -11,6 +11,7 @@ from django.db import models from django.urls import reverse_lazy from django.utils.timezone import now from django.utils.translation import gettext as _ +from guardian.mixins import GuardianUserMixin from model_utils.managers import InheritanceManager from structlog import get_logger @@ -41,7 +42,7 @@ class Group(UUIDModel): unique_together = (('name', 'parent',),) -class User(AbstractUser): +class User(GuardianUserMixin, AbstractUser): """Custom User model to allow easier adding o f user-based settings""" uuid = models.UUIDField(default=uuid4, editable=False) diff --git a/passbook/lib/admin.py b/passbook/lib/admin.py index e76b90b73..c0ddefa72 100644 --- a/passbook/lib/admin.py +++ b/passbook/lib/admin.py @@ -4,6 +4,7 @@ from django.apps import apps from django.contrib import admin from django.contrib.admin.sites import AlreadyRegistered from django.contrib.auth.admin import UserAdmin +from guardian.admin import GuardedModelAdmin from passbook.core.models import User @@ -13,10 +14,9 @@ def admin_autoregister(app): app_models = apps.get_app_config(app).get_models() for model in app_models: try: - admin.site.register(model) + admin.site.register(model, GuardedModelAdmin) except AlreadyRegistered: pass admin.site.register(User, UserAdmin) -admin_autoregister('passbook_core') diff --git a/passbook/lib/views.py b/passbook/lib/views.py new file mode 100644 index 000000000..64d1c761b --- /dev/null +++ b/passbook/lib/views.py @@ -0,0 +1,16 @@ +"""passbook helper views""" + +from django.views.generic import CreateView +from guardian.shortcuts import assign_perm + + +class CreateAssignPermView(CreateView): + """Assign permissions to object after creation""" + + permissions = [] + + def form_valid(self, form): + response = super().form_valid(form) + for permission in self.permissions: + assign_perm(permission, self.request.user, self.object) + return response diff --git a/passbook/root/settings.py b/passbook/root/settings.py index e09dfe6eb..fd2779406 100644 --- a/passbook/root/settings.py +++ b/passbook/root/settings.py @@ -53,10 +53,10 @@ LANGUAGE_COOKIE_NAME = 'passbook_language' AUTHENTICATION_BACKENDS = [ 'django.contrib.auth.backends.ModelBackend', + 'guardian.backends.ObjectPermissionBackend', ] # Application definition - INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', @@ -67,6 +67,8 @@ INSTALLED_APPS = [ 'django.contrib.postgres', # 'rest_framework', # 'drf_yasg', + 'guardian', + 'passbook.core.apps.PassbookCoreConfig', 'passbook.admin.apps.PassbookAdminConfig', 'passbook.api.apps.PassbookAPIConfig', @@ -97,6 +99,8 @@ INSTALLED_APPS = [ 'passbook.policies.webhook.apps.PassbookPoliciesWebhookConfig', ] +GUARDIAN_MONKEY_PATCH = False + REST_FRAMEWORK = { # Use Django's standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users.