Skip to content

Commit

Permalink
fixed authorization if auth function returns False
Browse files Browse the repository at this point in the history
* added mock to allow easier overwritting of auth
  functions
* tested when authorization *_detail function returns
  False - tests were failing. i.e. request was
  authorized, when it shouldn't have been
* updated code to raise an Unauthorized if *_detail
  functions return False
  • Loading branch information
Yoav Aner authored and toastdriven committed Mar 15, 2013
1 parent 905ae88 commit 2dff249
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
8 changes: 8 additions & 0 deletions tastypie/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,8 @@ def authorized_read_detail(self, object_list, bundle):
"""
try:
auth_result = self._meta.authorization.read_detail(object_list, bundle)
if not auth_result is True:
raise Unauthorized()
except Unauthorized, e:
self.unauthorized_result(e)

Expand All @@ -625,6 +627,8 @@ def authorized_create_detail(self, object_list, bundle):
"""
try:
auth_result = self._meta.authorization.create_detail(object_list, bundle)
if not auth_result is True:
raise Unauthorized()
except Unauthorized, e:
self.unauthorized_result(e)

Expand All @@ -649,6 +653,8 @@ def authorized_update_detail(self, object_list, bundle):
"""
try:
auth_result = self._meta.authorization.update_detail(object_list, bundle)
if not auth_result is True:
raise Unauthorized()
except Unauthorized, e:
self.unauthorized_result(e)

Expand All @@ -673,6 +679,8 @@ def authorized_delete_detail(self, object_list, bundle):
"""
try:
auth_result = self._meta.authorization.delete_detail(object_list, bundle)
if not auth_result:
raise Unauthorized()
except Unauthorized, e:
self.unauthorized_result(e)

Expand Down
34 changes: 32 additions & 2 deletions tests/authorization/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
from django.contrib.sites.models import Site
from tastypie.test import ResourceTestCase
from .models import AuthorProfile, Article
from .api.resources import PerUserAuthorization
try:
import simplejson as json
except ImportError:
import json

import mock

class PerUserAuthorizationTestCase(ResourceTestCase):
def setUp(self):
Expand Down Expand Up @@ -115,6 +116,11 @@ def test_get_detail(self):
self.assertKeys(second_article, ['added_on', 'authors', 'content', 'id', 'resource_uri', 'slug', 'title'])
self.assertEqual(second_article['id'], self.article_2.pk)

@mock.patch.object(PerUserAuthorization, "read_detail", lambda *args: False)
def test_get_unauthorized_detail(self):
resp = self.api_client.get(self.article_uri_1, format='json', authentication=self.author_auth_1)
self.assertHttpUnauthorized(resp)

def test_post_list(self):
# Should be able to create with reckless abandon.
self.assertEqual(Article.objects.count(), 3)
Expand All @@ -135,6 +141,15 @@ def test_post_list(self):
# Verify a new one has been added.
self.assertEqual(Article.objects.count(), 5)

@mock.patch.object(PerUserAuthorization, "create_detail", lambda *args: False)
def test_post_unauthorized_detail(self):
resp = self.api_client.post('/api/v1/article/', format='json', data={
'title': 'Yet Another Story',
'content': 'Stuff.',
'authors': [self.author_uri_1],
}, authentication=self.author_auth_1)
self.assertHttpUnauthorized(resp)

def test_put_list(self):
resp = self.api_client.get('/api/v1/article/', format='json', authentication=self.author_auth_2)
self.assertHttpOK(resp)
Expand Down Expand Up @@ -188,6 +203,15 @@ def test_put_detail(self):
self.assertEqual(Article.objects.get(pk=self.article_2.pk).title, 'Editorial: Why stuff is great')
self.assertEqual(Article.objects.get(pk=self.article_2.pk).content, 'Because you can buy buy buy & fill the gaping voids in your life.')

@mock.patch.object(PerUserAuthorization, "update_detail", lambda *args: False)
def test_put_unauthorized_detail(self):
resp = self.api_client.put(self.article_uri_1, format='json', data={
'title': 'Revised Story',
'content': "We didn't like the previous version.",
'authors': [self.author_uri_1],
}, authentication=self.author_auth_1)
self.assertHttpUnauthorized(resp)

def test_delete_list(self):
# Never a delete, not even once.
self.assertEqual(Article.objects.count(), 3)
Expand All @@ -210,4 +234,10 @@ def test_delete_detail(self):
self.assertEqual(Article.objects.count(), 3)

self.assertHttpUnauthorized(self.api_client.delete(self.article_uri_1, format='json', authentication=self.author_auth_3))
self.assertEqual(Article.objects.count(), 3)
self.assertEqual(Article.objects.count(), 3)

@mock.patch.object(PerUserAuthorization, "delete_detail", lambda *args: False)
def test_delete_unauthorized_detail(self):
self.assertEqual(Article.objects.count(), 3)
self.assertHttpUnauthorized(self.api_client.delete(self.article_uri_1, format='json', authentication=self.author_auth_1))
self.assertEqual(Article.objects.count(), 3)
1 change: 1 addition & 0 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ biplist
pyyaml
mimeparse>=0.1.3
python-dateutil>=2.1
mock

0 comments on commit 2dff249

Please sign in to comment.