From 6f82343d60afadce064e474f6b52f30cf86de80d Mon Sep 17 00:00:00 2001 From: Matthias Dellweg Date: Fri, 24 Apr 2026 11:24:49 +0200 Subject: [PATCH 1/3] WIP --- .github/workflows/scripts/before_install.sh | 5 +++++ ci_requirements.txt | 2 +- pulpcore/app/settings.py | 17 ++++++++++++++++- pulpcore/app/urls.py | 3 +++ pyproject.toml | 1 + 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scripts/before_install.sh b/.github/workflows/scripts/before_install.sh index 2d8d709cae9..cde52b40d56 100755 --- a/.github/workflows/scripts/before_install.sh +++ b/.github/workflows/scripts/before_install.sh @@ -79,6 +79,11 @@ services: image: "docker.io/pulp/pulp-fixtures:latest" env: BASE_URL: "http://pulp-fixtures:8080" + - name: "saml2-idp" + image: "ghcr.io/pfrest/mock-saml2-idp:latest" + env: + SP_ENTITY_ID: "http://pulp" + SP_ACS_LOCATION: "http://pulp/saml/acs/" VARSYAML if [ "$TEST" = "s3" ]; then diff --git a/ci_requirements.txt b/ci_requirements.txt index 8b137891791..268d042d873 100644 --- a/ci_requirements.txt +++ b/ci_requirements.txt @@ -1 +1 @@ - +pulpcore[saml2] diff --git a/pulpcore/app/settings.py b/pulpcore/app/settings.py index e79a2f26ad4..8e11210d1d8 100644 --- a/pulpcore/app/settings.py +++ b/pulpcore/app/settings.py @@ -604,6 +604,21 @@ def otel_middleware_hook(settings): return data +def saml2_settings_hook(settings): + data = {"dynaconf_merge": True} + if "LOGIN_URL" not in settings: + data["LOGIN_URL"] = "/saml2/login/" + if "SESSION_COOKIE_SECURE" not in settings: + data["SESSION_COOKIE_SECURE"] = True + if "SESSION_EXPIRE_AT_BROWSER_CLOSE" not in settings: + data["SESSION_EXPIRE_AT_BROWSER_CLOSE"] = True + if "SAML_CONFIG" in settings: + data["INSTALLED_APPS"] = ["djangosaml2"] + data["MIDDLEWARE"] = ["djangosaml2.middleware.SamlSessionMiddleware"] + data["AUTHENTICATION_BACKENDS"] = ["djangosaml2.backends.Saml2Backend"] + return data + + del preload_settings settings = DjangoDynaconf( @@ -628,7 +643,7 @@ def otel_middleware_hook(settings): otel_metrics_dispatch_interval_validator, distributed_publication_retention_period_validator, ], - post_hooks=(otel_middleware_hook,), + post_hooks=(otel_middleware_hook, saml2_settings_hook), ) _logger = getLogger(__name__) diff --git a/pulpcore/app/urls.py b/pulpcore/app/urls.py index 47423392483..1402589cc9c 100644 --- a/pulpcore/app/urls.py +++ b/pulpcore/app/urls.py @@ -245,6 +245,9 @@ class NoSchema(p.callback.cls): path("", include("social_django.urls", namespace=settings.SOCIAL_AUTH_URL_NAMESPACE)) ) +if "djangosaml2" in settings.INSTALLED_APPS: + urlpatterns.append(path("saml2/", include("djangosaml2.urls"))) + #: The Pulp Platform v3 API router, which can be used to manually register ViewSets with the API. root_router = PulpDefaultRouter() diff --git a/pyproject.toml b/pyproject.toml index d036370cb4d..6c4d318f298 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,7 @@ s3 = ["django-storages[boto3]==1.14.6"] google = ["django-storages[google]==1.14.6"] azure = ["django-storages[azure]==1.14.6"] prometheus = ["django-prometheus"] +saml2 = ["djangosaml2>=1.12.0,<1.13"] kafka = [ # Pinned because project warns "things might (and will) break with every update" "cloudevents==1.11.0", From c2503e017742b1c94fc1bed23a17d895e1aed71a Mon Sep 17 00:00:00 2001 From: Matthias Dellweg Date: Mon, 11 May 2026 16:04:11 +0200 Subject: [PATCH 2/3] Workaround DynaBox issue for pysaml2 --- pulpcore/app/settings.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pulpcore/app/settings.py b/pulpcore/app/settings.py index 8e11210d1d8..83dd717d75d 100644 --- a/pulpcore/app/settings.py +++ b/pulpcore/app/settings.py @@ -18,6 +18,8 @@ from cryptography.fernet import Fernet from django.core.exceptions import ImproperlyConfigured from dynaconf import DjangoDynaconf, Dynaconf, Validator +from dynaconf.base import Settings +from dynaconf.utils.functional import empty from pulpcore import constants @@ -621,8 +623,15 @@ def saml2_settings_hook(settings): del preload_settings +class PulpSettings(Settings): + def _ready(self): + self._store = self._store.to_dict() + + settings = DjangoDynaconf( __name__, + _wrapper_class=PulpSettings, + DYNABOXIFY=False, ENVVAR_PREFIX_FOR_DYNACONF="PULP", ENV_SWITCHER_FOR_DYNACONF="PULP_ENV", ENVVAR_FOR_DYNACONF="PULP_SETTINGS", @@ -679,3 +688,5 @@ def saml2_settings_hook(settings): settings.set("V3_DOMAIN_API_ROOT", api_root + "/api/v3/") settings.set("V3_API_ROOT_NO_FRONT_SLASH", settings.V3_API_ROOT.lstrip("/")) settings.set("V3_DOMAIN_API_ROOT_NO_FRONT_SLASH", settings.V3_DOMAIN_API_ROOT.lstrip("/")) + +settings._wrapped._ready() From 1bbc43e26abd98b59fbf7a7f12e54c5375fc5e26 Mon Sep 17 00:00:00 2001 From: Matthias Dellweg Date: Wed, 13 May 2026 09:12:37 +0200 Subject: [PATCH 3/3] Experiment with some settings No luck yet. --- pulpcore/app/settings.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pulpcore/app/settings.py b/pulpcore/app/settings.py index 83dd717d75d..27192e58274 100644 --- a/pulpcore/app/settings.py +++ b/pulpcore/app/settings.py @@ -19,7 +19,6 @@ from django.core.exceptions import ImproperlyConfigured from dynaconf import DjangoDynaconf, Dynaconf, Validator from dynaconf.base import Settings -from dynaconf.utils.functional import empty from pulpcore import constants @@ -608,21 +607,22 @@ def otel_middleware_hook(settings): def saml2_settings_hook(settings): data = {"dynaconf_merge": True} - if "LOGIN_URL" not in settings: - data["LOGIN_URL"] = "/saml2/login/" - if "SESSION_COOKIE_SECURE" not in settings: - data["SESSION_COOKIE_SECURE"] = True - if "SESSION_EXPIRE_AT_BROWSER_CLOSE" not in settings: - data["SESSION_EXPIRE_AT_BROWSER_CLOSE"] = True if "SAML_CONFIG" in settings: data["INSTALLED_APPS"] = ["djangosaml2"] data["MIDDLEWARE"] = ["djangosaml2.middleware.SamlSessionMiddleware"] data["AUTHENTICATION_BACKENDS"] = ["djangosaml2.backends.Saml2Backend"] + if "LOGIN_URL" not in settings: + data["LOGIN_URL"] = "/saml2/login/" + if "SESSION_COOKIE_SECURE" not in settings: + data["SESSION_COOKIE_SECURE"] = True + if "SESSION_EXPIRE_AT_BROWSER_CLOSE" not in settings: + data["SESSION_EXPIRE_AT_BROWSER_CLOSE"] = True return data del preload_settings + class PulpSettings(Settings): def _ready(self): self._store = self._store.to_dict()