Skip to content

Commit 351e172

Browse files
committed
2 parents 777ecb5 + 5ce1d6c commit 351e172

File tree

8 files changed

+66
-9
lines changed

8 files changed

+66
-9
lines changed

docs/api-guide/serializers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Declaring a serializer looks very similar to declaring a form:
3939
an existing model instance, or create a new model instance.
4040
"""
4141
if instance is not None:
42-
instance.title = attrs.get('title', instance.title)
42+
instance.email = attrs.get('email', instance.email)
4343
instance.content = attrs.get('content', instance.content)
4444
instance.created = attrs.get('created', instance.created)
4545
return instance

docs/api-guide/viewsets.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,6 @@ To create a base viewset class that provides `create`, `list` and `retrieve` ope
209209
mixins.ListMixin,
210210
mixins.RetrieveMixin,
211211
viewsets.GenericViewSet):
212-
pass
213-
214212
"""
215213
A viewset that provides `retrieve`, `update`, and `list` actions.
216214

docs/topics/credits.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ The following people have helped make REST framework great.
140140
* Alex Burgel - [aburgel]
141141
* David Medina - [copitux]
142142
* Areski Belaid - [areski]
143+
* Ethan Freman - [mindlace]
143144

144145
Many thanks to everyone who's contributed to the project.
145146

@@ -316,3 +317,4 @@ You can also contact [@_tomchristie][twitter] directly on twitter.
316317
[aburgel]: https://github.com/aburgel
317318
[copitux]: https://github.com/copitux
318319
[areski]: https://github.com/areski
320+
[mindlace]: https://github.com/mindlace

rest_framework/authentication.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,9 @@ def authenticate(self, request):
230230
try:
231231
consumer_key = oauth_request.get_parameter('oauth_consumer_key')
232232
consumer = oauth_provider_store.get_consumer(request, oauth_request, consumer_key)
233-
except oauth_provider.store.InvalidConsumerError as err:
234-
raise exceptions.AuthenticationFailed(err)
233+
except oauth_provider.store.InvalidConsumerError:
234+
msg = 'Invalid consumer token: %s' % oauth_request.get_parameter('oauth_consumer_key')
235+
raise exceptions.AuthenticationFailed(msg)
235236

236237
if consumer.status != oauth_provider.consts.ACCEPTED:
237238
msg = 'Invalid consumer key status: %s' % consumer.get_status_display()

rest_framework/routers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ class DefaultRouter(SimpleRouter):
215215
"""
216216
include_root_view = True
217217
include_format_suffixes = True
218+
root_view_name = 'api-root'
218219

219220
def get_api_root_view(self):
220221
"""
@@ -244,7 +245,7 @@ def get_urls(self):
244245
urls = []
245246

246247
if self.include_root_view:
247-
root_url = url(r'^$', self.get_api_root_view(), name='api-root')
248+
root_url = url(r'^$', self.get_api_root_view(), name=self.root_view_name)
248249
urls.append(root_url)
249250

250251
default_urls = super(DefaultRouter, self).get_urls()

rest_framework/tests/test_authentication.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,47 @@ def test_post_form_with_write_resource_passing_auth(self):
428428
response = self.csrf_client.post('/oauth-with-scope/', params)
429429
self.assertEqual(response.status_code, 200)
430430

431+
@unittest.skipUnless(oauth_provider, 'django-oauth-plus not installed')
432+
@unittest.skipUnless(oauth, 'oauth2 not installed')
433+
def test_bad_consumer_key(self):
434+
"""Ensure POSTing using HMAC_SHA1 signature method passes"""
435+
params = {
436+
'oauth_version': "1.0",
437+
'oauth_nonce': oauth.generate_nonce(),
438+
'oauth_timestamp': int(time.time()),
439+
'oauth_token': self.token.key,
440+
'oauth_consumer_key': 'badconsumerkey'
441+
}
442+
443+
req = oauth.Request(method="POST", url="http://testserver/oauth/", parameters=params)
444+
445+
signature_method = oauth.SignatureMethod_HMAC_SHA1()
446+
req.sign_request(signature_method, self.consumer, self.token)
447+
auth = req.to_header()["Authorization"]
448+
449+
response = self.csrf_client.post('/oauth/', HTTP_AUTHORIZATION=auth)
450+
self.assertEqual(response.status_code, 401)
451+
452+
@unittest.skipUnless(oauth_provider, 'django-oauth-plus not installed')
453+
@unittest.skipUnless(oauth, 'oauth2 not installed')
454+
def test_bad_token_key(self):
455+
"""Ensure POSTing using HMAC_SHA1 signature method passes"""
456+
params = {
457+
'oauth_version': "1.0",
458+
'oauth_nonce': oauth.generate_nonce(),
459+
'oauth_timestamp': int(time.time()),
460+
'oauth_token': 'badtokenkey',
461+
'oauth_consumer_key': self.consumer.key
462+
}
463+
464+
req = oauth.Request(method="POST", url="http://testserver/oauth/", parameters=params)
465+
466+
signature_method = oauth.SignatureMethod_HMAC_SHA1()
467+
req.sign_request(signature_method, self.consumer, self.token)
468+
auth = req.to_header()["Authorization"]
469+
470+
response = self.csrf_client.post('/oauth/', HTTP_AUTHORIZATION=auth)
471+
self.assertEqual(response.status_code, 401)
431472

432473
class OAuth2Tests(TestCase):
433474
"""OAuth 2.0 authentication"""

rest_framework/tests/test_routers.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from rest_framework.compat import include, patterns, url
77
from rest_framework.decorators import link, action
88
from rest_framework.response import Response
9-
from rest_framework.routers import SimpleRouter
9+
from rest_framework.routers import SimpleRouter, DefaultRouter
1010

1111
factory = RequestFactory()
1212

@@ -148,3 +148,17 @@ def test_urls_can_have_trailing_slash_removed(self):
148148
expected = ['^notes$', '^notes/(?P<pk>[^/]+)$']
149149
for idx in range(len(expected)):
150150
self.assertEqual(expected[idx], self.urls[idx].regex.pattern)
151+
152+
class TestNameableRoot(TestCase):
153+
def setUp(self):
154+
class NoteViewSet(viewsets.ModelViewSet):
155+
model = RouterTestModel
156+
self.router = DefaultRouter()
157+
self.router.root_view_name = 'nameable-root'
158+
self.router.register(r'notes', NoteViewSet)
159+
self.urls = self.router.urls
160+
161+
def test_router_has_custom_name(self):
162+
expected = 'nameable-root'
163+
self.assertEqual(expected, self.urls[0].name)
164+

rest_framework/views.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,10 @@ def dispatch(self, request, *args, **kwargs):
304304
`.dispatch()` is pretty much the same as Django's regular dispatch,
305305
but with extra hooks for startup, finalize, and exception handling.
306306
"""
307-
request = self.initialize_request(request, *args, **kwargs)
308-
self.request = request
309307
self.args = args
310308
self.kwargs = kwargs
309+
request = self.initialize_request(request, *args, **kwargs)
310+
self.request = request
311311
self.headers = self.default_response_headers # deprecate?
312312

313313
try:

0 commit comments

Comments
 (0)