From 0a43b9a16000721675f7f8314ed476bce8402d45 Mon Sep 17 00:00:00 2001 From: Janne Alatalo Date: Thu, 22 Aug 2019 15:16:51 +0300 Subject: [PATCH] Add support for custom login handler The custom login handler can be configured by setting the settings.LOGIN_URL variable. If LOGIN_URL is None or 'helpdesk:login', the app uses the default helpdesk login system. LOGIN_URL can be a view name or raw url. --- helpdesk/tests/test_login.py | 37 ++++++++++++++++++++++++++++++++++++ helpdesk/urls.py | 5 ++--- helpdesk/views/login.py | 21 ++++++++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 helpdesk/tests/test_login.py create mode 100644 helpdesk/views/login.py diff --git a/helpdesk/tests/test_login.py b/helpdesk/tests/test_login.py new file mode 100644 index 00000000..8f28e962 --- /dev/null +++ b/helpdesk/tests/test_login.py @@ -0,0 +1,37 @@ +from django.test import TestCase, override_settings +from django.urls import reverse + + +class TestLoginRedirect(TestCase): + + @override_settings(LOGIN_URL='/custom/login/') + def test_custom_login_view_with_url(self): + """Test login redirect when LOGIN_URL is set to custom url""" + response = self.client.get(reverse('helpdesk:login')) + # We expect that that helpdesk:home url is passed as next parameter in + # the redirect url, so that the custom login can redirect the browser + # back to helpdesk after the login. + home_url = reverse('helpdesk:home') + expected = '/custom/login/?next={}'.format(home_url) + self.assertRedirects(response, expected, fetch_redirect_response=False) + + @override_settings(LOGIN_URL='/custom/login/') + def test_custom_login_next_param(self): + """Test that the next url parameter is correctly relayed to custom login""" + next_param = "/redirect/back" + url = reverse('helpdesk:login') + "?next=" + next_param + response = self.client.get(url) + expected = '/custom/login/?next={}'.format(next_param) + self.assertRedirects(response, expected, fetch_redirect_response=False) + + @override_settings(LOGIN_URL='helpdesk:login', SITE_ID=1) + def test_default_login_view(self): + """Test that default login is used when LOGIN_URL is helpdesk:login""" + response = self.client.get(reverse('helpdesk:login')) + self.assertTemplateUsed(response, 'helpdesk/registration/login.html') + + @override_settings(LOGIN_URL=None, SITE_ID=1) + def test_login_url_none(self): + """Test that default login is used when LOGIN_URL is None""" + response = self.client.get(reverse('helpdesk:login')) + self.assertTemplateUsed(response, 'helpdesk/registration/login.html') diff --git a/helpdesk/urls.py b/helpdesk/urls.py index 28cab023..a2c63d1b 100644 --- a/helpdesk/urls.py +++ b/helpdesk/urls.py @@ -13,7 +13,7 @@ from django.contrib.auth import views as auth_views from django.views.generic import TemplateView from helpdesk import settings as helpdesk_settings -from helpdesk.views import feeds, staff, public, kb +from helpdesk.views import feeds, staff, public, kb, login class DirectTemplateView(TemplateView): @@ -185,8 +185,7 @@ urlpatterns += [ urlpatterns += [ url(r'^login/$', - auth_views.LoginView.as_view( - template_name='helpdesk/registration/login.html'), + login.login, name='login'), url(r'^logout/$', diff --git a/helpdesk/views/login.py b/helpdesk/views/login.py new file mode 100644 index 00000000..6e4cf5c3 --- /dev/null +++ b/helpdesk/views/login.py @@ -0,0 +1,21 @@ +from django.conf import settings +from django.contrib.auth import views as auth_views +from django.contrib.auth.views import redirect_to_login +from django.shortcuts import resolve_url + + +default_login_view = auth_views.LoginView.as_view( + template_name='helpdesk/registration/login.html') + + +def login(request): + login_url = settings.LOGIN_URL + # Prevent redirect loop by checking that LOGIN_URL is not this view's name + if login_url and login_url != request.resolver_match.view_name: + if 'next' in request.GET: + return_to = request.GET['next'] + else: + return_to = resolve_url('helpdesk:home') + return redirect_to_login(return_to, login_url) + else: + return default_login_view(request)