Skip to content
Snippets Groups Projects
Commit 09d856ae authored by Jean-Baptiste Pasquier's avatar Jean-Baptiste Pasquier
Browse files

Merge branch 'debugging' into 'master'

Overriding LDPViewset for POST permissions

See merge request !23
parents 4b533ae3 a29935b0
No related branches found
No related tags found
1 merge request!23Overriding LDPViewset for POST permissions
Pipeline #6007 passed
......@@ -7,6 +7,7 @@ from django.db.models.signals import pre_save, post_save
from django.dispatch import receiver
from djangoldp.models import Model
from .permissions import CirclePermissions, CircleMemberPermissions
from .views import CircleMembersViewset
MODEL_MODIFICATION_USER_FIELD = 'modification_user'
......@@ -56,10 +57,11 @@ class CircleMember(Model):
container_path = "circle-members/"
permission_classes = [CircleMemberPermissions]
anonymous_perms = []
authenticated_perms = []
owner_perms = []
authenticated_perms = ['view', 'add']
owner_perms = ['inherit']
unique_together = ['user', 'circle']
rdf_type='hd:circlemember'
rdf_type = 'hd:circlemember'
view_set = CircleMembersViewset
def save(self, *args, **kwargs):
if self.user:
......
......@@ -9,4 +9,5 @@ class User(AbstractUser, Model):
serializer_fields = ['@id', 'username', 'first_name', 'last_name', 'email']
anonymous_perms = ['view', 'add']
authenticated_perms = ['inherit', 'change']
owner_perms = ['inherit']
\ No newline at end of file
owner_perms = ['inherit']
nested_fields = ['circles']
\ No newline at end of file
......@@ -148,9 +148,40 @@ class PermissionsTestCase(APITestCase):
self.setUpCircle('Private', another_user)
response = self.client.post('/circles/1/members/', json.dumps({}), content_type='application/ld+json')
payload = {
'user': {'@id': self.user.urlid},
'circle': {'@id': self.circle.urlid},
'@context': {
'@vocab': "http://happy-dev.fr/owl/#",
'rdf': "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
'rdfs': "http://www.w3.org/2000/01/rdf-schema#",
'ldp': "http://www.w3.org/ns/ldp#",
'foaf': "http://xmlns.com/foaf/0.1/",
'name': "rdfs:label",
'acl': "http://www.w3.org/ns/auth/acl#",
'permissions': "acl:accessControl",
'mode': "acl:mode",
'inbox': "http://happy-dev.fr/owl/#inbox",
'object': "http://happy-dev.fr/owl/#object",
'author': "http://happy-dev.fr/owl/#author",
'account': "http://happy-dev.fr/owl/#account",
'jabberID': "foaf:jabberID",
'picture': "foaf:depiction",
'firstName': "http://happy-dev.fr/owl/#first_name",
'lastName': "http://happy-dev.fr/owl/#last_name",
'isAdmin': "http://happy-dev.fr/owl/#is_admin"
}
}
response = self.client.post('/circles/1/members/', json.dumps(payload), content_type='application/ld+json')
self.assertEqual(response.status_code, 403)
# TODO
'''payload.pop('user')
response = self.client.post('/users/{}/circles/'.format(self.user.pk), data=json.dumps(payload),
content_type='application/ld+json')
self.assertEqual(response.status_code, 403)'''
# adding a CircleMember - I am a member but not an admin
def test_post_circle_member(self):
self.setUpLoggedInUser()
......@@ -217,7 +248,7 @@ class PermissionsTestCase(APITestCase):
self.assertEqual(response.status_code, 204)
# adding a CircleMember - I am an admin
'''def test_post_circle_member_admin(self):
def test_post_circle_member_admin(self):
self.setUpLoggedInUser()
self.setUpCircle('Private', self.user)
......@@ -252,7 +283,7 @@ class PermissionsTestCase(APITestCase):
content_type='application/ld+json')
self.assertEqual(response.status_code, 201)
circle = Circle.objects.get(pk=self.circle.pk)
self.assertEqual(len(circle.members.all()), 2)'''
self.assertEqual(len(circle.members.all()), 2)
# adding a CircleMember - nested field
def test_post_circle_member_nested_admin(self):
......@@ -292,6 +323,15 @@ class PermissionsTestCase(APITestCase):
circle = Circle.objects.get(pk=self.circle.pk)
self.assertEqual(len(circle.members.all()), 2)
another_user = self._get_random_user()
body.pop('user')
response = self.client.post('/users/{}/circles/'.format(another_user.pk), data=json.dumps(body),
content_type='application/ld+json')
self.assertEqual(response.status_code, 201)
circle = Circle.objects.get(pk=self.circle.pk)
self.assertEqual(len(circle.members.all()), 3)
# removing a CircleMember - I am an admin
def test_delete_circle_member_admin(self):
self.setUpLoggedInUser()
......@@ -495,6 +535,76 @@ class PermissionsTestCase(APITestCase):
cm = CircleMember.objects.get(pk=1)
self.assertEqual(cm.circle.pk, self.circle.pk)
def test_hack_post_circle_member_to_admin(self):
self.setUpLoggedInUser()
another_user = self._get_random_user()
self.setUpCircle('Private', another_user)
payload = {
'circle': {'@id': self.circle.urlid},
'user': {'@id': self.user.urlid},
'is_admin': True,
'@context': {
'@vocab': "http://happy-dev.fr/owl/#",
'rdf': "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
'rdfs': "http://www.w3.org/2000/01/rdf-schema#",
'ldp': "http://www.w3.org/ns/ldp#",
'foaf': "http://xmlns.com/foaf/0.1/",
'name': "rdfs:label",
'acl': "http://www.w3.org/ns/auth/acl#",
'permissions': "acl:accessControl",
'mode': "acl:mode",
'inbox': "http://happy-dev.fr/owl/#inbox",
'object': "http://happy-dev.fr/owl/#object",
'author': "http://happy-dev.fr/owl/#author",
'account': "http://happy-dev.fr/owl/#account",
'jabberID': "foaf:jabberID",
'picture': "foaf:depiction",
'firstName': "http://happy-dev.fr/owl/#first_name",
'lastName': "http://happy-dev.fr/owl/#last_name",
'isAdmin': "http://happy-dev.fr/owl/#is_admin"
}
}
response = self.client.post('/circles/1/members/', data=json.dumps(payload), content_type='application/ld+json')
self.assertEqual(response.status_code, 403)
def test_hack_post_circle_member_again_to_admin(self):
self.setUpLoggedInUser()
another_user = self._get_random_user()
self.setUpCircle('Private', another_user)
CircleMember.objects.create(user=self.user, circle=self.circle, is_admin=False)
payload = {
'circle': {'@id': self.circle.urlid},
'user': {'@id': self.user.urlid},
'is_admin': True,
'@context': {
'@vocab': "http://happy-dev.fr/owl/#",
'rdf': "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
'rdfs': "http://www.w3.org/2000/01/rdf-schema#",
'ldp': "http://www.w3.org/ns/ldp#",
'foaf': "http://xmlns.com/foaf/0.1/",
'name': "rdfs:label",
'acl': "http://www.w3.org/ns/auth/acl#",
'permissions': "acl:accessControl",
'mode': "acl:mode",
'inbox': "http://happy-dev.fr/owl/#inbox",
'object': "http://happy-dev.fr/owl/#object",
'author': "http://happy-dev.fr/owl/#author",
'account': "http://happy-dev.fr/owl/#account",
'jabberID': "foaf:jabberID",
'picture': "foaf:depiction",
'firstName': "http://happy-dev.fr/owl/#first_name",
'lastName': "http://happy-dev.fr/owl/#last_name",
'isAdmin': "http://happy-dev.fr/owl/#is_admin"
}
}
self.client.post('/circles/1/members/', data=json.dumps(payload), content_type='application/ld+json')
self.assertFalse(CircleMember.objects.filter(user=self.user, circle=self.circle, is_admin=True).exists())
def test_update_circle_owner_distant(self):
self.setUpLoggedInUser()
self.setUpCircle('Public', self.user)
......
from djangoldp.filters import LocalObjectFilterBackend
from djangoldp.views import LDPViewSet
from djangoldp.models import Model
from djangoldp_circle.models import Circle
class CircleMembersViewset(LDPViewSet):
def is_safe_create(self, user, validated_data, *args, **kwargs):
from djangoldp_circle.models import Circle, CircleMember
try:
circle = Circle.objects.get(urlid=validated_data['circle']['urlid'])
# public circles any user can add
if circle.status == 'Public':
return True
# other circles any circle member can add a user
if circle.members.filter(user=user).exists():
return True
except Circle.DoesNotExist:
return True
return False
class CirclesJoinableViewset(LDPViewSet):
......
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