Skip to content

Commit

Permalink
i This is a combination of 2 commits.
Browse files Browse the repository at this point in the history
BOM-1045
-Added django 2.0,2.1,2.2 tests to travis
-Moved from djangorestframework-jwt to drf-jwt
-Updated Code files
-Updated Requirement files
-Updated Settings
-version bump
  • Loading branch information
Ayub-Khan committed Mar 9, 2020
1 parent d357b22 commit 55ff432
Show file tree
Hide file tree
Showing 16 changed files with 61 additions and 52 deletions.
9 changes: 7 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ python:
- 3.5

env:
- TOXENV=django111-drf37 AFTER_SUCCESS=codecov INSTALL_EXTRAS=codecov
- TOXENV=django111-drf38
- TOXENV=django111-drf39 AFTER_SUCCESS=codecov INSTALL_EXTRAS=codecov
- TOXENV=django111-drf39
- TOXENV=django111-drflatest
- TOXENV=django20-drf39
- TOXENV=django20-drflatest
- TOXENV=django21-drf39
- TOXENV=django21-drflatest
- TOXENV=django22-drf39
- TOXENV=django22-drflatest

matrix:
include:
Expand Down
2 changes: 1 addition & 1 deletion edx_rest_framework_extensions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
""" edx Django REST Framework extensions. """

__version__ = '4.0.0' # pragma: no cover
__version__ = '4.0.1' # pragma: no cover
10 changes: 5 additions & 5 deletions edx_rest_framework_extensions/auth/jwt/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

import logging

import jwt
from django.contrib.auth import get_user_model
from django.middleware.csrf import CsrfViewMiddleware
from rest_framework import exceptions
from rest_framework_jwt.authentication import (
BaseJSONWebTokenAuthentication,
JSONWebTokenAuthentication,
)
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

from edx_rest_framework_extensions.auth.jwt.constants import USE_JWT_COOKIE_HEADER
from edx_rest_framework_extensions.auth.jwt.decoder import jwt_decode_handler
Expand Down Expand Up @@ -78,6 +76,8 @@ def authenticate(self, request):
# CSRF passed validation with authenticated user
return user_and_auth

except jwt.InvalidTokenError:
raise exceptions.AuthenticationFailed()
except Exception as ex:
# Errors in production do not need to be logged (as they may be noisy),
# but debug logging can help quickly resolve issues during development.
Expand Down Expand Up @@ -166,7 +166,7 @@ def enforce_csrf(self, request):

