Skip to content

Commit

Permalink
Override LoginView to provide an SSO button
Browse files Browse the repository at this point in the history
This change moves our login template override to the `login` app, adds a subclass of Wagtail's `LoginView` to provide extra SSO context, and then adds a "Sign-in with SSO" button if SSO is enabled.

This simplifies some of our URLs around SSO (always having /admin/login respond), and moves one of our override templates out of `wagtailadmin_overrides` and justifies its existence a little bit more.
  • Loading branch information
willbarton committed May 22, 2024
1 parent 06f3006 commit ca63940
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 34 deletions.
2 changes: 1 addition & 1 deletion cfgov/cfgov/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@
# Configure login/out URLs for OIDC
LOGIN_URL = "oidc_authentication_init"
LOGIN_REDIRECT_URL = reverse_lazy("wagtailadmin_home")
LOGOUT_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = reverse_lazy("cfgov_login")
ALLOW_LOGOUT_GET_METHOD = True

# This OIDC client's id and secret
Expand Down
1 change: 1 addition & 0 deletions cfgov/cfgov/tests/test_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"^django-admin/",
"^login",
"^logout",
"^oidc/",
"^password/",
"^tasks/",
]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
{% extends "wagtailadmin/login.html" %}
{% load wagtailadmin_tags %}

{% block below_login %}
{% if sso_enabled %}
<hr>
<p><a href="{% url 'oidc_authentication_init' %}" class="button" style="text-align: center;">Sign in with Single Sign-On</a></p>
<hr>
{% endif %}
<p>This is a Consumer Financial Protection Bureau (CFPB) information system. The CFPB is an independent agency of the United States Government. CFPB information systems are provided for the processing of official information only. Unauthorized or improper use of this system may result in administrative action, as well as civil and criminal penalties.</p>
<p>Because this is a CFPB information system, you have no reasonable expectation of privacy regarding any communication or data, transiting or stored, on this information system. All data contained in CFPB information systems is owned by the CFPB, and your use of the CFPB information system serves as your consent to your usage being monitored, intercepted, recorded, read, copied, captured, or otherwise audited in any manner by authorized personnel, including, but not limited to, employees, contractors, and/or agents of the United States Government.</p>
{% endblock %}
16 changes: 16 additions & 0 deletions cfgov/login/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django.test import TestCase, override_settings
from django.urls import reverse


class LoginViewTestCase(TestCase):

@override_settings(ENABLE_SSO=True)
def test_view_gets_sso_enabled_context(self):
response = self.client.get(reverse("cfgov_login"))
self.assertTrue(response.context["sso_enabled"])
pass

@override_settings(ENABLE_SSO=False)
def test_view_gets_sso_disabled_context(self):
response = self.client.get(reverse("cfgov_login"))
self.assertFalse(response.context["sso_enabled"])
62 changes: 29 additions & 33 deletions cfgov/login/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,32 @@
from django.urls import include, re_path, reverse_lazy
from django.views.generic.base import RedirectView

from login.views import LoginView

if settings.ENABLE_SSO: # pragma: no cover
urlpatterns = [
# If SSO auth is enabled, /login will redirect to /oidc/login,
# which in turn will redirect to the configured identity provider.
re_path(r"^oidc/", include("mozilla_django_oidc.urls")),
re_path(
r"^admin/login/$",
RedirectView.as_view(
url=reverse_lazy("oidc_authentication_init"), query_string=True
),
),
re_path(
r"^admin/logout/$",
RedirectView.as_view(
url=reverse_lazy("oidc_logout"),
query_string=True,
),
),
]
else:
urlpatterns = [
# When SSO is not enabled, the Django login should redirect to Wagtail
re_path(
r"^django-admin/login/$",
RedirectView.as_view(
url=reverse_lazy("wagtailadmin_login"), query_string=True
),
),
]

urlpatterns = urlpatterns + [
# Redirect root-level /login and /logout to Wagtail's URLs
urlpatterns = [
# Include OIDC URLs
re_path(r"^oidc/", include("mozilla_django_oidc.urls")),
# Override Wagtail's login URL with our subclass
re_path(r"^admin/login/", LoginView.as_view(), name="cfgov_login"),
# Redirect root-level /login and /logout
re_path(
r"^login/$",
RedirectView.as_view(
url=reverse_lazy("wagtailadmin_login"), query_string=True
url=reverse_lazy("cfgov_login"), query_string=True
),
),
re_path(
r"^logout/$",
RedirectView.as_view(
url=reverse_lazy("wagtailadmin_logout"), query_string=True
url=reverse_lazy("cfgov_login"), query_string=True
),
),
# Redirect the Django admin login to Wagtail
re_path(
r"^django-admin/login/$",
RedirectView.as_view(
url=reverse_lazy("cfgov_login"), query_string=True
),
),
# Redirect Django's password change view to Wagtail's
Expand All @@ -55,3 +38,16 @@
),
),
]

if settings.ENABLE_SSO: # pragma: no cover
urlpatterns = urlpatterns + [
# Redirect logout to the OIDC logout to make sure we clear our OIDC
# session information
re_path(
r"^admin/logout/$",
RedirectView.as_view(
url=reverse_lazy("oidc_logout"),
query_string=True,
),
),
]
12 changes: 12 additions & 0 deletions cfgov/login/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.conf import settings

from wagtail.admin.views.account import LoginView as WagtailLoginView


class LoginView(WagtailLoginView):
template_name = "login/login.html"

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["sso_enabled"] = settings.ENABLE_SSO
return context

0 comments on commit ca63940

Please sign in to comment.