Files
manage/backend/src/media_library_viewer_api/integrations/authentik.py
T
2026-07-14 21:41:24 +00:00

86 lines
2.8 KiB
Python

"""Authentik service definition for read-only directory and access metadata."""
from __future__ import annotations
from typing import TYPE_CHECKING, Any
from pydantic import Field
from media_library_viewer_api.clients.authentik import AuthentikClient
from media_library_viewer_api.integrations.base import (
SecretField,
ServiceBaseUrl,
ServiceConfigBase,
ServiceDefinition,
TestResult,
WidgetConfigBase,
translate_connection_error,
widget_kind,
)
if TYPE_CHECKING:
from media_library_viewer_api.services.settings_store import SettingsStore
def test_connection(config: dict[str, Any], secrets: dict[str, str], store: SettingsStore) -> TestResult:
"""Probe the least-expensive Authentik directory endpoint."""
try:
client = AuthentikClient(
base_url=str(config.get("base_url") or "").rstrip("/"),
api_token=str(secrets.get("api_token") or ""),
timeout=float(config.get("timeout_seconds") or 60),
)
result = client.users(page=1, page_size=1)
return TestResult(ok=True, detail="Connected to Authentik.", evidence=f"{result.get('total', 0)} users")
except Exception as exc:
return translate_connection_error(exc, context="Authentik")
class AuthentikConfig(ServiceConfigBase):
"""Non-secret Authentik connection config."""
base_url: ServiceBaseUrl
timeout_seconds: int = Field(default=60, ge=1, le=300)
class AuthentikListWidgetConfig(WidgetConfigBase):
"""Bounded display count for read-only Authentik list widgets."""
limit: int = Field(default=10, ge=1, le=50)
DEFINITION = ServiceDefinition(
service_type="authentik",
name="Authentik",
description="Read-only user directory, groups, and application access metadata.",
config_model=AuthentikConfig,
secret_fields=[SecretField(key="api_token", label="API token", required=True)],
widget_kinds=[
widget_kind(
kind="access_summary",
name="User access summary",
description="User group memberships and explicit staff/superuser status; not effective authorization.",
model_cls=AuthentikListWidgetConfig,
default_config={"limit": 10},
refresh_interval_ms=60_000,
),
widget_kind(
kind="groups",
name="Groups",
description="Read-only Authentik group list.",
model_cls=AuthentikListWidgetConfig,
default_config={"limit": 10},
refresh_interval_ms=60_000,
),
widget_kind(
kind="applications",
name="Applications",
description="Read-only Authentik application list.",
model_cls=AuthentikListWidgetConfig,
default_config={"limit": 10},
refresh_interval_ms=60_000,
),
],
test_callable=test_connection,
)