recipe-maintainer: public snapshot (secrets + deployment plans removed, single commit)
Sanitized single-commit public mirror of recipe-maintainer. - Removed test-ssh/.testenv (live creds); added test-ssh/.testenv.example placeholders. - Removed plans/ and planned-updates/ (deployment-planning docs) so no client/ deployment domains appear in the public repo. - All other secret stores were already gitignored. - docs.coopcloud.tech retained as a submodule (public upstream).
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
name = "authentik"
|
||||
|
||||
[dependencies]
|
||||
requires = []
|
||||
test_requires = ["ld2"] # oidc_integration test needs the ld2 lasuite-docs instance
|
||||
@@ -0,0 +1,30 @@
|
||||
# Authentik — First-Time Setup
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- DNS: `authentik.<domain_suffix>` must resolve to the server
|
||||
|
||||
## Steps
|
||||
|
||||
1. **Create the app:**
|
||||
```bash
|
||||
abra app new authentik --server <SERVER> --domain authentik.<DOMAIN_SUFFIX> --no-input
|
||||
```
|
||||
|
||||
2. **Generate secrets:**
|
||||
```bash
|
||||
abra app secret generate authentik.<DOMAIN_SUFFIX> --all -m --no-input
|
||||
```
|
||||
Save output to `recipe-info/testsecrets/authentik.<DOMAIN_SUFFIX>`.
|
||||
|
||||
3. **Deploy:**
|
||||
```bash
|
||||
abra app deploy authentik.<DOMAIN_SUFFIX> --chaos --force --no-input
|
||||
```
|
||||
|
||||
4. **Verify:** curl `https://authentik.<DOMAIN_SUFFIX>` returns HTTP 200.
|
||||
|
||||
## Notes
|
||||
|
||||
- Admin credentials: username `akadmin`, password from `admin_pass` secret in testsecrets.
|
||||
- The bootstrap token (`AK_TOKEN`) is the `bootstrap_token` secret — needed by SSO setup scripts for other recipes.
|
||||
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Setup Authentik OIDC integration for La Suite Docs (ld2).
|
||||
|
||||
Creates an OAuth2 provider, application, and test user in Authentik,
|
||||
then inserts the client secret and updates the Docs env file with
|
||||
Authentik OIDC endpoints.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
|
||||
from lib.abra import app_secret_insert
|
||||
from lib.authentik import AuthentikAdmin
|
||||
from lib.env import apply_env_overrides, get_abra_env_path, read_env_file
|
||||
from lib.models import load_default_instance
|
||||
from lib.secrets import load_secrets
|
||||
|
||||
# Configuration
|
||||
PROVIDER_NAME = "lasuite-docs"
|
||||
APP_SLUG = "lasuite-docs"
|
||||
CLIENT_ID = "docs"
|
||||
TEST_USER = "testuser"
|
||||
TEST_PASS = "testpass123"
|
||||
TEST_EMAIL = f"{TEST_USER}@test.example.com"
|
||||
|
||||
def main():
|
||||
inst = load_default_instance()
|
||||
ak_domain = inst.default_domain("authentik")
|
||||
# Docs instance uses a custom domain (ld2) to avoid conflict with keycloak-backed docs
|
||||
DOCS_DOMAIN = f"ld2.{inst.domain_suffix}"
|
||||
ak_url = f"https://{ak_domain}"
|
||||
|
||||
# Get Authentik admin token from synced secrets
|
||||
ak_secrets = load_secrets(ak_domain)
|
||||
ak_token = ak_secrets["admin_token"]
|
||||
|
||||
ak = AuthentikAdmin(ak_url, ak_token)
|
||||
|
||||
# Resolve Authentik UUIDs
|
||||
uuids = ak.resolve_uuids()
|
||||
|
||||
# Step 1: Create OAuth2 provider
|
||||
provider_pk, client_secret = ak.ensure_provider(
|
||||
PROVIDER_NAME, CLIENT_ID,
|
||||
redirect_uris=[{
|
||||
"matching_mode": "strict",
|
||||
"url": f"https://{DOCS_DOMAIN}/api/v1.0/callback/",
|
||||
}],
|
||||
uuids=uuids,
|
||||
)
|
||||
|
||||
# Step 2: Create application
|
||||
ak.ensure_application("La Suite Docs", APP_SLUG, provider_pk,
|
||||
f"https://{DOCS_DOMAIN}")
|
||||
|
||||
# Step 3: Create test user
|
||||
user_pk = ak.ensure_user(TEST_USER, TEST_EMAIL, TEST_PASS)
|
||||
app_password = ak.ensure_app_password(user_pk)
|
||||
|
||||
# Step 4: Insert client secret into Docs via abra
|
||||
print("=== Insert OIDC client secret into Docs (ld2) ===", flush=True)
|
||||
env_path = get_abra_env_path(inst.server, DOCS_DOMAIN)
|
||||
if not env_path.exists():
|
||||
print(f" WARNING: Docs env file not found at {env_path}", flush=True)
|
||||
print(f" Create the app first: abra app new lasuite-docs --server {inst.server} --domain {DOCS_DOMAIN} --no-input", flush=True)
|
||||
print(" Skipping secret insertion and env update", flush=True)
|
||||
else:
|
||||
env_data = read_env_file(env_path)
|
||||
current_version = env_data.get("SECRET_OIDC_RPCS_VERSION", "v1")
|
||||
next_num = int(current_version.lstrip("v")) + 1
|
||||
next_version = f"v{next_num}"
|
||||
print(f" Current secret version: {current_version}", flush=True)
|
||||
print(f" Inserting as: {next_version}", flush=True)
|
||||
app_secret_insert(DOCS_DOMAIN, "oidc_rpcs", next_version, client_secret)
|
||||
|
||||
# Step 5: Update Docs env with Authentik OIDC settings
|
||||
print("=== Update Docs OIDC settings in env file ===", flush=True)
|
||||
apply_env_overrides(env_path, {
|
||||
"SECRET_OIDC_RPCS_VERSION": next_version,
|
||||
"AUTH_DOMAIN": ak_domain,
|
||||
"OIDC_OP_JWKS_ENDPOINT": f"https://{ak_domain}/application/o/{APP_SLUG}/jwks/",
|
||||
"OIDC_OP_AUTHORIZATION_ENDPOINT": f"https://{ak_domain}/application/o/authorize/",
|
||||
"OIDC_OP_TOKEN_ENDPOINT": f"https://{ak_domain}/application/o/token/",
|
||||
"OIDC_OP_USER_ENDPOINT": f"https://{ak_domain}/application/o/userinfo/",
|
||||
"OIDC_RP_CLIENT_ID": CLIENT_ID,
|
||||
})
|
||||
|
||||
# Step 6: Write credentials file
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
creds_file = os.path.join(script_dir, f"authentik-test-credentials.{inst.domain_suffix}.toml")
|
||||
print(f"=== Write credentials to {creds_file} ===", flush=True)
|
||||
with open(creds_file, "w") as f:
|
||||
f.write(f'# Authentik OIDC credentials for La Suite Docs (ld2) test instance\n')
|
||||
f.write(f'#\n')
|
||||
f.write(f'# Authentik instance: {ak_domain}\n')
|
||||
f.write(f'# Application slug: {APP_SLUG}\n')
|
||||
f.write(f'# Created by: setup_docs_integration.py\n')
|
||||
f.write(f'\n')
|
||||
f.write(f'# Authentik admin\n')
|
||||
f.write(f'ak_token = "{ak_token}"\n')
|
||||
f.write(f'\n')
|
||||
f.write(f'# OIDC provider\n')
|
||||
f.write(f'ak_app_slug = "{APP_SLUG}"\n')
|
||||
f.write(f'ak_client_id = "{CLIENT_ID}"\n')
|
||||
f.write(f'ak_client_secret = "{client_secret}"\n')
|
||||
f.write(f'\n')
|
||||
f.write(f'# Authentik OIDC endpoints\n')
|
||||
f.write(f'ak_token_endpoint = "https://{ak_domain}/application/o/token/"\n')
|
||||
f.write(f'ak_userinfo_endpoint = "https://{ak_domain}/application/o/userinfo/"\n')
|
||||
f.write(f'ak_discovery_endpoint = "https://{ak_domain}/application/o/{APP_SLUG}/.well-known/openid-configuration"\n')
|
||||
f.write(f'\n')
|
||||
f.write(f'# Test user (password for browser login, app_password for password grant)\n')
|
||||
f.write(f'ak_test_user = "{TEST_USER}"\n')
|
||||
f.write(f'ak_test_pass = "{TEST_PASS}"\n')
|
||||
f.write(f'ak_test_app_password = "{app_password}"\n')
|
||||
f.write(f'ak_test_email = "{TEST_EMAIL}"\n')
|
||||
f.write(f'\n')
|
||||
f.write(f'# Docs instance\n')
|
||||
f.write(f'docs_domain = "{DOCS_DOMAIN}"\n')
|
||||
print(f" Written to {creds_file}", flush=True)
|
||||
|
||||
print("", flush=True)
|
||||
print("=== Authentik OIDC integration setup complete ===", flush=True)
|
||||
print("", flush=True)
|
||||
print("Next steps:", flush=True)
|
||||
print(f" 1. Redeploy Docs: abra app deploy {DOCS_DOMAIN} --chaos --force --no-input", flush=True)
|
||||
print(f" 2. Run OIDC test: python3 recipe-info/authentik/tests/oidc_integration.py", flush=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,140 @@
|
||||
# Authentik Migration Test
|
||||
|
||||
Test that upgrading from 10.1.4+2025.10.2 (using `media:/media` mount) to 10.2.0+2026.2.1 (using `media:/data/media` mount) works correctly and preserves data.
|
||||
|
||||
## Overview
|
||||
|
||||
1. Deploy the old version
|
||||
2. Seed test data into the media volume
|
||||
3. Upgrade to the new version
|
||||
4. Verify media files are accessible at the new path
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Deploy old version
|
||||
|
||||
Check out the pre-migration tag and deploy:
|
||||
|
||||
```bash
|
||||
cd ~/.abra/recipes/authentik
|
||||
git checkout 10.1.4+2025.10.2
|
||||
```
|
||||
|
||||
Deploy:
|
||||
|
||||
```bash
|
||||
abra app deploy authentik.<DOMAIN_SUFFIX> --chaos --force --no-input
|
||||
```
|
||||
|
||||
Wait for the app to become healthy:
|
||||
|
||||
```bash
|
||||
abra app ps authentik.<DOMAIN_SUFFIX> --chaos --no-input -m
|
||||
```
|
||||
|
||||
### 2. Seed test data into the media volume
|
||||
|
||||
Create a marker file in the old `/media` volume:
|
||||
|
||||
```bash
|
||||
script -qefc "abra app run authentik.<DOMAIN_SUFFIX> app -- sh -c 'echo migration-test-marker > /media/test-migration-marker.txt && echo created'" /dev/null
|
||||
```
|
||||
|
||||
Verify the file was created:
|
||||
|
||||
```bash
|
||||
script -qefc "abra app run authentik.<DOMAIN_SUFFIX> app -- cat /media/test-migration-marker.txt" /dev/null
|
||||
```
|
||||
|
||||
Expected output: `migration-test-marker`
|
||||
|
||||
Record existing files in `/media` for comparison:
|
||||
|
||||
```bash
|
||||
script -qefc "abra app run authentik.<DOMAIN_SUFFIX> app -- ls -la /media/" /dev/null
|
||||
```
|
||||
|
||||
### 3. Upgrade to new version
|
||||
|
||||
Switch to the new version (with `media:/data/media` mount point change):
|
||||
|
||||
```bash
|
||||
cd ~/.abra/recipes/authentik
|
||||
git checkout <new-tag-or-branch>
|
||||
```
|
||||
|
||||
Deploy the upgrade:
|
||||
|
||||
```bash
|
||||
abra app deploy authentik.<DOMAIN_SUFFIX> --chaos --force --no-input
|
||||
```
|
||||
|
||||
Wait for convergence (authentik runs database migrations on startup):
|
||||
|
||||
```bash
|
||||
sleep 60
|
||||
abra app ps authentik.<DOMAIN_SUFFIX> --chaos --no-input -m
|
||||
```
|
||||
|
||||
### 4. Verify post-upgrade state
|
||||
|
||||
#### 4a. Health check
|
||||
|
||||
```bash
|
||||
python3 recipe-info/authentik/tests/health_check.py
|
||||
```
|
||||
|
||||
#### 4b. Marker file preserved at new path
|
||||
|
||||
The mount point change means `media:/data/media` — files that were at the volume root now appear under `/data/media/`:
|
||||
|
||||
```bash
|
||||
script -qefc "abra app run authentik.<DOMAIN_SUFFIX> app -- cat /data/media/test-migration-marker.txt" /dev/null
|
||||
```
|
||||
|
||||
Expected output: `migration-test-marker`
|
||||
|
||||
#### 4c. Directory listing
|
||||
|
||||
Verify the old files are now under `/data/media/`:
|
||||
|
||||
```bash
|
||||
script -qefc "abra app run authentik.<DOMAIN_SUFFIX> app -- ls -la /data/media/" /dev/null
|
||||
```
|
||||
|
||||
Compare with the listing from step 2 — all files from the old `/media/` should now appear under `/data/media/`.
|
||||
|
||||
#### 4d. Version label
|
||||
|
||||
```bash
|
||||
abra app ps authentik.<DOMAIN_SUFFIX> --chaos --no-input -m
|
||||
```
|
||||
|
||||
Confirm the version label shows `10.2.0+2026.2.1`.
|
||||
|
||||
#### 4e. Full test suite
|
||||
|
||||
```bash
|
||||
python3 recipe-info/authentik/tests/health_check.py
|
||||
python3 recipe-info/authentik/tests/oidc_integration.py
|
||||
```
|
||||
|
||||
### 5. Clean up test marker
|
||||
|
||||
```bash
|
||||
script -qefc "abra app run authentik.<DOMAIN_SUFFIX> app -- rm /data/media/test-migration-marker.txt" /dev/null
|
||||
```
|
||||
|
||||
## Pass/fail criteria
|
||||
|
||||
| Check | Expected |
|
||||
|-------|----------|
|
||||
| Pre-upgrade health check | HTTP 200 |
|
||||
| Marker file created in old `/media` | `migration-test-marker` |
|
||||
| Post-upgrade health check | HTTP 200 |
|
||||
| Marker file at `/data/media/test-migration-marker.txt` | `migration-test-marker` |
|
||||
| `/data/media/` contains old files | Matches pre-upgrade listing |
|
||||
| Version label updated | `10.2.0+2026.2.1` |
|
||||
| OIDC integration test | PASS |
|
||||
|
||||
All checks must pass for the migration test to pass.
|
||||
@@ -0,0 +1,85 @@
|
||||
# Authentik Test Plan
|
||||
|
||||
Target: `https://authentik.<DOMAIN_SUFFIX>`
|
||||
|
||||
## Services
|
||||
|
||||
| Service | Image | Purpose |
|
||||
|---------|-------|---------|
|
||||
| app | `ghcr.io/goauthentik/server` | Web server (port 9000) |
|
||||
| worker | `ghcr.io/goauthentik/server` | Background worker |
|
||||
| db | `postgres:15` | PostgreSQL database |
|
||||
|
||||
## Test Setup
|
||||
|
||||
Before running all tests, the following must be in place:
|
||||
|
||||
### 1. Deploy authentik
|
||||
|
||||
```bash
|
||||
abra app deploy authentik.<DOMAIN_SUFFIX> --chaos --force --no-input
|
||||
```
|
||||
|
||||
### 2. Deploy the ld2 instance (test dependency)
|
||||
|
||||
The OIDC integration test uses a second La Suite Docs instance (`ld2`) as the relying party. This is separate from the primary `lasuite-docs` instance (which uses Keycloak for SSO).
|
||||
|
||||
If `ld2` does not exist yet, create it:
|
||||
```bash
|
||||
abra app new lasuite-docs --server <SERVER> --domain ld2.<DOMAIN_SUFFIX> --no-input
|
||||
abra app secret generate ld2.<DOMAIN_SUFFIX> --all -m --no-input
|
||||
abra app deploy ld2.<DOMAIN_SUFFIX> --chaos --force --no-input
|
||||
```
|
||||
|
||||
If it already exists, just deploy:
|
||||
```bash
|
||||
abra app deploy ld2.<DOMAIN_SUFFIX> --chaos --force --no-input
|
||||
```
|
||||
|
||||
### 3. Run the Authentik-Docs integration setup
|
||||
|
||||
```bash
|
||||
python3 recipe-info/authentik/setup_docs_integration.py
|
||||
```
|
||||
|
||||
This configures authentik as the OIDC provider for ld2:
|
||||
1. Creates an OAuth2 provider (`lasuite-docs`) via the authentik REST API
|
||||
2. Creates an Application linked to the provider
|
||||
3. Creates a test user (`testuser` / `testpass123`) with an APP_PASSWORD token
|
||||
4. Inserts the OIDC client secret into the ld2 Docs app via `abra app secret insert`
|
||||
5. Updates the ld2 env file with authentik OIDC endpoints
|
||||
6. Writes credentials to `authentik-test-credentials.<DOMAIN_SUFFIX>.toml`
|
||||
|
||||
### 4. Redeploy ld2 with OIDC config
|
||||
|
||||
```bash
|
||||
abra app deploy ld2.<DOMAIN_SUFFIX> --chaos --force --no-input
|
||||
```
|
||||
|
||||
## Automated Tests
|
||||
|
||||
- `tests/health_check.py` — HTTP 200 check on the main URL
|
||||
- `tests/oidc_integration.py` — Full OIDC flow: obtains a token from authentik for a test user, then authenticates against the ld2 La Suite Docs API
|
||||
|
||||
### Credentials
|
||||
|
||||
| Key | Description |
|
||||
|-----|-------------|
|
||||
| `ak_token` | Authentik admin bootstrap token |
|
||||
| `ak_client_id` / `ak_client_secret` | OIDC client ID and secret |
|
||||
| `ak_test_user` / `ak_test_pass` | Test user credentials (password for browser login) |
|
||||
| `ak_test_app_password` | APP_PASSWORD token for password grant (authentik requires this instead of regular passwords) |
|
||||
| `ak_test_email` | Test user email |
|
||||
|
||||
Stored in `authentik-test-credentials.<DOMAIN_SUFFIX>.toml`.
|
||||
|
||||
## Manual Verification
|
||||
|
||||
1. Open `https://authentik.<DOMAIN_SUFFIX>` in a browser — should show the authentik login page
|
||||
2. Log in with admin credentials: `akadmin` / `<admin_pass from testsecrets>`
|
||||
3. Navigate to Admin Interface — should load the admin dashboard
|
||||
4. Check System → System Tasks — background worker should be processing tasks
|
||||
5. Navigate to Applications → Providers — verify `lasuite-docs` OAuth2 provider exists
|
||||
6. Navigate to Applications → Applications — verify `lasuite-docs` application exists
|
||||
7. Open `https://ld2.<DOMAIN_SUFFIX>` — click Login and verify the OIDC redirect to authentik works
|
||||
8. Log in as `testuser` / `testpass123` — should redirect back to Docs as the authenticated user
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Health check for Authentik."""
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..'))
|
||||
from utils.tests.helpers import http_get, resolve_domain
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--domain', default=os.environ.get('TEST_DOMAIN'))
|
||||
args = parser.parse_args()
|
||||
domain = args.domain or resolve_domain('authentik')
|
||||
url = f"https://{domain}"
|
||||
|
||||
print(f"Checking Authentik at {url} ...")
|
||||
status, _ = http_get(url)
|
||||
if status == 200:
|
||||
print(f"PASS: Authentik returned HTTP {status}")
|
||||
else:
|
||||
print(f"FAIL: Authentik returned HTTP {status} (expected 200)")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Authentik 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, _load_settings,
|
||||
)
|
||||
|
||||
|
||||
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()
|
||||
|
||||
# Docs (ld2) domain — computed from settings
|
||||
settings = _load_settings()
|
||||
instance = settings["default_instance"]
|
||||
suffix = settings["instances"][instance]["domain_suffix"]
|
||||
docs_domain = f"ld2.{suffix}"
|
||||
docs_url = f"https://{docs_domain}"
|
||||
|
||||
ak_domain = args.domain or resolve_domain('authentik')
|
||||
ak_url = f"https://{ak_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.<domain_suffix>.toml")
|
||||
print("Run setup_docs_integration.py first.")
|
||||
sys.exit(1)
|
||||
|
||||
print("=== Authentik OIDC Integration Test ===")
|
||||
print()
|
||||
|
||||
# Step 1: Check lasuite-docs (ld2) is deployed
|
||||
print("Step 1: Checking lasuite-docs (ld2) is deployed ...")
|
||||
status, _ = http_get(docs_url)
|
||||
if status == 0:
|
||||
print(f" FAIL: lasuite-docs is not reachable at {docs_url}")
|
||||
sys.exit(1)
|
||||
elif status >= 500:
|
||||
print(f" FAIL: lasuite-docs returned HTTP {status}")
|
||||
sys.exit(1)
|
||||
print(f" OK: lasuite-docs (ld2) 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: Authenticate against Docs API
|
||||
print("Step 4: Calling Docs API with Authentik token ...")
|
||||
status, body = http_get(
|
||||
f"{docs_url}/api/v1.0/users/me/",
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
timeout=30,
|
||||
)
|
||||
if status != 200:
|
||||
print(f" FAIL: Docs API returned HTTP {status} (expected 200)")
|
||||
sys.exit(1)
|
||||
|
||||
user_email = (body or {}).get("email", "")
|
||||
expected_email = creds["ak_test_email"]
|
||||
if user_email == expected_email:
|
||||
print(f" PASS: Docs returned authenticated user '{user_email}'")
|
||||
else:
|
||||
print(f" FAIL: Expected email '{expected_email}', got '{user_email}'")
|
||||
sys.exit(1)
|
||||
|
||||
print()
|
||||
print("PASS: Authentik OIDC integration test passed")
|
||||
print(" Authentik issued a valid token, Docs (ld2) accepted it and returned the correct user.")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,15 @@
|
||||
# Authentik Upstream
|
||||
|
||||
## Main Project
|
||||
|
||||
- **Repository:** https://github.com/goauthentik/authentik
|
||||
- **Releases:** https://github.com/goauthentik/authentik/releases
|
||||
- **Website:** https://goauthentik.io
|
||||
- **Docs:** https://docs.goauthentik.io
|
||||
|
||||
## Images
|
||||
|
||||
| Service | Image | Release Notes |
|
||||
|---------|-------|---------------|
|
||||
| app, worker | `ghcr.io/goauthentik/server` | https://github.com/goauthentik/authentik/releases |
|
||||
| db | `postgres` | https://www.postgresql.org/docs/release/ |
|
||||
Reference in New Issue
Block a user