#!/usr/bin/env python3 """Immich OIDC integration test.""" import argparse import os import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..')) from utils.tests.helpers import ( http_get, http_post, load_toml_credentials, resolve_domain, ) def main(): if os.environ.get('SKIP_INTEGRATION') == '1': print("SKIP: OIDC integration test (SKIP_INTEGRATION=1)") return parser = argparse.ArgumentParser() parser.add_argument('--domain', default=os.environ.get('TEST_DOMAIN')) args = parser.parse_args() domain = args.domain or resolve_domain('immich') url = f"https://{domain}" recipe_dir = os.path.join(os.path.dirname(__file__), '..') creds = load_toml_credentials(recipe_dir, 'authentik') if creds is None: print("FAIL: Credentials file not found: authentik-test-credentials..toml") print("Run setup_authentik_integration.py first.") sys.exit(1) print("=== Immich OIDC Integration Test ===") print() # Step 1: Check Immich is deployed print("Step 1: Checking Immich is deployed ...") status, _ = http_get(url) if status == 0: print(f" FAIL: Immich is not reachable at {url}") sys.exit(1) elif status >= 500: print(f" FAIL: Immich returned HTTP {status}") sys.exit(1) print(f" OK: Immich is reachable (HTTP {status})") # Step 2: Verify Authentik OIDC discovery print("Step 2: Checking Authentik OIDC discovery ...") discovery_url = creds["ak_discovery_endpoint"] status, _ = http_get(discovery_url) if status != 200: print(f" FAIL: OIDC discovery returned HTTP {status}") print(f" URL: {discovery_url}") sys.exit(1) print(f" PASS: OIDC discovery endpoint OK (app '{creds['ak_app_slug']}')") # Step 3: Obtain token from Authentik print("Step 3: Obtaining token from Authentik for test user ...") print(" Using APP_PASSWORD for password grant (authentik requirement)") status, data = http_post( creds["ak_token_endpoint"], data={ "grant_type": "password", "client_id": creds["ak_client_id"], "client_secret": creds["ak_client_secret"], "username": creds["ak_test_user"], "password": creds["ak_test_app_password"], "scope": "openid email profile", }, content_type="application/x-www-form-urlencoded", ) access_token = (data or {}).get("access_token", "") if not access_token: error = (data or {}).get("error_description", (data or {}).get("error", "unknown")) print(f" FAIL: Token request failed: {error}") sys.exit(1) print(f" PASS: Got access token ({len(access_token)} chars)") # Step 4: Verify Immich OAuth endpoint print("Step 4: Checking Immich OAuth endpoint ...") status, body = http_post( f"{url}/api/oauth/authorize", data={"redirectUri": f"{url}/auth/login"}, ) oauth_url = (body or {}).get("url", "") if not oauth_url: error = (body or {}).get("message", (body or {}).get("error", "unknown")) print(f" FAIL: OAuth authorize endpoint failed: {error}") sys.exit(1) print(" PASS: OAuth authorize returned redirect URL") print() print("PASS: Immich OIDC integration test passed") print(" Authentik OIDC discovery OK, token grant OK, Immich OAuth endpoint active.") if __name__ == '__main__': main()