From 86b58438e9a22dd62cd51cad3ca676bdd54e5643 Mon Sep 17 00:00:00 2001 From: Diana Catalina Olarte Date: Mon, 6 May 2024 21:58:08 +1000 Subject: [PATCH] feat: allow user set language preference --- .../lang_pref_middleware_p_test_v1.py | 8 +++++ .../backends/lang_pref_middleware_p_v1.py | 9 ++++++ .../edxapp_wrapper/language_preference.py | 11 +++++++ eox_tenant/settings/common.py | 1 + eox_tenant/settings/test.py | 2 ++ eox_tenant/tenant_wise/__init__.py | 8 ++++- eox_tenant/tenant_wise/proxies.py | 29 +++++++++++++++++++ 7 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 eox_tenant/edxapp_wrapper/backends/lang_pref_middleware_p_test_v1.py create mode 100644 eox_tenant/edxapp_wrapper/backends/lang_pref_middleware_p_v1.py create mode 100644 eox_tenant/edxapp_wrapper/language_preference.py diff --git a/eox_tenant/edxapp_wrapper/backends/lang_pref_middleware_p_test_v1.py b/eox_tenant/edxapp_wrapper/backends/lang_pref_middleware_p_test_v1.py new file mode 100644 index 00000000..66dda12a --- /dev/null +++ b/eox_tenant/edxapp_wrapper/backends/lang_pref_middleware_p_test_v1.py @@ -0,0 +1,8 @@ +""" +LanguagePreferenceMiddleware Backend for testing. +""" +from unittest.mock import MagicMock + +def get_language_preference_middleware(): + """Backend to mock the LanguagePreferenceMiddleware for testing.""" + return MagicMock() diff --git a/eox_tenant/edxapp_wrapper/backends/lang_pref_middleware_p_v1.py b/eox_tenant/edxapp_wrapper/backends/lang_pref_middleware_p_v1.py new file mode 100644 index 00000000..6d416e7e --- /dev/null +++ b/eox_tenant/edxapp_wrapper/backends/lang_pref_middleware_p_v1.py @@ -0,0 +1,9 @@ +""" +LanguagePreferenceMiddleware Backend. +""" +from openedx.core.djangoapps.lang_pref.middleware import LanguagePreferenceMiddleware # pylint: disable=import-error + + +def get_language_preference_middleware(): + """Backend to get the LanguagePreferenceMiddleware from openedx.""" + return LanguagePreferenceMiddleware diff --git a/eox_tenant/edxapp_wrapper/language_preference.py b/eox_tenant/edxapp_wrapper/language_preference.py new file mode 100644 index 00000000..49ee648b --- /dev/null +++ b/eox_tenant/edxapp_wrapper/language_preference.py @@ -0,0 +1,11 @@ +""" Backend abstraction. """ +from importlib import import_module + +from django.conf import settings + + +def get_language_preference_middleware(*args, **kwargs): + """ Get DarkLangMiddleware. """ + backend_function = settings.LANGUAGE_PREFERENCE_MIDDLEWARE + backend = import_module(backend_function) + return backend.get_language_preference_middleware(*args, **kwargs) \ No newline at end of file diff --git a/eox_tenant/settings/common.py b/eox_tenant/settings/common.py index d1921690..d74d0e37 100644 --- a/eox_tenant/settings/common.py +++ b/eox_tenant/settings/common.py @@ -47,6 +47,7 @@ def plugin_settings(settings): settings.EOX_MAX_CONFIG_OVERRIDE_SECONDS = 300 settings.EDXMAKO_MODULE_BACKEND = 'eox_tenant.edxapp_wrapper.backends.edxmako_l_v1' settings.UTILS_MODULE_BACKEND = 'eox_tenant.edxapp_wrapper.backends.util_h_v1' + settings.LANGUAGE_PREFERENCE_MIDDLEWARE = 'eox_tenant.edxapp_wrapper.backends.lang_pref_middleware_p_v1' settings.CHANGE_DOMAIN_DEFAULT_SITE_NAME = "stage.edunext.co" settings.EOX_TENANT_LOAD_PERMISSIONS = True settings.EOX_TENANT_APPEND_LMS_MIDDLEWARE_CLASSES = False diff --git a/eox_tenant/settings/test.py b/eox_tenant/settings/test.py index b4a9f1f5..9e837172 100644 --- a/eox_tenant/settings/test.py +++ b/eox_tenant/settings/test.py @@ -84,6 +84,8 @@ def plugin_settings(settings): # pylint: disable=function-redefined settings.FEATURES['USE_REDIRECTION_MIDDLEWARE'] = False settings.GET_SITE_CONFIGURATION_MODULE = 'eox_tenant.edxapp_wrapper.backends.site_configuration_module_test_v1' settings.GET_THEMING_HELPERS = 'eox_tenant.edxapp_wrapper.backends.theming_helpers_test_v1' + settings.LANGUAGE_PREFERENCE_MIDDLEWARE = 'eox_tenant.edxapp_wrapper.backends.lang_pref_middleware_p_test_v1' + settings.EOX_TENANT_SKIP_FILTER_FOR_TESTS = True settings.EOX_TENANT_LOAD_PERMISSIONS = False if hasattr(settings, 'OAUTH2_PROVIDER'): diff --git a/eox_tenant/tenant_wise/__init__.py b/eox_tenant/tenant_wise/__init__.py index 9e2edef1..8f38067f 100644 --- a/eox_tenant/tenant_wise/__init__.py +++ b/eox_tenant/tenant_wise/__init__.py @@ -11,7 +11,7 @@ from eox_tenant.constants import LMS_ENVIRONMENT from eox_tenant.tenant_aware_functions.released_languages import tenant_languages -from eox_tenant.tenant_wise.proxies import TenantSiteConfigProxy +from eox_tenant.tenant_wise.proxies import LanguagePreferenceMiddlewareProxy, TenantSiteConfigProxy def load_tenant_wise_overrides(): @@ -39,6 +39,12 @@ def load_tenant_wise_overrides(): model='released_languages', proxy=tenant_languages ) + + set_as_proxy( + modules='openedx.core.djangoapps.lang_pref.middleware', + model='LanguagePreferenceMiddleware', + proxy=LanguagePreferenceMiddlewareProxy + ) def set_as_proxy(modules, model, proxy): diff --git a/eox_tenant/tenant_wise/proxies.py b/eox_tenant/tenant_wise/proxies.py index 05ddcbae..5cfecf82 100644 --- a/eox_tenant/tenant_wise/proxies.py +++ b/eox_tenant/tenant_wise/proxies.py @@ -8,12 +8,15 @@ import six from django.conf import settings from django.core.cache import cache +from django.http import parse_cookie from eox_tenant.edxapp_wrapper.site_configuration_module import get_site_configuration_models +from eox_tenant.edxapp_wrapper.language_preference import get_language_preference_middleware from eox_tenant.models import Microsite, TenantConfig, TenantOrganization from eox_tenant.utils import clean_serializable_values SiteConfigurationModels = get_site_configuration_models() +LanguagePreferenceMiddleware = get_language_preference_middleware() TENANT_ALL_ORGS_CACHE_KEY = "tenant.all_orgs_list" EOX_TENANT_CACHE_KEY_TIMEOUT = getattr( @@ -204,3 +207,29 @@ def pre_load_values_by_org(cls, val_name): cls.set_key_to_cache(key, result) cls.set_key_to_cache(pre_load_value_key, True) + +class LanguagePreferenceMiddlewareProxy(LanguagePreferenceMiddleware): + """This Middleware will be used if you have FEATURES["EDNX_SITE_AWARE_LOCALE"] in True. + Allow the user set the language preference for the site, avoiding the default LANGUAGE_CODE. + + The previous behavior was modified here + https://github.com/openedx/edx-platform/blob/open-release/palm.master/openedx/core/djangoapps/lang_pref/middleware.py#L61-L62 + """ + + class Meta: + """ Set as a proxy model. """ + proxy = True + + def process_request(self, request): + """ + 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. + """ + original_user_language_cookie = parse_cookie(request.META.get("HTTP_COOKIE", "")).get( + settings.LANGUAGE_COOKIE_NAME + ) + + if original_user_language_cookie: + request.COOKIES[settings.LANGUAGE_COOKIE_NAME] = original_user_language_cookie + + return self.get_response(request) \ No newline at end of file