From 3b684450439abdbaf2f0d9c4524e225c733afd36 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Tue, 20 Oct 2015 10:51:44 +0200 Subject: [PATCH 1/4] Sugguest users to use the custom OAuthLibCore with DRF --- docs/rest-framework/getting_started.rst | 1 + .../ext/rest_framework/oauth2_backends.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 oauth2_provider/ext/rest_framework/oauth2_backends.py diff --git a/docs/rest-framework/getting_started.rst b/docs/rest-framework/getting_started.rst index 58d9abb13..ea1a90507 100644 --- a/docs/rest-framework/getting_started.rst +++ b/docs/rest-framework/getting_started.rst @@ -104,6 +104,7 @@ Also add the following to your `settings.py` module: OAUTH2_PROVIDER = { # this is the list of available scopes 'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'} + 'OAUTH2_BACKEND_CLASS': 'oauth2_provider.ext.rest_framework.oauth2_backends.OAuthLibCore', } REST_FRAMEWORK = { diff --git a/oauth2_provider/ext/rest_framework/oauth2_backends.py b/oauth2_provider/ext/rest_framework/oauth2_backends.py new file mode 100644 index 000000000..58d206d55 --- /dev/null +++ b/oauth2_provider/ext/rest_framework/oauth2_backends.py @@ -0,0 +1,19 @@ +from rest_framework.request import Request +from oauth2_provider import oauth2_backends + + +class OAuthLibCore(oauth2_backends.OAuthLibCore): + """Backend for Django Rest Framework""" + + def extract_body(self, request): + """ + We can read only once the body in Django, + so in case of DRF we avoid to read it before the framework does. + This use case often happen during multipart form requests. + + NB: it forces you to use the `Authorization` request header + for authentication and not pass the credentials in the request body + """ + if isinstance(request, Request): + return request.data.items() + return super(OAuthLibCore, self).extract_body(request) From fc807b2f01b4422b8002f200c749ec25392ba221 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Tue, 20 Oct 2015 10:52:54 +0200 Subject: [PATCH 2/4] Improve the DRF backend to reject non active users --- .../ext/rest_framework/authentication.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/oauth2_provider/ext/rest_framework/authentication.py b/oauth2_provider/ext/rest_framework/authentication.py index 35c7439ad..40d526516 100644 --- a/oauth2_provider/ext/rest_framework/authentication.py +++ b/oauth2_provider/ext/rest_framework/authentication.py @@ -1,4 +1,7 @@ +from django.utils.translation import ugettext_lazy as _ + from rest_framework.authentication import BaseAuthentication +from rest_framework import exceptions from ...oauth2_backends import get_oauthlib_core @@ -16,11 +19,15 @@ def authenticate(self, request): """ oauthlib_core = get_oauthlib_core() valid, r = oauthlib_core.verify_request(request, scopes=[]) - if valid: - return r.user, r.access_token - else: + + if not valid: return None + if not r.user.is_active: + raise exceptions.AuthenticationFailed(_('User inactive or deleted.')) + + return r.user, r.access_token + def authenticate_header(self, request): """ Bearer is the only finalized type currently From dcb695883904d9c694a19ad1969bb4b0e68a9fd2 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Tue, 20 Oct 2015 10:55:32 +0200 Subject: [PATCH 3/4] Adding myself to the contributor list --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 34e66b331..39da7c53a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -14,3 +14,4 @@ Ash Christopher Rodney Richardson Hiroki Kiyohara Diego Garcia +Pierre Dulac From 8f55c69cdd27ca151b146457ea3afe4e9129ea6d Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Sat, 31 Oct 2015 01:13:39 +0100 Subject: [PATCH 4/4] Fix DRF edge cases and the 2.x support --- oauth2_provider/ext/rest_framework/oauth2_backends.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/oauth2_provider/ext/rest_framework/oauth2_backends.py b/oauth2_provider/ext/rest_framework/oauth2_backends.py index 58d206d55..f0ce84b75 100644 --- a/oauth2_provider/ext/rest_framework/oauth2_backends.py +++ b/oauth2_provider/ext/rest_framework/oauth2_backends.py @@ -15,5 +15,12 @@ def extract_body(self, request): for authentication and not pass the credentials in the request body """ if isinstance(request, Request): - return request.data.items() + try: + # support DRF 2.x + if not hasattr(request, 'data'): + return request.DATA.items() + return request.data.items() + except (ValueError, AttributeError): + # complex json request (list?) is not easily serializable + return "" return super(OAuthLibCore, self).extract_body(request)