mazani uzivatelu
This commit is contained in:
+6
-1
@@ -64,7 +64,12 @@ def get_gitea_public_url() -> str:
|
|||||||
|
|
||||||
|
|
||||||
def get_gitea_server_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:
|
def get_gitea_admin_token() -> str:
|
||||||
|
|||||||
@@ -154,6 +154,14 @@ def set_user_enabled(user_id: int, enabled: bool) -> None:
|
|||||||
con.close()
|
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(
|
def update_gitea_sync_state(
|
||||||
user_id: int,
|
user_id: int,
|
||||||
status: str,
|
status: str,
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ def _request_json(method: str, path: str, payload: dict | None = None, expected:
|
|||||||
detail = exc.read().decode("utf-8", errors="replace")
|
detail = exc.read().decode("utf-8", errors="replace")
|
||||||
raise RuntimeError(f"Gitea API returned HTTP {exc.code}: {detail}") from exc
|
raise RuntimeError(f"Gitea API returned HTTP {exc.code}: {detail}") from exc
|
||||||
except (URLError, TimeoutError, json.JSONDecodeError) as 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:
|
def _email(user: dict) -> str:
|
||||||
|
|||||||
+41
-1
@@ -6,7 +6,7 @@ from fastapi.responses import HTMLResponse, RedirectResponse
|
|||||||
|
|
||||||
from app.auth import require_user
|
from app.auth import require_user
|
||||||
from app.db.audit import log_audit_event
|
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.gitea_provisioning import sync_gitea_user
|
||||||
from app.templates.layout import page
|
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">
|
<form method="post" action="/portal/admin/users/{user_id_html}/sync-gitea" class="inline-form">
|
||||||
<button type="submit" class="btn-secondary">Sync Gitea</button>
|
<button type="submit" class="btn-secondary">Sync Gitea</button>
|
||||||
</form>
|
</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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
"""
|
"""
|
||||||
@@ -291,3 +294,40 @@ def sync_gitea_user_action(user_id: int, user=Depends(require_user)):
|
|||||||
status_code=303,
|
status_code=303,
|
||||||
)
|
)
|
||||||
return RedirectResponse(url="/portal/admin/users?message=" + quote("Gitea synchronized."), 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)
|
||||||
|
|||||||
Reference in New Issue
Block a user