From 769b63d45769d8efa3d10b7700dd2e70777c4232 Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Sun, 9 Mar 2025 19:16:07 +0100 Subject: [PATCH 1/4] chore: replace jet fork by django-jet-reboot --- .gitmodules | 3 - jdav_web/jet | 1 - jdav_web/templates/admin/base.html | 439 +++++++++++++++++++++++++++++ requirements.txt | 8 + 4 files changed, 447 insertions(+), 4 deletions(-) delete mode 100644 .gitmodules delete mode 160000 jdav_web/jet create mode 100644 jdav_web/templates/admin/base.html diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 7540d5b..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "jdav_web/jet"] - path = jdav_web/jet - url = https://git.flavigny.de/jdavlb/jet/ diff --git a/jdav_web/jet b/jdav_web/jet deleted file mode 160000 index 0126d55..0000000 --- a/jdav_web/jet +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0126d5596fcba43730ecc7e6cbc0987b12f0640d diff --git a/jdav_web/templates/admin/base.html b/jdav_web/templates/admin/base.html new file mode 100644 index 0000000..f7d55f2 --- /dev/null +++ b/jdav_web/templates/admin/base.html @@ -0,0 +1,439 @@ +{% load i18n static jet_tags %} +{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %} +{% jet_get_current_theme as THEME %} +{% jet_get_current_version as JET_VERSION %} +{% block html %} + +{% block title %}{% endblock %} + + + + + + + + + + +{% block extrastyle %}{% endblock %} +{% if LANGUAGE_BIDI %}{% endif %} +{% jet_get_date_format as date_format %} +{% jet_get_time_format as time_format %} +{% jet_get_datetime_format as datetime_format %} + + + + + +{% jet_static_translation_urls as translation_urls %} +{% for url in translation_urls %} + +{% endfor %} + +{% block extrahead %}{% endblock %} +{% block blockbots %}{% endblock %} + + + +{% load i18n %} + + + + +
+ + {% if not is_popup %} + + + + + {% block breadcrumbs %} + + {% endblock %} + {% endif %} + + {% block messages %} + {% if messages %} + + {% endif %} + {% endblock messages %} + + +
+ {% block pretitle %}{% endblock %} + {% block content_title %}{% if title %}

{{ title }}

