Skip to content

Commit

Permalink
✨ [#1902/1903] Logout for DigiD/eHerkenning via OIDC
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenbal committed Dec 5, 2023
1 parent ec9c794 commit 748e767
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 5 deletions.
6 changes: 6 additions & 0 deletions src/digid_eherkenning_oidc_generics/digid_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .views import (
DigiDOIDCAuthenticationCallbackView,
DigiDOIDCAuthenticationRequestView,
DigiDOIDCLogoutView,
)

app_name = "digid_oidc"
Expand All @@ -21,4 +22,9 @@
DigiDOIDCAuthenticationRequestView.as_view(),
name="init",
),
path(
"logout/",
DigiDOIDCLogoutView.as_view(),
name="logout",
),
] + urlpatterns
6 changes: 6 additions & 0 deletions src/digid_eherkenning_oidc_generics/eherkenning_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .views import (
eHerkenningOIDCAuthenticationCallbackView,
eHerkenningOIDCAuthenticationRequestView,
eHerkenningOIDCLogoutView,
)

app_name = "eherkenning_oidc"
Expand All @@ -21,4 +22,9 @@
eHerkenningOIDCAuthenticationRequestView.as_view(),
name="init",
),
path(
"logout/",
eHerkenningOIDCLogoutView.as_view(),
name="logout",
),
] + urlpatterns
39 changes: 39 additions & 0 deletions src/digid_eherkenning_oidc_generics/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import logging

from django.conf import settings
from django.contrib import auth
from django.core.exceptions import SuspiciousOperation
from django.http import HttpResponseRedirect
from django.shortcuts import resolve_url
from django.views import View

import requests
from furl import furl
from mozilla_django_oidc.views import (
OIDCAuthenticationCallbackView as _OIDCAuthenticationCallbackView,
OIDCAuthenticationRequestView as _OIDCAuthenticationRequestView,
Expand Down Expand Up @@ -86,6 +92,31 @@ def get(self, request):
return self.login_failure()


class OIDCLogoutView(View):
def get_success_url(self):
return resolve_url(settings.LOGOUT_REDIRECT_URL)

def get(self, request):
if "oidc_id_token" in request.session:
logout_endpoint = self.config_class.get_solo().oidc_op_logout_endpoint
if logout_endpoint:
logout_url = furl(logout_endpoint).set(
{
"id_token_hint": request.session["oidc_id_token"],
}
)
requests.get(str(logout_url))

del request.session["oidc_id_token"]

if "oidc_login_next" in request.session:
del request.session["oidc_login_next"]

auth.logout(request)

return HttpResponseRedirect(self.get_success_url())


class DigiDOIDCAuthenticationRequestView(
SoloConfigDigiDMixin, OIDCAuthenticationRequestView
):
Expand All @@ -98,6 +129,10 @@ class DigiDOIDCAuthenticationCallbackView(
auth_backend_class = OIDCAuthenticationDigiDBackend


class DigiDOIDCLogoutView(SoloConfigDigiDMixin, OIDCLogoutView):
pass


class eHerkenningOIDCAuthenticationRequestView(
SoloConfigEHerkenningMixin, OIDCAuthenticationRequestView
):
Expand All @@ -108,3 +143,7 @@ class eHerkenningOIDCAuthenticationCallbackView(
SoloConfigEHerkenningMixin, OIDCAuthenticationCallbackView
):
auth_backend_class = OIDCAuthenticationEHerkenningBackend


class eHerkenningOIDCLogoutView(SoloConfigEHerkenningMixin, OIDCLogoutView):
pass
25 changes: 20 additions & 5 deletions src/open_inwoner/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
from privates.storages import PrivateMediaFileSystemStorage
from timeline_logger.models import TimelineLog

from digid_eherkenning_oidc_generics.models import (
OpenIDConnectDigiDConfig,
OpenIDConnectEHerkenningConfig,
)
from open_inwoner.utils.hash import create_sha256_hash
from open_inwoner.utils.validators import (
CharFieldValidator,
Expand Down Expand Up @@ -399,11 +403,22 @@ def require_necessary_fields(self) -> bool:
return False

def get_logout_url(self) -> str:
return (
reverse("digid:logout")
if self.login_type == LoginTypeChoices.digid
else reverse("logout")
)
# Exit early, because for some reason reverse("logout") fails after checking
# the singletonmodels
if self.login_type not in [
LoginTypeChoices.digid,
LoginTypeChoices.eherkenning,
]:
return reverse("logout")

if self.login_type == LoginTypeChoices.digid:
if OpenIDConnectDigiDConfig.get_solo().enabled:
return reverse("digid_oidc:logout")
return reverse("digid:logout")
elif self.login_type == LoginTypeChoices.eherkenning:
if OpenIDConnectEHerkenningConfig.get_solo().enabled:
return reverse("eherkenning_oidc:logout")
return reverse("eherkenning:logout")

def get_contact_update_url(self):
return reverse("profile:contact_edit", kwargs={"uuid": self.uuid})
Expand Down
2 changes: 2 additions & 0 deletions src/open_inwoner/conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,8 @@
OIDC_AUTHENTICATE_CLASS = "mozilla_django_oidc_db.views.OIDCAuthenticationRequestView"
OIDC_CALLBACK_CLASS = "mozilla_django_oidc_db.views.OIDCCallbackView"
OIDC_AUTHENTICATION_CALLBACK_URL = "oidc_authentication_callback"
# ID token is required to enable OIDC logout
OIDC_STORE_ID_TOKEN = True
MOZILLA_DJANGO_OIDC_DB_CACHE = "oidc"
MOZILLA_DJANGO_OIDC_DB_CACHE_TIMEOUT = 1

Expand Down

0 comments on commit 748e767

Please sign in to comment.