Deploy to valhalla / deploy (push) Has been cancelled
Add Recyclarr to the media stack, pin database/object-store/Caddy/Vault images with Watchtower disabled, expose JDownloader at jd.ginnoir.com, and restrict minio/homarr/docs to internal_only. Mark TB-002–004 and TB-033 complete; bundle batch-3 OIDC env for FreshRSS, ownCloud, and Reactive Resume.
89 lines
3.6 KiB
Python
89 lines
3.6 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"]),
|
|
("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")
|