"""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"]), ("owncloud", "owncloud-web", [ "https://files.ginnoir.com/index.php/apps/openidconnect/redirect", "https://files.ginnoir.com/apps/openidconnect/redirect", ]), ("resume", "reactive-resume", ["https://resume.ginnoir.com/api/auth/oauth2/callback/custom"]), ("freshrss", "freshrss", ["https://freshrss.ginnoir.com/i/oidc/"]), ] 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", "owncloud": "homelab-files", "resume": "homelab-resume", "freshrss": "homelab-freshrss", } 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")