diff --git a/HISTORY.rst b/HISTORY.rst index 2641abb9a3..30ddf3283a 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,7 +1,11 @@ 3.1 (2018-XX-XX) ================ -- Fix crop transformation argument parsing. +- Fix crop transformation argument parsing. Thanks to Jordan Wages + (@wagesj45). Closes GitLab issue #490 - Add error checking to the crop transformation arguments. +- Fix post login redirection to honor the ?next= URL query string + argument. Thanks go to K.C. Wong (@dvusboy1). Closes GitLab + issue #489. 3.0.1 (2018-07-08) ================= diff --git a/mayan/apps/authentication/tests/test_views.py b/mayan/apps/authentication/tests/test_views.py index 49e6186304..c7b3e58409 100644 --- a/mayan/apps/authentication/tests/test_views.py +++ b/mayan/apps/authentication/tests/test_views.py @@ -205,3 +205,18 @@ class UserLoginTestCase(BaseTestCase): response = self.client.get(reverse('documents:document_list')) self.assertEqual(response.status_code, 200) + + def test_username_login_redirect(self): + TEST_REDIRECT_URL = '/about/' + + response = self.client.post( + '{}?next={}'.format( + reverse(settings.LOGIN_URL), TEST_REDIRECT_URL + ), { + 'username': TEST_ADMIN_USERNAME, + 'password': TEST_ADMIN_PASSWORD, + 'remember_me': False + }, follow=True + ) + + self.assertEqual(response.redirect_chain, [(TEST_REDIRECT_URL, 302)]) diff --git a/mayan/apps/authentication/views.py b/mayan/apps/authentication/views.py index 2728217de6..b969c804af 100644 --- a/mayan/apps/authentication/views.py +++ b/mayan/apps/authentication/views.py @@ -10,6 +10,7 @@ from django.contrib.auth.views import ( from django.http import HttpResponseRedirect from django.shortcuts import redirect, resolve_url from django.urls import reverse +from django.utils.http import is_safe_url from django.utils.translation import ugettext_lazy as _ from stronghold.decorators import public @@ -26,6 +27,7 @@ def login_view(request): Control how the use is to be authenticated, options are 'email' and 'username' """ + success_url_allowed_hosts = set() kwargs = {'template_name': 'authentication/login.html'} if setting_login_method.value == 'email': @@ -33,10 +35,25 @@ def login_view(request): else: kwargs['authentication_form'] = UsernameAuthenticationForm + allowed_hosts = {request.get_host()} + allowed_hosts.update(success_url_allowed_hosts) + + redirect_to = request.POST.get( + REDIRECT_FIELD_NAME, request.GET.get(REDIRECT_FIELD_NAME, '') + ) + + url_is_safe = is_safe_url( + url=redirect_to, + allowed_hosts=allowed_hosts, + require_https=request.is_secure(), + ) + + url = redirect_to if url_is_safe else '' + if not request.user.is_authenticated: extra_context = { 'appearance_type': 'plain', - REDIRECT_FIELD_NAME: resolve_url(settings.LOGIN_REDIRECT_URL) + REDIRECT_FIELD_NAME: url or resolve_url(settings.LOGIN_REDIRECT_URL) } result = login(request, extra_context=extra_context, **kwargs)