diff --git a/.env.example b/.env.example index 4199907..0df5ff7 100644 --- a/.env.example +++ b/.env.example @@ -31,3 +31,8 @@ ENABLE_SOFT_DELETE=false KEEP_DELETED_TRANSACTIONS_FOR=365 TASK_WORKERS=1 # This only work if you're using the single container option. Increase to have more open queues via procrastinate, you probably don't need to increase this. + +# OIDC Configuration +OIDC_CLIENT_ID="" +OIDC_CLIENT_SECRET="" +OIDC_SERVER_URL="" diff --git a/=0.58.2 b/=0.58.2 new file mode 100644 index 0000000..d4bc4b3 --- /dev/null +++ b/=0.58.2 @@ -0,0 +1,6 @@ +Defaulting to user installation because normal site-packages is not writeable +Requirement already satisfied: django-allauth in /home/jules/.local/lib/python3.10/site-packages (65.8.1) +Requirement already satisfied: Django>=4.2.16 in /home/jules/.local/lib/python3.10/site-packages (from django-allauth) (5.1.9) +Requirement already satisfied: asgiref>=3.8.1 in /home/jules/.local/lib/python3.10/site-packages (from django-allauth) (3.8.1) +Requirement already satisfied: typing-extensions>=4 in /usr/local/lib/python3.10/dist-packages (from asgiref>=3.8.1->django-allauth) (4.13.2) +Requirement already satisfied: sqlparse>=0.3.1 in /home/jules/.local/lib/python3.10/site-packages (from Django>=4.2.16->django-allauth) (0.5.3) diff --git a/README.md b/README.md index f93ca56..de98b4b 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,26 @@ To create the first user, open the container's console using Unraid's UI, by cli | ADMIN_EMAIL | string | None | Automatically creates an admin account with this email. Must have `ADMIN_PASSWORD` also set. | | ADMIN_PASSWORD | string | None | Automatically creates an admin account with this password. Must have `ADMIN_EMAIL` also set. | +## OIDC Configuration + +WYGIWYH supports login via OpenID Connect (OIDC) through `django-allauth`. This allows users to authenticate using an external OIDC provider. + +To configure OIDC, you need to set the following environment variables: + +| Variable | Description | +|----------------------|-----------------------------------------------------------------------------| +| `OIDC_CLIENT_ID` | The Client ID provided by your OIDC provider. | +| `OIDC_CLIENT_SECRET` | The Client Secret provided by your OIDC provider. | +| `OIDC_SERVER_URL` | The base URL of your OIDC provider's discovery document or authorization server (e.g., `https://your-provider.com/auth/realms/your-realm`). `django-allauth` will use this to discover the necessary endpoints (authorization, token, userinfo, etc.). | + +**Callback URL (Redirect URI):** + +When configuring your OIDC provider, you will need to provide a callback URL (also known as a Redirect URI). For WYGIWYH, using `django-allauth` with the provider ID 'oidc' (as configured in `settings.py`), the default callback URL is: + +`https://your.wygiwyh.domain/accounts/oidc/login/callback/` + +Replace `https://your.wygiwyh.domain` with the actual URL where your WYGIWYH instance is accessible. + # How it works Check out our [Wiki](https://github.com/eitchtee/WYGIWYH/wiki) for more information. diff --git a/app/WYGIWYH/settings.py b/app/WYGIWYH/settings.py index be6886b..52bbf76 100644 --- a/app/WYGIWYH/settings.py +++ b/app/WYGIWYH/settings.py @@ -42,6 +42,7 @@ INSTALLED_APPS = [ "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", + "django.contrib.sites", "whitenoise.runserver_nostatic", "django.contrib.staticfiles", "webpack_boilerplate", @@ -74,8 +75,14 @@ INSTALLED_APPS = [ "apps.calendar_view.apps.CalendarViewConfig", "apps.dca.apps.DcaConfig", "pwa", + "allauth", + "allauth.account", + "allauth.socialaccount", + "allauth.socialaccount.providers.openid_connect", ] +SITE_ID = 1 + MIDDLEWARE = [ "django_browser_reload.middleware.BrowserReloadMiddleware", "apps.common.middleware.thread_local.ThreadLocalMiddleware", @@ -91,6 +98,7 @@ MIDDLEWARE = [ "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "hijack.middleware.HijackUserMiddleware", + "allauth.account.middleware.AccountMiddleware", ] ROOT_URLCONF = "WYGIWYH.urls" @@ -307,6 +315,37 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" LOGIN_REDIRECT_URL = "/" LOGIN_URL = "/login/" +LOGOUT_REDIRECT_URL = "/login/" + +# Allauth settings +AUTHENTICATION_BACKENDS = [ + "django.contrib.auth.backends.ModelBackend", # Keep default + "allauth.account.auth_backends.AuthenticationBackend", +] + +SOCIALACCOUNT_PROVIDERS = { + 'oidc': { + 'APPS': [ + { + 'provider_id': 'oidc', + 'name': 'OpenID Connect', + 'client_id': os.getenv('OIDC_CLIENT_ID'), + 'secret': os.getenv('OIDC_CLIENT_SECRET'), + 'settings': { + 'server_url': os.getenv('OIDC_SERVER_URL'), + } + } + ] + } +} + +ACCOUNT_AUTHENTICATION_METHOD = 'email' +ACCOUNT_EMAIL_REQUIRED = True +ACCOUNT_USERNAME_REQUIRED = False +ACCOUNT_USER_MODEL_USERNAME_FIELD = None +ACCOUNT_EMAIL_VERIFICATION = 'optional' +SOCIALACCOUNT_ADAPTER = 'allauth.socialaccount.adapter.DefaultSocialAccountAdapter' +ACCOUNT_ADAPTER = 'allauth.account.adapter.DefaultAccountAdapter' # CRISPY FORMS CRISPY_ALLOWED_TEMPLATE_PACKS = ["bootstrap5", "crispy_forms/pure_text"] diff --git a/app/WYGIWYH/urls.py b/app/WYGIWYH/urls.py index a9612fb..24bcaee 100644 --- a/app/WYGIWYH/urls.py +++ b/app/WYGIWYH/urls.py @@ -36,6 +36,7 @@ urlpatterns = [ SpectacularSwaggerView.as_view(url_name="schema"), name="swagger-ui", ), + path('accounts/', include('allauth.urls')), # allauth urls path("", include("apps.transactions.urls")), path("", include("apps.common.urls")), path("", include("apps.users.urls")), diff --git a/app/templates/users/login.html b/app/templates/users/login.html index 341884c..ce54b57 100644 --- a/app/templates/users/login.html +++ b/app/templates/users/login.html @@ -2,6 +2,7 @@ {% load i18n %} {% load settings %} {% load crispy_forms_tags %} +{% load socialaccount %} {% block title %}Login{% endblock %} @@ -25,6 +26,26 @@
{% translate "Social login is not configured." %}
+ {% endif %} +