diff --git a/openedx/core/djangoapps/user_authn/cookies.py b/openedx/core/djangoapps/user_authn/cookies.py index d36d299a3d00..37c90ead55da 100644 --- a/openedx/core/djangoapps/user_authn/cookies.py +++ b/openedx/core/djangoapps/user_authn/cookies.py @@ -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 @@ -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 @@ -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 diff --git a/openedx/core/djangoapps/user_authn/tests/test_cookies.py b/openedx/core/djangoapps/user_authn/tests/test_cookies.py index 3d0e1fcdcb08..5036d5a871f5 100644 --- a/openedx/core/djangoapps/user_authn/tests/test_cookies.py +++ b/openedx/core/djangoapps/user_authn/tests/test_cookies.py @@ -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 @@ -17,6 +20,7 @@ from student.tests.factories import UserFactory, AnonymousUserFactory +@ddt.ddt class CookieTests(TestCase): def setUp(self): super(CookieTests, self).setUp() @@ -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):