diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py index 304933b9c260b642630f4bad29a24e21ebe10165..1af1ca6fc68eeb7d9b0dd1bc8cb5d8b587cfd291 100644 --- a/djangoldp/serializers.py +++ b/djangoldp/serializers.py @@ -3,6 +3,7 @@ from typing import Any from urllib import parse from django.conf import settings +from django.contrib.auth import get_user_model from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ValidationError as DjangoValidationError from django.core.urlresolvers import get_resolver, resolve, get_script_prefix, Resolver404 @@ -440,7 +441,8 @@ class LDPSerializer(HyperlinkedModelSerializer): slug_field = Model.slug_field(self.__class__.Meta.model) ret[slug_field] = match.kwargs[slug_field] except Resolver404: - pass + if 'urlid' in data: + ret['urlid'] = data['urlid'] return ret else: @@ -459,6 +461,15 @@ class LDPSerializer(HyperlinkedModelSerializer): serializer.id = '{}{}/'.format(serializer.id, kwargs['context']['view'].nested_field) return serializer + def to_internal_value(self, data): + user_case = self.Meta.model is get_user_model() and '@id' in data and not data['@id'].startswith(settings.BASE_URL) + if user_case: + data['username'] = 'external' + ret = super().to_internal_value(data) + if user_case: + ret['username'] = data['@id'] + return ret + def get_value(self, dictionary): try: object_list = dictionary["@graph"] @@ -532,6 +543,8 @@ class LDPSerializer(HyperlinkedModelSerializer): field_name in validated_data) and not field_name is None: many_to_many.append((field_name, validated_data.pop(field_name))) validated_data = self.remove_empty_value(validated_data) + if model is get_user_model() and 'urlid' in validated_data and not 'username' in validated_data: + validated_data['username'] = validated_data.pop('urlid') instance = model.objects.create(**validated_data) for field_name, value in many_to_many: @@ -561,9 +574,9 @@ class LDPSerializer(HyperlinkedModelSerializer): else: setattr(instance, attr, value) - instance.save() self.save_or_update_nested_list(instance, nested_fields) + instance.save() return instance diff --git a/djangoldp/tests/models.py b/djangoldp/tests/models.py index 8d6757635a775089c867996cbc851f8e441bdbef..cbc473d19dfda84e83a89daeb2de4af9dd6b2ab9 100644 --- a/djangoldp/tests/models.py +++ b/djangoldp/tests/models.py @@ -2,6 +2,10 @@ from django.conf import settings from django.contrib.auth import get_user_model from django.db import models from django.utils.datetime_safe import date +from django.urls import reverse_lazy + +import validators + from djangoldp.models import Model @@ -158,5 +162,26 @@ class Post(Model): owner_perms = ['inherit'] +class Circle(Model): + description = models.CharField(max_length=255) + team = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True) + + class Meta: + nested_fields = ["team"] + anonymous_perms = ['view', 'add', 'delete', 'add', 'change', 'control'] + authenticated_perms = ["inherit"] + rdf_type = 'hd:circle' + depth = 1 + +def webid(self): + # hack : We user webid as username for external user (since it's an uniq identifier too) + if validators.url(self.username): + webid = self.username + else: + webid = '{0}{1}'.format(settings.BASE_URL, reverse_lazy('user-detail', kwargs={'pk': self.pk})) + return webid + get_user_model()._meta.serializer_fields = ['@id', 'username', 'first_name', 'last_name', 'email', 'userprofile', - 'conversation_set', ] + 'conversation_set', 'circle_set'] +get_user_model().webid = webid +get_user_model()._meta.anonymous_perms=['view', 'add'] diff --git a/djangoldp/tests/tests_save.py b/djangoldp/tests/tests_save.py index 8885ecb3b1c563a07bd302923887582794c54154..0c97d5c356520adfa266c1b75a6c5426b95ebbd1 100644 --- a/djangoldp/tests/tests_save.py +++ b/djangoldp/tests/tests_save.py @@ -1,13 +1,25 @@ +from django.contrib.auth import get_user_model from django.test import TestCase +from rest_framework.test import APIRequestFactory, APIClient from rest_framework.utils import json from djangoldp.models import Model from djangoldp.serializers import LDPSerializer -from djangoldp.tests.models import Skill, JobOffer, Invoice, LDPDummy, Resource, Post +from djangoldp.tests.models import Skill, JobOffer, Invoice, LDPDummy, Resource, Post, Circle class Save(TestCase): + def setUp(self): + self.factory = APIRequestFactory() + self.client = APIClient() + self.user = get_user_model().objects.create_user(username='john', email='jlennon@beatles.com', + password='glass onion') + self.client.force_authenticate(self.user) + + def tearDown(self): + pass + def test_save_m2m_graph_with_many_nested(self): invoice = { "@graph": [ @@ -311,20 +323,18 @@ class Save(TestCase): content_type='application/ld+json') self.assertEqual(response.status_code, 201) saved_post = Post.objects.get(pk=1) - self.assertEqual(saved_post.urlid, "https://happy-dev.fr/posts/1/") + self.assertEqual(saved_post.urlid, "http://happy-dev.fr/posts/1/") - def test_auto_id(self): + def test_nested_container_user_federated(self): + circle = Circle.objects.create() body = { - '@id': "./", - 'content': "post update", - 'peer_user': "", - '@context': { - "@vocab": "http://happy-dev.fr/owl/#", - } + 'http://happy-dev.fr/owl/#@id': "http://external.user/user/1/", } - response = self.client.post('/posts/', data=json.dumps(body), + response = self.client.post('/circles/{}/team/'.format(circle.pk), + data=json.dumps(body), content_type='application/ld+json') self.assertEqual(response.status_code, 201) - saved_post = Post.objects.get(pk=1) - self.assertEqual(saved_post.urlid, "http://happy-dev.fr/posts/1/") + self.assertEqual(response.data['circle_set']['ldp:contains'][0]['@id'], + "http://testserver/circles/{}/".format(circle.pk)) + self.assertEqual(response.data['@id'], "http://external.user/user/1/") diff --git a/djangoldp/tests/tests_temp.py b/djangoldp/tests/tests_temp.py index eaef247795d1c2842633147f9a346149df3a459f..ef7792a2a2cb08b941457637778f05cb736becd5 100644 --- a/djangoldp/tests/tests_temp.py +++ b/djangoldp/tests/tests_temp.py @@ -2,44 +2,13 @@ from django.contrib.auth.models import User from django.test import TestCase from rest_framework.test import APIRequestFactory, APIClient -from djangoldp.tests.models import Resource - - class TestTemp(TestCase): def setUp(self): self.factory = APIRequestFactory() self.client = APIClient() self.user = User.objects.create_user(username='john', email='jlennon@beatles.com', password='glass onion') + self.client.force_authenticate(self.user) def tearDown(self): pass - - def test_nested_container_federated(self): - resource = Resource.objects.create() - body = { - 'http://happy-dev.fr/owl/#@id': "http://external.job/job/1", - } - - response = self.client.post('/resources/{}/joboffers/'.format(resource.pk), - data=json.dumps(body), - content_type='application/ld+json') - self.assertEqual(response.status_code, 201) - self.assertEqual(response.data['resources']['ldp:contains'][0]['@id'], "http://testserver/resources/{}/".format(resource.pk)) - self.assertEqual(response.data['@id'], "http://external.job/job/1") - - def test_m2m_new_link_federated(self): - resource = Resource.objects.create() - body = { - 'http://happy-dev.fr/owl/#joboffers': { - 'http://happy-dev.fr/owl/#@id': 'http://external.job/job/1', - } - } - - response = self.client.put('/resources/{}/'.format(resource.pk), - data=json.dumps(body), - content_type='application/ld+json') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.data['joboffers']['ldp:contains'][0]['@id'], - "http://external.job/job/1") - diff --git a/djangoldp/tests/tests_update.py b/djangoldp/tests/tests_update.py index 7db97dee730dc73f4dbdaffc8b7546cbdbb3a167..a9a7dca25d4582ecf4d16e21761c74c6f99c3755 100644 --- a/djangoldp/tests/tests_update.py +++ b/djangoldp/tests/tests_update.py @@ -4,7 +4,7 @@ from rest_framework.test import APIRequestFactory, APIClient from rest_framework.utils import json from djangoldp.serializers import LDPSerializer -from djangoldp.tests.models import Post, UserProfile, Resource +from djangoldp.tests.models import Post, UserProfile, Resource, Circle from djangoldp.tests.models import Skill, JobOffer, Conversation, Message @@ -492,3 +492,19 @@ class Update(TestCase): self.assertEqual(response.status_code, 200) self.assertEqual(response.data['joboffers']['ldp:contains'][0]['@id'], "http://external.job/job/1") + + def test_m2m_user_link_federated(self): + circle = Circle.objects.create(description="cicle name") + body = { + 'http://happy-dev.fr/owl/#description': 'circle name', + 'http://happy-dev.fr/owl/#team': { + 'http://happy-dev.fr/owl/#@id': 'http://external.user/user/1', + } + } + + response = self.client.put('/circles/{}/'.format(circle.pk), + data=json.dumps(body), + content_type='application/ld+json') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.data['team']['ldp:contains'][0]['@id'], + "http://external.user/user/1")