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

diff --git a/oauth2client/contrib/django_util/views.py b/oauth2client/contrib/django_util/views.py
index 4858f20..009b544 100644
--- a/oauth2client/contrib/django_util/views.py
+++ b/oauth2client/contrib/django_util/views.py
@@ -170,7 +170,10 @@
          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():
@@ -178,13 +181,11 @@
                 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)
diff --git a/tests/contrib/django_util/test_decorators.py b/tests/contrib/django_util/test_decorators.py
index 836e4cc..f237f88 100644
--- a/tests/contrib/django_util/test_decorators.py
+++ b/tests/contrib/django_util/test_decorators.py
@@ -92,7 +92,7 @@
 
         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
 
@@ -183,7 +183,7 @@
 
         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'])
diff --git a/tests/contrib/django_util/test_views.py b/tests/contrib/django_util/test_views.py
index b6b6c22..dc06661 100644
--- a/tests/contrib/django_util/test_views.py
+++ b/tests/contrib/django_util/test_views.py
@@ -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
@@ -117,22 +116,50 @@
         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):