Skip to content

Commit

Permalink
Display login screen on unrecoverable error
Browse files Browse the repository at this point in the history
  • Loading branch information
ukanga committed Dec 5, 2024
1 parent 5f4f902 commit 226bf0f
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 10 deletions.
3 changes: 3 additions & 0 deletions oidc/templates/oidc/oidc_unrecoverable_error.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
<div class="content">
<div class="content-body">
<p class="error-message">{{ error }}</a></p>
{% if login_url %}
<p>Something went wrong, please try again later - <a href="{{ login_url }}">login</a>.</p>
{% endif %}
</div>
</div>
{% endblock %}
23 changes: 18 additions & 5 deletions oidc/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from rest_framework.decorators import action
from rest_framework.renderers import JSONRenderer, TemplateHTMLRenderer
from rest_framework.response import Response
from rest_framework.reverse import reverse

import oidc.settings as default
from oidc.client import (
Expand Down Expand Up @@ -111,7 +112,7 @@ def _get_client(self, auth_server: str) -> Optional[OpenIDClient]:

@action(methods=["GET"], detail=False)
def login(self, request: HttpRequest, **kwargs: dict) -> HttpResponse:
client = self._get_client(**kwargs)
client = self._get_client(auth_server=kwargs.get("auth_server"))
if client:
return client.login(redirect_after=request.query_params.get("next"))
return HttpResponseBadRequest(
Expand All @@ -120,7 +121,7 @@ def login(self, request: HttpRequest, **kwargs: dict) -> HttpResponse:

@action(methods=["GET"], detail=False)
def logout(self, request: HttpRequest, **kwargs: dict) -> HttpResponse:
client = self._get_client(**kwargs)
client = self._get_client(auth_server=kwargs.get("auth_server"))
if client:
response = client.logout()

Expand Down Expand Up @@ -265,7 +266,7 @@ def _clean_user_data(self, user_data) -> Tuple[dict, Optional[list]]:

@action(methods=["POST"], detail=False)
def callback(self, request: HttpRequest, **kwargs: dict) -> HttpResponse: # noqa
client = self._get_client(**kwargs)
client = self._get_client(auth_server=kwargs.get("auth_server"))
user = None
redirect_after = None
if client:
Expand Down Expand Up @@ -396,8 +397,20 @@ def callback(self, request: HttpRequest, **kwargs: dict) -> HttpResponse: # noq
return self.generate_successful_response(
request, user, redirect_after=redirect_after
)
return HttpResponseBadRequest(
_("Unable to process OpenID connect authentication request."),
auth_servers = list(settings.OPENID_CONNECT_AUTH_SERVERS.keys())
default_auth_server = auth_servers[0] if auth_servers else "default"
return Response(
{
"error": _("Unable to process OpenID connect authentication request."),
"error_title": _(
"Unable to process OpenID connect authentication request."
),
"login_url": reverse(
"openid_connect_login", kwargs={"auth_server": default_auth_server}
),
},
status=status.HTTP_400_BAD_REQUEST,
template_name="oidc/oidc_unrecoverable_error.html",
)

def create_login_user(self, user_data: dict):
Expand Down
12 changes: 12 additions & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Test Settings
"""

import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Expand Down Expand Up @@ -48,3 +49,14 @@

ROOT_URLCONF = "oidc.urls"
SECRET_KEY = "secret"

TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [
os.path.join(BASE_DIR, "oidc/templates"),
os.path.join(BASE_DIR, "tests/templates"),
],
"APP_DIRS": True,
}
]
49 changes: 49 additions & 0 deletions tests/templates/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test title</title>
<meta name="description" content="">
<meta name="author" content="">


<!-- Le styles -->
{% block styles %}

{% endblock %}

<!-- spot to insert stuff for google maps -->
{% block additional-headers %}{% endblock %}


</head>

{% block body %}

<body>
<div class="container">
{% block message %}
{% if message or messages or message_list %}
{% include "message.html" %}
{% endif %}
{% endblock %}
{% block content %}
{% if template %}{% include template %}{% endif %}
{{ content|safe }}
{% endblock %}
</div>


{% block javascript %}

<!-- Le javascript -->

{% endblock %}

{% block additional-javascript %}{% endblock %}


</body>
{% endblock %}
</html>

12 changes: 7 additions & 5 deletions tests/test_viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,10 +754,12 @@ def test_direct_access_to_callback_fails(self):
"""
# Mock two ID Tokens
view = UserModelOpenIDConnectViewset.as_view({"get": "callback"})
request = self.factory.get("/oidc/default/callback")
response = view(request, auth_server="default")
request = self.factory.get("/oidc/default/callback", format="html")
response = view(request, auth_server="default", format="html")
self.assertEqual(response.status_code, 400)
self.assertEqual(
response.content.decode("utf-8"),
"Unable to process OpenID connect authentication request.",
response.render()
content = response.content.decode("utf-8")
self.assertTrue(
"Unable to process OpenID connect authentication request." in content
)
self.assertTrue("Something went wrong, please try again later" in content)

0 comments on commit 226bf0f

Please sign in to comment.