From 739e27efff987f98d1a6b37d05accc34192d473c Mon Sep 17 00:00:00 2001 From: Saira Bano <79838286+sbanoeon@users.noreply.github.com> Date: Fri, 13 Sep 2024 15:02:24 +0200 Subject: [PATCH] 186 OIDC logout does not work (#204) * chore: add logout url, redirect url and logout method * fix(entirety): remove unused settings * fix(entirety): include example env for redirect urls * chore(entirety): wrapper function for oidc logout * fix: add OIDC logout endpoint * chore(entirety): separate env variables for each auth mode * chore(entirety): fix default variable login_url --------- Co-authored-by: Sebastian Blechmann --- app/Entirety/.env.EXAMPLE | 7 +++++++ app/Entirety/entirety/settings.py | 29 +++++++++++++++++++++-------- app/Entirety/users/views.py | 23 +++++++++++++++++++++++ 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/app/Entirety/.env.EXAMPLE b/app/Entirety/.env.EXAMPLE index aa70cc64..4933f616 100644 --- a/app/Entirety/.env.EXAMPLE +++ b/app/Entirety/.env.EXAMPLE @@ -28,11 +28,18 @@ LOKI_SRC_HOST=entirety LOKI_TIMEZONE=Europe/Berlin LOCAL_AUTH=True +LOGIN_URL=/ +LOGIN_REDIRECT_URL=/ +LOGOUT_REDIRECT_URL=/ # OIDC +OIDC_LOGIN_URL=/oidc/authenticate +OIDC_LOGIN_REDIRECT_URL=/oidc/callback/ +OIDC_LOGOUT_REDIRECT_URL=/ OIDC_OP_AUTHORIZATION_ENDPOINT= OIDC_OP_JWKS_ENDPOINT= OIDC_OP_TOKEN_ENDPOINT= OIDC_OP_USER_ENDPOINT= +OIDC_OP_LOGOUT_ENDPOINT= OIDC_RP_CLIENT_ID= OIDC_RP_CLIENT_SECRET= OIDC_SUPER_ADMIN_ROLE=super_admin diff --git a/app/Entirety/entirety/settings.py b/app/Entirety/entirety/settings.py index 97b674b0..963d752d 100644 --- a/app/Entirety/entirety/settings.py +++ b/app/Entirety/entirety/settings.py @@ -125,7 +125,6 @@ class Settings(PydanticSettings): CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" - CRISPY_TEMPLATE_PACK = "bootstrap5" MIDDLEWARE: List[str] = [ @@ -324,20 +323,27 @@ def secret_key_not_empty(cls, v) -> str: # https://docs.djangoproject.com/en/4.0/ref/settings/#databases DATABASES: Databases = Field({}) + LOGIN_REDIRECT_URL: str = Field(default="/", env="LOGIN_REDIRECT_URL") + LOGIN_URL: str = Field(default="/", env="LOGIN_URL") LOGOUT_REDIRECT_URL: str = Field(default="/", env="LOGOUT_REDIRECT_URL") - if __auth.LOCAL_AUTH: - LOGIN_REDIRECT_URL: str = Field(default="/", env="LOGIN_REDIRECT_URL") - else: + if not __auth.LOCAL_AUTH: INSTALLED_APPS.append("mozilla_django_oidc") MIDDLEWARE.append("mozilla_django_oidc.middleware.SessionRefresh") AUTHENTICATION_BACKENDS: Sequence[str] = ("entirety.oidc.CustomOIDCAB",) - LOGIN_URL: str = Field(default="/oidc/authenticate", env="LOGIN_URL") + OIDC_LOGIN_URL: str = Field(default="/oidc/authenticate", env="OIDC_LOGIN_URL") + LOGIN_URL = OIDC_LOGIN_URL + + OIDC_LOGIN_REDIRECT_URL: str = Field( + default="/oidc/callback/", env="OIDC_LOGIN_REDIRECT_URL" + ) + LOGIN_REDIRECT_URL = OIDC_LOGIN_REDIRECT_URL - LOGIN_REDIRECT_URL: str = Field( - default="/oidc/callback/", env="LOGIN_REDIRECT_URL" + OIDC_LOGOUT_REDIRECT_URL: str = Field( + default="/", env="OIDC_LOGOUT_REDIRECT_URL" ) + LOGOUT_REDIRECT_URL = OIDC_LOGOUT_REDIRECT_URL OIDC_RP_SIGN_ALGO: str = Field(default="RS256", env="OIDC_RP_SIGN_ALGO") OIDC_OP_JWKS_ENDPOINT: str = Field(env="OIDC_OP_JWKS_ENDPOINT") @@ -349,6 +355,11 @@ def secret_key_not_empty(cls, v) -> str: ) OIDC_OP_TOKEN_ENDPOINT: str = Field(env="OIDC_OP_TOKEN_ENDPOINT") OIDC_OP_USER_ENDPOINT: str = Field(env="OIDC_OP_USER_ENDPOINT") + OIDC_OP_LOGOUT_ENDPOINT: str = Field(env="OIDC_OP_LOGOUT_ENDPOINT") + OIDC_OP_LOGOUT_URL_METHOD: str = Field( + default="users.views.provider_logout", env="OIDC_OP_LOGOUT_URL_METHOD" + ) + OIDC_STORE_ID_TOKEN: bool = Field(default=True, env="OIDC_STORE_ID_TOKEN") OIDC_SUPER_ADMIN_ROLE: str = Field( default="super_admin", env="OIDC_SUPER_ADMIN_ROLE" @@ -360,7 +371,9 @@ def secret_key_not_empty(cls, v) -> str: default="project_admin", env="OIDC_PROJECT_ADMIN_ROLE" ) OIDC_USER_ROLE: str = Field(default="user", env="OIDC_USER_ROLE") - OIDC_TOKEN_ROLE_PATH: str = Field(default="$.entirety.roles", env="OIDC_TOKEN_ROLE_PATH") + OIDC_TOKEN_ROLE_PATH: str = Field( + default="$.entirety.roles", env="OIDC_TOKEN_ROLE_PATH" + ) # Internationalization # https://docs.djangoproject.com/en/4.0/topics/i18n/ diff --git a/app/Entirety/users/views.py b/app/Entirety/users/views.py index 4f7b91c7..c2d9c968 100644 --- a/app/Entirety/users/views.py +++ b/app/Entirety/users/views.py @@ -1,3 +1,6 @@ +from urllib.parse import urlencode + +from django.conf import settings from django.contrib.auth.decorators import login_required from django.shortcuts import render @@ -9,3 +12,23 @@ def user_info(request, *args, **kwargs): form = UserForm(instance=request.user) context = {"form": form} return render(request, "profile.html", context=context) + + +def provider_logout(request): + logout_url = settings.OIDC_OP_LOGOUT_ENDPOINT + + oidc_id_token = request.session.get("oidc_id_token", None) + if oidc_id_token: + logout_url = ( + settings.OIDC_OP_LOGOUT_ENDPOINT + + "?" + + urlencode( + { + "id_token_hint": oidc_id_token, + "post_logout_redirect_uri": request.build_absolute_uri( + location=settings.LOGOUT_REDIRECT_URL + ), + } + ) + ) + return logout_url