Skip to content
This repository has been archived by the owner on Nov 5, 2019. It is now read-only.

Commit

Permalink
Fix django authorization redirect by correctly checking validity of c…
Browse files Browse the repository at this point in the history
…redentials (#651)
  • Loading branch information
waprin authored and Jon Wayne Parrott committed Sep 16, 2016
1 parent 9f0618d commit 8a6e3b2
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 11 deletions.
13 changes: 7 additions & 6 deletions oauth2client/contrib/django_util/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,21 +170,22 @@ def oauth2_authorize(request):
A redirect to Google OAuth2 Authorization.
"""
return_url = request.GET.get('return_url', None)
if not return_url:
return_url = request.META.get('HTTP_REFERER', '/')

scopes = request.GET.getlist('scopes', django_util.oauth2_settings.scopes)
# Model storage (but not session storage) requires a logged in user
if django_util.oauth2_settings.storage_model:
if not request.user.is_authenticated():
return redirect('{0}?next={1}'.format(
settings.LOGIN_URL, parse.quote(request.get_full_path())))
# This checks for the case where we ended up here because of a logged
# out user but we had credentials for it in the first place
elif get_storage(request).get() is not None:
return redirect(return_url)
else:
user_oauth = django_util.UserOAuth2(request, scopes, return_url)
if user_oauth.has_credentials():
return redirect(return_url)

scopes = request.GET.getlist('scopes', django_util.oauth2_settings.scopes)

if not return_url:
return_url = request.META.get('HTTP_REFERER', '/')
flow = _make_flow(request=request, scopes=scopes, return_url=return_url)
auth_url = flow.step1_get_authorize_url()
return shortcuts.redirect(auth_url)
4 changes: 2 additions & 2 deletions tests/contrib/django_util/test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def test_specified_scopes(self, dictionary_storage_mock):

credentials_mock = mock.Mock(
scopes=set(django.conf.settings.GOOGLE_OAUTH2_SCOPES))
credentials_mock.has_scopes = True
credentials_mock.has_scopes = mock.Mock(return_value=True)
credentials_mock.is_valid = True
dictionary_storage_mock.get.return_value = credentials_mock

Expand Down Expand Up @@ -183,7 +183,7 @@ def test_specified_scopes(self, OAuth2Credentials):

credentials_mock = mock.Mock(
scopes=set(django.conf.settings.GOOGLE_OAUTH2_SCOPES))
credentials_mock.has_scopes = False
credentials_mock.has_scopes = mock.Mock(return_value=False)
OAuth2Credentials.from_json.return_value = credentials_mock

@decorators.oauth_required(scopes=['additional-scope'])
Expand Down
33 changes: 30 additions & 3 deletions tests/contrib/django_util/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

from oauth2client import client
import oauth2client.contrib.django_util
from oauth2client.contrib.django_util import models
from oauth2client.contrib.django_util import views
from tests.contrib import django_util as tests_django_util
from tests.contrib.django_util import models as tests_models
Expand Down Expand Up @@ -117,22 +116,50 @@ def test_authorize_works_explicit_return_url(self):
response = views.oauth2_authorize(request)
self.assertIsInstance(response, http.HttpResponseRedirect)

def test_authorized_user_not_logged_in_redirects(self):
def test_authorized_user_no_credentials_redirects(self):
request = self.factory.get('oauth2/oauth2authorize',
data={'return_url': '/return_endpoint'})
request.session = self.session

authorized_user = django_models.User.objects.create_user(
username='bill2', email='[email protected]', password='hunter2')
credentials = models.CredentialsField()

tests_models.CredentialsModel.objects.create(
user_id=authorized_user,
credentials=None)

request.user = authorized_user
response = views.oauth2_authorize(request)
self.assertIsInstance(response, http.HttpResponseRedirect)

def test_already_authorized(self):
request = self.factory.get('oauth2/oauth2authorize',
data={'return_url': '/return_endpoint'})
request.session = self.session

authorized_user = django_models.User.objects.create_user(
username='bill2', email='[email protected]', password='hunter2')

credentials = _Credentials()
tests_models.CredentialsModel.objects.create(
user_id=authorized_user,
credentials=credentials)

request.user = authorized_user
response = views.oauth2_authorize(request)
self.assertIsInstance(response, http.HttpResponseRedirect)
self.assertEqual(response.url, '/return_endpoint')


class _Credentials(object):
# Can't use mock when testing Django models
# https://code.djangoproject.com/ticket/25493
def __init__(self):
self.invalid = False
self.scopes = set()

def has_scopes(self, _):
return True


class Oauth2CallbackTest(tests_django_util.TestWithDjangoEnvironment):
Expand Down

0 comments on commit 8a6e3b2

Please sign in to comment.