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

Fix django authorization redirect by correctly checking validity of credentials #651

Merged
merged 1 commit into from
Sep 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:

This comment was marked as spam.

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