feat(admin): invitationslinks med gruppe og udløbstid
Udrullet direkte til prod 2026-09-29; importeret her så repo == prod. Bruger Authentik-flowet weircon-invitation (grupper og engangs via fixed_data og politikker i flowet). Claude-Session: https://claude.ai/code/session_012LCTmU2ewo8tnM1dByYAoG
This commit is contained in:
@@ -271,6 +271,59 @@ async def admin_user_save(request: Request, pk: int):
|
||||
return RedirectResponse(f"/admin/users?saved=Bruger gemt{note}", status_code=303)
|
||||
|
||||
|
||||
INV_VARIGHED = [(30, "30 minutter"), (120, "2 timer"), (1440, "1 dag"), (4320, "3 dage"),
|
||||
(10080, "7 dage"), (20160, "14 dage"), (43200, "30 dage")]
|
||||
|
||||
|
||||
@app.get("/admin/invitations", response_class=HTMLResponse)
|
||||
async def admin_invitations(request: Request, ny: str = "", saved: str = ""):
|
||||
user = require_admin(request)
|
||||
grupper = [g for g in await ak.list_groups() if g["name"] not in ak.INV_SKJUL]
|
||||
navn = {str(g["pk"]): g["name"] for g in await ak.list_groups()}
|
||||
invs = await ak.list_invitations()
|
||||
from datetime import datetime, timezone
|
||||
nu = datetime.now(timezone.utc)
|
||||
for i in invs:
|
||||
i["gruppenavne"] = [navn.get(str(x), "?") for x in i["grupper"]]
|
||||
try:
|
||||
rest = datetime.fromisoformat(i["expires"].replace("Z", "+00:00")) - nu
|
||||
sek = int(rest.total_seconds())
|
||||
i["udloebet"] = sek <= 0
|
||||
i["rest"] = ("udløbet" if sek <= 0 else f"{sek // 86400} dage" if sek >= 86400
|
||||
else f"{sek // 3600} timer" if sek >= 3600 else f"{max(sek // 60, 1)} min")
|
||||
except Exception:
|
||||
i["udloebet"], i["rest"] = False, "?"
|
||||
nyt = next((i for i in invs if str(i["pk"]) == ny), None)
|
||||
return templates.TemplateResponse(request, "admin_invitations.html", {
|
||||
"request": request, "user": user, "is_admin": True, "grupper": grupper,
|
||||
"invitationer": invs, "nyt": nyt, "varigheder": INV_VARIGHED, "saved": saved})
|
||||
|
||||
|
||||
@app.post("/admin/invitations")
|
||||
async def admin_invitations_create(request: Request):
|
||||
require_admin(request)
|
||||
f = await request.form()
|
||||
grupper = f.getlist("grupper")
|
||||
minutter = int(f.get("minutter") or 20160)
|
||||
if minutter not in {m for m, _ in INV_VARIGHED}:
|
||||
minutter = 20160
|
||||
if not grupper:
|
||||
return RedirectResponse("/admin/invitations?saved=Vælg mindst én gruppe", status_code=303)
|
||||
ok, res = await ak.create_invitation((f.get("label") or "").strip(), grupper, minutter,
|
||||
engangs=bool(f.get("engangs")))
|
||||
if not ok:
|
||||
return RedirectResponse(f"/admin/invitations?saved=Kunne ikke oprette: {res[:120]}", status_code=303)
|
||||
return RedirectResponse(f"/admin/invitations?ny={res}", status_code=303)
|
||||
|
||||
|
||||
@app.post("/admin/invitations/{pk}/slet")
|
||||
async def admin_invitations_delete(request: Request, pk: str):
|
||||
require_admin(request)
|
||||
ok = await ak.delete_invitation(pk)
|
||||
return RedirectResponse(f"/admin/invitations?saved={'Invitationen er tilbagekaldt' if ok else 'Kunne ikke tilbagekalde'}",
|
||||
status_code=303)
|
||||
|
||||
|
||||
@app.get("/admin/groups", response_class=HTMLResponse)
|
||||
async def admin_groups(request: Request, saved: str = ""):
|
||||
user = require_admin(request)
|
||||
|
||||
Reference in New Issue
Block a user