{% endif %}{% endblock %} + {% block content %} + {% block object-tools %}{% endblock %} + {{ content }} + {% endblock %} + {% block sidebar %}{% endblock %} +
+
+ + + {% block footer %}{% endblock %} + + {% jet_delete_confirmation_context as delete_confirmation_context %} + {{ delete_confirmation_context }} + + {% jet_change_form_sibling_links_enabled as show_siblings %} + {% if change and show_siblings %} +
+ {% spaceless %} + {% jet_previous_object as sibling %} + + + + {% if sibling %} + {{ sibling.label }} + {% else %} + --- + {% endif %} + + + + {% jet_next_object as sibling %} + + + + {% if sibling %} + {{ sibling.label }} + {% else %} + --- + {% endif %} + + + {% endspaceless %} +
+ {% endif %} + + {% jet_get_side_menu_compact as SIDE_MENU_COMPACT %} + {% if not is_popup %} + + + + + {% endif %} + + {% jet_get_themes as THEMES %} + {% if THEMES %} +
  • +
    {% trans "current theme" %}
    + +
  • + {% endif %} +
    + + + +{% endblock %} diff --git a/requirements.txt b/requirements.txt index 08b607e..086063b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,10 @@ +alabaster==0.7.16 amqp==5.0.9 asgiref==3.4.1 auditlog3==1.0.1 babel==2.16.0 bcrypt==4.0.1 +beautifulsoup4==4.13.3 billiard==3.6.4.0 bleach==6.0.0 celery==5.2.3 @@ -19,15 +21,18 @@ Django==4.0.1 django-appconf==1.0.5 django-celery-beat==2.5.0 django-celery-email==3.0.0 +django-jet-reboot==1.3.10 django-markdownify==0.9.3 django-markdownx==4.0.2 django-nested-admin==4.0.2 django-split-settings==1.2.0 django-timezone-field==5.0 docutils==0.21.2 +et_xmlfile==2.0.0 idna==3.3 imagesize==1.4.1 importlib-metadata==6.2.0 +importlib_resources==6.5.2 Jinja2==3.1.4 kombu==5.2.3 Markdown==3.4.3 @@ -37,6 +42,7 @@ openpyxl==3.1.5 packaging==24.2 Pillow==9.0.0 prompt-toolkit==3.0.24 +pycountry==24.6.1 Pygments==2.18.0 pymemcache==4.0.0 pyparsing==3.0.6 @@ -47,10 +53,12 @@ python-monkey-business==1.0.0 pytz==2021.3 redis==4.1.0 requests==2.32.3 +rstr==3.2.2 rules==3.3 schwifty==2024.11.0 six==1.16.0 snowballstemmer==2.2.0 +soupsieve==2.6 Sphinx==7.4.7 sphinxawesome-theme==5.3.2 sphinxcontrib-applehelp==2.0.0 From de95c76ac7f01a1763835dd83d7ce0623a1ed1bd Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Sun, 9 Mar 2025 19:53:57 +0100 Subject: [PATCH 2/4] chore: update Django to 4.2.20 --- jdav_web/templates/admin/index.html | 12 ++++++++++++ requirements.txt | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/jdav_web/templates/admin/index.html b/jdav_web/templates/admin/index.html index 7bb5776..6d60e91 100644 --- a/jdav_web/templates/admin/index.html +++ b/jdav_web/templates/admin/index.html @@ -2,6 +2,18 @@ {% load i18n static common %} {% block content %} +
    diff --git a/requirements.txt b/requirements.txt index 086063b..9e3be3a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ alabaster==0.7.16 amqp==5.0.9 -asgiref==3.4.1 +asgiref==3.8.1 auditlog3==1.0.1 babel==2.16.0 bcrypt==4.0.1 @@ -17,7 +17,7 @@ click-repl==0.2.0 coverage==7.5.4 cron-descriptor==1.2.35 Deprecated==1.2.13 -Django==4.0.1 +Django==4.2.20 django-appconf==1.0.5 django-celery-beat==2.5.0 django-celery-email==3.0.0 From 7c5152c5b0115f173dfc6b986bdcfc20db264884 Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Sun, 9 Mar 2025 20:10:21 +0100 Subject: [PATCH 3/4] feat: oauth provider --- jdav_web/jdav_web/settings/__init__.py | 1 + jdav_web/jdav_web/settings/components/base.py | 3 +++ jdav_web/jdav_web/settings/components/oauth.py | 11 +++++++++++ jdav_web/jdav_web/urls.py | 4 +++- jdav_web/logindata/oauth.py | 11 +++++++++++ requirements.txt | 6 ++++++ 6 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 jdav_web/jdav_web/settings/components/oauth.py create mode 100644 jdav_web/logindata/oauth.py diff --git a/jdav_web/jdav_web/settings/__init__.py b/jdav_web/jdav_web/settings/__init__.py index 1fe9471..248f7d1 100644 --- a/jdav_web/jdav_web/settings/__init__.py +++ b/jdav_web/jdav_web/settings/__init__.py @@ -58,6 +58,7 @@ base_settings = [ 'components/emails.py', 'components/texts.py', 'components/locale.py', + 'components/oauth.py', ] include(*base_settings) diff --git a/jdav_web/jdav_web/settings/components/base.py b/jdav_web/jdav_web/settings/components/base.py index e546624..f3b5d89 100644 --- a/jdav_web/jdav_web/settings/components/base.py +++ b/jdav_web/jdav_web/settings/components/base.py @@ -52,6 +52,7 @@ INSTALLED_APPS = [ 'django_celery_beat', 'rules', 'jet', + 'oauth2_provider', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -196,3 +197,5 @@ STARTPAGE_URL_NAME_PATTERN = "[\w\-: *]" # admins to contact on error messages ADMINS = get_var('section', 'admins', default=[]) + +LOGIN_URL = '/de/kompass/login/' diff --git a/jdav_web/jdav_web/settings/components/oauth.py b/jdav_web/jdav_web/settings/components/oauth.py new file mode 100644 index 0000000..5e8b831 --- /dev/null +++ b/jdav_web/jdav_web/settings/components/oauth.py @@ -0,0 +1,11 @@ +OAUTH2_PROVIDER = { + "OIDC_ENABLED": True, + "PKCE_REQUIRED": False, + "OAUTH2_VALIDATOR_CLASS": "logindata.oauth.CustomOAuth2Validator", + "OIDC_RSA_PRIVATE_KEY": get_var('oauth', 'oidc_rsa_private_key', default=''), + "SCOPES": { + "openid": "OpenID Connect scope", + "profile": "profile scope", + "email": "email scope", + }, +} diff --git a/jdav_web/jdav_web/urls.py b/jdav_web/jdav_web/urls.py index b32210c..1b034c0 100644 --- a/jdav_web/jdav_web/urls.py +++ b/jdav_web/jdav_web/urls.py @@ -13,13 +13,14 @@ Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ -from django.urls import re_path, include +from django.urls import path, re_path, include from django.contrib import admin from django.conf.urls.static import static from django.conf.urls.i18n import i18n_patterns from django.conf import settings from django.utils.translation import gettext_lazy as _ from django.views.generic.base import RedirectView +from oauth2_provider import urls as oauth2_urls from .views import media_access admin.site.index_title = _('Startpage') @@ -36,6 +37,7 @@ urlpatterns = i18n_patterns( re_path(r'^LBAlpin/Programm(/)?(20)?[0-9]{0,2}', include('ludwigsburgalpin.urls', namespace="ludwigsburgalpin")), re_path(r'^_nested_admin/', include('nested_admin.urls')), + path('o/', include(oauth2_urls)), re_path(r'^', include('startpage.urls', namespace="startpage")), ) diff --git a/jdav_web/logindata/oauth.py b/jdav_web/logindata/oauth.py new file mode 100644 index 0000000..06d870b --- /dev/null +++ b/jdav_web/logindata/oauth.py @@ -0,0 +1,11 @@ +from oauth2_provider.oauth2_validators import OAuth2Validator + + +class CustomOAuth2Validator(OAuth2Validator): + # Set `oidc_claim_scope = None` to ignore scopes that limit which claims to return, + # otherwise the OIDC standard scopes are used. + + def get_additional_claims(self, request): + return { + "preferred_username": request.user.username + } diff --git a/requirements.txt b/requirements.txt index 9e3be3a..abfb4de 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,7 @@ billiard==3.6.4.0 bleach==6.0.0 celery==5.2.3 certifi==2021.10.8 +cffi==1.17.1 charset-normalizer==2.0.10 click==8.0.3 click-didyoumean==0.3.0 @@ -16,6 +17,7 @@ click-plugins==1.1.1 click-repl==0.2.0 coverage==7.5.4 cron-descriptor==1.2.35 +cryptography==44.0.2 Deprecated==1.2.13 Django==4.2.20 django-appconf==1.0.5 @@ -25,6 +27,7 @@ django-jet-reboot==1.3.10 django-markdownify==0.9.3 django-markdownx==4.0.2 django-nested-admin==4.0.2 +django-oauth-toolkit==3.0.1 django-split-settings==1.2.0 django-timezone-field==5.0 docutils==0.21.2 @@ -34,15 +37,18 @@ imagesize==1.4.1 importlib-metadata==6.2.0 importlib_resources==6.5.2 Jinja2==3.1.4 +jwcrypto==1.5.6 kombu==5.2.3 Markdown==3.4.3 MarkupSafe==3.0.2 mysqlclient==2.1.0 +oauthlib==3.2.2 openpyxl==3.1.5 packaging==24.2 Pillow==9.0.0 prompt-toolkit==3.0.24 pycountry==24.6.1 +pycparser==2.22 Pygments==2.18.0 pymemcache==4.0.0 pyparsing==3.0.6 From 3de28c3729d47da5d769237bf4aac3a7f0bfa5e8 Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Sun, 23 Mar 2025 10:41:54 +0100 Subject: [PATCH 4/4] feat(logindata/oauth): add email field --- jdav_web/logindata/oauth.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/jdav_web/logindata/oauth.py b/jdav_web/logindata/oauth.py index 06d870b..ee0e5f3 100644 --- a/jdav_web/logindata/oauth.py +++ b/jdav_web/logindata/oauth.py @@ -6,6 +6,8 @@ class CustomOAuth2Validator(OAuth2Validator): # otherwise the OIDC standard scopes are used. def get_additional_claims(self, request): - return { - "preferred_username": request.user.username - } + if request.user.member: + context = {'email': request.user.member.email} + else: + context = {} + return dict(context, preferred_username=request.user.username)