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:
Executable
+102
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python3
|
||||
"""OIDC integration test for La Suite Docs + Keycloak."""
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
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():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--domain', default=os.environ.get('TEST_DOMAIN'))
|
||||
args = parser.parse_args()
|
||||
|
||||
recipe_dir = os.path.join(os.path.dirname(__file__), '..')
|
||||
creds = load_toml_credentials(recipe_dir, 'keycloak')
|
||||
if creds is None:
|
||||
print("FAIL: Credentials file not found: keycloak-test-credentials.<domain_suffix>.toml")
|
||||
print("Run setup_keycloak_integration.py first.")
|
||||
sys.exit(1)
|
||||
|
||||
docs_domain = args.domain or resolve_domain('lasuite-docs')
|
||||
kc_domain = resolve_domain('keycloak')
|
||||
docs_url = f"https://{docs_domain}"
|
||||
kc_url = f"https://{kc_domain}"
|
||||
|
||||
print("Testing OIDC integration: La Suite Docs <-> Keycloak")
|
||||
print()
|
||||
|
||||
# Step 1: Verify Docs redirects to Keycloak
|
||||
print("Step 1: Checking Docs OIDC redirect ...")
|
||||
try:
|
||||
req = urllib.request.Request(f"{docs_url}/api/v1.0/authenticate/")
|
||||
opener = urllib.request.build_opener(NoRedirectHandler())
|
||||
resp = opener.open(req, timeout=15)
|
||||
redirect_url = resp.headers.get('Location', '')
|
||||
except urllib.error.HTTPError as e:
|
||||
redirect_url = e.headers.get('Location', '') if e.headers else ''
|
||||
|
||||
expected_prefix = f"{kc_url}/realms/{creds['kc_realm']}/protocol/openid-connect/auth"
|
||||
if expected_prefix in (redirect_url or ''):
|
||||
print(f" PASS: Docs redirects to Keycloak realm '{creds['kc_realm']}'")
|
||||
else:
|
||||
print(f" FAIL: Expected redirect to Keycloak, got: {redirect_url}")
|
||||
sys.exit(1)
|
||||
|
||||
# Step 2: Obtain token from Keycloak
|
||||
print("Step 2: Obtaining token from Keycloak ...")
|
||||
token_url = f"{kc_url}/realms/{creds['kc_realm']}/protocol/openid-connect/token"
|
||||
status, data = http_post(
|
||||
token_url,
|
||||
data={
|
||||
"grant_type": "password",
|
||||
"client_id": creds["kc_client_id"],
|
||||
"client_secret": creds["kc_client_secret"],
|
||||
"username": creds["kc_test_user"],
|
||||
"password": creds["kc_test_pass"],
|
||||
"scope": "openid email",
|
||||
},
|
||||
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: Could not obtain token from Keycloak: {error}")
|
||||
sys.exit(1)
|
||||
print(f" PASS: Obtained access token from Keycloak ({len(access_token)} chars)")
|
||||
|
||||
# Step 3: Use token to access Docs API
|
||||
print("Step 3: Accessing Docs API with Keycloak token ...")
|
||||
status, body = http_get(
|
||||
f"{docs_url}/api/v1.0/users/me/",
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
)
|
||||
if status != 200:
|
||||
print(f" FAIL: Docs API returned HTTP {status} (expected 200)")
|
||||
sys.exit(1)
|
||||
|
||||
user_email = (body or {}).get("email", "")
|
||||
expected_email = f"{creds['kc_test_user']}@test.example.com"
|
||||
if user_email == expected_email:
|
||||
print(f" PASS: Docs API returned user with email '{user_email}'")
|
||||
else:
|
||||
print(f" FAIL: Expected email '{expected_email}', got '{user_email}'")
|
||||
sys.exit(1)
|
||||
|
||||
print()
|
||||
print("PASS: OIDC integration test passed — Docs authenticates via Keycloak")
|
||||
|
||||
|
||||
class NoRedirectHandler(urllib.request.HTTPRedirectHandler):
|
||||
def redirect_request(self, req, fp, code, msg, headers, newurl):
|
||||
raise urllib.error.HTTPError(newurl, code, msg, headers, fp)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user