Files
authentik/tests/live.py
Connor Peshek a3b0180049 providers/oauth: make rp init logout oidc certification changes (#21815)
* providers/oauth: make rp init logout oidc certification changes

* update test

* slight rework

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add oidc certification tests

* test

* fix backchannel url

* make urls uniform

* update to main

* remove env bind

* cleanup patch

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fixup

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add traefik healthcheck

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix healthcheck

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2026-05-04 19:11:59 +02:00

141 lines
4.4 KiB
Python

from os import unlink, write
from sys import stderr
from tempfile import mkstemp
from urllib.parse import urlencode
from channels.testing import ChannelsLiveServerTestCase
from django.apps import apps
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.urls import reverse
from docker.types import Healthcheck
from dramatiq import get_broker
from structlog.stdlib import get_logger
from yaml import safe_dump
from authentik.core.apps import Setup
from authentik.core.models import User
from authentik.core.tests.utils import create_test_admin_user
from authentik.tasks.test import use_test_broker
from tests._process import TestDatabaseProcess
from tests.decorators import IS_CI, get_local_ip
from tests.docker import DockerTestCase
class E2ETestMixin(DockerTestCase):
host = get_local_ip()
user: User
serve_static = True
ProtocolServerProcess = TestDatabaseProcess
def setUp(self):
if IS_CI:
print("::group::authentik Logs", file=stderr)
apps.get_app_config("authentik_tenants").ready()
self.wait_timeout = 60
self.logger = get_logger()
self.user = create_test_admin_user()
Setup.set(True)
super().setUp()
@classmethod
def _pre_setup(cls):
use_test_broker()
return super()._pre_setup()
def _post_teardown(self):
broker = get_broker()
broker.flush_all()
broker.close()
return super()._post_teardown()
def tearDown(self):
if IS_CI:
print("::endgroup::", file=stderr)
super().tearDown()
def url(self, view: str, query: dict | None = None, **kwargs) -> str:
"""reverse `view` with `**kwargs` into full URL using live_server_url"""
url = self.live_server_url + reverse(view, kwargs=kwargs)
if query:
return url + "?" + urlencode(query)
return url
class SSLLiveMixin(DockerTestCase):
"""Mixin to provide an SSL-enabled webserver for integration/e2e tests that require it.
Overrides `live_server_url` and as such other all usual helper functions will return an HTTPS
URL. Certificate is self-signed and random on each run."""
def setUp(self):
super().setUp()
self._setup_traefik()
def tearDown(self):
super().tearDown()
unlink(self._traefik_config)
@property
def live_server_url(self):
return f"https://{self.host}:{self._traefik_port}"
def _setup_traefik(self):
config = {
"http": {
"routers": {
"authentik": {
"rule": "PathPrefix(`/`)",
"entryPoints": ["websecure"],
"service": "authentik",
"tls": {},
}
},
"services": {
"authentik": {"loadBalancer": {"servers": [{"url": super().live_server_url}]}}
},
}
}
fd, self._traefik_config = mkstemp()
write(fd, safe_dump(config).encode())
traefik = self.run_container(
image="docker.io/library/traefik:3.1",
command=[
"--providers.file.filename=/etc/traefik/dynamic.yml",
"--providers.file.watch=true",
"--entrypoints.websecure.address=:9443",
"--log.level=DEBUG",
"--api=true",
"--api.dashboard=true",
"--api.insecure=true",
"--ping=true",
],
healthcheck=Healthcheck(
test=["CMD", "traefik", "healthcheck", "--ping"],
interval=5 * 1_000 * 1_000_000,
start_period=1 * 1_000 * 1_000_000,
),
ports={
"9443": None,
},
volumes={
self._traefik_config: {
"bind": "/etc/traefik/dynamic.yml",
}
},
)
# {
# "8443/tcp": [
# {"HostIp": "0.0.0.0", "HostPort": "8443"},
# {"HostIp": "::", "HostPort": "8443"},
# ],
# }
self._traefik_port = traefik.ports["9443/tcp"][0]["HostPort"]
class E2ETestCase(E2ETestMixin, StaticLiveServerTestCase):
"""E2E Test case with django static live server"""
class ChannelsE2ETestCase(E2ETestMixin, ChannelsLiveServerTestCase):
"""E2E Test case with channels live server (websocket + static)"""