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