Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions openedx/core/djangoapps/user_authn/cookies.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

def are_logged_in_cookies_set(request):
""" Check whether the request has logged in cookies set. """
if settings.FEATURES.get('DISABLE_SET_JWT_COOKIES_FOR_TESTS', False):
if _are_jwt_cookies_disabled():
cookies_that_should_exist = DEPRECATED_LOGGED_IN_COOKIE_NAMES
else:
cookies_that_should_exist = ALL_LOGGED_IN_COOKIE_NAMES
Expand Down Expand Up @@ -252,19 +252,7 @@ def _get_user_info_cookie_data(request, user):
def _create_and_set_jwt_cookies(response, request, cookie_settings, user=None, refresh_token=None):
""" Sets a cookie containing a JWT on the response. """

# Skip setting JWT cookies for most unit tests, since it raises errors when
# a login oauth client cannot be found in the database in ``_get_login_oauth_client``.
# This solution is not ideal, but see https://github.com/edx/edx-platform/pull/19180#issue-226706355
# for a discussion of alternative solutions that did not work or were halted.
if settings.FEATURES.get('DISABLE_SET_JWT_COOKIES_FOR_TESTS', False):
return

# For Ironwood, we don't set JWK settings by default. Make sure we don't fail trying
# to use empty settings. This means by default, micro-frontends won't work, but Ironwood
# has none. Also, OAuth scopes won't work, but that is still a new and specialized feature.
# Installations that need them can create JWKs and add them to the settings.
private_signing_jwk = settings.JWT_AUTH['JWT_PRIVATE_SIGNING_JWK']
if private_signing_jwk == "None" or not private_signing_jwk:
if _are_jwt_cookies_disabled():
return

# For security reasons, the JWT that is embedded inside the cookie expires
Expand Down Expand Up @@ -337,3 +325,25 @@ def _get_login_oauth_client():
raise AuthFailedError(
u"OAuth Client for the Login service, '{}', is not configured.".format(login_client_id)
)


def _are_jwt_cookies_disabled():
"""
Returns whether the use of JWT cookies is disabled.
"""
# Skip JWT cookies for most unit tests, since it raises errors when
# a login oauth client cannot be found in the database in ``_get_login_oauth_client``.
# This solution is not ideal, but see https://github.com/edx/edx-platform/pull/19180#issue-226706355
# for a discussion of alternative solutions that did not work or were halted.
if settings.FEATURES.get('DISABLE_SET_JWT_COOKIES_FOR_TESTS', False):
return True

# For Ironwood, we don't set JWK settings by default. Make sure we don't fail trying
# to use empty settings. This means by default, micro-frontends won't work, but Ironwood
# has none. Also, OAuth scopes won't work, but that is still a new and specialized feature.
# Installations that need them can create JWKs and add them to the settings.
private_signing_jwk = settings.JWT_AUTH['JWT_PRIVATE_SIGNING_JWK']
if private_signing_jwk == "None" or not private_signing_jwk:
return True

return False
28 changes: 18 additions & 10 deletions openedx/core/djangoapps/user_authn/tests/test_cookies.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# pylint: disable=missing-docstring
from __future__ import unicode_literals

import itertools

import ddt
from mock import MagicMock, patch
import six
from django.conf import settings
Expand All @@ -17,6 +20,7 @@
from student.tests.factories import UserFactory, AnonymousUserFactory


@ddt.ddt
class CookieTests(TestCase):
def setUp(self):
super(CookieTests, self).setUp()
Expand Down Expand Up @@ -117,16 +121,20 @@ def test_set_logged_in_jwt_cookies(self):
self._assert_consistent_expires(response)
self._assert_recreate_jwt_from_cookies(response, can_recreate=True)

@patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False})
def test_delete_and_are_logged_in_cookies_set(self):
setup_login_oauth_client()
response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
self._copy_cookies_to_request(response, self.request)
self.assertTrue(cookies_api.are_logged_in_cookies_set(self.request))

cookies_api.delete_logged_in_cookies(response)
self._copy_cookies_to_request(response, self.request)
self.assertFalse(cookies_api.are_logged_in_cookies_set(self.request))
@ddt.data(*itertools.product([True, False], [True, False]))
@ddt.unpack
def test_delete_and_are_logged_in_cookies_set(self, jwt_cookies_disabled, jwk_is_set):
jwt_private_signing_jwk = settings.JWT_AUTH['JWT_PRIVATE_SIGNING_JWK'] if jwk_is_set else None
with patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": jwt_cookies_disabled}):
with patch.dict("django.conf.settings.JWT_AUTH", {"JWT_PRIVATE_SIGNING_JWK": jwt_private_signing_jwk}):
setup_login_oauth_client()
response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
self._copy_cookies_to_request(response, self.request)
self.assertTrue(cookies_api.are_logged_in_cookies_set(self.request))

cookies_api.delete_logged_in_cookies(response)
self._copy_cookies_to_request(response, self.request)
self.assertFalse(cookies_api.are_logged_in_cookies_set(self.request))

@patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False})
def test_refresh_jwt_cookies(self):
Expand Down