Skip to content

Commit 8a6e3b2

Browse files
waprinJon Wayne Parrott
authored and
Jon Wayne Parrott
committed
Fix django authorization redirect by correctly checking validity of credentials (googleapis#651)
1 parent 9f0618d commit 8a6e3b2

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

oauth2client/contrib/django_util/views.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,21 +170,22 @@ def oauth2_authorize(request):
170170
A redirect to Google OAuth2 Authorization.
171171
"""
172172
return_url = request.GET.get('return_url', None)
173+
if not return_url:
174+
return_url = request.META.get('HTTP_REFERER', '/')
173175

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

184-
scopes = request.GET.getlist('scopes', django_util.oauth2_settings.scopes)
185-
186-
if not return_url:
187-
return_url = request.META.get('HTTP_REFERER', '/')
188189
flow = _make_flow(request=request, scopes=scopes, return_url=return_url)
189190
auth_url = flow.step1_get_authorize_url()
190191
return shortcuts.redirect(auth_url)

tests/contrib/django_util/test_decorators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def test_specified_scopes(self, dictionary_storage_mock):
9292

9393
credentials_mock = mock.Mock(
9494
scopes=set(django.conf.settings.GOOGLE_OAUTH2_SCOPES))
95-
credentials_mock.has_scopes = True
95+
credentials_mock.has_scopes = mock.Mock(return_value=True)
9696
credentials_mock.is_valid = True
9797
dictionary_storage_mock.get.return_value = credentials_mock
9898

@@ -183,7 +183,7 @@ def test_specified_scopes(self, OAuth2Credentials):
183183

184184
credentials_mock = mock.Mock(
185185
scopes=set(django.conf.settings.GOOGLE_OAUTH2_SCOPES))
186-
credentials_mock.has_scopes = False
186+
credentials_mock.has_scopes = mock.Mock(return_value=False)
187187
OAuth2Credentials.from_json.return_value = credentials_mock
188188

189189
@decorators.oauth_required(scopes=['additional-scope'])

tests/contrib/django_util/test_views.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
from oauth2client import client
2828
import oauth2client.contrib.django_util
29-
from oauth2client.contrib.django_util import models
3029
from oauth2client.contrib.django_util import views
3130
from tests.contrib import django_util as tests_django_util
3231
from tests.contrib.django_util import models as tests_models
@@ -117,22 +116,50 @@ def test_authorize_works_explicit_return_url(self):
117116
response = views.oauth2_authorize(request)
118117
self.assertIsInstance(response, http.HttpResponseRedirect)
119118

120-
def test_authorized_user_not_logged_in_redirects(self):
119+
def test_authorized_user_no_credentials_redirects(self):
121120
request = self.factory.get('oauth2/oauth2authorize',
122121
data={'return_url': '/return_endpoint'})
123122
request.session = self.session
124123

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

127+
tests_models.CredentialsModel.objects.create(
128+
user_id=authorized_user,
129+
credentials=None)
130+
131+
request.user = authorized_user
132+
response = views.oauth2_authorize(request)
133+
self.assertIsInstance(response, http.HttpResponseRedirect)
134+
135+
def test_already_authorized(self):
136+
request = self.factory.get('oauth2/oauth2authorize',
137+
data={'return_url': '/return_endpoint'})
138+
request.session = self.session
139+
140+
authorized_user = django_models.User.objects.create_user(
141+
username='bill2', email='[email protected]', password='hunter2')
142+
143+
credentials = _Credentials()
129144
tests_models.CredentialsModel.objects.create(
130145
user_id=authorized_user,
131146
credentials=credentials)
132147

133148
request.user = authorized_user
134149
response = views.oauth2_authorize(request)
135150
self.assertIsInstance(response, http.HttpResponseRedirect)
151+
self.assertEqual(response.url, '/return_endpoint')
152+
153+
154+
class _Credentials(object):
155+
# Can't use mock when testing Django models
156+
# https://code.djangoproject.com/ticket/25493
157+
def __init__(self):
158+
self.invalid = False
159+
self.scopes = set()
160+
161+
def has_scopes(self, _):
162+
return True
136163

137164

138165
class Oauth2CallbackTest(tests_django_util.TestWithDjangoEnvironment):

0 commit comments

Comments
 (0)