From fdb689f9b552f219dd677b3b8421ceebcfd5b1e2 Mon Sep 17 00:00:00 2001 From: gnunamed Date: Wed, 5 Jun 2013 13:53:00 -0500 Subject: [PATCH 1/6] Update serializers.md --- docs/api-guide/serializers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index 71f0abb73..9b6a547f8 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -39,7 +39,7 @@ Declaring a serializer looks very similar to declaring a form: an existing model instance, or create a new model instance. """ if instance is not None: - instance.title = attrs.get('title', instance.title) + instance.email = attrs.get('email', instance.email) instance.content = attrs.get('content', instance.content) instance.created = attrs.get('created', instance.created) return instance From ecb8a460c99238a959d8e7600af5b692f13c40d9 Mon Sep 17 00:00:00 2001 From: Alex Burgel Date: Wed, 5 Jun 2013 16:59:19 -0400 Subject: [PATCH 2/6] Fix serialization exception when using non-existent consumer --- rest_framework/authentication.py | 5 ++- rest_framework/tests/test_authentication.py | 41 +++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index 9caca7889..f659a172e 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -230,8 +230,9 @@ class OAuthAuthentication(BaseAuthentication): try: consumer_key = oauth_request.get_parameter('oauth_consumer_key') consumer = oauth_provider_store.get_consumer(request, oauth_request, consumer_key) - except oauth_provider.store.InvalidConsumerError as err: - raise exceptions.AuthenticationFailed(err) + except oauth_provider.store.InvalidConsumerError: + msg = 'Invalid consumer token: %s' % oauth_request.get_parameter('oauth_consumer_key') + raise exceptions.AuthenticationFailed(msg) if consumer.status != oauth_provider.consts.ACCEPTED: msg = 'Invalid consumer key status: %s' % consumer.get_status_display() diff --git a/rest_framework/tests/test_authentication.py b/rest_framework/tests/test_authentication.py index d46ac0798..6a50be064 100644 --- a/rest_framework/tests/test_authentication.py +++ b/rest_framework/tests/test_authentication.py @@ -428,6 +428,47 @@ class OAuthTests(TestCase): response = self.csrf_client.post('/oauth-with-scope/', params) self.assertEqual(response.status_code, 200) + @unittest.skipUnless(oauth_provider, 'django-oauth-plus not installed') + @unittest.skipUnless(oauth, 'oauth2 not installed') + def test_bad_consumer_key(self): + """Ensure POSTing using HMAC_SHA1 signature method passes""" + params = { + 'oauth_version': "1.0", + 'oauth_nonce': oauth.generate_nonce(), + 'oauth_timestamp': int(time.time()), + 'oauth_token': self.token.key, + 'oauth_consumer_key': 'badconsumerkey' + } + + req = oauth.Request(method="POST", url="http://testserver/oauth/", parameters=params) + + signature_method = oauth.SignatureMethod_HMAC_SHA1() + req.sign_request(signature_method, self.consumer, self.token) + auth = req.to_header()["Authorization"] + + response = self.csrf_client.post('/oauth/', HTTP_AUTHORIZATION=auth) + self.assertEqual(response.status_code, 401) + + @unittest.skipUnless(oauth_provider, 'django-oauth-plus not installed') + @unittest.skipUnless(oauth, 'oauth2 not installed') + def test_bad_token_key(self): + """Ensure POSTing using HMAC_SHA1 signature method passes""" + params = { + 'oauth_version': "1.0", + 'oauth_nonce': oauth.generate_nonce(), + 'oauth_timestamp': int(time.time()), + 'oauth_token': 'badtokenkey', + 'oauth_consumer_key': self.consumer.key + } + + req = oauth.Request(method="POST", url="http://testserver/oauth/", parameters=params) + + signature_method = oauth.SignatureMethod_HMAC_SHA1() + req.sign_request(signature_method, self.consumer, self.token) + auth = req.to_header()["Authorization"] + + response = self.csrf_client.post('/oauth/', HTTP_AUTHORIZATION=auth) + self.assertEqual(response.status_code, 401) class OAuth2Tests(TestCase): """OAuth 2.0 authentication""" From e483c4fed686d7e3c7787d2e3eaa5ec4665399ff Mon Sep 17 00:00:00 2001 From: Ryan Kaskel Date: Fri, 7 Jun 2013 10:07:42 +0100 Subject: [PATCH 3/6] Remove pass statement before docstring. --- docs/api-guide/viewsets.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 2783da98f..79257e2af 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -209,8 +209,6 @@ To create a base viewset class that provides `create`, `list` and `retrieve` ope mixins.ListMixin, mixins.RetrieveMixin, viewsets.GenericViewSet): - pass - """ A viewset that provides `retrieve`, `update`, and `list` actions. From ae2887ffc41b1e05d6706f51b00266efccad7a58 Mon Sep 17 00:00:00 2001 From: Ethan Fremen Date: Fri, 7 Jun 2013 19:25:39 -0700 Subject: [PATCH 4/6] Set the args and kwargs before initializing the request. Allows get_parser_context to function correctly. Signed-off-by: Ethan Fremen --- rest_framework/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_framework/views.py b/rest_framework/views.py index 0c1ea7d76..c28d2835f 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -304,10 +304,10 @@ class APIView(View): `.dispatch()` is pretty much the same as Django's regular dispatch, but with extra hooks for startup, finalize, and exception handling. """ - request = self.initialize_request(request, *args, **kwargs) - self.request = request self.args = args self.kwargs = kwargs + request = self.initialize_request(request, *args, **kwargs) + self.request = request self.headers = self.default_response_headers # deprecate? try: From d89aade343ba816644c393d3d073b7ddcb795947 Mon Sep 17 00:00:00 2001 From: Ethan Fremen Date: Fri, 7 Jun 2013 19:49:18 -0700 Subject: [PATCH 5/6] Allow the default router to have a custom name. Signed-off-by: Ethan Fremen --- rest_framework/routers.py | 3 ++- rest_framework/tests/test_routers.py | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/rest_framework/routers.py b/rest_framework/routers.py index 9764e5692..f70c2cdb1 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -215,6 +215,7 @@ class DefaultRouter(SimpleRouter): """ include_root_view = True include_format_suffixes = True + root_view_name = 'api-root' def get_api_root_view(self): """ @@ -244,7 +245,7 @@ class DefaultRouter(SimpleRouter): urls = [] if self.include_root_view: - root_url = url(r'^$', self.get_api_root_view(), name='api-root') + root_url = url(r'^$', self.get_api_root_view(), name=self.root_view_name) urls.append(root_url) default_urls = super(DefaultRouter, self).get_urls() diff --git a/rest_framework/tests/test_routers.py b/rest_framework/tests/test_routers.py index a7534f70b..291142cf9 100644 --- a/rest_framework/tests/test_routers.py +++ b/rest_framework/tests/test_routers.py @@ -6,7 +6,7 @@ from rest_framework import serializers, viewsets from rest_framework.compat import include, patterns, url from rest_framework.decorators import link, action from rest_framework.response import Response -from rest_framework.routers import SimpleRouter +from rest_framework.routers import SimpleRouter, DefaultRouter factory = RequestFactory() @@ -148,3 +148,17 @@ class TestTrailingSlash(TestCase): expected = ['^notes$', '^notes/(?P[^/]+)$'] for idx in range(len(expected)): self.assertEqual(expected[idx], self.urls[idx].regex.pattern) + +class TestNameableRoot(TestCase): + def setUp(self): + class NoteViewSet(viewsets.ModelViewSet): + model = RouterTestModel + self.router = DefaultRouter() + self.router.root_view_name = 'nameable-root' + self.router.register(r'notes', NoteViewSet) + self.urls = self.router.urls + + def test_router_has_custom_name(self): + expected = 'nameable-root' + self.assertEqual(expected, self.urls[0].name) + From 5ce1d6c86bb0831916ba4137560d84295ac7ec95 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 8 Jun 2013 09:38:21 +0200 Subject: [PATCH 6/6] Added @mindlace for work on #922. Thx! --- docs/topics/credits.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/topics/credits.md b/docs/topics/credits.md index db5229222..b4bd3561e 100644 --- a/docs/topics/credits.md +++ b/docs/topics/credits.md @@ -140,6 +140,7 @@ The following people have helped make REST framework great. * Alex Burgel - [aburgel] * David Medina - [copitux] * Areski Belaid - [areski] +* Ethan Freman - [mindlace] Many thanks to everyone who's contributed to the project. @@ -316,3 +317,4 @@ You can also contact [@_tomchristie][twitter] directly on twitter. [aburgel]: https://github.com/aburgel [copitux]: https://github.com/copitux [areski]: https://github.com/areski +[mindlace]: https://github.com/mindlace