def is_jwt_authenticated(request):
successful_authenticator = getattr(request, 'successful_authenticator', None)
if not isinstance(successful_authenticator, BaseJSONWebTokenAuthentication):
if not isinstance(successful_authenticator, JSONWebTokenAuthentication):
return False
if not getattr(request, 'auth', None):
logger.error(
Expand Down
16 changes: 8 additions & 8 deletions edx_rest_framework_extensions/auth/jwt/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from edx_django_utils import monitoring
from edx_django_utils.cache import RequestCache
from rest_framework.request import Request
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

from edx_rest_framework_extensions.auth.jwt.constants import (
JWT_DELIMITER,
Expand Down Expand Up @@ -80,7 +80,7 @@ def process_view(self, request, view_func, view_args, view_kwargs): # pylint: d
view_class = _get_view_class(view_func)

view_authentication_classes = getattr(view_class, 'authentication_classes', tuple())
if _includes_base_class(view_authentication_classes, BaseJSONWebTokenAuthentication):
if _includes_base_class(view_authentication_classes, JSONWebTokenAuthentication):
self._add_missing_jwt_permission_classes(view_class)


Expand Down Expand Up @@ -184,7 +184,7 @@ class JwtAuthCookieMiddleware(MiddlewareMixin):
This middleware must appear before any AuthenticationMiddleware. For example::
MIDDLEWARE_CLASSES = (
MIDDLEWARE = (
'edx_rest_framework_extensions.auth.jwt.middleware.JwtAuthCookieMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
)
Expand All @@ -205,7 +205,7 @@ def process_view(self, request, view_func, view_args, view_kwargs): # pylint: d
"""
Reconstitute the full JWT and add a new cookie on the request object.
"""
assert hasattr(request, 'session'), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'." # noqa E501 line too long
assert hasattr(request, 'session'), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'." # noqa E501 line too long

use_jwt_cookie_requested = request.META.get(USE_JWT_COOKIE_HEADER)
header_payload_cookie = request.COOKIES.get(jwt_cookie_header_payload_name())
Expand Down Expand Up @@ -248,7 +248,7 @@ def process_view(self, request, view_func, view_args, view_kwargs): # pylint: d

def _get_user_from_jwt(request, view_func):
user = get_user(request)
if user.is_authenticated():
if user.is_authenticated:
return user

try:
Expand All @@ -271,14 +271,14 @@ def _get_user_from_jwt(request, view_func):

def _get_jwt_authentication_class(view_func):
"""
Returns the first DRF Authentication class that is a subclass of BaseJSONWebTokenAuthentication
Returns the first DRF Authentication class that is a subclass of JSONWebTokenAuthentication
"""
view_class = _get_view_class(view_func)
view_authentication_classes = getattr(view_class, 'authentication_classes', tuple())
if _includes_base_class(view_authentication_classes, BaseJSONWebTokenAuthentication):
if _includes_base_class(view_authentication_classes, JSONWebTokenAuthentication):
return next(
current_class for current_class in view_authentication_classes
if issubclass(current_class, BaseJSONWebTokenAuthentication)
if issubclass(current_class, JSONWebTokenAuthentication)
)
return None

Expand Down
24 changes: 12 additions & 12 deletions edx_rest_framework_extensions/auth/jwt/tests/test_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ViewSet
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

from edx_rest_framework_extensions.auth.jwt.constants import USE_JWT_COOKIE_HEADER
from edx_rest_framework_extensions.auth.jwt.cookies import (
Expand Down Expand Up @@ -45,7 +45,7 @@ class SomeIncludedPermissionClass:
pass


class SomeJwtAuthenticationSubclass(BaseJSONWebTokenAuthentication):
class SomeJwtAuthenticationSubclass(JSONWebTokenAuthentication):
pass


Expand Down Expand Up @@ -183,7 +183,7 @@ class HasNoCondPermView(APIView):
self.assertIn(NotJwtRestrictedApplication, HasNoCondPermView.permission_classes)


class MockJwtAuthentication(BaseJSONWebTokenAuthentication):
class MockJwtAuthentication(JSONWebTokenAuthentication):
"""
Authenticates a user if the reconstituted jwt cookie contains the expected value.
Expand Down Expand Up @@ -276,15 +276,15 @@ def setUp(self):
('/loginredirectifunauthenticated/', True, 200),
('/isauthenticatedandloginredirect/', False, 302),
('/isauthenticatedandloginredirect/', True, 200),
('/isauthenticated/', False, 403),
('/isauthenticated/', True, 403),
('/isauthenticated/', False, 401),
('/isauthenticated/', True, 401),
('/nopermissionsrequired/', False, 200),
('/nopermissionsrequired/', True, 200),
)
@ddt.unpack
@override_settings(
ROOT_URLCONF='edx_rest_framework_extensions.auth.jwt.tests.test_middleware',
MIDDLEWARE_CLASSES=(
MIDDLEWARE=(
'django.contrib.sessions.middleware.SessionMiddleware',
'edx_rest_framework_extensions.auth.jwt.middleware.JwtRedirectToLoginIfUnauthenticatedMiddleware',
'edx_rest_framework_extensions.auth.jwt.middleware.JwtAuthCookieMiddleware',
Expand All @@ -304,15 +304,15 @@ def test_login_required_middleware(self, url, has_jwt_cookies, expected_status):
('/loginredirectifunauthenticated/', True, 302),
('/isauthenticatedandloginredirect/', False, 302),
('/isauthenticatedandloginredirect/', True, 302),
('/isauthenticated/', False, 403),
('/isauthenticated/', True, 403),
('/isauthenticated/', False, 401),
('/isauthenticated/', True, 401),
('/nopermissionsrequired/', False, 200),
('/nopermissionsrequired/', True, 200),
)
@ddt.unpack
@override_settings(
ROOT_URLCONF='edx_rest_framework_extensions.auth.jwt.tests.test_middleware',
MIDDLEWARE_CLASSES=(
MIDDLEWARE=(
'django.contrib.sessions.middleware.SessionMiddleware',
'edx_rest_framework_extensions.auth.jwt.tests.test_middleware.OverriddenJwtRedirectToLoginIfUnauthenticatedMiddleware', # noqa E501 line too long
'edx_rest_framework_extensions.auth.jwt.middleware.JwtAuthCookieMiddleware',
Expand All @@ -334,7 +334,7 @@ class CheckRequestUserForJwtAuthMiddleware(MiddlewareMixin):
set the request.user.
"""
def process_view(self, request, view_func, view_args, view_kwargs): # pylint: disable=unused-argument
assert request.user.is_authenticated(), 'Request.user was expected to be authenticated.'
assert request.user.is_authenticated, 'Request.user was expected to be authenticated.'


class CheckRequestUserAnonymousForJwtAuthMiddleware(MiddlewareMixin):
Expand All @@ -343,7 +343,7 @@ class CheckRequestUserAnonymousForJwtAuthMiddleware(MiddlewareMixin):
the user (e.g. a failed cookie).
"""
def process_view(self, request, view_func, view_args, view_kwargs): # pylint: disable=unused-argument
assert not request.user.is_authenticated(), 'Request.user was expected to be anonymous.'
assert not request.user.is_authenticated, 'Request.user was expected to be anonymous.'


@ddt.ddt
Expand Down Expand Up @@ -422,7 +422,7 @@ def test_set_request_user_with_use_jwt_cookie(
)
with override_settings(
ROOT_URLCONF='edx_rest_framework_extensions.auth.jwt.tests.test_middleware',
MIDDLEWARE_CLASSES=(
MIDDLEWARE=(
'django.contrib.sessions.middleware.SessionMiddleware',
'edx_rest_framework_extensions.auth.jwt.middleware.JwtAuthCookieMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
Expand Down
2 changes: 1 addition & 1 deletion edx_rest_framework_extensions/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class RequestMetricsMiddleware(MiddlewareMixin):
This middleware is dependent on the RequestCacheMiddleware. You must
include this middleware later. For example::
MIDDLEWARE_CLASSES = (
MIDDLEWARE = (
'edx_django_utils.cache.middleware.RequestCacheMiddleware',
'edx_rest_framework_extensions.middleware.RequestMetricsMiddleware',
)
Expand Down
6 changes: 3 additions & 3 deletions edx_rest_framework_extensions/tests/test_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from rest_framework.authentication import SessionAuthentication
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

from edx_rest_framework_extensions import permissions
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
Expand Down Expand Up @@ -105,7 +105,7 @@ class JwtApplicationPermissionsTests(TestCase):
@ddt.data(
*product(
(permissions.JwtRestrictedApplication, permissions.NotJwtRestrictedApplication),
(JwtAuthentication, BaseJSONWebTokenAuthentication, SessionAuthentication, None),
(JwtAuthentication, JSONWebTokenAuthentication, SessionAuthentication, None),
(True, False),
)
)
Expand All @@ -116,7 +116,7 @@ def test_has_permission(self, permission_class, authentication_class, is_restric
request.user = factories.UserFactory()
request.auth = generate_jwt(request.user, is_restricted=is_restricted)

is_jwt_auth_subclass = issubclass(type(request.successful_authenticator), BaseJSONWebTokenAuthentication)
is_jwt_auth_subclass = issubclass(type(request.successful_authenticator), JSONWebTokenAuthentication)

has_permission = permission_class().has_permission(request, view=None)
expected_restricted_permission = is_restricted and is_jwt_auth_subclass
Expand Down
4 changes: 2 additions & 2 deletions requirements/base.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

Django>=1.11
djangorestframework>=3.2.0,<3.10
djangorestframework-jwt>=1.7.2,<2.0.0
drf-jwt
django-waffle
edx-django-utils
edx-opaque-keys
pyjwkest==1.3.2
pyjwkest
python-dateutil>=2.0
requests>=2.7.0
rest-condition>=1.0.3
Expand Down
10 changes: 5 additions & 5 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
certifi==2019.11.28 # via requests
chardet==3.0.4 # via requests
django-waffle==0.18.0 # via -c requirements/constraints.txt, -r requirements/base.in, edx-django-utils
django==1.11.29 # via -c requirements/constraints.txt, -r requirements/base.in, edx-django-utils, rest-condition
djangorestframework-jwt==1.11.0 # via -r requirements/base.in
djangorestframework==3.9.4 # via -r requirements/base.in, rest-condition
django==1.11.29 # via -c requirements/constraints.txt, -r requirements/base.in, drf-jwt, edx-django-utils, rest-condition
djangorestframework==3.9.4 # via -r requirements/base.in, drf-jwt, rest-condition
drf-jwt==1.14.0 # via -r requirements/base.in
edx-django-utils==3.0 # via -r requirements/base.in
edx-opaque-keys==2.0.1 # via -r requirements/base.in
future==0.18.2 # via pyjwkest
Expand All @@ -18,8 +18,8 @@ newrelic==5.8.0.136 # via edx-django-utils
pbr==5.4.4 # via stevedore
psutil==1.2.1 # via edx-django-utils
pycryptodomex==3.9.7 # via pyjwkest
pyjwkest==1.3.2 # via -r requirements/base.in
pyjwt==1.7.1 # via djangorestframework-jwt
pyjwkest==1.4.2 # via -r requirements/base.in
pyjwt==1.7.1 # via drf-jwt
pymongo==3.10.1 # via edx-opaque-keys
python-dateutil==2.8.1 # via -r requirements/base.in
pytz==2019.3 # via django
Expand Down
5 changes: 4 additions & 1 deletion requirements/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@
django<2.0

# django-waffle 0.19.0 dropped support for Django 2.0 and 2.1.
django-waffle<0.19.0
django-waffle<0.19.0

# django22 tests are failing.
drf-jwt<1.15.0
12 changes: 6 additions & 6 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ coverage==4.5.4 # via -r requirements/test.txt, pytest-cov
ddt==1.2.2 # via -r requirements/test.txt
distlib==0.3.0 # via -r requirements/test.txt, virtualenv
django-waffle==0.18.0 # via -c requirements/constraints.txt, -r requirements/base.txt, -r requirements/test.txt, edx-django-utils
django==1.11.29 # via -c requirements/constraints.txt, -r requirements/base.txt, -r requirements/test.txt, edx-django-utils, rest-condition
djangorestframework-jwt==1.11.0 # via -r requirements/base.txt, -r requirements/test.txt
djangorestframework==3.9.4 # via -r requirements/base.txt, -r requirements/test.txt, rest-condition
django==1.11.29 # via -c requirements/constraints.txt, -r requirements/base.txt, -r requirements/test.txt, drf-jwt, edx-django-utils, rest-condition
djangorestframework==3.9.4 # via -r requirements/base.txt, -r requirements/test.txt, drf-jwt, rest-condition
docutils==0.16 # via -r requirements/docs.txt, sphinx
drf-jwt==1.14.0 # via -r requirements/base.txt, -r requirements/test.txt
edx-django-utils==3.0 # via -r requirements/base.txt, -r requirements/test.txt
edx-lint==1.4.1 # via -r requirements/test.txt
edx-opaque-keys==2.0.1 # via -r requirements/base.txt, -r requirements/test.txt
Expand Down Expand Up @@ -50,8 +50,8 @@ py==1.8.1 # via -r requirements/test.txt, pytest, tox
pycodestyle==2.5.0 # via -r requirements/test.txt
pycryptodomex==3.9.7 # via -r requirements/base.txt, -r requirements/test.txt, pyjwkest
pygments==2.5.2 # via -r requirements/docs.txt, sphinx
pyjwkest==1.3.2 # via -r requirements/base.txt, -r requirements/test.txt
pyjwt==1.7.1 # via -r requirements/base.txt, -r requirements/test.txt, djangorestframework-jwt
pyjwkest==1.4.2 # via -r requirements/base.txt, -r requirements/test.txt
pyjwt==1.7.1 # via -r requirements/base.txt, -r requirements/test.txt, drf-jwt
pylint-celery==0.3 # via -r requirements/test.txt, edx-lint
pylint-django==2.0.11 # via -r requirements/test.txt, edx-lint
pylint-plugin-utils==0.6 # via -r requirements/test.txt, pylint-celery, pylint-django
Expand All @@ -69,7 +69,7 @@ semantic-version==2.8.4 # via -r requirements/base.txt, -r requirements/test.t
six==1.14.0 # via -r requirements/base.txt, -r requirements/docs.txt, -r requirements/test.txt, astroid, edx-lint, edx-opaque-keys, httpretty, mock, packaging, pathlib2, pyjwkest, python-dateutil, stevedore, tox, virtualenv
snowballstemmer==2.0.0 # via -r requirements/docs.txt, sphinx
sphinx-rtd-theme==0.4.3 # via -r requirements/docs.txt
sphinx==2.4.3 # via -r requirements/docs.txt, sphinx-rtd-theme
sphinx==2.4.4 # via -r requirements/docs.txt, sphinx-rtd-theme
sphinxcontrib-applehelp==1.0.2 # via -r requirements/docs.txt, sphinx
sphinxcontrib-devhelp==1.0.2 # via -r requirements/docs.txt, sphinx
sphinxcontrib-htmlhelp==1.0.3 # via -r requirements/docs.txt, sphinx
Expand Down
2 changes: 1 addition & 1 deletion requirements/docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ requests==2.23.0 # via -c requirements/test.txt, sphinx
six==1.14.0 # via -c requirements/test.txt, packaging
snowballstemmer==2.0.0 # via sphinx
sphinx-rtd-theme==0.4.3 # via -r requirements/docs.in
sphinx==2.4.3 # via -r requirements/docs.in, sphinx-rtd-theme
sphinx==2.4.4 # via -r requirements/docs.in, sphinx-rtd-theme
sphinxcontrib-applehelp==1.0.2 # via sphinx
sphinxcontrib-devhelp==1.0.2 # via sphinx
sphinxcontrib-htmlhelp==1.0.3 # via sphinx
Expand Down
1 change: 0 additions & 1 deletion requirements/test.in
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,3 @@ pycodestyle
pytest-cov
pytest-django
tox>=2.3.1,<3.0.0
pyjwkest==1.3.2
6 changes: 3 additions & 3 deletions requirements/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ coverage==4.5.4 # via -r requirements/test.in, pytest-cov
ddt==1.2.2 # via -r requirements/test.in
distlib==0.3.0 # via virtualenv
django-waffle==0.18.0 # via -c requirements/constraints.txt, -r requirements/base.txt, edx-django-utils
djangorestframework-jwt==1.11.0 # via -r requirements/base.txt
drf-jwt==1.14.0 # via -r requirements/base.txt
edx-django-utils==3.0 # via -r requirements/base.txt
edx-lint==1.4.1 # via -r requirements/test.in
edx-opaque-keys==2.0.1 # via -r requirements/base.txt
Expand All @@ -41,8 +41,8 @@ psutil==1.2.1 # via -r requirements/base.txt, edx-django-utils
py==1.8.1 # via pytest, tox
pycodestyle==2.5.0 # via -r requirements/test.in
pycryptodomex==3.9.7 # via -r requirements/base.txt, pyjwkest
pyjwkest==1.3.2 # via -r requirements/base.txt, -r requirements/test.in
pyjwt==1.7.1 # via -r requirements/base.txt, djangorestframework-jwt
pyjwkest==1.4.2 # via -r requirements/base.txt
pyjwt==1.7.1 # via -r requirements/base.txt, drf-jwt
pylint-celery==0.3 # via edx-lint
pylint-django==2.0.11 # via edx-lint
pylint-plugin-utils==0.6 # via pylint-celery, pylint-django
Expand Down
2 changes: 2 additions & 0 deletions test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'django.contrib.auth',
'django.contrib.contenttypes',
'edx_rest_framework_extensions',
'rest_framework_jwt',
'waffle',
)

Expand Down Expand Up @@ -50,6 +51,7 @@

'JWT_VERIFY_EXPIRATION': True,

'JWT_AUTH_HEADER_PREFIX': 'JWT',
# JWT_ISSUERS enables token decoding for multiple issuers (Note: This is not a native DRF-JWT field)
# We use it to allow different values for the 'ISSUER' field, but keep the same SECRET_KEY and
# AUDIENCE values across all issuers.
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py35-django{111,20,21,22}-drf{37,38,39,latest},quality, docs
envlist = py35-django{111,20,21,22}-drf{39,latest},quality, docs

[testenv]
setenv =
Expand Down

0 comments on commit 55ff432

Please sign in to comment.