diff --git a/openedx/core/djangoapps/dark_lang/middleware.py b/openedx/core/djangoapps/dark_lang/middleware.py index 4663478fff..36c4798a79 100644 --- a/openedx/core/djangoapps/dark_lang/middleware.py +++ b/openedx/core/djangoapps/dark_lang/middleware.py @@ -16,7 +16,7 @@ from django.utils.deprecation import MiddlewareMixin from openedx.core.djangoapps.dark_lang import DARK_LANGUAGE_KEY from openedx.core.djangoapps.dark_lang.models import DarkLangConfig -from openedx.core.djangoapps.lang_pref import COOKIE_DURATION +from openedx.core.djangoapps.lang_pref.helpers import set_language_cookie from openedx.core.djangoapps.site_configuration.helpers import get_value from openedx.core.djangoapps.user_api.preferences.api import get_user_preference @@ -110,13 +110,7 @@ class DarkLangMiddleware(MiddlewareMixin): language = get_value('LANGUAGE_CODE', None) if language: request.session[LANGUAGE_SESSION_KEY] = language - response.set_cookie( - settings.LANGUAGE_COOKIE_NAME, - value=language, - domain=settings.SHARED_COOKIE_DOMAIN, - max_age=COOKIE_DURATION, - secure=request.is_secure() - ) + set_language_cookie(request, response, language) def _fuzzy_match(self, lang_code): """Returns a fuzzy match for lang_code""" @@ -174,10 +168,4 @@ class DarkLangMiddleware(MiddlewareMixin): # Set the session key to the requested preview lang request.session[LANGUAGE_SESSION_KEY] = preview_lang - response.set_cookie( - settings.LANGUAGE_COOKIE_NAME, - value=preview_lang, - domain=settings.SHARED_COOKIE_DOMAIN, - max_age=COOKIE_DURATION, - secure=request.is_secure() - ) + set_language_cookie(request, response, preview_lang) diff --git a/openedx/core/djangoapps/lang_pref/helpers.py b/openedx/core/djangoapps/lang_pref/helpers.py new file mode 100644 index 0000000000..27b8541684 --- /dev/null +++ b/openedx/core/djangoapps/lang_pref/helpers.py @@ -0,0 +1,36 @@ +""" +Language preference cookie helper functions +""" +from django.conf import settings + +from openedx.core.djangoapps.lang_pref import COOKIE_DURATION + + +def get_language_cookie(request, default=None): + """ + Return the language cookie stored in the request object. + """ + return request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME, default) + + +def set_language_cookie(request, response, value): + """ + Set the language cookie in the response object. + """ + response.set_cookie( + settings.LANGUAGE_COOKIE_NAME, + value=value, + domain=settings.SHARED_COOKIE_DOMAIN, + max_age=COOKIE_DURATION, + secure=request.is_secure(), + samesite="None" if request.is_secure() else "Lax", + ) + + +def unset_language_cookie(response): + """ + Remove the language cookie from the response object. + """ + response.delete_cookie( + settings.LANGUAGE_COOKIE_NAME, domain=settings.SHARED_COOKIE_DOMAIN + ) diff --git a/openedx/core/djangoapps/lang_pref/middleware.py b/openedx/core/djangoapps/lang_pref/middleware.py index 8e568baaf7..d0a787c5da 100644 --- a/openedx/core/djangoapps/lang_pref/middleware.py +++ b/openedx/core/djangoapps/lang_pref/middleware.py @@ -3,14 +3,14 @@ Middleware for Language Preferences """ -from django.conf import settings from django.utils.deprecation import MiddlewareMixin from django.utils.translation import LANGUAGE_SESSION_KEY from django.utils.translation.trans_real import parse_accept_lang_header from openedx.core.djangoapps.dark_lang import DARK_LANGUAGE_KEY from openedx.core.djangoapps.dark_lang.models import DarkLangConfig -from openedx.core.djangoapps.lang_pref import COOKIE_DURATION, LANGUAGE_HEADER, LANGUAGE_KEY +from openedx.core.djangoapps.lang_pref import LANGUAGE_HEADER, LANGUAGE_KEY +from openedx.core.djangoapps.lang_pref import helpers as lang_pref_helpers from openedx.core.djangoapps.user_api.errors import UserAPIInternalError, UserAPIRequestError from openedx.core.djangoapps.user_api.preferences.api import get_user_preference, set_user_preference from openedx.core.lib.mobile_utils import is_request_from_mobile_app @@ -29,7 +29,7 @@ class LanguagePreferenceMiddleware(MiddlewareMixin): If a user's UserPreference contains a language preference, use the user's preference. Save the current language preference cookie as the user's preferred language. """ - cookie_lang = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME, None) + cookie_lang = lang_pref_helpers.get_language_cookie(request) if cookie_lang: if request.user.is_authenticated: # DarkLangMiddleware will take care of this so don't change anything @@ -82,17 +82,8 @@ class LanguagePreferenceMiddleware(MiddlewareMixin): # If set, set the user_pref in the LANGUAGE_COOKIE_NAME if user_pref and not is_request_from_mobile_app(request): - response.set_cookie( - settings.LANGUAGE_COOKIE_NAME, - value=user_pref, - domain=settings.SHARED_COOKIE_DOMAIN, - max_age=COOKIE_DURATION, - secure=request.is_secure() - ) + lang_pref_helpers.set_language_cookie(request, response, user_pref) else: - response.delete_cookie( - settings.LANGUAGE_COOKIE_NAME, - domain=settings.SHARED_COOKIE_DOMAIN - ) + lang_pref_helpers.unset_language_cookie(response) return response diff --git a/openedx/core/djangoapps/lang_pref/tests/test_middleware.py b/openedx/core/djangoapps/lang_pref/tests/test_middleware.py index 725478bab3..b62b05b7d9 100644 --- a/openedx/core/djangoapps/lang_pref/tests/test_middleware.py +++ b/openedx/core/djangoapps/lang_pref/tests/test_middleware.py @@ -75,6 +75,7 @@ class TestUserPreferenceMiddleware(CacheIsolationTestCase): domain=settings.SESSION_COOKIE_DOMAIN, max_age=COOKIE_DURATION, secure=self.request.is_secure(), + samesite="Lax" ) else: response.delete_cookie.assert_called_with( diff --git a/openedx/core/djangoapps/lang_pref/views.py b/openedx/core/djangoapps/lang_pref/views.py index af753701f4..b98b06a33f 100644 --- a/openedx/core/djangoapps/lang_pref/views.py +++ b/openedx/core/djangoapps/lang_pref/views.py @@ -10,7 +10,8 @@ from django.http import HttpResponse from django.utils.translation import LANGUAGE_SESSION_KEY from django.views.decorators.csrf import ensure_csrf_cookie -from openedx.core.djangoapps.lang_pref import COOKIE_DURATION, LANGUAGE_KEY +from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY +from openedx.core.djangoapps.lang_pref.helpers import set_language_cookie @ensure_csrf_cookie @@ -24,11 +25,5 @@ def update_session_language(request): language = data.get(LANGUAGE_KEY, settings.LANGUAGE_CODE) if request.session.get(LANGUAGE_SESSION_KEY, None) != language: request.session[LANGUAGE_SESSION_KEY] = str(language) - response.set_cookie( - settings.LANGUAGE_COOKIE_NAME, - language, - domain=settings.SHARED_COOKIE_DOMAIN, - max_age=COOKIE_DURATION, - secure=request.is_secure(), - ) + set_language_cookie(request, response, language) return response