From 7fe965e98bb1b7beddfbb7a97fb1b34b30887805 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Fri, 26 Jul 2019 16:07:58 +0200 Subject: [PATCH] add kwargs template_base to LoginView (#35083) --- mellon/templates/mellon/base.html | 2 +- mellon/views.py | 15 ++++++++++++--- tests/templates/theme.html | 7 +++++++ tests/test_sso_slo.py | 22 ++++++++++++++++++++++ tests/urls_tests.py | 2 -- tests/urls_tests_template_base.py | 26 ++++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 tests/templates/theme.html create mode 100644 tests/urls_tests_template_base.py diff --git a/mellon/templates/mellon/base.html b/mellon/templates/mellon/base.html index bfa03f4..c6828de 100644 --- a/mellon/templates/mellon/base.html +++ b/mellon/templates/mellon/base.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends template_base|default:"base.html" %} {% block extra_scripts %} {% block mellon_extra_scripts %} diff --git a/mellon/views.py b/mellon/views.py index 29b2ca9..07113d4 100644 --- a/mellon/views.py +++ b/mellon/views.py @@ -128,6 +128,10 @@ class ProfileMixin(object): class LoginView(ProfileMixin, LogMixin, View): + @property + def template_base(self): + return self.kwargs.get('template_base', 'base.html') + def get_idp(self, request): entity_id = request.POST.get('entityID') or request.GET.get('entityID') if not entity_id: @@ -186,6 +190,7 @@ class LoginView(ProfileMixin, LogMixin, View): next_url = error_url or self.get_next_url(default=resolve_url(settings.LOGIN_REDIRECT_URL)) return render(request, 'mellon/authentication_failed.html', { + 'template_base': self.template_base, 'debug': settings.DEBUG, 'reason': reason, 'status_codes': status_codes, @@ -253,12 +258,15 @@ class LoginView(ProfileMixin, LogMixin, View): self.log.warning('user %s (NameID is %r) is inactive, login refused', user, attributes['name_id_content']) return render(request, 'mellon/inactive_user.html', { + 'template_base': self.template_base, 'user': user, 'saml_attributes': attributes}) else: self.log.warning('no user found for NameID %r', attributes['name_id_content']) - return render(request, 'mellon/user_not_found.html', - {'saml_attributes': attributes}) + return render(request, 'mellon/user_not_found.html', { + 'template_base': self.template_base, + 'saml_attributes': attributes + }) request.session['lasso_session_dump'] = login.session.dump() return HttpResponseRedirect(next_url) @@ -379,7 +387,8 @@ class LoginView(ProfileMixin, LogMixin, View): url = app_settings.DISCOVERY_SERVICE_URL params = { # prevent redirect loops with the discovery service - 'entityID': request.build_absolute_uri(reverse('mellon_metadata')), + 'entityID': request.build_absolute_uri( + reverse('mellon_metadata')), 'return': return_url, } if is_passive: diff --git a/tests/templates/theme.html b/tests/templates/theme.html new file mode 100644 index 0000000..31a0faa --- /dev/null +++ b/tests/templates/theme.html @@ -0,0 +1,7 @@ + + +

Theme is ok

+ {% block content %} + {% endblock %} + + diff --git a/tests/test_sso_slo.py b/tests/test_sso_slo.py index 578b5c7..42d1636 100644 --- a/tests/test_sso_slo.py +++ b/tests/test_sso_slo.py @@ -23,6 +23,7 @@ import xml.etree.ElementTree as ET import lasso +import pytest from pytest import fixture import django @@ -224,6 +225,27 @@ def test_sso_request_denied(db, app, idp, caplog, sp_settings): u'urn:oasis:names:tc:SAML:2.0:status:RequestDenied']" in caplog.text +@pytest.mark.urls('urls_tests_template_base') +def test_template_base(db, app, idp, caplog, sp_settings): + response = app.get(reverse('mellon_login')) + url, body, relay_state = idp.process_authn_request_redirect( + response['Location'], + auth_result=False, + msg='User is not allowed to login') + response = app.post(reverse('mellon_login'), params={'SAMLResponse': body, 'RelayState': relay_state}) + assert 'Theme is ok' in response.text + + +def test_no_template_base(db, app, idp, caplog, sp_settings): + response = app.get(reverse('mellon_login')) + url, body, relay_state = idp.process_authn_request_redirect( + response['Location'], + auth_result=False, + msg='User is not allowed to login') + response = app.post(reverse('mellon_login'), params={'SAMLResponse': body, 'RelayState': relay_state}) + assert 'Theme is ok' not in response.text + + def test_sso_request_denied_artifact(db, app, caplog, sp_settings, idp_metadata, idp_private_key, rf): sp_settings.MELLON_DEFAULT_ASSERTION_CONSUMER_BINDING = 'artifact' request = rf.get('/') diff --git a/tests/urls_tests.py b/tests/urls_tests.py index 52500a4..651f131 100644 --- a/tests/urls_tests.py +++ b/tests/urls_tests.py @@ -13,8 +13,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import django - from django.conf.urls import url, include from django.http import HttpResponse diff --git a/tests/urls_tests_template_base.py b/tests/urls_tests_template_base.py new file mode 100644 index 0000000..a4cf96f --- /dev/null +++ b/tests/urls_tests_template_base.py @@ -0,0 +1,26 @@ +# django-mellon - SAML2 authentication for Django +# Copyright (C) 2014-2019 Entr'ouvert +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from django.conf.urls import url, include +from django.http import HttpResponse + + +def homepage(request): + return HttpResponse('ok') + +urlpatterns = [ + url('^', include('mellon.urls'), kwargs={'template_base': 'theme.html'}), + url('^$', homepage, name='homepage'), +] -- 2.23.0