providers/oauth2: fix end-session view not working, add tests
This commit is contained in:
		@ -0,0 +1,36 @@
 | 
			
		||||
{% extends 'login/base_full.html' %}
 | 
			
		||||
 | 
			
		||||
{% load static %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
{% load passbook_utils %}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
{% trans 'End session' %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block card_title %}
 | 
			
		||||
{% blocktrans with application=application.name %}
 | 
			
		||||
You've logged out of {{ application }}.
 | 
			
		||||
{% endblocktrans %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block card %}
 | 
			
		||||
<form method="POST" class="pf-c-form">
 | 
			
		||||
    {% if message %}
 | 
			
		||||
    <h3>{% trans message %}</h3>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
 | 
			
		||||
    <a id="pb-back-home" href="{% url 'passbook_core:overview' %}" class="pf-c-button pf-m-primary">{% trans 'Go back to passbook' %}</a>
 | 
			
		||||
 | 
			
		||||
    <a id="logout" href="{% url 'passbook_flows:default-invalidation' %}" class="pf-c-button pf-m-secondary">{% trans 'Log out of passbook' %}</a>
 | 
			
		||||
 | 
			
		||||
    {% if application.get_launch_url %}
 | 
			
		||||
    <a href="{{ application.get_launch_url }}" class="pf-c-button pf-m-secondary">
 | 
			
		||||
        {% blocktrans with application=application.name %}
 | 
			
		||||
            Log back into {{ application }}
 | 
			
		||||
        {% endblocktrans %}
 | 
			
		||||
    </a>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
 | 
			
		||||
</form>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
@ -20,12 +20,16 @@ urlpatterns = [
 | 
			
		||||
        csrf_exempt(protected_resource_view([SCOPE_OPENID])(UserInfoView.as_view())),
 | 
			
		||||
        name="userinfo",
 | 
			
		||||
    ),
 | 
			
		||||
    path("end-session/", EndSessionView.as_view(), name="end-session",),
 | 
			
		||||
    path(
 | 
			
		||||
        "introspect/",
 | 
			
		||||
        csrf_exempt(TokenIntrospectionView.as_view()),
 | 
			
		||||
        name="token-introspection",
 | 
			
		||||
    ),
 | 
			
		||||
    path(
 | 
			
		||||
        "<slug:application_slug>/end-session/",
 | 
			
		||||
        EndSessionView.as_view(),
 | 
			
		||||
        name="end-session",
 | 
			
		||||
    ),
 | 
			
		||||
    path("<slug:application_slug>/jwks/", JWKSView.as_view(), name="jwks"),
 | 
			
		||||
    path(
 | 
			
		||||
        "<slug:application_slug>/.well-known/openid-configuration",
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,10 @@ class ProviderInfoView(View):
 | 
			
		||||
                reverse("passbook_providers_oauth2:userinfo")
 | 
			
		||||
            ),
 | 
			
		||||
            "end_session_endpoint": self.request.build_absolute_uri(
 | 
			
		||||
                reverse("passbook_providers_oauth2:end-session")
 | 
			
		||||
                reverse(
 | 
			
		||||
                    "passbook_providers_oauth2:end-session",
 | 
			
		||||
                    kwargs={"application_slug": provider.application.slug},
 | 
			
		||||
                )
 | 
			
		||||
            ),
 | 
			
		||||
            "introspection_endpoint": self.request.build_absolute_uri(
 | 
			
		||||
                reverse("passbook_providers_oauth2:token-introspection")
 | 
			
		||||
 | 
			
		||||
@ -1,45 +1,22 @@
 | 
			
		||||
"""passbook OAuth2 Session Views"""
 | 
			
		||||
from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit
 | 
			
		||||
from typing import Any, Dict
 | 
			
		||||
 | 
			
		||||
from django.contrib.auth.views import LogoutView
 | 
			
		||||
from django.http import HttpRequest, HttpResponse
 | 
			
		||||
from django.shortcuts import get_object_or_404
 | 
			
		||||
from django.views.generic.base import TemplateView
 | 
			
		||||
 | 
			
		||||
from passbook.core.models import Application
 | 
			
		||||
from passbook.providers.oauth2.models import OAuth2Provider
 | 
			
		||||
from passbook.providers.oauth2.utils import client_id_from_id_token
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class EndSessionView(LogoutView):
 | 
			
		||||
class EndSessionView(TemplateView):
 | 
			
		||||
    """Allow the client to end the Session"""
 | 
			
		||||
 | 
			
		||||
    def dispatch(
 | 
			
		||||
        self, request: HttpRequest, application_slug: str, *args, **kwargs
 | 
			
		||||
    ) -> HttpResponse:
 | 
			
		||||
    template_name = "providers/oauth2/end_session.html"
 | 
			
		||||
 | 
			
		||||
        application = get_object_or_404(Application, slug=application_slug)
 | 
			
		||||
        provider: OAuth2Provider = get_object_or_404(
 | 
			
		||||
            OAuth2Provider, pk=application.provider_id
 | 
			
		||||
    def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
 | 
			
		||||
        context["application"] = get_object_or_404(
 | 
			
		||||
            Application, slug=self.kwargs["application_slug"]
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        id_token_hint = request.GET.get("id_token_hint", "")
 | 
			
		||||
        post_logout_redirect_uri = request.GET.get("post_logout_redirect_uri", "")
 | 
			
		||||
        state = request.GET.get("state", "")
 | 
			
		||||
 | 
			
		||||
        if id_token_hint:
 | 
			
		||||
            client_id = client_id_from_id_token(id_token_hint)
 | 
			
		||||
            try:
 | 
			
		||||
                provider = OAuth2Provider.objects.get(client_id=client_id)
 | 
			
		||||
                if post_logout_redirect_uri in provider.post_logout_redirect_uris:
 | 
			
		||||
                    if state:
 | 
			
		||||
                        uri = urlsplit(post_logout_redirect_uri)
 | 
			
		||||
                        query_params = parse_qs(uri.query)
 | 
			
		||||
                        query_params["state"] = state
 | 
			
		||||
                        uri = uri._replace(query=urlencode(query_params, doseq=True))
 | 
			
		||||
                        self.next_page = urlunsplit(uri)
 | 
			
		||||
                    else:
 | 
			
		||||
                        self.next_page = post_logout_redirect_uri
 | 
			
		||||
            except OAuth2Provider.DoesNotExist:
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
        return super().dispatch(request, *args, **kwargs)
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user