Commit 43efee48 authored by Calum Mackervoy's avatar Calum Mackervoy

django guardian permissions returned in user_permissions

parent 780ba31d
Pipeline #7268 passed with stage
in 1 minute and 25 seconds
......@@ -21,6 +21,7 @@ class Model(models.Model):
@classmethod
def get_view_set(cls):
'''returns the view_set defined in the model Meta or the LDPViewSet class'''
view_set = getattr(cls._meta, 'view_set', getattr(cls.Meta, 'view_set', None))
if view_set is None:
from djangoldp.views import LDPViewSet
......@@ -29,6 +30,7 @@ class Model(models.Model):
@classmethod
def get_container_path(cls):
'''returns the url path which is used to access actions on this model (e.g. /users/)'''
path = getattr(cls._meta, 'container_path', getattr(cls.Meta, 'container_path', None))
if path is None:
path = "{}s".format(cls._meta.object_name.lower())
......@@ -123,6 +125,7 @@ class Model(models.Model):
@classonlymethod
def __clean_path(cls, path):
'''ensures path is Django-friendly'''
if not path.startswith("/"):
path = "/{}".format(path)
if not path.endswith("/"):
......@@ -131,10 +134,12 @@ class Model(models.Model):
@classonlymethod
def get_permission_classes(cls, related_model, default_permissions_classes):
'''returns the permission_classes set in the models Meta class'''
return cls.get_meta(related_model, 'permission_classes', default_permissions_classes)
@classonlymethod
def get_meta(cls, model_class, meta_name, default=None):
'''returns the models Meta class'''
if hasattr(model_class, 'Meta'):
meta = getattr(model_class.Meta, meta_name, default)
else:
......@@ -150,6 +155,7 @@ class Model(models.Model):
@classmethod
def is_external(cls, value):
'''returns True if the urlid of the value passed is from an external source'''
try:
return value.urlid is not None and not value.urlid.startswith(settings.SITE_URL)
except:
......@@ -189,6 +195,7 @@ if 'djangoldp_account' not in settings.DJANGOLDP_PACKAGES:
# hack : We user webid as username for external user (since it's an uniq identifier too)
if validators.url(self.username):
webid = self.username
# unable to use username, so use user-detail URL with primary key
else:
webid = '{0}{1}'.format(settings.BASE_URL, reverse_lazy('user-detail', kwargs={'pk': self.pk}))
return webid
......
from django.core.exceptions import PermissionDenied
from django.db.models.base import ModelBase
from rest_framework.permissions import BasePermission
from guardian.shortcuts import get_perms
class LDPPermissions(BasePermission):
"""
Default permissions
Anon: None
Auth: None but herit from Anon
Ownr: None but herit from Auth
Auth: None but inherit from Anon
Owner: None but inherit from Auth
"""
anonymous_perms = ['view']
authenticated_perms = ['inherit']
......@@ -19,7 +20,7 @@ class LDPPermissions(BasePermission):
Filter user permissions for a model class
"""
# sorted out param mess
# this may be a permission for the model class, or an instance
if isinstance(obj_or_model, ModelBase):
model = obj_or_model
else:
......@@ -41,18 +42,39 @@ class LDPPermissions(BasePermission):
if 'inherit' in owner_perms:
owner_perms = owner_perms + list(set(authenticated_perms) - set(owner_perms))
# return permissions
# apply Django-Guardian (object-level) permissions
perms = []
if obj is not None:
guardian_perms = get_perms(user, obj)
model_name = model._meta.model_name
print('model_name is ' + model_name)
print('guardian_perms are ' + str(guardian_perms))
# remove model name from the permissions
forbidden_string = "_" + model_name
perms = [p.replace(forbidden_string, '') for p in guardian_perms]
print('before applying anon, owner, auth: ' + str(perms))
if user.is_anonymous():
return anonymous_perms
print('is_anonymous ' + str(anonymous_perms))
perms = perms + anonymous_perms
else:
if obj and hasattr(model._meta, 'owner_field') and (
getattr(obj, getattr(model._meta, 'owner_field')) == user
or getattr(obj, getattr(model._meta, 'owner_field')) == user.urlid
or getattr(obj, getattr(model._meta, 'owner_field')) == user.id):
return owner_perms
print('is_owner ' + str(owner_perms))
perms = perms + owner_perms
else:
return authenticated_perms
print('is_authenticated ' + str(authenticated_perms))
perms = perms + authenticated_perms
print('returning perms ' + str(perms))
return perms
def filter_user_perms(self, user, obj_or_model, permissions):
# Only used on Model.get_permissions to translate permissions to LDP
......
......@@ -10,6 +10,7 @@ from djangoldp.views import LDPViewSet
def __clean_path(path):
'''ensures path is Django-friendly'''
if path.startswith("/"):
path = path[1:]
if not path.endswith("/"):
......@@ -29,11 +30,15 @@ for package in settings.DJANGOLDP_PACKAGES:
except ModuleNotFoundError:
pass
# fetch a list of all models which subclass DjangoLDP Model
model_classes = {cls.__name__: cls for cls in Model.__subclasses__()}
# append urls for all DjangoLDP Model subclasses
for class_name in model_classes:
model_class = model_classes[class_name]
# the path is the url for this model
path = __clean_path(model_class.get_container_path())
# urls_fct will be a method which generates urls for a ViewSet (defined in LDPViewSet)
urls_fct = model_class.get_view_set().urls
urlpatterns.append(url(r'^' + path, include(
urls_fct(model=model_class,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment