138 lines
7 KiB
Python
138 lines
7 KiB
Python
"""Administration: Teams und Nutzer."""
|
|
|
|
from typing import Annotated
|
|
|
|
from fastapi import APIRouter, Form, Request
|
|
from fastapi.responses import HTMLResponse, Response
|
|
|
|
from app import web
|
|
from app.core.database import now
|
|
from app.core.errors import Invalid
|
|
from app.identity import admin
|
|
from app.uploads import service as uploads
|
|
|
|
Text = Annotated[str, Form()]
|
|
Flag = Annotated[bool, Form()]
|
|
|
|
|
|
def router() -> APIRouter:
|
|
r = APIRouter()
|
|
|
|
def teams_page(request: Request, principal, error: str = "", status: int = 200) -> HTMLResponse:
|
|
admin.require(principal)
|
|
with web.db(request).session() as session:
|
|
rows = admin.teams(session)
|
|
return web.render(request, "admin_teams.html", {"rows": rows, "error": error}, status)
|
|
|
|
def team_page(request: Request, principal, team_id: int, error: str = "", notice: str = "",
|
|
status: int = 200) -> HTMLResponse:
|
|
admin.require(principal)
|
|
settings = web.settings(request)
|
|
with web.db(request).session() as session:
|
|
workspaces = admin.team_workspaces(session, team_id)
|
|
context = {"team": admin.get_team(session, team_id), "members": admin.team_members(session, team_id),
|
|
"workspaces": workspaces, "error": error, "notice": notice,
|
|
"storage": {w.id: uploads.storage(session, settings, w) for w in workspaces},
|
|
"default_storage_mb": settings.workspace_storage_mb}
|
|
return web.render(request, "admin_team.html", context, status)
|
|
|
|
def users_page(request: Request, principal, error: str = "", notice: str = "", status: int = 200,
|
|
issued: tuple[str, str] | None = None) -> HTMLResponse:
|
|
admin.require(principal)
|
|
with web.db(request).session() as session:
|
|
context = {"users": admin.users(session), "teams_by_user": admin.teams_by_user(session),
|
|
"error": error, "notice": notice, "issued": issued, "now": now()}
|
|
return web.render(request, "admin_users.html", context, status)
|
|
|
|
@r.get("/admin/teams")
|
|
def teams(request: Request, principal: web.User) -> HTMLResponse:
|
|
return teams_page(request, principal)
|
|
|
|
@r.post("/admin/teams")
|
|
def create_team(request: Request, principal: web.Checked, slug: Text, name: Text) -> Response:
|
|
try:
|
|
with web.db(request).session() as session:
|
|
team = admin.save_team(session, principal, None, slug=slug, name=name)
|
|
except Invalid as e:
|
|
return teams_page(request, principal, str(e), 400)
|
|
return web.redirect(f"/admin/teams/{team.id}")
|
|
|
|
@r.get("/admin/teams/{team_id}")
|
|
def team(request: Request, principal: web.User, team_id: int) -> HTMLResponse:
|
|
return team_page(request, principal, team_id)
|
|
|
|
def team_action(request: Request, principal, team_id: int, action, notice: str) -> Response:
|
|
try:
|
|
with web.db(request).session() as session:
|
|
action(session)
|
|
except Invalid as e:
|
|
return team_page(request, principal, team_id, error=str(e), status=400)
|
|
return team_page(request, principal, team_id, notice=notice)
|
|
|
|
@r.post("/admin/teams/{team_id}")
|
|
def update_team(request: Request, principal: web.Checked, team_id: int, slug: Text, name: Text) -> Response:
|
|
return team_action(request, principal, team_id,
|
|
lambda s: admin.save_team(s, principal, team_id, slug=slug, name=name), "Gespeichert.")
|
|
|
|
@r.post("/admin/teams/{team_id}/delete")
|
|
def delete_team(request: Request, principal: web.Checked, team_id: int) -> Response:
|
|
try:
|
|
with web.db(request).session() as session:
|
|
admin.delete_team(session, principal, team_id)
|
|
except Invalid as e:
|
|
return team_page(request, principal, team_id, error=str(e), status=400)
|
|
return web.redirect("/admin/teams")
|
|
|
|
@r.post("/admin/teams/{team_id}/workspaces/{workspace_id}/storage")
|
|
def set_storage(request: Request, principal: web.Checked, team_id: int, workspace_id: int,
|
|
limit_mb: Text = "") -> Response:
|
|
return team_action(request, principal, team_id,
|
|
lambda s: admin.set_storage_limit(s, principal, workspace_id, limit_mb),
|
|
"Speicherkontingent gespeichert.")
|
|
|
|
@r.post("/admin/teams/{team_id}/members")
|
|
def add_member(request: Request, principal: web.Checked, team_id: int, username: Text) -> Response:
|
|
return team_action(request, principal, team_id,
|
|
lambda s: admin.add_member(s, principal, team_id, username), "Mitglied hinzugefügt.")
|
|
|
|
@r.post("/admin/teams/{team_id}/members/{user_id}/remove")
|
|
def remove_member(request: Request, principal: web.Checked, team_id: int, user_id: int) -> Response:
|
|
return team_action(request, principal, team_id,
|
|
lambda s: admin.remove_member(s, principal, team_id, user_id),
|
|
"Entfernt, inklusive aller Workspace-Mitgliedschaften in diesem Team.")
|
|
|
|
@r.get("/admin/users")
|
|
def users(request: Request, principal: web.User) -> HTMLResponse:
|
|
return users_page(request, principal)
|
|
|
|
@r.post("/admin/users")
|
|
def create_user(request: Request, principal: web.Checked, username: Text, display_name: Text = "",
|
|
is_admin: Flag = False, email: Text = "") -> Response:
|
|
try:
|
|
with web.db(request).session() as session:
|
|
user, secret = admin.create_user(session, principal, username, display_name, is_admin, email)
|
|
except Invalid as e:
|
|
return users_page(request, principal, error=str(e), status=400)
|
|
return users_page(request, principal, issued=(user.username, secret),
|
|
notice="Nutzer angelegt. Jetzt einem Team zuordnen.")
|
|
|
|
@r.post("/admin/users/{user_id}/reset-password")
|
|
def reset_password(request: Request, principal: web.Checked, user_id: int) -> Response:
|
|
with web.db(request).session() as session:
|
|
user, secret = admin.reset_password(session, principal, user_id)
|
|
return users_page(request, principal, issued=(user.username, secret),
|
|
notice="Passwort zurückgesetzt; alle Sitzungen des Nutzers sind beendet.")
|
|
|
|
@r.post("/admin/users/{user_id}")
|
|
def update_user(request: Request, principal: web.Checked, user_id: int, display_name: Text = "",
|
|
is_admin: Flag = False, active: Flag = False, is_global_approver: Flag = False,
|
|
email: Text = "") -> Response:
|
|
try:
|
|
with web.db(request).session() as session:
|
|
admin.update_user(session, principal, user_id, display_name=display_name, is_admin=is_admin,
|
|
active=active, is_global_approver=is_global_approver, email=email)
|
|
except Invalid as e:
|
|
return users_page(request, principal, error=str(e), status=400)
|
|
return users_page(request, principal, notice="Gespeichert.")
|
|
|
|
return r
|