mazani uzivatelu

This commit is contained in:
JiriUhlir
2026-06-12 09:58:52 +02:00
parent ddc65322c5
commit 5d12028a97
4 changed files with 56 additions and 3 deletions
+6 -1
View File
@@ -64,7 +64,12 @@ def get_gitea_public_url() -> str:
def get_gitea_server_url() -> str:
return get_gitea_public_url() or INTERNAL_GITEA_URL
return (
read_env_value("GITEA_SERVER_URL", "")
or read_env_value("GITEA_INTERNAL_URL", "")
or get_gitea_public_url()
or INTERNAL_GITEA_URL
).rstrip("/")
def get_gitea_admin_token() -> str:
+8
View File
@@ -154,6 +154,14 @@ def set_user_enabled(user_id: int, enabled: bool) -> None:
con.close()
def delete_user(user_id: int) -> None:
run_migrations()
con = get_connection()
con.execute("DELETE FROM users WHERE id = ?", (user_id,))
con.commit()
con.close()
def update_gitea_sync_state(
user_id: int,
status: str,
+1 -1
View File
@@ -136,7 +136,7 @@ def _request_json(method: str, path: str, payload: dict | None = None, expected:
detail = exc.read().decode("utf-8", errors="replace")
raise RuntimeError(f"Gitea API returned HTTP {exc.code}: {detail}") from exc
except (URLError, TimeoutError, json.JSONDecodeError) as exc:
raise RuntimeError(f"Gitea API request failed: {exc}") from exc
raise RuntimeError(f"Gitea API request failed for {base_url}{path}: {exc}") from exc
def _email(user: dict) -> str:
+41 -1
View File
@@ -6,7 +6,7 @@ from fastapi.responses import HTMLResponse, RedirectResponse
from app.auth import require_user
from app.db.audit import log_audit_event
from app.db.users import ROLES, count_enabled_admins, get_user, list_users, set_user_enabled, update_user_role
from app.db.users import ROLES, count_enabled_admins, delete_user, get_user, list_users, set_user_enabled, update_user_role
from app.gitea_provisioning import sync_gitea_user
from app.templates.layout import page
@@ -132,6 +132,9 @@ def users_page(request: Request, message: str = "", error: str = "", user=Depend
<form method="post" action="/portal/admin/users/{user_id_html}/sync-gitea" class="inline-form">
<button type="submit" class="btn-secondary">Sync Gitea</button>
</form>
<form method="post" action="/portal/admin/users/{user_id_html}/delete" class="inline-form" onsubmit="return confirm('Delete this user? This removes the portal account.');">
<button type="submit" class="btn-secondary">Delete</button>
</form>
</td>
</tr>
"""
@@ -291,3 +294,40 @@ def sync_gitea_user_action(user_id: int, user=Depends(require_user)):
status_code=303,
)
return RedirectResponse(url="/portal/admin/users?message=" + quote("Gitea synchronized."), status_code=303)
@router.post("/admin/users/{user_id}/delete")
def delete_user_action(user_id: int, user=Depends(require_user)):
require_admin(user)
target = get_user(user_id)
if not target:
raise HTTPException(status_code=404, detail="User not found")
if int(user.get("id")) == user_id:
return RedirectResponse(
url="/portal/admin/users?error=" + quote("Cannot delete your own user account."),
status_code=303,
)
if (target.get("role") or "").lower() == "admin" and count_enabled_admins(excluding_user_id=user_id) == 0:
return RedirectResponse(
url="/portal/admin/users?error=" + quote("Cannot delete the last enabled admin."),
status_code=303,
)
set_user_enabled(user_id, False)
target = get_user(user_id) or target
sync_result = sync_gitea_user(target)
if sync_result.get("status") == "error":
return RedirectResponse(
url="/portal/admin/users?error=" + quote(f"User disabled, but Gitea sync failed: {sync_result.get('error')}"),
status_code=303,
)
delete_user(user_id)
log_audit_event(
user,
action="user.deleted",
target_type="user",
target_id=user_id,
metadata={"username": target.get("username"), "role": target.get("role"), "gitea_sync_status": sync_result.get("status")},
)
return RedirectResponse(url="/portal/admin/users?message=" + quote("User deleted."), status_code=303)