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:
Krzysztof Klimonda
2013-04-05 19:34:31 +02:00
parent 3b10868832
commit c0bf9d992e
2 changed files with 40 additions and 1 deletions

View File

@@ -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())

View File

@@ -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'