def test_setlang_null_next_valid(self): """ The set_language view can be used to change the session language. The user is redirected to the "next" argument. """ lang_code = self._get_inactive_language_code() post_data = dict(language=lang_code) response = self.client.post(reverse("kolibri:core:set_language"), post_data) self.assertEqual(response.status_code, 200) self.assertEqual( response.content.decode("utf-8"), translate_url(reverse("kolibri:core:redirect_user"), lang_code), ) self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) next_url = reverse("kolibri:kolibri.plugins.learn:learn") post_data = dict(language=None, next=next_url) response = self.client.post(reverse("kolibri:core:set_language"), post_data) self.assertEqual(response.status_code, 200) self.assertEqual( response.content.decode("utf-8"), translate_url(reverse("kolibri:kolibri.plugins.learn:learn"), "en"), ) self.assertFalse(LANGUAGE_SESSION_KEY in self.client.session)
def set_language(request): """ Since this view changes how the user will see the rest of the site, it must only be accessed as a POST request. If called as a GET request, it will error. """ lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER) next_url = urlsplit(request.POST.get("next")) if request.POST.get("next") else None if lang_code and check_for_language(lang_code): if next_url and is_valid_path(next_url.path): # If it is a recognized Kolibri path, then translate it to the new language and return it. next_path = urlunsplit( ( next_url[0], next_url[1], translate_url(next_url[2], lang_code), next_url[3], next_url[4], ) ) else: next_path = translate_url(reverse("kolibri:core:redirect_user"), lang_code) response = HttpResponse(next_path) if hasattr(request, "session"): request.session[LANGUAGE_SESSION_KEY] = lang_code # Always set cookie response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, ) else: lang_code = ( get_device_language() or get_accept_headers_language(request) or get_settings_language() ) if next_url and is_valid_path(next_url.path): # If it is a recognized Kolibri path, then translate it using the default language code for this device next_path = urlunsplit( ( next_url[0], next_url[1], translate_url(next_url[2], lang_code), next_url[3], next_url[4], ) ) else: next_path = translate_url(reverse("kolibri:core:redirect_user"), lang_code) response = HttpResponse(next_path) if hasattr(request, "session"): request.session.pop(LANGUAGE_SESSION_KEY, "") response.delete_cookie(settings.LANGUAGE_COOKIE_NAME) return response
def test_translate_url_utility(self): with translation.override("en"): self.assertEqual(translate_url("/en/non-existent/", "nl"), "/en/non-existent/") self.assertEqual(translate_url("/en/users/", "nl"), "/nl/gebruikers/") # Namespaced URL self.assertEqual(translate_url("/en/account/register/", "nl"), "/nl/profiel/registeren/") self.assertEqual(translation.get_language(), "en") with translation.override("nl"): self.assertEqual(translate_url("/nl/gebruikers/", "en"), "/en/users/") self.assertEqual(translation.get_language(), "nl")
def test_translate_url_utility(self): with translation.override('en'): self.assertEqual(translate_url('/en/nonexistent/', 'nl'), '/en/nonexistent/') self.assertEqual(translate_url('/en/users/', 'nl'), '/nl/gebruikers/') # Namespaced URL self.assertEqual(translate_url('/en/account/register/', 'nl'), '/nl/profiel/registeren/') self.assertEqual(translation.get_language(), 'en') with translation.override('nl'): self.assertEqual(translate_url('/nl/gebruikers/', 'en'), '/en/users/') self.assertEqual(translation.get_language(), 'nl')
def test_translate_url_utility(self): with translation.override('en'): self.assertEqual(translate_url('/en/nonexistent/', 'nl'), '/en/nonexistent/') self.assertEqual(translate_url('/en/users/', 'nl'), '/nl/gebruikers/') # Namespaced URL self.assertEqual(translate_url('/en/account/register/', 'nl'), '/nl/profiel/registreren/') self.assertEqual(translation.get_language(), 'en') with translation.override('nl'): self.assertEqual(translate_url('/nl/gebruikers/', 'en'), '/en/users/') self.assertEqual(translation.get_language(), 'nl')
def set_language(request): """ Redirect to a given URL while setting the chosen language in the session (if enabled) and in a cookie. The URL and the language code need to be specified in the request parameters. Since this view changes how the user will see the rest of the site, it must only be accessed as a POST request. If called as a GET request, it will redirect to the page in the request (the 'next' parameter) without changing any state. """ next = request.POST.get('next', request.GET.get('next')) if ((next or not request.is_ajax()) and not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure())): next = request.META.get('HTTP_REFERER') next = next and unquote(next) # HTTP_REFERER may be encoded. if not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure()): next = '/' response = HttpResponseRedirect(next) if next else HttpResponse(status=204) if request.method == 'POST': lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER) if lang_code and check_for_language(lang_code): if next: next_trans = translate_url(next, lang_code) if next_trans != next: response = HttpResponseRedirect(next_trans) if hasattr(request, 'session'): request.session[LANGUAGE_SESSION_KEY] = lang_code response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, ) return response
def set_language(request): """ Redirect to a given url while setting the chosen language in the session or cookie. The url and the language code need to be specified in the request parameters. Since this view changes how the user will see the rest of the site, it must only be accessed as a POST request. If called as a GET request, it will redirect to the page in the request (the 'next' parameter) without changing any state. """ next = request.POST.get('next', request.GET.get('next')) if not is_safe_url(url=next, host=request.get_host()): next = request.META.get('HTTP_REFERER') if not is_safe_url(url=next, host=request.get_host()): next = '/' response = http.HttpResponseRedirect(next) if request.method == 'POST': lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER) if lang_code and check_for_language(lang_code): next_trans = translate_url(next, lang_code) if next_trans != next: response = http.HttpResponseRedirect(next_trans) if hasattr(request, 'session'): request.session[LANGUAGE_SESSION_KEY] = lang_code else: response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN) return response
def set_lang(request): next = request.POST.get('next', request.GET.get('next')) if ((next or not request.is_ajax()) and not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure())): next = request.META.get('HTTP_REFERER') next = next and unquote(next) # HTTP_REFERER may be encoded. if not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure()): next = '/' response = HttpResponseRedirect(next) if next else HttpResponse(status=204) if request.method == 'POST': lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER) if lang_code and check_for_language(lang_code): if next: next_trans = translate_url(next, lang_code) response = HttpResponseRedirect(next_trans + "position") if hasattr(request, 'session'): request.session[LANGUAGE_SESSION_KEY] = lang_code response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, ) return response
def get_language_menu(request): from django.core.urlresolvers import reverse menu = [] for language_code, language_name in settings.LANGUAGES: if settings.MESTO_SITE == 'mesto' and language_code == 'hu': continue else: translated_url = translate_url(request.get_full_path(), language_code) if request.user.is_authenticated(): url = '%s?next=%s' % (reverse('profile_set_language', args=[language_code ]), translated_url) else: url = translated_url item = (language_name, url) if language_code == request.LANGUAGE_CODE: menu.insert(0, item) else: menu.append(item) return menu
def set_language(request): """ Redirect to a given URL while setting the chosen language in the session (if enabled) and in a cookie. The URL and the language code need to be specified in the request parameters. Since this view changes how the user.txt will see the rest of the site, it must only be accessed as a POST request. If called as a GET request, it will redirect to the page in the request (the 'next' parameter) without changing any state. """ next = request.POST.get('next', request.GET.get('next')) if ((next or not request.is_ajax()) and not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure())): next = request.META.get('HTTP_REFERER') next = next and unquote(next) # HTTP_REFERER may be encoded. if not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure()): next = '/' response = HttpResponseRedirect(next) if next else HttpResponse(status=204) if request.method == 'POST': lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER) if lang_code and check_for_language(lang_code): if next: next_trans = translate_url(next, lang_code) if next_trans != next: response = HttpResponseRedirect(next_trans) if hasattr(request, 'session'): request.session[LANGUAGE_SESSION_KEY] = lang_code response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, ) return response
def set_language(request): """ Copy of i18n set_language but without csrf_token """ next_url = request.POST.get('next', request.GET.get('next')) response = HttpResponseRedirect(next_url) if next_url else HttpResponse( status=204) if request.method == 'POST': lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER) if lang_code and next_url: if next_url[len(next_url) - 1] != "/": next_url += "/" response = HttpResponseRedirect(translate_url(next_url, lang_code)) response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, secure=settings.LANGUAGE_COOKIE_SECURE, httponly=settings.LANGUAGE_COOKIE_HTTPONLY, samesite=settings.LANGUAGE_COOKIE_SAMESITE, ) return response
def set_language(request): """ Redirect to a given url while setting the chosen language in the session or cookie. The url and the language code need to be specified in the request parameters. Since this view changes how the user will see the rest of the site, it must only be accessed as a POST request. If called as a GET request, it will redirect to the page in the request (the 'next' parameter) without changing any state. """ next = request.POST.get("next", request.GET.get("next")) if (next or not request.is_ajax()) and not is_safe_url(url=next, host=request.get_host()): next = request.META.get("HTTP_REFERER") if not is_safe_url(url=next, host=request.get_host()): next = "/" response = http.HttpResponseRedirect(next) if next else http.HttpResponse(status=204) if request.method == "POST": lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER) if lang_code and check_for_language(lang_code): if next: next_trans = translate_url(next, lang_code) if next_trans != next: response = http.HttpResponseRedirect(next_trans) if hasattr(request, "session"): request.session[LANGUAGE_SESSION_KEY] = lang_code else: response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, ) return response
def get(self, request, *args, **kwargs): next = request.GET.get('next') lang_code = request.GET.get('language') response = HttpResponseRedirect(next) if next else HttpResponse( status=204) if lang_code and check_for_language(lang_code): if next: next_trans = translate_url(next, lang_code) if next_trans != next: response = HttpResponseRedirect(next_trans) if hasattr(request, 'session'): # Storing the language in the session is deprecated. # (RemovedInDjango40Warning) request.session[LANGUAGE_SESSION_KEY] = lang_code response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, secure=settings.LANGUAGE_COOKIE_SECURE, httponly=settings.LANGUAGE_COOKIE_HTTPONLY, samesite=settings.LANGUAGE_COOKIE_SAMESITE, ) return response
def set_language(request): """ Since this view changes how the user will see the rest of the site, it must only be accessed as a POST request. If called as a GET request, it will error. """ payload = json.loads(request.body) lang_code = payload.get(LANGUAGE_QUERY_PARAMETER) next_url = urlsplit(payload.get("next")) if payload.get("next") else None if lang_code and lang_code in SUPPORTED_LANGUAGES: if next_url and is_valid_path(next_url.path): # If it is a recognized path, then translate it to the new language and return it. next_path = urlunsplit( ( next_url[0], next_url[1], translate_url(next_url[2], lang_code), next_url[3], next_url[4], ) ) else: # Just redirect to the base URL w/ the lang_code next_path = translate_url(reverse('base'), lang_code) response = HttpResponse(next_path) if hasattr(request, "session"): request.session[LANGUAGE_SESSION_KEY] = lang_code else: lang_code = get_language() if next_url and is_valid_path(next_url.path): # If it is a recognized path, then translate it using the default language code for this device next_path = urlunsplit( ( next_url[0], next_url[1], translate_url(next_url[2], lang_code), next_url[3], next_url[4], ) ) else: # Just redirect to the base URL w/ the lang_code, likely the default language next_path = translate_url(reverse('base'), lang_code) response = HttpResponse(next_path) if hasattr(request, "session"): request.session.pop(LANGUAGE_SESSION_KEY, "") return response
def translate_url(context: Dict[str, Any], language: Optional[str]) -> str: """Get the absolute URL of the current page for the specified language. Usage: {% translate_url 'en' %} """ url = context['request'].build_absolute_uri() return urls.translate_url(url, language)
def current_url_for_lang(context, lang: str): if 'request' not in context: return "" path = context['request'].build_absolute_uri() if path[len(path) - 1] != "/": path += "/" return translate_url(path, lang)
def test_translate_url_utility(self): with translation.override("en"): self.assertEqual(translate_url("/en/nonexistent/", "nl"), "/en/nonexistent/") self.assertEqual(translate_url("/en/users/", "nl"), "/nl/gebruikers/") # Namespaced URL self.assertEqual(translate_url("/en/account/register/", "nl"), "/nl/profiel/registreren/") # path() URL pattern self.assertEqual( translate_url("/en/account/register-as-path/", "nl"), "/nl/profiel/registreren-als-pad/", ) self.assertEqual(translation.get_language(), "en") # URL with parameters. self.assertEqual( translate_url("/en/with-arguments/regular-argument/", "nl"), "/nl/with-arguments/regular-argument/", ) self.assertEqual( translate_url( "/en/with-arguments/regular-argument/optional.html", "nl"), "/nl/with-arguments/regular-argument/optional.html", ) with translation.override("nl"): self.assertEqual(translate_url("/nl/gebruikers/", "en"), "/en/users/") self.assertEqual(translation.get_language(), "nl")
def test_translate_url_utility(self): with translation.override('en'): self.assertEqual(translate_url('/en/nonexistent/', 'nl'), '/en/nonexistent/') self.assertEqual(translate_url('/en/users/', 'nl'), '/nl/gebruikers/') # Namespaced URL self.assertEqual(translate_url('/en/account/register/', 'nl'), '/nl/profiel/registreren/') # path() URL pattern self.assertEqual( translate_url('/en/account/register-as-path/', 'nl'), '/nl/profiel/registreren-als-pad/') self.assertEqual(translation.get_language(), 'en') # URL with parameters. self.assertEqual( translate_url('/en/with-arguments/regular-argument/', 'nl'), '/nl/with-arguments/regular-argument/', ) self.assertEqual( translate_url( '/en/with-arguments/regular-argument/optional.html', 'nl'), '/nl/with-arguments/regular-argument/optional.html', ) with translation.override('nl'): self.assertEqual(translate_url('/nl/gebruikers/', 'en'), '/en/users/') self.assertEqual(translation.get_language(), 'nl')
def get_success_url(self): url = super().get_success_url() user = self.request.user if user.is_authenticated: user_language = user.settings.language url = translate_url(url, user_language) activate(user_language) if hasattr(self.request, 'session'): self.request.session[LANGUAGE_SESSION_KEY] = user_language return url
def change_lang(context, lang=None, *args, **kwargs): """ Get active page's url by a specified language Usage: {% change_lang 'en' %} """ if 'request' not in context: return "/%s" % lang path = context['request'].path return translate_url(path, lang)
def translate_url(context: Dict[str, Any], language: Optional[str]) -> str: """Get the absolute URL of the current page for the specified language. Usage: {% translate_url 'en' %} """ try: url = context['request'].build_absolute_uri() return urls.translate_url(url, language) except Exception as e: print('core/templatetags/core/translate_url:', e)
def languages(request): languages_list = [] for language_code, language_name in settings.LANGUAGES: languages_list.append((language_code, language_name, translate_url(str(request.path), language_code))) return { 'languages': languages_list, }
def myset_language(request): """ Redirect to a given url while setting the chosen language in the session or cookie. The url and the language code need to be specified in the request parameters. Since this view changes how the user will see the rest of the site, it must only be accessed as a POST request. If called as a GET request, it will redirect to the page in the request (the 'next' parameter) without changing any state. """ def update_profile(request, lang_code): user_id = request.user.id users = User.objects.filter(pk=user_id) if len(users) > 0: user = users[0] else: return user.profile.language = lang_code user.save() next = request.POST.get('next', request.GET.get('next')) if ((next or not request.is_ajax()) and not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure())): next = request.META.get('HTTP_REFERER') if next: next = urlunquote(next) # HTTP_REFERER may be encoded. if not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure()): next = '/' response = http.HttpResponseRedirect(next) if next else http.HttpResponse( status=204) if request.method == 'POST': lang_code = request.POST.get('language') if lang_code and check_for_language(lang_code): if next: next_trans = translate_url(next, lang_code) if next_trans != next: response = http.HttpResponseRedirect(next_trans) if hasattr(request, 'session'): request.session[LANGUAGE_SESSION_KEY] = lang_code else: response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, ) update_profile(request=request, lang_code=lang_code) return response
def change_lang(context, lang=None, *args, **kwargs): """ Returns the translated version of the current URL. Example: <a href="{% change_lang 'en' %}">English version</a> Adapted from: https://stackoverflow.com/a/57578343 """ path = context['request'].path return translate_url(path, lang)
def set_language(request): """ Redirect to a given URL while setting the chosen language in the session (if enabled) and in a cookie. The URL and the language code need to be specified in the request parameters. Since this view changes how the user will see the rest of the site, it must only be accessed as a POST request. If called as a GET request, it will redirect to the page in the request (the 'next' parameter) without changing any state. """ next_url = request.POST.get("next", request.GET.get("next")) if next_url and not url_has_allowed_host_and_scheme( url=next_url, allowed_hosts={request.get_host()}, require_https=request.is_secure(), ): next_url = request.META.get("HTTP_REFERER") # HTTP_REFERER may be encoded. next_url = next_url and unquote(next_url) if not url_has_allowed_host_and_scheme( url=next_url, allowed_hosts={request.get_host()}, require_https=request.is_secure(), ): next_url = "/" response = HttpResponseRedirect(next_url) if next_url else HttpResponse( status=204) if request.method == "POST": lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER) if lang_code and check_for_language(lang_code): if next_url: next_trans = translate_url(next_url, lang_code) if next_trans != next_url: response = HttpResponseRedirect(next_trans) if hasattr(request, "session"): # Storing the language in the session is deprecated. # (RemovedInDjango40Warning) request.session[LANGUAGE_SESSION_KEY] = lang_code response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, secure=settings.LANGUAGE_COOKIE_SECURE, httponly=settings.LANGUAGE_COOKIE_HTTPONLY, samesite=settings.LANGUAGE_COOKIE_SAMESITE, ) if request.user.is_authenticated: request.user.userprofile.lang = lang_code request.user.userprofile.save() return response
def test_sitemap(client, product): product_url = build_absolute_uri(product.get_absolute_url()) category_url = build_absolute_uri(product.category.get_absolute_url()) expected_urls = [product_url, category_url] language_codes = [lang_code for lang_code, lang_name in settings.LANGUAGES] expected_urls_i18n = [ translate_url(url, language_code) for url in expected_urls for language_code in language_codes ] response = client.get(reverse('django.contrib.sitemaps.views.sitemap')) sitemap_links = [url['location'] for url in response.context['urlset']] assert sorted(sitemap_links) == sorted(expected_urls_i18n)
def test_setlang(self): """ The set_language view can be used to change the session language. """ lang_code = self._get_inactive_language_code() post_data = dict(language=lang_code) response = self.client.post(reverse("kolibri:core:set_language"), post_data) self.assertEqual(response.status_code, 200) self.assertEqual( response.content.decode("utf-8"), translate_url(reverse("kolibri:core:redirect_user"), lang_code), ) self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def test_sitemap(client, product): product_url = build_absolute_uri(product.get_absolute_url()) category_url = build_absolute_uri( product.category.get_absolute_url()) expected_urls = [product_url, category_url] language_codes = [lang_code for lang_code, lang_name in settings.LANGUAGES] expected_urls_i18n = [ translate_url(url, language_code) for url in expected_urls for language_code in language_codes] response = client.get(reverse('django.contrib.sitemaps.views.sitemap')) sitemap_links = [url['location'] for url in response.context['urlset']] assert sorted(sitemap_links) == sorted(expected_urls_i18n)
def get_languages_menu(context): path = context['request'].get_full_path() current_ln = get_language() langs = [] for ln in LANGUAGES: langs.append({ 'name': ln[1], 'code': ln[0], 'link': translate_url(path, ln[0]), 'active': True if current_ln == ln[0] else False }) return render_to_string('sitemenu/_languages.html', {'langs': langs,})
def test_setlang_next_invalid(self): """ The set_language view can be used to change the session language. The user is redirected to user redirect if the "next" argument is invalid. """ lang_code = self._get_inactive_language_code() next_url = "/not/a/real/url" post_data = dict(language=lang_code, next=next_url) response = self.client.post(reverse("kolibri:core:set_language"), post_data) self.assertEqual(response.status_code, 200) self.assertEqual( response.content.decode("utf-8"), translate_url(reverse("kolibri:core:redirect_user"), lang_code), ) self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def get_languages_menu(context): path = context['request'].get_full_path() current_ln = get_language() langs = [] for ln in LANGUAGES: langs.append({ 'name': ln[1], 'code': ln[0], 'link': translate_url(path, ln[0]), 'active': True if current_ln == ln[0] else False }) return render_to_string('sitemenu/_languages.html', { 'langs': langs, })
def translate_current_url(context, lang): query = '' try: url = context['request'].get_full_path() except KeyError: pass else: if '?' in url: url, query = url.split('?') else: url = url url = translate_url(url, lang) url = url + '?' + query if query else url return url
def set_language(request): """ Redirect to a given URL while setting the chosen language in the session (if enabled) and in a cookie. The URL and the language code need to be specified in the request parameters. Since this view changes how the user will see the rest of the site, it must only be accessed as a POST request. If called as a GET request, it will redirect to the page in the request (the 'next' parameter) without changing any state. """ next_url = request.POST.get('next', request.GET.get('next')) if ((next_url or request.accepts('text/html')) and not url_has_allowed_host_and_scheme( url=next_url, allowed_hosts={request.get_host()}, require_https=request.is_secure(), )): next_url = request.META.get('HTTP_REFERER') # HTTP_REFERER may be encoded. next_url = next_url and unquote(next_url) if not url_has_allowed_host_and_scheme( url=next_url, allowed_hosts={request.get_host()}, require_https=request.is_secure(), ): next_url = '/' response = HttpResponseRedirect(next_url) if next_url else HttpResponse( status=204) if request.method == 'POST': lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER) if lang_code and check_for_language(lang_code): if next_url: next_trans = translate_url(next_url, lang_code) if next_trans != next_url: response = HttpResponseRedirect(next_trans) response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, secure=settings.LANGUAGE_COOKIE_SECURE, httponly=settings.LANGUAGE_COOKIE_HTTPONLY, samesite=settings.LANGUAGE_COOKIE_SAMESITE, ) return response
def post(self, request, *args, **kwargs): LANGUAGE_PARAMETER = 'language' next = remove_query_param_from_url( request.POST.get('next', request.GET.get('next')), 'hl') if ((next or not request.is_ajax()) and not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure())): next = remove_query_param_from_url( request.META.get('HTTP_REFERER'), 'hl') next = next and unquote(next) # HTTP_REFERER may be encoded. if not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure()): next = '/' response = HttpResponseRedirect(next) if next else HttpResponse( status=204) if request.method == 'POST': lang_code = request.POST.get(LANGUAGE_PARAMETER) if lang_code and check_for_language(lang_code): if next: next_trans = translate_url(next, lang_code) if next_trans != next: response = HttpResponseRedirect(next_trans) if request.user.is_authenticated: enrollment = self.user_course_data if enrollment: enrollment.language = lang_code enrollment.save() else: userprofile = request.user.userprofile userprofile.language = lang_code userprofile.save() else: if hasattr(request, 'session'): request.session[LANGUAGE_SESSION_KEY] = lang_code response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN, ) request.REQUEST_LANG = lang_code return response
def test_setlang_for_ajax(self): """ The set_language view returns 200 for AJAX calls by default. """ lang_code = self._get_inactive_language_code() post_data = dict(language=lang_code) response = self.client.post( reverse("kolibri:core:set_language"), post_data, HTTP_X_REQUESTED_WITH="XMLHttpRequest", ) self.assertEqual(response.status_code, 200) self.assertEqual( response.content.decode("utf-8"), translate_url(reverse("kolibri:core:redirect_user"), lang_code), ) self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def get_success_url(self): ''' Rediect url after login ''' url = super(Login, self).get_success_url() user = self.request.user language = user.user_settings.language if url == reverse('index'): url = get_url_link(user, url) url = translate_url(url, language) activate(language) if hasattr(self.request, 'session'): self.request.session[LANGUAGE_SESSION_KEY] = language return url
def test_set_language_redirects_to_current_endpoint(client): user_language_point = "en" new_user_language = "fr" new_user_language_point = "/fr/" test_endpoint = "checkout:index" # get a English translated url (.../en/...) # and the expected url after we change it current_url = reverse(test_endpoint) expected_url = translate_url(current_url, new_user_language) # check the received urls: # - current url is english (/en/) (default from tests.settings); # - expected url is french (/fr/) assert user_language_point in current_url assert user_language_point not in expected_url assert new_user_language_point in expected_url # ensure we are getting directed to english page, not anything else response = client.get(reverse(test_endpoint), follow=True) new_url = response.request["PATH_INFO"] assert new_url == current_url # change the user language to French, # and tell the view we want to be redirected to our current page set_language_url = reverse("set_language") data = {"language": new_user_language, "next": current_url} redirect_response = client.post(set_language_url, data, follow=True) new_url = redirect_response.request["PATH_INFO"] # check if we got redirected somewhere else assert new_url != current_url # now check if we got redirect the endpoint we wanted to go back # in the new language (checkout:index) assert expected_url == new_url