Media sites get Caddy forward_auth; Authentik scripts cover all proxy providers. BookStack OIDC and Plane admin routing fixes included, plus ops scripts for external auth on valhalla.
80 lines
3.2 KiB
Python
80 lines
3.2 KiB
Python
"""Create OAuth2 providers for batch-1 apps with native SSO (ak shell: exec(open(...).read()))."""
|
|
from authentik.core.models import Application
|
|
from authentik.crypto.models import CertificateKeyPair
|
|
from authentik.flows.models import Flow
|
|
from authentik.outposts.models import Outpost
|
|
from authentik.providers.oauth2.models import OAuth2Provider, RedirectURI, RedirectURIMatchingMode, SubModes
|
|
from authentik.providers.proxy.models import ProxyProvider
|
|
|
|
AUTHZ = Flow.objects.get(slug="default-provider-authorization-implicit-consent")
|
|
INVALID = Flow.objects.get(slug="default-provider-invalidation-flow")
|
|
DEFAULT_MAPPINGS = OAuth2Provider.objects.get(name="famapp").property_mappings.all()
|
|
SIGNING_KEY = CertificateKeyPair.objects.get(name="authentik Self-signed Certificate")
|
|
|
|
# slug, provider name, redirect URI(s)
|
|
OIDC_APPS = [
|
|
("bookstack", "bookstack", ["https://docs.ginnoir.com/oidc/callback"]),
|
|
("gitea", "gitea", ["https://gitea.ginnoir.com/user/oauth2/Authentik/callback"]),
|
|
("portainer", "portainer", ["https://portainer.ginnoir.com/"]),
|
|
("minio", "minio-console", ["https://minio.ginnoir.com/oauth_callback"]),
|
|
]
|
|
|
|
native_slugs = []
|
|
for slug, pname, redirects in OIDC_APPS:
|
|
provider, created = OAuth2Provider.objects.update_or_create(
|
|
name=pname,
|
|
defaults={
|
|
"authorization_flow": AUTHZ,
|
|
"invalidation_flow": INVALID,
|
|
"signing_key": SIGNING_KEY,
|
|
"sub_mode": SubModes.USER_UUID if slug == "bookstack" else SubModes.HASHED_USER_ID,
|
|
"redirect_uris": [
|
|
RedirectURI(matching_mode=RedirectURIMatchingMode.STRICT, url=url)
|
|
for url in redirects
|
|
],
|
|
"access_code_validity": "minutes=1",
|
|
"access_token_validity": "hours=24",
|
|
"refresh_token_validity": "days=30",
|
|
},
|
|
)
|
|
provider.property_mappings.set(DEFAULT_MAPPINGS)
|
|
provider.save()
|
|
|
|
app, _ = Application.objects.update_or_create(
|
|
slug=slug,
|
|
defaults={
|
|
"name": pname.replace("-", " ").title(),
|
|
"provider": provider,
|
|
"meta_launch_url": redirects[0].split("/oidc")[0].split("/user/oauth2")[0].rstrip("/"),
|
|
"policy_engine_mode": "any",
|
|
},
|
|
)
|
|
app.provider = provider
|
|
app.save()
|
|
|
|
native_slugs.append(slug)
|
|
print(f"oauth2 {slug} created={created} client_id={provider.client_id}")
|
|
print(f" {slug.upper()}_OIDC_CLIENT_ID={provider.client_id}")
|
|
print(f" {slug.upper()}_OIDC_CLIENT_SECRET={provider.client_secret}")
|
|
|
|
# Drop native-OIDC apps from the embedded proxy outpost (avoid double auth).
|
|
PROXY_NAMES = {
|
|
"bookstack": "homelab-bookstack",
|
|
"gitea": "homelab-gitea",
|
|
"portainer": "homelab-portainer",
|
|
"minio": "homelab-minio",
|
|
}
|
|
outpost = Outpost.objects.get(name="authentik Embedded Outpost")
|
|
for slug in native_slugs:
|
|
pname = PROXY_NAMES.get(slug)
|
|
if not pname:
|
|
continue
|
|
try:
|
|
proxy = ProxyProvider.objects.get(name=pname)
|
|
outpost.providers.remove(proxy)
|
|
print(f"removed proxy {pname} from embedded outpost")
|
|
except ProxyProvider.DoesNotExist:
|
|
print(f"proxy {pname} not found (ok)")
|
|
|
|
print("done — configure each app with printed client_id/secret")
|