Compare commits

..

3 Commits

Author SHA1 Message Date
Jens Langhammer
30e2e255d4 add oidcc-config-certification-test-plan
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2026-05-09 00:51:06 +02:00
Jens Langhammer
e40cb7eca3 check that finished test module is in correct state
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2026-05-09 00:49:06 +02:00
Jens Langhammer
0bf99fe379 allow for non-variant
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2026-05-09 00:48:32 +02:00
10 changed files with 78 additions and 48 deletions

View File

@@ -1,26 +1,38 @@
<!--
👋 Hi there! Welcome. Please check the contributing guidelines: https://docs.goauthentik.io/docs/developer-docs/#how-can-i-contribute
👋 Hi there! Welcome.
⚠️ Open this PR from a feature branch, not from main: https://docs.goauthentik.io/developer-docs/contributing/#always-use-feature-branches
Please check the Contributing guidelines: https://docs.goauthentik.io/docs/developer-docs/#how-can-i-contribute
⚠️ IMPORTANT: Make sure you are opening this PR from a FEATURE BRANCH, not from your main branch!
If you opened this PR from your main branch, please close it and create a new feature branch instead.
For more information, see: https://docs.goauthentik.io/developer-docs/contributing/#always-use-feature-branches
-->
## Details
### What does this PR change?
### Why is this change needed?
### How was this tested?
### Linked issues
<!--
Use `closes #N` to auto-close on merge. Use `refs #N` for related issues that this PR does not close.
Explain what this PR changes, what the rationale behind the change is, if any new requirements are introduced or any breaking changes caused by this PR.
Ideally also link an Issue for context that this PR will close using `closes #`
-->
REPLACE ME
---
## Checklist
- [ ] The project has been linted, built, and tested (`make all`)
- [ ] The documentation has been updated and formatted (`make docs`)
- [ ] Local tests pass (`ak test authentik/`)
- [ ] The code has been formatted (`make lint-fix`)
If an API change has been made
- [ ] The API schema and clients have been updated (`make gen`)
If changes to the frontend have been made
- [ ] The code has been formatted (`make web`)
If applicable
- [ ] The documentation has been updated
- [ ] The documentation has been formatted (`make docs`)

View File

@@ -284,6 +284,8 @@ jobs:
job:
- name: oidc_basic
glob: tests/openid_conformance/test_oidc_basic.py
- name: oidc_config
glob: tests/openid_conformance/test_oidc_config.py
- name: oidc_implicit
glob: tests/openid_conformance/test_oidc_implicit.py
- name: oidc_rp-initiated

View File

@@ -100,7 +100,7 @@ class SAMLProviderSerializer(ProviderSerializer):
try:
return request.build_absolute_uri(
reverse(
"authentik_providers_saml:metadata-download",
"authentik_providers_saml:base",
kwargs={"application_slug": instance.application.slug},
)
)

View File

@@ -147,7 +147,7 @@ class AssertionProcessor:
return self.http_request.build_absolute_uri(
reverse(
"authentik_providers_saml:metadata-download",
"authentik_providers_saml:base",
kwargs={"application_slug": self.provider.application.slug},
)
)

View File

@@ -48,7 +48,7 @@ class MetadataProcessor:
return self.http_request.build_absolute_uri(
reverse(
"authentik_providers_saml:metadata-download",
"authentik_providers_saml:base",
kwargs={"application_slug": self.provider.application.slug},
)
)

View File

@@ -19,12 +19,6 @@ from authentik.tenants.models import Tenant
class FlagJSONField(JSONDictField):
def to_internal_value(self, data: str):
flags = super().to_internal_value(data)
for flag in Flag.available(visibility="system", exclude_system=False):
flags[flag().key] = flag.get()
return flags
def to_representation(self, value: dict) -> dict:
new_value = value.copy()
for flag in Flag.available(exclude_system=False):
@@ -39,10 +33,13 @@ class FlagJSONField(JSONDictField):
def run_validators(self, value: dict):
super().run_validators(value)
for flag in Flag.available():
for flag in Flag.available(exclude_system=False):
_flag = flag()
if _flag.key not in value:
continue
if _flag.visibility == "system":
value.pop(_flag.key, None)
continue
flag_value = value.get(_flag.key)
flag_type = get_args(_flag.__orig_bases__[0])[0]
if flag_value and not isinstance(flag_value, flag_type):

View File

@@ -85,30 +85,10 @@ class TestLocalSettingsAPI(APITestCase):
"flags": {"tenants_test_flag_sys": 123},
},
)
print(response.content)
self.assertEqual(response.status_code, 200)
self.tenant.refresh_from_db()
self.assertEqual(self.tenant.flags, {"setup": False, "tenants_test_flag_sys": False})
def test_settings_flags_system_empty_put(self):
"""Test settings API"""
self.tenant.flags = {}
self.tenant.save()
class _TestFlag(Flag[bool], key="tenants_test_flag_sys"):
default = False
visibility = "system"
self.client.force_login(self.local_admin)
response = self.client.patch(
reverse("authentik_api:tenant_settings"),
data={
"flags": {},
},
)
self.assertEqual(response.status_code, 200)
self.tenant.refresh_from_db()
self.assertEqual(self.tenant.flags, {"setup": False, "tenants_test_flag_sys": False})
self.assertEqual(self.tenant.flags, {})
def test_command(self):
self.tenant.flags = {}

View File

@@ -63,7 +63,10 @@ class TestOpenIDConformance(SSLLiveMixin, SeleniumTestCase):
}
def run_test(
self, test_name: str, test_plan_config: dict[str, Any], test_variant: dict[str, Any]
self,
test_name: str,
test_plan_config: dict[str, Any],
test_variant: dict[str, Any] | None = None,
):
self.conformance = Conformance(f"https://{self.host}:8443/", None, verify_ssl=False)
@@ -82,7 +85,14 @@ class TestOpenIDConformance(SSLLiveMixin, SeleniumTestCase):
)
module_id = module_instance["id"]
self.run_single_test(module_id)
self.conformance.wait_for_state(module_id, ["FINISHED"], timeout=self.wait_timeout)
module = self.conformance.wait_for_state(
module_id, ["FINISHED"], timeout=self.wait_timeout
)
self.assertIn(
module["result"],
["PASSED", "SKIPPED", "WARNING"],
f"Module {module['testName']} did not finish with expected status.",
)
sleep(2)
self.conformance.export_html(plan_id, Path(__file__).parent / "exports")

View File

@@ -205,7 +205,7 @@ class Conformance:
info = self.get_module_info(module_id)
status: str | None = info.get("status")
if status in required_states:
return status
return info
if status == "INTERRUPTED":
raise ConformanceException(f"Test module {module_id} has moved to INTERRUPTED")
sleep(1)

View File

@@ -0,0 +1,29 @@
from authentik.providers.oauth2.models import IssuerMode, OAuth2Provider
from tests.decorators import retry
from tests.live import SSLLiveMixin
from tests.openid_conformance.base import TestOpenIDConformance
class TestOpenIDConformanceConfig(TestOpenIDConformance, SSLLiveMixin):
def setUp(self):
super().setUp()
OAuth2Provider.objects.filter(name__startswith="oidc-conformance-").update(
issuer_mode=IssuerMode.PER_PROVIDER
)
@retry()
def test_oidcc_config_certification_test_plan(self):
self.run_test(
"oidcc-config-certification-test-plan",
{
"alias": "authentik",
"description": "authentik",
"server": {
"discoveryUrl": self.url(
"authentik_providers_oauth2:provider-info",
application_slug="oidc-conformance-1",
),
},
},
)