Skip to content
Snippets Groups Projects
Commit 55edbb37 authored by Thibaud's avatar Thibaud
Browse files

Merge branch '84-permissions-empty' into 'master'

Resolve "AnonymousReadOnly permissions empty"

Closes #84

See merge request startinblox/djangoldp-packages/djangoldp!33
parents 0b6e9b0c 576dd2c1
No related branches found
No related tags found
1 merge request!33Resolve "AnonymousReadOnly permissions empty"
Pipeline #784 passed with stage
in 1 minute and 20 seconds
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,12 @@ class WACPermissions(permissions.DjangoObjectPermissions):
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}
def has_permission(self, request, view):
if request.method == 'OPTIONS':
return True
return super().has_permission(request, view)
else:
return super().has_permission(request, view)
class ObjectFilter(filters.BaseFilterBackend):
......@@ -41,15 +43,41 @@ 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 InboxPermissions(WACPermissions):
"""
Anonymous users: can create notifications but can't read
Logged in users: can create notifications but can't read
Inbox owners: can read + update all notifications
"""
filter_class = ObjectFilter
def has_permission(self, request, view):
if view.action in ['create', 'retrieve', 'update', 'partial_update', 'destroy']:
return True
else:
return super().has_permission(request, view)
def has_object_permission(self, request, view, obj):
if view.action == "create":
return True
if hasattr(obj._meta, 'auto_author'):
if request.user == getattr(obj, obj._meta.auto_author):
return True
return super().has_object_permission(request, view)
class AnonymousReadOnly(permissions.DjangoObjectPermissions):
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
"""
anonymous_perms = [{'mode': {'@type': 'view'}}]
authenticated_perms = [{'mode': {'@type': 'view'}}, {'mode': {'@type': 'add'}}]
author_perms = [{'mode': {'@type': 'view'}}, {'mode': {'@type': 'add'}}, {'mode': {'@type': 'change'}}]
def has_permission(self, request, view):
if view.action in ['list', 'retrieve']:
return True
......@@ -67,27 +95,4 @@ class AnonymousReadOnly(permissions.DjangoObjectPermissions):
if author == request.user:
return True
else:
return super().has_object_permission(request, view, obj)
class InboxPermissions(permissions.DjangoObjectPermissions):
"""
Anonymous users: can create notifications but can't read
Logged in users: can create notifications but can't read
Inbox owners: can read + update all notifications
"""
filter_class = ObjectFilter
def has_permission(self, request, view):
if view.action in ['create', 'retrieve', 'update', 'partial_update', 'destroy']:
return True
else:
return super().has_permission(request, view)
def has_object_permission(self, request, view, obj):
if view.action == "create":
return True
if hasattr(obj._meta, 'auto_author'):
if request.user == getattr(obj, obj._meta.auto_author):
return True
return super().has_object_permission(request, view)
return super().has_object_permission(request, view, obj)
\ No newline at end of file
......@@ -19,6 +19,7 @@ from rest_framework.utils.serializer_helpers import ReturnDict
from djangoldp.fields import LDPUrlField, IdURLField
from djangoldp.models import Model
from djangoldp import permissions
class LDListMixin:
......@@ -202,6 +203,18 @@ class LDPSerializer(HyperlinkedModelSerializer):
data['@type'] = obj._meta.rdf_type
data['permissions'] = [{'mode': {'@type': name.split('_')[0]}} for name in
get_perms(self.context['request'].user, obj)]
if self.context['request'].user.is_anonymous:
data['permissions'] += permissions.AnonymousReadOnly.anonymous_perms
elif self.context['request'].user.is_authenticated:
if hasattr(obj._meta, 'auto_author'):
data['permissions'] += permissions.AnonymousReadOnly.author_perms
else:
data['permissions'] += permissions.AnonymousReadOnly.authenticated_perms
if hasattr(obj._meta, 'rdf_context'):
data['@context'] = obj._meta.rdf_context
return data
def build_standard_field(self, field_name, model_field):
......
from django.contrib.auth.models import AnonymousUser
from django.test import TestCase, RequestFactory
from guardian.shortcuts import get_anonymous_user
from djangoldp.permissions import AnonymousReadOnly
from djangoldp.tests.models import JobOffer
from djangoldp.views import LDPViewSet
......@@ -9,8 +11,8 @@ from djangoldp.views import LDPViewSet
class TestAnonymousUserPermissions(TestCase):
def setUp(self):
self.factory = RequestFactory()
# self.c = Client()
self.user = AnonymousUser
self.user = get_anonymous_user()
self.job = JobOffer.objects.create(title="job")
def test_get_request_with_anonymousUser(self):
request = self.factory.get("/job-offers/")
......@@ -18,26 +20,36 @@ class TestAnonymousUserPermissions(TestCase):
my_view = LDPViewSet.as_view({'get': 'list'},
model=JobOffer,
nested_fields=["skills"],
permission_classes=[AnonymousReadOnly])
permission_classes=(AnonymousReadOnly,))
response = my_view(request)
self.assertEqual(response.status_code, 200)
def test_request_options_create_with_anonymousUser(self):
request = self.factory.options("/job-offers/")
def test_post_request_with_anonymousUser(self):
request = self.factory.post("/job-offers/")
request.user = self.user
my_view = LDPViewSet.as_view({'options': 'create'},
my_view = LDPViewSet.as_view({'post': 'create'},
model=JobOffer,
nested_fields=["skills"],
permission_classes=[AnonymousReadOnly])
permission_classes=(AnonymousReadOnly,))
response = my_view(request)
self.assertEqual(response.status_code, 403)
def test_request_options_update_with_anonymousUser(self):
request = self.factory.options("/job-offers/")
def test_put_request_with_anonymousUser(self):
request = self.factory.put("/job-offers/")
request.user = self.user
my_view = LDPViewSet.as_view({'options': 'update'},
my_view = LDPViewSet.as_view({'put': 'update'},
model=JobOffer,
nested_fields=["skills"],
permission_classes=[AnonymousReadOnly])
response = my_view(request)
permission_classes=(AnonymousReadOnly,))
response = my_view(request, pk=self.job.pk)
self.assertEqual(response.status_code, 403)
def test_patch_request_with_anonymousUser(self):
request = self.factory.patch("/job-offers/")
request.user = self.user
my_view = LDPViewSet.as_view({'patch': 'partial_update'},
model=JobOffer,
nested_fields=["skills"],
permission_classes=(AnonymousReadOnly,))
response = my_view(request, pk=self.job.pk)
self.assertEqual(response.status_code, 403)
\ No newline at end of file
......@@ -9,7 +9,6 @@ from djangoldp.views import LDPViewSet
class TestUserPermissions(TestCase):
def setUp(self):
self.factory = RequestFactory()
# self.c = Client()
self.user = User.objects.create_user(username='john', email='jlennon@beatles.com', password='glass onion')
self.job = JobOffer.objects.create(title="job")
......@@ -24,24 +23,24 @@ class TestUserPermissions(TestCase):
response = my_view(request)
self.assertEqual(response.status_code, 200)
def test_request_options_create_with_user(self):
def test_post_request_with_user(self):
request = self.factory.options('/job-offers/')
request.user = self.user
my_view = LDPViewSet.as_view({'options': 'create'}, model=JobOffer, nested_fields=["skills"],
my_view = LDPViewSet.as_view({'post': 'create'}, model=JobOffer, nested_fields=["skills"],
permission_classes=[AnonymousReadOnly])
response = my_view(request)
self.assertEqual(response.status_code, 201)
self.assertEqual(response.status_code, 200)
def test_request_options_update_with_user(self):
def test_put_request_with_user(self):
request = self.factory.options('/job-offers/' + str(self.job.pk) + "/")
request.user = self.user
my_view = LDPViewSet.as_view({'options': 'update'}, model=JobOffer, nested_fields=["skills"],
my_view = LDPViewSet.as_view({'put': 'update'}, model=JobOffer, nested_fields=["skills"],
permission_classes=[AnonymousReadOnly])
response = my_view(request, pk=self.job.pk)
self.assertEqual(response.status_code, 200)
def test_request_patch_with_user(self):
request = self.factory.patch('/job-offers/' + str(self.job.pk) + "/")
request = self.factory.options('/job-offers/' + str(self.job.pk) + "/")
request.user = self.user
my_view = LDPViewSet.as_view({'patch': 'partial_update'}, model=JobOffer, nested_fields=["skills"])
response = my_view(request, pk=self.job.pk)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment