From c881a75c528f28377ab332c7412ba7c42e0707b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Cant=C3=B9?= Date: Wed, 3 Jul 2024 10:10:17 +0200 Subject: [PATCH] add openid connect login --- .env.example | 5 +++++ docker-compose.yml | 7 ++++++- pyproject.toml | 2 +- src/apps/users/adapters.py | 11 +++++++++++ src/config/settings/base.py | 21 ++++++++++++++++++++- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index 6bed8a9..105f7ae 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,7 @@ POSTGRES_PASSWORD=postgres DJANGO_SECRET_KEY=secret + +# Generate a client id/client secret on keycloack +OIDC_CLIENT_ID= +OIDC_SECRET= +OIDC_PROVIDER_URL=https://keycloak.nina.no/realms/nina/ diff --git a/docker-compose.yml b/docker-compose.yml index 41e5d2f..76549ff 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,8 +5,13 @@ volumes: x-django-env: &django-env DATABASE_URL: "postgis://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres?sslmode=disable" DJANGO_SETTINGS_MODULE: config.settings.production - DJANGO_ACCOUNT_ALLOW_REGISTRATION: "False" USE_DOCKER: "yes" + OIDC_PROVIDER_ID: nina + OIDC_CLIENT_ID: "${OIDC_CLIENT_ID}" + OIDC_SECRET: "${OIDC_SECRET}" + OIDC_PROVIDER_URL: "${OIDC_PROVIDER_URL}" + OIDC_PROVIDER_NAME: NINA + x-django-prod-env: &django-prod-env <<: *django-env diff --git a/pyproject.toml b/pyproject.toml index 0268b22..f38e8dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,7 +40,7 @@ dependencies = [ "django-template-partials", "neapolitan", "fontawesomefree", - "django-allauth-ui==0.3.8", + "django-allauth-ui==1.1.6", "django-widget-tweaks", "django-taggit", "django-tables2", diff --git a/src/apps/users/adapters.py b/src/apps/users/adapters.py index 7910bb5..7b2b104 100644 --- a/src/apps/users/adapters.py +++ b/src/apps/users/adapters.py @@ -3,6 +3,7 @@ from typing import Self from allauth.account.adapter import DefaultAccountAdapter +from allauth.socialaccount.adapter import DefaultSocialAccountAdapter from django.conf import settings from django.http import HttpRequest @@ -10,3 +11,13 @@ class AccountAdapter(DefaultAccountAdapter): def is_open_for_signup(self: Self, request: HttpRequest) -> bool: return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True) + + +class SocialAccountAdapter(DefaultSocialAccountAdapter): + """ + just for debugging obscure integration exceptions + """ + + def authentication_error(self, *args, **kwargs): + print(args, kwargs) + return super().authentication_error(*args, **kwargs) diff --git a/src/config/settings/base.py b/src/config/settings/base.py index 184de93..cc71b92 100644 --- a/src/config/settings/base.py +++ b/src/config/settings/base.py @@ -304,7 +304,7 @@ # django-allauth # ------------------------------------------------------------------------------ -ACCOUNT_ALLOW_REGISTRATION = env.bool("DJANGO_ACCOUNT_ALLOW_REGISTRATION", False) +ACCOUNT_ALLOW_REGISTRATION = True # https://django-allauth.readthedocs.io/en/latest/configuration.html ACCOUNT_AUTHENTICATION_METHOD = "email" # https://django-allauth.readthedocs.io/en/latest/configuration.html @@ -317,9 +317,28 @@ ACCOUNT_EMAIL_VERIFICATION = "none" # https://django-allauth.readthedocs.io/en/latest/configuration.html ACCOUNT_ADAPTER = "apps.users.adapters.AccountAdapter" +SOCIALACCOUNT_ADAPTER = "apps.users.adapters.SocialAccountAdapter" # https://django-allauth.readthedocs.io/en/latest/forms.html ACCOUNT_FORMS = {"signup": "apps.users.forms.UserSignupForm"} +SOCIALACCOUNT_ONLY = True +SOCIALACCOUNT_PROVIDERS = { + "openid_connect": { + "APPS": [ + { + "provider_id": env("OIDC_PROVIDER_ID"), + "name": env("OIDC_PROVIDER_NAME"), + "client_id": env("OIDC_CLIENT_ID"), + "secret": env("OIDC_SECRET"), + "settings": { + "server_url": env("OIDC_PROVIDER_URL"), + }, + }, + ] + } +} + + # Django REST-Framework REST_FRAMEWORK = { "DEFAULT_PERMISSION_CLASSES": [