From c7800acaa032eb237d58d6d1b89a99d16b94492b Mon Sep 17 00:00:00 2001
From: Robert Raposa <rraposa@edx.org>
Date: Fri, 13 Jul 2018 09:32:53 -0400
Subject: [PATCH] Restore "Upgrade DOT to 1.1.2."

This upgrades DOT by reverting the revert.

This reverts commit 4d8b9c3

ARCH-180
---
 cms/envs/common.py                            |  1 +
 lms/envs/common.py                            |  4 ++-
 .../oauth_dispatch/dot_overrides/backends.py  | 18 +++++++++++
 .../dot_overrides/validators.py               | 15 ---------
 .../oauth_dispatch/dot_overrides/views.py     |  9 +++---
 .../oauth_dispatch/tests/test_views.py        | 31 ++++++++++---------
 requirements/edx/base.in                      |  6 ++--
 requirements/edx/base.txt                     | 13 ++++----
 requirements/edx/development.txt              | 11 ++++---
 requirements/edx/paver.in                     |  2 +-
 requirements/edx/paver.txt                    |  5 ++-
 requirements/edx/testing.txt                  | 11 ++++---
 12 files changed, 71 insertions(+), 55 deletions(-)
 create mode 100644 openedx/core/djangoapps/oauth_dispatch/dot_overrides/backends.py

