mirror of
https://github.com/pinry/pinry.git
synced 2025-11-13 16:45:41 +01:00
Make sure that users can't impersonate each other when creating pins
We weren't checking if the Pin submitter is the logged user which made it possible to pass any submitter to the Pin resource create call. Fix it, and make the submitter optional.
This commit is contained in:
@@ -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())
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user