diff --git a/pinry/core/api.py b/pinry/core/api.py index 0088aba..c516538 100644 --- a/pinry/core/api.py +++ b/pinry/core/api.py @@ -100,6 +100,20 @@ class PinResource(ModelResource): bundle.data['image'] = '/api/v1/image/{}/'.format(image.pk) return bundle + def hydrate(self, bundle): + """Run some early/generic processing + + Make sure that user is authorized to create Pins first, before + we hydrate the Image resource, creating the Image object in process + """ + submitter = bundle.data.get('submitter', None) + if not submitter: + bundle.data['submitter'] = '/api/v1/user/{}/'.format(bundle.request.user.pk) + else: + if not '/api/v1/user/{}/'.format(bundle.request.user.pk) == submitter: + raise Unauthorized("You are not authorized to create Pins for other users") + return bundle + def dehydrate_tags(self, bundle): return map(str, bundle.obj.tags.all()) diff --git a/pinry/core/tests/api.py b/pinry/core/tests/api.py index 8cffb0a..afed398 100644 --- a/pinry/core/tests/api.py +++ b/pinry/core/tests/api.py @@ -2,6 +2,7 @@ import mock from django_images.models import Thumbnail from taggit.models import Tag +from tastypie.exceptions import Unauthorized from tastypie.test import ResourceTestCase from .helpers import ImageFactory, PinFactory, UserFactory @@ -65,9 +66,10 @@ class PinResourceTest(ResourceTestCase): @mock.patch('requests.get', mock_requests_get) def test_post_create_url(self): + url = 'http://testserver/mocked/logo.png' post_data = { 'submitter': '/api/v1/user/1/', - 'url': 'http://testserver/mocked/logo.png', + 'url': url, 'description': 'That\'s an Apple!' } response = self.api_client.post('/api/v1/pin/', data=post_data) @@ -75,6 +77,15 @@ class PinResourceTest(ResourceTestCase): self.assertEqual(Pin.objects.count(), 1) self.assertEqual(Image.objects.count(), 1) + # submitter is optional, current user will be used by default + post_data = { + 'url': url, + 'description': 'That\'s an Apple!', + 'origin': None + } + response = self.api_client.post('/api/v1/pin/', data=post_data) + self.assertHttpCreated(response) + @mock.patch('requests.get', mock_requests_get) def test_post_create_url_with_empty_tags(self): url = 'http://testserver/mocked/logo.png' @@ -91,6 +102,20 @@ class PinResourceTest(ResourceTestCase): pin = Pin.objects.get(url=url) self.assertEqual(pin.tags.count(), 0) + @mock.patch('requests.get', mock_requests_get) + def test_post_create_url_unauthorized(self): + url = 'http://testserver/mocked/logo.png' + post_data = { + 'submitter': '/api/v1/user/2/', + 'url': url, + 'description': 'That\'s an Apple!', + 'tags': [] + } + with self.assertRaises(Unauthorized): + response = self.api_client.post('/api/v1/pin/', data=post_data) + self.assertEqual(Pin.objects.count(), 0) + self.assertEqual(Image.objects.count(), 0) + @mock.patch('requests.get', mock_requests_get) def test_post_create_url_with_empty_origin(self): url = 'http://testserver/mocked/logo.png'