Odstranil jsem hardcoded IP fallbacky z portálového Python kódu:
DEFAULT_APPFACTORY_HOST = "192.168.66.130" je pryč z config.py (line 10). DEFAULT_GITEA_URL = "http://192.168.66.130:3000" je pryč z auth.py (line 24). Doplněné chování: APPFACTORY_HOST se odvozuje přes helper: env APPFACTORY_HOST, potom APPFACTORY_PORTAL_PUBLIC_URL, potom request host. Gitea browser redirect používá jen explicitní veřejnou URL z GITEA_URL nebo GITEA_ROOT_URL. Server-side Gitea token/userinfo requesty používají GITEA_URL, potom GITEA_ROOT_URL, jinak interní Docker URL http://appfactory-gitea:3000. Gitea login tlačítko se zobrazí jen při kompletní konfiguraci: public URL, client id, client secret a redirect URI. Přímý Gitea login bez kompletní konfigurace vrací čitelnou chybu.
This commit is contained in:
+42
-1
@@ -8,7 +8,7 @@ APPFACTORY_ENV = "/opt/appfactory/config/appfactory.env"
|
||||
|
||||
DEFAULT_BACKUP_DIR = "/opt/appfactory/backups"
|
||||
DEFAULT_GITEA_ORG = "appfactory"
|
||||
DEFAULT_APPFACTORY_HOST = "192.168.66.130"
|
||||
INTERNAL_GITEA_URL = "http://appfactory-gitea:3000"
|
||||
|
||||
PORTAL_PREFIX = "/portal"
|
||||
|
||||
@@ -58,6 +58,47 @@ def get_google_redirect_uri() -> str:
|
||||
return ""
|
||||
|
||||
|
||||
def get_gitea_public_url() -> str:
|
||||
return (read_env_value("GITEA_URL", "") or read_env_value("GITEA_ROOT_URL", "")).rstrip("/")
|
||||
|
||||
|
||||
def get_gitea_server_url() -> str:
|
||||
return get_gitea_public_url() or INTERNAL_GITEA_URL
|
||||
|
||||
|
||||
def get_gitea_redirect_uri() -> str:
|
||||
redirect_uri = read_env_value("GITEA_OAUTH_REDIRECT_URI", "").strip()
|
||||
if redirect_uri:
|
||||
return redirect_uri
|
||||
|
||||
public_url = get_portal_public_url()
|
||||
if public_url:
|
||||
return f"{public_url}/auth/gitea/callback"
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
def is_gitea_oauth_button_enabled() -> bool:
|
||||
return bool(
|
||||
get_gitea_public_url()
|
||||
and read_env_value("GITEA_OAUTH_CLIENT_ID", "")
|
||||
and read_env_value("GITEA_OAUTH_CLIENT_SECRET", "")
|
||||
and get_gitea_redirect_uri()
|
||||
)
|
||||
|
||||
|
||||
def get_appfactory_host(request_host: str = "") -> str:
|
||||
configured_host = read_env_value("APPFACTORY_HOST", "").strip()
|
||||
if configured_host:
|
||||
return configured_host
|
||||
|
||||
public_url = get_portal_public_url()
|
||||
if public_url:
|
||||
return public_url.split("://", 1)[-1].split("/", 1)[0].split(":", 1)[0]
|
||||
|
||||
return (request_host or "").split(":", 1)[0]
|
||||
|
||||
|
||||
def get_auth_domain_readiness() -> dict[str, bool]:
|
||||
google_enabled = read_env_bool("GOOGLE_OAUTH_ENABLED")
|
||||
google_client_id = read_env_value("GOOGLE_CLIENT_ID", "")
|
||||
|
||||
+7
-6
@@ -7,11 +7,12 @@ from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
|
||||
from ..auth import require_user
|
||||
from ..config import (
|
||||
DEFAULT_APPFACTORY_HOST,
|
||||
DEFAULT_GITEA_ORG,
|
||||
DELETE_APP_SCRIPT,
|
||||
DEPLOY_SCRIPT,
|
||||
GENERATE_COMPOSE_SCRIPT,
|
||||
get_appfactory_host,
|
||||
get_gitea_public_url,
|
||||
read_env_value,
|
||||
)
|
||||
from ..db.apps import (
|
||||
@@ -206,9 +207,9 @@ def apps_page(
|
||||
offset = (page_number - 1) * DEFAULT_PAGE_SIZE
|
||||
apps = apps[offset : offset + DEFAULT_PAGE_SIZE]
|
||||
|
||||
gitea_url = read_env_value("GITEA_URL", "")
|
||||
gitea_url = get_gitea_public_url()
|
||||
gitea_org = read_env_value("GITEA_ORG", DEFAULT_GITEA_ORG)
|
||||
host = read_env_value("APPFACTORY_HOST", DEFAULT_APPFACTORY_HOST)
|
||||
host = get_appfactory_host(request.url.hostname or "")
|
||||
|
||||
rows = ""
|
||||
|
||||
@@ -226,8 +227,8 @@ def apps_page(
|
||||
memory_label = memory or "výchozí"
|
||||
cpus_label = cpus or "výchozí"
|
||||
|
||||
http_clone = html.escape(f"git clone {gitea_url}/{gitea_org}/{app_id}.git")
|
||||
ssh_clone = html.escape(f"git clone ssh://git@{host}:2222/{gitea_org}/{app_id}.git")
|
||||
http_clone = html.escape(f"git clone {gitea_url}/{gitea_org}/{app_id}.git") if gitea_url else ""
|
||||
ssh_clone = html.escape(f"git clone ssh://git@{host}:2222/{gitea_org}/{app_id}.git") if host else ""
|
||||
|
||||
rows += f"""
|
||||
<tr class="service-row">
|
||||
@@ -970,7 +971,7 @@ def create_app(
|
||||
user=user,
|
||||
)
|
||||
|
||||
gitea_url = read_env_value("GITEA_URL", "").rstrip("/")
|
||||
gitea_url = get_gitea_public_url()
|
||||
gitea_org = read_env_value("GITEA_ORG", DEFAULT_GITEA_ORG)
|
||||
repository_url = f"{gitea_url}/{gitea_org}/{app_id}.git" if gitea_url else None
|
||||
owner_value = clean_optional(owner) or user.get("display_name") or user.get("username") or None
|
||||
|
||||
+25
-13
@@ -10,12 +10,19 @@ from fastapi import APIRouter, Form, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
|
||||
from app.auth import authenticate_user, current_user, find_or_create_oauth_user
|
||||
from app.config import get_google_redirect_uri, is_google_oauth_button_enabled, read_env_value
|
||||
from app.config import (
|
||||
get_gitea_public_url,
|
||||
get_gitea_redirect_uri,
|
||||
get_gitea_server_url,
|
||||
get_google_redirect_uri,
|
||||
is_gitea_oauth_button_enabled,
|
||||
is_google_oauth_button_enabled,
|
||||
read_env_value,
|
||||
)
|
||||
from app.db.audit import log_audit_event
|
||||
from app.templates.layout import page
|
||||
|
||||
router = APIRouter()
|
||||
DEFAULT_GITEA_URL = "http://192.168.66.130:3000"
|
||||
GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth"
|
||||
GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token"
|
||||
GOOGLE_USERINFO_URL = "https://openidconnect.googleapis.com/v1/userinfo"
|
||||
@@ -54,12 +61,13 @@ def gitea_login(request: Request):
|
||||
if current_user(request):
|
||||
return RedirectResponse(url="/portal/operations", status_code=303)
|
||||
|
||||
gitea_url = read_env_value("GITEA_URL", DEFAULT_GITEA_URL).rstrip("/")
|
||||
gitea_url = get_gitea_public_url()
|
||||
client_id = read_env_value("GITEA_OAUTH_CLIENT_ID", "")
|
||||
redirect_uri = read_env_value("GITEA_OAUTH_REDIRECT_URI", "")
|
||||
if not client_id or not redirect_uri:
|
||||
client_secret = read_env_value("GITEA_OAUTH_CLIENT_SECRET", "")
|
||||
redirect_uri = get_gitea_redirect_uri()
|
||||
if not gitea_url or not client_id or not client_secret or not redirect_uri:
|
||||
_log_gitea_failure("missing_oauth_config")
|
||||
return _render_login("Přihlášení přes Gitea není správně nastavené.")
|
||||
return _render_login("Gitea login is not fully configured.")
|
||||
|
||||
state = secrets.token_urlsafe(32)
|
||||
request.session["gitea_oauth_state"] = state
|
||||
@@ -227,10 +235,10 @@ def logout(request: Request):
|
||||
|
||||
|
||||
def _exchange_gitea_code(code: str) -> str:
|
||||
gitea_url = read_env_value("GITEA_URL", DEFAULT_GITEA_URL).rstrip("/")
|
||||
gitea_url = get_gitea_server_url()
|
||||
client_id = read_env_value("GITEA_OAUTH_CLIENT_ID", "")
|
||||
client_secret = read_env_value("GITEA_OAUTH_CLIENT_SECRET", "")
|
||||
redirect_uri = read_env_value("GITEA_OAUTH_REDIRECT_URI", "")
|
||||
redirect_uri = get_gitea_redirect_uri()
|
||||
if not client_id or not client_secret or not redirect_uri:
|
||||
raise RuntimeError("Missing Gitea OAuth configuration")
|
||||
|
||||
@@ -260,7 +268,7 @@ def _exchange_gitea_code(code: str) -> str:
|
||||
|
||||
|
||||
def _fetch_gitea_user(access_token: str) -> dict:
|
||||
gitea_url = read_env_value("GITEA_URL", DEFAULT_GITEA_URL).rstrip("/")
|
||||
gitea_url = get_gitea_server_url()
|
||||
request = UrlRequest(
|
||||
f"{gitea_url}/api/v1/user",
|
||||
headers={
|
||||
@@ -350,6 +358,13 @@ def _render_login(error: str | None = None) -> str:
|
||||
error_html = ""
|
||||
if error:
|
||||
error_html = f'<p class="alert alert-danger">{html.escape(error)}</p>'
|
||||
gitea_login_html = ""
|
||||
if is_gitea_oauth_button_enabled():
|
||||
gitea_login_html = """
|
||||
<p>
|
||||
<a class="btn" href="/portal/auth/gitea/login">Sign in with Gitea</a>
|
||||
</p>
|
||||
"""
|
||||
google_login_html = ""
|
||||
if is_google_oauth_button_enabled():
|
||||
google_login_html = """
|
||||
@@ -365,10 +380,7 @@ def _render_login(error: str | None = None) -> str:
|
||||
<h2>CSBot Services Portal</h2>
|
||||
<p class="muted">Doporučené přihlášení je přes Gitea. Lokální účet slouží pouze jako nouzový administrátorský přístup.</p>
|
||||
{error_html}
|
||||
|
||||
<p>
|
||||
<a class="btn" href="/portal/auth/gitea/login">Přihlásit přes Gitea</a>
|
||||
</p>
|
||||
{gitea_login_html}
|
||||
|
||||
{google_login_html}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user