From e75b47fa8d7c6a810eb92bc7cdb06b1eaef8f190 Mon Sep 17 00:00:00 2001 From: Kumi Date: Fri, 27 Jun 2025 16:35:33 +0200 Subject: [PATCH] feat: Styling for OIDC-related pages --- .snapshotignore | 1 - duckpond/core/claims.py | 23 ++++++ .../templates/oidc_provider/authorize.html | 78 +++++++++++++++++++ .../oidc_provider/end_session_prompt.html | 55 +++++++++++++ .../core/templates/oidc_provider/error.html | 59 ++++++++++++++ duckpond/core/views.py | 14 +--- duckpond/duckpond/settings.py | 3 +- 7 files changed, 218 insertions(+), 15 deletions(-) create mode 100644 duckpond/core/claims.py create mode 100644 duckpond/core/templates/oidc_provider/authorize.html create mode 100644 duckpond/core/templates/oidc_provider/end_session_prompt.html create mode 100644 duckpond/core/templates/oidc_provider/error.html diff --git a/.snapshotignore b/.snapshotignore index 9d7d973..6f233cf 100644 --- a/.snapshotignore +++ b/.snapshotignore @@ -1,3 +1,2 @@ migrations/ .ruff_cache/ -admin/ \ No newline at end of file diff --git a/duckpond/core/claims.py b/duckpond/core/claims.py new file mode 100644 index 0000000..287802d --- /dev/null +++ b/duckpond/core/claims.py @@ -0,0 +1,23 @@ +from django.utils.translation import gettext_lazy as _ +from oidc_provider.lib.claims import ScopeClaims + + +class DuckpondClaims(ScopeClaims): + info_membership = ( + _("Membership"), + _("Information about your membership."), + ) + + def scope_membership(self): + dic = { + "tier_id": self.user.membership.tier.id if self.user.membership else None, + "tier": self.user.membership.tier.name if self.user.membership else None, + "status": self.user.membership.is_active if self.user.membership else None, + } + + return dic + + info_profile = ( + _("Profile"), + _("Access to some basic profile information, including your preferred name."), + ) diff --git a/duckpond/core/templates/oidc_provider/authorize.html b/duckpond/core/templates/oidc_provider/authorize.html new file mode 100644 index 0000000..ce93b39 --- /dev/null +++ b/duckpond/core/templates/oidc_provider/authorize.html @@ -0,0 +1,78 @@ +{% extends "base.html" %} +{% load i18n %} +{% block title %} + {% trans "Authorize" %} +{% endblock %} +{% block content %} +
+

{% trans "Authorization Request" %}

+
+

+ {{ client.name }} {% trans "is requesting access to your account." %} +

+
+ {% if scopes %} +
+

{% trans "This application will be able to:" %}

+
    + {% for scope in scopes %} +
  • + + {{ scope.description }} +
  • + {% endfor %} +
+
+ {% endif %} +
+ {% csrf_token %} + {{ hidden_inputs }} +
+ + +
+
+
+ +{% endblock %} diff --git a/duckpond/core/templates/oidc_provider/end_session_prompt.html b/duckpond/core/templates/oidc_provider/end_session_prompt.html new file mode 100644 index 0000000..5ab7593 --- /dev/null +++ b/duckpond/core/templates/oidc_provider/end_session_prompt.html @@ -0,0 +1,55 @@ +{% extends "base.html" %} +{% load i18n %} +{% block title %} + {% trans "Logout" %} +{% endblock %} +{% block content %} +
+
+ +
+

{% trans "Logout" %}

+

{% trans "Are you sure you want to log out?" %}

+ {% if client %} +

+ {% blocktrans with client_name=client.name %} + You will be logged out from {{ client_name }}. + {% endblocktrans %} +

+ {% endif %} +
+ {% csrf_token %} + + + +
+ + {% trans "Cancel" %} +
+
+
+ +{% endblock %} diff --git a/duckpond/core/templates/oidc_provider/error.html b/duckpond/core/templates/oidc_provider/error.html new file mode 100644 index 0000000..8584e10 --- /dev/null +++ b/duckpond/core/templates/oidc_provider/error.html @@ -0,0 +1,59 @@ +{% extends "base.html" %} +{% load i18n %} +{% block title %} + {% trans "Error" %} +{% endblock %} +{% block content %} +
+
+ +
+

{% trans "Authentication Error" %}

+
+ {% if error %} +

+ {% trans "Error:" %} {{ error }} +

+ {% endif %} + {% if error_description %}

{{ error_description }}

{% endif %} +
+ +
+ +{% endblock %} diff --git a/duckpond/core/views.py b/duckpond/core/views.py index 6fc243a..ed3c59d 100644 --- a/duckpond/core/views.py +++ b/duckpond/core/views.py @@ -41,21 +41,9 @@ def userinfo(claims, user): Custom function for OIDC userinfo endpoint """ claims["name"] = user.get_preferred_name() - claims["given_name"] = user.first_name - claims["family_name"] = user.last_name claims["email"] = user.email claims["email_verified"] = user.email_verified - - # Add membership information if available - try: - membership = user.membership - claims["membership"] = { - "tier": membership.tier.name, - "active": membership.is_active, - "expiry_date": membership.expiry_date.isoformat(), - } - except: - pass + claims["address"]["formatted"] = user.address return claims diff --git a/duckpond/duckpond/settings.py b/duckpond/duckpond/settings.py index 52b1b14..4df3211 100644 --- a/duckpond/duckpond/settings.py +++ b/duckpond/duckpond/settings.py @@ -37,7 +37,6 @@ INSTALLED_APPS = [ "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", - "oidc_provider", "mjml", "dbsettings", "duckpond.core", @@ -45,6 +44,7 @@ INSTALLED_APPS = [ "duckpond.member_area", "duckpond.payments", "django.contrib.admin", + "oidc_provider", ] MIDDLEWARE = [ @@ -182,6 +182,7 @@ LOGIN_URL = "/login/" LOGOUT_REDIRECT_URL = "/" OIDC_USERINFO = "duckpond.core.views.userinfo" +OIDC_EXTRA_SCOPE_CLAIMS = 'duckpond.core.claims.DuckpondClaims' # Email settings