diff --git a/cms/envs/common.py b/cms/envs/common.py
index 74605df72fc..b76885baed7 100644
--- a/cms/envs/common.py
+++ b/cms/envs/common.py
@@ -1112,6 +1112,7 @@ INSTALLED_APPS = [
     # These are apps that aren't strictly needed by Studio, but are imported by
     # other apps that are.  Django 1.8 wants to have imported models supported
     # by installed apps.
+    'openedx.core.djangoapps.oauth_dispatch.apps.OAuthDispatchAppConfig',
     'oauth_provider',
     'courseware',
     'survey.apps.SurveyConfig',
diff --git a/lms/envs/common.py b/lms/envs/common.py
index 6396ba01946..ffb163c9759 100644
--- a/lms/envs/common.py
+++ b/lms/envs/common.py
@@ -644,7 +644,9 @@ derived_collection_entry('DEFAULT_TEMPLATE_ENGINE', 'DIRS')
 
 ###############################################################################################
 
-AUTHENTICATION_BACKENDS = ['openedx.core.djangoapps.oauth_dispatch.dot_overrides.validators.EdxRateLimitedAllowAllUsersModelBackend']
+AUTHENTICATION_BACKENDS = [
+    'openedx.core.djangoapps.oauth_dispatch.dot_overrides.backends.EdxRateLimitedAllowAllUsersModelBackend'
+]
 STUDENT_FILEUPLOAD_MAX_SIZE = 4 * 1000 * 1000  # 4 MB
 MAX_FILEUPLOADS_PER_INPUT = 20
 
diff --git a/openedx/core/djangoapps/oauth_dispatch/dot_overrides/backends.py b/openedx/core/djangoapps/oauth_dispatch/dot_overrides/backends.py
new file mode 100644
index 00000000000..664d0d79168
--- /dev/null
+++ b/openedx/core/djangoapps/oauth_dispatch/dot_overrides/backends.py
@@ -0,0 +1,18 @@
+"""
+Custom authentication backends.
+"""
+from django.contrib.auth.backends import AllowAllUsersModelBackend as UserModelBackend
+from ratelimitbackend.backends import RateLimitMixin
+
+
+class EdxRateLimitedAllowAllUsersModelBackend(RateLimitMixin, UserModelBackend):
+    """
+    Authentication backend needed to incorporate rate limiting of login attempts - but also
+    enabling users with is_active of False in the Django auth_user model to still authenticate.
+    This is necessary for mobile users using 3rd party auth who have not activated their accounts,
+    Inactive users who use 1st party auth (username/password auth) will still fail login attempts,
+    just at a higher layer, in the login_user view.
+
+    See: https://openedx.atlassian.net/browse/TNL-4516
+    """
+    pass
diff --git a/openedx/core/djangoapps/oauth_dispatch/dot_overrides/validators.py b/openedx/core/djangoapps/oauth_dispatch/dot_overrides/validators.py
index 5214622995f..bc265a035cd 100644
--- a/openedx/core/djangoapps/oauth_dispatch/dot_overrides/validators.py
+++ b/openedx/core/djangoapps/oauth_dispatch/dot_overrides/validators.py
@@ -6,14 +6,12 @@ from __future__ import unicode_literals
 from datetime import datetime
 
 from django.contrib.auth import authenticate, get_user_model
-from django.contrib.auth.backends import AllowAllUsersModelBackend as UserModelBackend
 from django.db.models.signals import pre_save
 from django.dispatch import receiver
 from oauth2_provider.models import AccessToken
 from oauth2_provider.oauth2_validators import OAuth2Validator
 from oauth2_provider.scopes import get_scopes_backend
 from pytz import utc
-from ratelimitbackend.backends import RateLimitMixin
 
 from ..models import RestrictedApplication
 
@@ -27,19 +25,6 @@ def on_access_token_presave(sender, instance, *args, **kwargs):  # pylint: disab
         instance.expires = datetime(1970, 1, 1, tzinfo=utc)
 
 
-class EdxRateLimitedAllowAllUsersModelBackend(RateLimitMixin, UserModelBackend):
-    """
-    Authentication backend needed to incorporate rate limiting of login attempts - but also
-    enabling users with is_active of False in the Django auth_user model to still authenticate.
-    This is necessary for mobile users using 3rd party auth who have not activated their accounts,
-    Inactive users who use 1st party auth (username/password auth) will still fail login attempts,
-    just at a higher layer, in the login_user view.
-
-    See: https://openedx.atlassian.net/browse/TNL-4516
-    """
-    pass
-
-
 class EdxOAuth2Validator(OAuth2Validator):
     """
     Validator class that implements edX-specific custom behavior:
diff --git a/openedx/core/djangoapps/oauth_dispatch/dot_overrides/views.py b/openedx/core/djangoapps/oauth_dispatch/dot_overrides/views.py
index 0485f1c6654..ba238b8a0bd 100644
--- a/openedx/core/djangoapps/oauth_dispatch/dot_overrides/views.py
+++ b/openedx/core/djangoapps/oauth_dispatch/dot_overrides/views.py
@@ -5,7 +5,7 @@ from __future__ import unicode_literals
 
 from oauth2_provider.exceptions import OAuthToolkitError
 from oauth2_provider.http import HttpResponseUriRedirect
-from oauth2_provider.models import get_application_model
+from oauth2_provider.models import get_access_token_model, get_application_model
 from oauth2_provider.scopes import get_scopes_backend
 from oauth2_provider.settings import oauth2_settings
 from oauth2_provider.views import AuthorizationView
@@ -69,11 +69,12 @@ class EdxOAuth2AuthorizationView(AuthorizationView):
                 uri, headers, body, status = self.create_authorization_response(
                     request=self.request, scopes=" ".join(scopes),
                     credentials=credentials, allow=True)
-                return HttpResponseUriRedirect(uri)
+                return HttpResponseUriRedirect(uri, application.get_allowed_schemes())
 
             # *** Changed the if statement that checked for require_approval to an assert.
             assert require_approval == 'auto_even_if_expired'
-            tokens = request.user.accesstoken_set.filter(
+            tokens = get_access_token_model().objects.filter(
+                user=request.user,
                 application=kwargs['application'],
                 # *** Purposefully keeping this commented out code to highlight that
                 # our version of the implementation does NOT filter by expiration date.
@@ -86,7 +87,7 @@ class EdxOAuth2AuthorizationView(AuthorizationView):
                     uri, headers, body, status = self.create_authorization_response(
                         request=self.request, scopes=" ".join(scopes),
                         credentials=credentials, allow=True)
-                    return HttpResponseUriRedirect(uri)
+                    return HttpResponseUriRedirect(uri, application.get_allowed_schemes())
 
             # render an authorization prompt so the user can approve
             # the application's requested scopes
diff --git a/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py b/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py
index 312e0e5e157..a13adabb182 100644
--- a/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py
+++ b/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py
@@ -684,36 +684,39 @@ class TestRevokeTokenView(AccessTokenLoginMixin, _DispatchingViewTestCase):  # p
             'token': token,
         }
 
-    def _assert_refresh_token_invalidated(self):
+    def assert_refresh_token_status_code(self, refresh_token, expected_status_code):
         """
-        Asserts that oauth assigned refresh_token is not valid
+        Asserts the status code using oauth assigned refresh_token
         """
         response = self.client.post(
             self.access_token_url,
-            self.access_token_post_body_with_refresh_token(self.refresh_token)
+            self.access_token_post_body_with_refresh_token(refresh_token)
         )
-        self.assertEqual(response.status_code, 401)
+        self.assertEqual(response.status_code, expected_status_code)
 
-    def verify_revoke_token(self, token):
+    def revoke_token(self, token):
         """
-        Verifies access of token before and after revoking
+        Revokes the passed access or refresh token
         """
-        self._assert_access_token_is_valid()
-
         response = self.client.post(self.revoke_token_url, self.revoke_token_post_body(token))
         self.assertEqual(response.status_code, 200)
 
-        self._assert_access_token_invalidated()
-        self._assert_refresh_token_invalidated()
-
     def test_revoke_refresh_token_dot(self):
         """
-        Tests invalidation/revoke of user tokens against refresh token for django-oauth-toolkit
+        Tests invalidation/revoke of refresh token for django-oauth-toolkit
         """
-        self.verify_revoke_token(self.refresh_token)
+        self.assert_refresh_token_status_code(self.refresh_token, expected_status_code=200)
+
+        self.revoke_token(self.refresh_token)
+
+        self.assert_refresh_token_status_code(self.refresh_token, expected_status_code=401)
 
     def test_revoke_access_token_dot(self):
         """
         Tests invalidation/revoke of user access token for django-oauth-toolkit
         """
-        self.verify_revoke_token(self.access_token)
+        self._assert_access_token_is_valid(self.access_token)
+
+        self.revoke_token(self.access_token)
+
+        self._assert_access_token_invalidated(self.access_token)
diff --git a/requirements/edx/base.in b/requirements/edx/base.in
index 801111fe57d..d1a23ffbac5 100644
--- a/requirements/edx/base.in
+++ b/requirements/edx/base.in
@@ -46,7 +46,7 @@ django-method-override==0.1.0
 django-model-utils==3.0.0
 django-mptt>=0.8.6,<0.9
 django-mysql
-django-oauth-toolkit==0.12.0
+django-oauth-toolkit<1.2            # Provides oAuth2 capabilities for Django. 1.2+ requires Django 2 and Python 3.5
 django-pyfs
 django-ratelimit
 django-ratelimit-backend==1.1.1
@@ -104,7 +104,7 @@ MySQL-python                        # Driver for the default production relation
 newrelic                            # New Relic agent for performance monitoring
 nodeenv==1.1.1                      # Utility for managing Node.js environments; we use this for deployments and testing
 numpy==1.6.2                        # Fast numeric array computation, used in some problem types
-oauthlib==2.0.1                     # OAuth specification support for authenticating via LTI or other Open edX services
+oauthlib                            # OAuth specification support for authenticating via LTI or other Open edX services
 pdfminer                            # Used in shoppingcart for extracting/parsing pdf text
 piexif==1.0.2                       # Exif image metadata manipulation, used in the profile_images app
 Pillow                              # Image manipulation library; used for course assets, profile images, invoice PDFs, etc.
@@ -133,7 +133,7 @@ pysrt==0.4.7                        # Support for SubRip subtitle files, used in
 pytz==2016.10                       # Time zone information database
 PyYAML                              # Used to parse XModule resource templates
 redis==2.10.6                       # celery task broker
-requests-oauthlib==0.6.1            # Simplifies use of OAuth via the requests library, used for CCX and LTI
+requests-oauthlib                   # Simplifies use of OAuth via the requests library, used for CCX and LTI
 rules                               # Django extension for rules-based authorization checks
 sailthru-client==2.2.3              # For Sailthru integration
 Shapely==1.2.16                     # Geometry library, used for image click regions in capa
diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt
index 03e651dfcc1..d6d544038e4 100644
--- a/requirements/edx/base.txt
+++ b/requirements/edx/base.txt
@@ -56,8 +56,10 @@ boto3==1.4.8
 boto==2.39.0
 botocore==1.8.17
 celery==3.1.25
+certifi==2018.8.13
 cffi==1.11.5
 charade==1.0.3            # via pysrt
+chardet==3.0.4
 click==6.7                # via user-util
 coreapi==2.3.3            # via django-rest-swagger, openapi-codec
 coreschema==0.0.4         # via coreapi
@@ -69,7 +71,6 @@ defusedxml==0.4.1
 django-appconf==1.0.2     # via django-statici18n
 django-babel-underscore==0.5.2
 django-babel==0.6.2       # via django-babel-underscore
-django-braces==1.13.0     # via django-oauth-toolkit
 django-classy-tags==0.8.0  # via django-sekizai
 django-config-models==0.2.0
 django-cors-headers==2.1.0
@@ -84,7 +85,7 @@ django-model-utils==3.0.0
 django-mptt==0.8.7
 django-multi-email-field==0.5.1  # via edx-enterprise
 django-mysql==2.4.1
-django-oauth-toolkit==0.12.0
+django-oauth-toolkit==1.1.2
 django-object-actions==0.10.0  # via edx-enterprise
 django-pyfs==2.0
 django-ratelimit-backend==1.1.1
@@ -173,7 +174,7 @@ nltk==3.3.0
 nodeenv==1.1.1
 numpy==1.6.2
 oauth2==1.9.0.post1
-oauthlib==2.0.1
+oauthlib==2.1.0
 openapi-codec==1.3.2      # via django-rest-swagger
 path.py==8.2.1
 pathtools==0.1.2
@@ -208,8 +209,8 @@ pyuca==1.1
 pyyaml==3.13
 redis==2.10.6
 reportlab==3.5.6
-requests-oauthlib==0.6.1
-requests==2.9.1
+requests-oauthlib==1.0.0
+requests==2.19.1
 rest-condition==1.0.3
 rfc6266-parser==0.0.5.post2
 rules==2.0
@@ -232,7 +233,7 @@ sympy==0.7.1
 tincan==0.0.5             # via edx-enterprise
 unicodecsv==0.14.1
 uritemplate==3.0.0        # via coreapi
-urllib3==1.23             # via elasticsearch
+urllib3==1.23
 user-util==0.1.5
 voluptuous==0.11.5
 watchdog==0.9.0
diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt
index e23652b8938..2111e9f1d99 100644
--- a/requirements/edx/development.txt
+++ b/requirements/edx/development.txt
@@ -66,8 +66,10 @@ boto3==1.4.8
 boto==2.39.0
 botocore==1.8.17
 celery==3.1.25
+certifi==2018.8.13
 cffi==1.11.5
 charade==1.0.3
+chardet==3.0.4
 click-log==0.1.8
 click==6.7
 colorama==0.3.9
@@ -87,7 +89,6 @@ diff-cover==0.9.8
 django-appconf==1.0.2
 django-babel-underscore==0.5.2
 django-babel==0.6.2
-django-braces==1.13.0
 django-classy-tags==0.8.0
 django-config-models==0.2.0
 django-cors-headers==2.1.0
@@ -103,7 +104,7 @@ django-model-utils==3.0.0
 django-mptt==0.8.7
 django-multi-email-field==0.5.1
 django-mysql==2.4.1
-django-oauth-toolkit==0.12.0
+django-oauth-toolkit==1.1.2
 django-object-actions==0.10.0
 django-pyfs==2.0
 django-ratelimit-backend==1.1.1
@@ -221,7 +222,7 @@ nltk==3.3.0
 nodeenv==1.1.1
 numpy==1.6.2
 oauth2==1.9.0.post1
-oauthlib==2.0.1
+oauthlib==2.1.0
 openapi-codec==1.3.2
 pa11ycrawler==1.6.2
 packaging==17.1           # via sphinx
@@ -287,8 +288,8 @@ queuelib==1.5.0
 radon==2.2.0
 redis==2.10.6
 reportlab==3.5.6
-requests-oauthlib==0.6.1
-requests==2.9.1
+requests-oauthlib==1.0.0
+requests==2.19.1
 rest-condition==1.0.3
 rfc6266-parser==0.0.5.post2
 rules==2.0
diff --git a/requirements/edx/paver.in b/requirements/edx/paver.in
index e51f84e944d..4be620eed2f 100644
--- a/requirements/edx/paver.in
+++ b/requirements/edx/paver.in
@@ -17,7 +17,7 @@ paver                               # Build, distribution and deployment scripti
 psutil==1.2.1                       # Library for retrieving information on running processes and system utilization
 pymongo==2.9.1                      # via edx-opaque-keys
 python-memcached==1.48              # Python interface to the memcached memory cache daemon
-requests==2.9.1                     # Simple interface for making HTTP requests
+requests                            # Simple interface for making HTTP requests
 stevedore==1.10.0                   # via edx-opaque-keys
 watchdog                            # Used in paver watch_assets
 wrapt==1.10.5                       # Decorator utilities used in the @timed paver task decorator
diff --git a/requirements/edx/paver.txt b/requirements/edx/paver.txt
index 8de84d7f48d..557b65f4c3c 100644
--- a/requirements/edx/paver.txt
+++ b/requirements/edx/paver.txt
@@ -6,7 +6,10 @@
 #
 argh==0.26.2              # via watchdog
 argparse==1.4.0           # via stevedore
+certifi==2018.8.13        # via requests
+chardet==3.0.4            # via requests
 edx-opaque-keys==0.4.4
+idna==2.7                 # via requests
 lazy==1.1
 libsass==0.10.0
 markupsafe==1.0
@@ -19,7 +22,7 @@ psutil==1.2.1
 pymongo==2.9.1
 python-memcached==1.48
 pyyaml==3.13              # via watchdog
-requests==2.9.1
+requests==2.19.1
 six==1.11.0               # via edx-opaque-keys, libsass, paver, stevedore
 stevedore==1.10.0
 watchdog==0.9.0
diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt
index 8c3112e19cc..e858f3295f2 100644
--- a/requirements/edx/testing.txt
+++ b/requirements/edx/testing.txt
@@ -63,8 +63,10 @@ boto3==1.4.8
 boto==2.39.0
 botocore==1.8.17
 celery==3.1.25
+certifi==2018.8.13
 cffi==1.11.5
 charade==1.0.3
+chardet==3.0.4
 click-log==0.1.8          # via edx-lint
 click==6.7
 colorama==0.3.9           # via radon
@@ -84,7 +86,6 @@ diff-cover==0.9.8
 django-appconf==1.0.2
 django-babel-underscore==0.5.2
 django-babel==0.6.2
-django-braces==1.13.0
 django-classy-tags==0.8.0
 django-config-models==0.2.0
 django-cors-headers==2.1.0
@@ -99,7 +100,7 @@ django-model-utils==3.0.0
 django-mptt==0.8.7
 django-multi-email-field==0.5.1
 django-mysql==2.4.1
-django-oauth-toolkit==0.12.0
+django-oauth-toolkit==1.1.2
 django-object-actions==0.10.0
 django-pyfs==2.0
 django-ratelimit-backend==1.1.1
@@ -212,7 +213,7 @@ nltk==3.3.0
 nodeenv==1.1.1
 numpy==1.6.2
 oauth2==1.9.0.post1
-oauthlib==2.0.1
+oauthlib==2.1.0
 openapi-codec==1.3.2
 pa11ycrawler==1.6.2
 parsel==1.5.0             # via scrapy
@@ -275,8 +276,8 @@ queuelib==1.5.0           # via scrapy
 radon==2.2.0
 redis==2.10.6
 reportlab==3.5.6
-requests-oauthlib==0.6.1
-requests==2.9.1
+requests-oauthlib==1.0.0
+requests==2.19.1
 rest-condition==1.0.3
 rfc6266-parser==0.0.5.post2
 rules==2.0
-- 
GitLab