diff --git a/djangoldp/permissions.py b/djangoldp/permissions.py index 49ef6a968cbbced48ec4b78b1fbcb901795f6b87..8ee9a441d1972e2083d84cd93df5fec4041868a1 100644 --- a/djangoldp/permissions.py +++ b/djangoldp/permissions.py @@ -1,6 +1,6 @@ from rest_framework import permissions from rest_framework import filters -from guardian.shortcuts import get_objects_for_user, get_user_perms +from guardian.shortcuts import get_objects_for_user """ Liste des actions passées dans views selon le protocole REST : @@ -26,10 +26,23 @@ class WACPermissions(permissions.DjangoObjectPermissions): 'PATCH': ['%(app_label)s.change_%(model_name)s'], 'DELETE': ['%(app_label)s.delete_%(model_name)s'], } + + # All LDP permissions must extnd WACPermissions. Otherwise there + # will be problems when view is nons. + def has_permission(self, request, view): if request.method == 'OPTIONS': return True - return super().has_permission(request, view) + elif view: + return super().has_permission(request, view) + else: + return False + + def has_object_permission(self, request, view, obj): + if view: + return super().has_object_permission(request, view, obj) + else: + return False class ObjectFilter(filters.BaseFilterBackend): @@ -41,36 +54,10 @@ class ObjectFilter(filters.BaseFilterBackend): objects = get_objects_for_user(request.user, perm, klass=queryset) return objects -class ObjectPermission(permissions.DjangoObjectPermissions): +class ObjectPermission(WACPermissions): filter_class = ObjectFilter -class AnonymousReadOnly(permissions.DjangoObjectPermissions): - """ - Anonymous users: can read all posts - Logged in users: can read all posts + create new posts - Author: can read all posts + create new posts + update their own - """ - def has_permission(self, request, view): - if view.action in ['list', 'retrieve']: - return True - else: - return super().has_permission(request, view) - - def has_object_permission(self, request, view, obj): - if view.action == "create" and request.user.is_authenticated(): - return True - elif view.action == "retrieve": - return True - elif view.action in ['update', 'partial_update', 'destroy']: - if hasattr(obj._meta, 'auto_author'): - author = getattr(obj, obj._meta.auto_author) - if author == request.user: - return True - else: - return super().has_object_permission(request, view, obj) - - -class InboxPermissions(permissions.DjangoObjectPermissions): +class InboxPermissions(WACPermissions): """ Anonymous users: can create notifications but can't read Logged in users: can create notifications but can't read @@ -91,3 +78,27 @@ class InboxPermissions(permissions.DjangoObjectPermissions): return True return super().has_object_permission(request, view) +class AnonymousReadOnly(WACPermissions): + """ + Anonymous users: can read all posts + Logged in users: can read all posts + create new posts + Author: can read all posts + create new posts + update their own + """ + def has_permission(self, request, view): + if request.method == "GET": + return True + else: + return super().has_permission(request, view) + return False + + def has_object_permission(self, request, view, obj): + if request.method == "GET": + return True + elif request.method == "POST" and request.user.is_authenticated(): + return True + elif request.method in ('PUT', 'PATCH'): + if hasattr(obj._meta, 'auto_author'): + author = getattr(obj, obj._meta.auto_author) + if author == request.user: + return True + return False \ No newline at end of file diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py index f1ef3e8ba76833a53cec6df719f3e3027a882e7d..9ea4d717bc61a918e765b692f20b18ca7d6373ea 100644 --- a/djangoldp/serializers.py +++ b/djangoldp/serializers.py @@ -24,6 +24,7 @@ from rest_framework.utils.field_mapping import get_nested_relation_kwargs from rest_framework.utils.serializer_helpers import ReturnDict from djangoldp.fields import LDPUrlField, IdURLField +from djangoldp import permissions class LDListMixin: def to_internal_value(self, data): @@ -199,7 +200,24 @@ class LDPSerializer(HyperlinkedModelSerializer): get_perms(self.context['request'].user, obj)] if hasattr(obj._meta, 'permission_classes'): - data['permissions'] += [{'mode': {'@type':str(perm.__name__)}} for perm in obj._meta.permission_classes] + currentRequest = self.context['request'] + permList = obj._meta.permission_classes + if permList: + for perm in permList: + if issubclass (perm, permissions.WACPermissions): + allowed = perm.has_permission(perm, currentRequest, None) + + if allowed: + allowed = perm.has_object_permission(perm, currentRequest, None, obj) + + if allowed and currentRequest.method == 'GET': + data['permissions'] += [{'mode': {'@type': 'view'}}] + elif allowed and currentRequest.method == 'POST': + data['permissions'] += [{'mode': {'@type': 'add'}}] + elif allowed and currentRequest.method == 'PUT': + data['permissions'] += [{'mode': {'@type': 'change'}}] + elif allowed and currentRequest.method == 'PATCH': + data['permissions'] += [{'mode': {'@type': 'change'}}] if hasattr(obj._meta, 'rdf_context'): data['@context'] = obj._meta.rdf_context