Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add user lang cookie preference #265

Merged
merged 2 commits into from
May 23, 2024
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
LanguagePreferenceMiddleware Backend.
"""


def get_language_preference_middleware():
"""Backend to get the LanguagePreferenceMiddleware from openedx."""
class LanguagePreferenceMiddleware:
"""LanguagePreferenceMiddleware Backend Mock."""
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
# Simulate the behavior of LanguagePreferenceMiddleware
# For example, set a language preference in the request
request.LANGUAGE_CODE = 'en'
return self.get_response(request)
return LanguagePreferenceMiddleware
11 changes: 11 additions & 0 deletions eox_core/edxapp_wrapper/language_preference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
""" Backend abstraction. """
from importlib import import_module

from django.conf import settings


def get_language_preference_middleware(*args, **kwargs):
""" Get LanguagePreferenceMiddleware. """
backend_function = settings.EOX_CORE_LANG_PREF_BACKEND
backend = import_module(backend_function)
return backend.get_language_preference_middleware(*args, **kwargs)
25 changes: 24 additions & 1 deletion eox_core/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
from django.db import IntegrityError
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.http import Http404, HttpResponseRedirect
from django.http import Http404, HttpResponseRedirect, parse_cookie
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin
from requests.exceptions import HTTPError
from social_core.exceptions import AuthAlreadyAssociated, AuthFailed, AuthUnreachableProvider

from eox_core.edxapp_wrapper.configuration_helpers import get_configuration_helper
from eox_core.edxapp_wrapper.language_preference import get_language_preference_middleware
from eox_core.edxapp_wrapper.third_party_auth import get_tpa_exception_middleware
from eox_core.models import Redirection
from eox_core.utils import cache, fasthash
Expand All @@ -38,6 +39,7 @@ class EoxTenantAuthException:

configuration_helper = get_configuration_helper() # pylint: disable=invalid-name
ExceptionMiddleware = get_tpa_exception_middleware()
LanguagePreferenceMiddleware = get_language_preference_middleware()

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -282,3 +284,24 @@ def process_exception(self, request, exception):
return super().process_exception(request, new_exception)

return super().process_exception(request, exception)


class UserLanguagePreferenceMiddleware(LanguagePreferenceMiddleware):
"""This Middleware allows 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
"""
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)
1 change: 1 addition & 0 deletions eox_core/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def plugin_settings(settings):
settings.EOX_CORE_BEARER_AUTHENTICATION = 'eox_core.edxapp_wrapper.backends.bearer_authentication_j_v1'
settings.EOX_CORE_ASYNC_TASKS = []
settings.EOX_CORE_THIRD_PARTY_AUTH_BACKEND = 'eox_core.edxapp_wrapper.backends.third_party_auth_l_v1'
settings.EOX_CORE_LANG_PREF_BACKEND = 'eox_core.edxapp_wrapper.backends.lang_pref_middleware_p_v1'

if settings.EOX_CORE_USER_ENABLE_MULTI_TENANCY:
settings.EOX_CORE_USER_ORIGIN_SITE_SOURCES = [
Expand Down
5 changes: 5 additions & 0 deletions eox_core/settings/production.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ def plugin_settings(settings): # pylint: disable=function-redefined
'eox_core.middleware.TPAExceptionMiddleware'
]

settings.MIDDLEWARE.insert(
settings.MIDDLEWARE.index("openedx.core.djangoapps.lang_pref.middleware.LanguagePreferenceMiddleware") + 1,
"eox_core.middleware.UserLanguagePreferenceMiddleware",
)

# Sentry Integration
sentry_integration_dsn = getattr(settings, 'ENV_TOKENS', {}).get(
'EOX_CORE_SENTRY_INTEGRATION_DSN',
Expand Down
1 change: 1 addition & 0 deletions eox_core/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def plugin_settings(settings): # pylint: disable=function-redefined
settings.EOX_CORE_USER_UPDATE_SAFE_FIELDS = ["is_active", "password", "fullname"]
settings.EOX_CORE_BEARER_AUTHENTICATION = 'eox_core.edxapp_wrapper.backends.bearer_authentication_j_v1_test'
settings.EOX_CORE_THIRD_PARTY_AUTH_BACKEND = 'eox_core.edxapp_wrapper.backends.third_party_auth_l_v1'
settings.EOX_CORE_LANG_PREF_BACKEND = 'eox_core.edxapp_wrapper.backends.lang_pref_middleware_p_v1_test'


SETTINGS = SettingsClass()
Expand Down
36 changes: 35 additions & 1 deletion eox_core/tests/test_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
Test module for the custom Middlewares
"""
import mock
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.http import Http404
from django.test import RequestFactory, TestCase

from eox_core.middleware import PathRedirectionMiddleware, RedirectionsMiddleware
from eox_core.middleware import PathRedirectionMiddleware, RedirectionsMiddleware, UserLanguagePreferenceMiddleware
from eox_core.models import Redirection


Expand Down Expand Up @@ -165,3 +166,36 @@ def test_redirection(self, redirection_get_mock):
result = self.middleware_instance.process_request(request)

self.assertIsNotNone(result)


class UserLanguagePreferenceMiddlewareTestCase(TestCase):
"""
Test the UserLanguagePreferenceMiddleware.
"""
def setUp(self):
self.factory = RequestFactory()
self.middleware = UserLanguagePreferenceMiddleware(get_response=lambda req: None)

def test_process_request_with_language_cookie(self):
"""
Test if the language cookie is set correctly in the request.
"""
language_code = 'fr'
request = self.factory.get('/')
request.META['HTTP_COOKIE'] = f'{settings.LANGUAGE_COOKIE_NAME}={language_code}'
self.middleware(request)

# Check if the language cookie was set correctly in the request
self.assertIn(settings.LANGUAGE_COOKIE_NAME, request.COOKIES)
self.assertEqual(request.COOKIES[settings.LANGUAGE_COOKIE_NAME], language_code)

def test_process_request_without_language_cookie(self):
"""
Test if the language cookie is not set in the request.
"""

request = self.factory.get('/')
self.middleware(request)

# Check that the language cookie is not set in the request
self.assertNotIn(settings.LANGUAGE_COOKIE_NAME, request.COOKIES)
Loading