Změny:
Přidaná centrální runtime konfigurace public URL, HTTPS a Google OAuth readiness v config.py (line 37). Google OAuth přidaný jako volitelná další možnost přihlášení, bez nahrazení lokálního/Gitea loginu, v auth.py (line 128). Default Google redirect URI se skládá z APPFACTORY_PORTAL_PUBLIC_URL + /auth/google/callback, bez hardcoded IP/localhost/domény. Readiness JSON endpoint přidán na /portal/migration-readiness/auth-domain-config; vrací jen boolean hodnoty, žádné secrety, v migration_readiness.py (line 112). UI sekce Auth & Domain Readiness přidaná do Migration Readiness v migration_readiness.py (line 41). Audit event auth_domain_readiness.viewed se zapisuje při zobrazení readiness stránky v migration_readiness.py (line 133). APPFACTORY_ENABLE_HTTPS se promítá i do secure session cookies v main.py (line 19).
This commit is contained in:
@@ -4,6 +4,11 @@ from fastapi import APIRouter, Depends, Form, HTTPException, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
|
||||
from app.auth import require_user
|
||||
from app.config import (
|
||||
get_auth_domain_readiness,
|
||||
get_google_redirect_uri,
|
||||
get_portal_public_url,
|
||||
)
|
||||
from app.db.audit import log_audit_event
|
||||
from app.db.jobs import create_job
|
||||
from app.db.migration_readiness import (
|
||||
@@ -27,6 +32,43 @@ def render_readiness_pill(ready: bool) -> str:
|
||||
return '<span class="pill pill-danger">NOT READY</span>'
|
||||
|
||||
|
||||
def render_boolean_pill(enabled: bool) -> str:
|
||||
if enabled:
|
||||
return '<span class="pill pill-success">YES</span>'
|
||||
return '<span class="pill">NO</span>'
|
||||
|
||||
|
||||
def render_auth_domain_readiness() -> str:
|
||||
readiness = get_auth_domain_readiness()
|
||||
public_url = get_portal_public_url() or "relative/proxy mode"
|
||||
redirect_uri = get_google_redirect_uri() or "not configured"
|
||||
warning = ""
|
||||
|
||||
if readiness["google_oauth_enabled"] and (
|
||||
not readiness["portal_public_url_configured"] or not readiness["google_redirect_uri_configured"]
|
||||
):
|
||||
warning = """
|
||||
<div class="alert alert-danger">
|
||||
<strong>Google OAuth is enabled but domain readiness is incomplete.</strong>
|
||||
<p>Set APPFACTORY_PORTAL_PUBLIC_URL or APPFACTORY_ENABLE_HTTPS=true with APPFACTORY_PORTAL_DOMAIN, and make sure a Google redirect URI is available.</p>
|
||||
</div>
|
||||
"""
|
||||
|
||||
return f"""
|
||||
<div class="card">
|
||||
<h2>Auth & Domain Readiness</h2>
|
||||
<table>
|
||||
<tr><th>Portal public URL</th><td>{html.escape(public_url)}</td></tr>
|
||||
<tr><th>HTTPS enabled</th><td>{render_boolean_pill(readiness["https_enabled"])}</td></tr>
|
||||
<tr><th>Google OAuth enabled</th><td>{render_boolean_pill(readiness["google_oauth_enabled"])}</td></tr>
|
||||
<tr><th>Google OAuth configured</th><td>{render_boolean_pill(readiness["google_oauth_configured"])}</td></tr>
|
||||
<tr><th>Google redirect URI effective value</th><td>{html.escape(redirect_uri)}</td></tr>
|
||||
</table>
|
||||
{warning}
|
||||
</div>
|
||||
"""
|
||||
|
||||
|
||||
def render_script_result(title: str, script_name: str, summary: dict) -> str:
|
||||
job = summary.get("job")
|
||||
job_rows = f'<tr><td colspan="2">Zatím není uložený žádný výsledek skriptu {html.escape(script_name)}.</td></tr>'
|
||||
@@ -67,6 +109,11 @@ def render_script_result(title: str, script_name: str, summary: dict) -> str:
|
||||
"""
|
||||
|
||||
|
||||
@router.get("/migration-readiness/auth-domain-config")
|
||||
def auth_domain_readiness_config(user=Depends(require_user)):
|
||||
return get_auth_domain_readiness()
|
||||
|
||||
|
||||
@router.get("/migration-readiness", response_class=HTMLResponse)
|
||||
def migration_readiness_page(request: Request, user=Depends(require_user)):
|
||||
latest_job = get_latest_preflight_job()
|
||||
@@ -81,6 +128,12 @@ def migration_readiness_page(request: Request, user=Depends(require_user)):
|
||||
target_id=PREFLIGHT_SCRIPT,
|
||||
metadata={"job_id": job.get("id") if job else None},
|
||||
)
|
||||
log_audit_event(
|
||||
user,
|
||||
action="auth_domain_readiness.viewed",
|
||||
target_type="auth_domain_readiness",
|
||||
metadata=get_auth_domain_readiness(),
|
||||
)
|
||||
|
||||
job_rows = '<tr><td colspan="2">Zatím není uložený žádný výsledek preflight kontroly.</td></tr>'
|
||||
if job:
|
||||
@@ -147,6 +200,8 @@ def migration_readiness_page(request: Request, user=Depends(require_user)):
|
||||
<div class="stat-card stat-danger"><span>FAIL</span><strong>{html.escape(str(summary["fail_count"]))}</strong></div>
|
||||
</div>
|
||||
|
||||
{render_auth_domain_readiness()}
|
||||
|
||||
<div class="card">
|
||||
<h2>Poslední preflight úloha</h2>
|
||||
<table>
|
||||
@@ -204,4 +259,3 @@ def run_bootstrap_v2(mode: str = Form(...), user=Depends(require_user)):
|
||||
source="portal_manual",
|
||||
)
|
||||
return RedirectResponse(url=f"/portal/jobs/{job_id}", status_code=303)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user