Add peer review evidence export and restrict AQMM access
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
|
||||
from fastapi import APIRouter, Request
|
||||
from fastapi.responses import RedirectResponse, StreamingResponse
|
||||
|
||||
from app.core.db.common import CommonSessionLocal
|
||||
from app.core.http_responses import ui_access_denied
|
||||
from app.core.security.csrf import get_or_create_csrf_token
|
||||
from app.core.security.session_auth import get_current_user
|
||||
from app.core.templating import templates
|
||||
from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
|
||||
from app.modules.peer_review_export.service import (
|
||||
build_peer_review_evidence,
|
||||
build_peer_review_zip,
|
||||
can_view_peer_review_export,
|
||||
list_peer_review_engagements,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/peer-review", tags=["peer-review-evidence-export-ui"])
|
||||
|
||||
|
||||
def _ctx(request: Request, db, user, **extra):
|
||||
base = {
|
||||
"request": request,
|
||||
"current_user": user,
|
||||
"current_user_roles": get_user_roles(db, user.id),
|
||||
"current_user_permissions": get_user_permissions(db, user.id),
|
||||
"csrf_token": get_or_create_csrf_token(request),
|
||||
"title": "Peer Review Evidence Export",
|
||||
}
|
||||
base.update(extra)
|
||||
return base
|
||||
|
||||
|
||||
def _safe_filename(value: str) -> str:
|
||||
value = re.sub(r"[^A-Za-z0-9._-]+", "_", str(value or "").strip())
|
||||
value = value.strip("._")
|
||||
return value or "peer_review_evidence"
|
||||
|
||||
|
||||
@router.get("/evidence")
|
||||
def evidence_index(request: Request, financial_year: str = "", q: str = ""):
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
user = get_current_user(request, db=db)
|
||||
if not user:
|
||||
return RedirectResponse(url="/login", status_code=303)
|
||||
if not can_view_peer_review_export(db, user):
|
||||
return ui_access_denied()
|
||||
payload = list_peer_review_engagements(db, request, user, financial_year=financial_year, q=q)
|
||||
return templates.TemplateResponse(
|
||||
"modules/peer_review_export/templates/peer_review_export/index.html",
|
||||
_ctx(request, db, user, **payload),
|
||||
)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("/evidence/{subscription_id}")
|
||||
def evidence_detail(request: Request, subscription_id: int):
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
user = get_current_user(request, db=db)
|
||||
if not user:
|
||||
return RedirectResponse(url="/login", status_code=303)
|
||||
if not can_view_peer_review_export(db, user):
|
||||
return ui_access_denied()
|
||||
try:
|
||||
payload = build_peer_review_evidence(db, request, user, subscription_id)
|
||||
except ValueError:
|
||||
return ui_access_denied()
|
||||
return templates.TemplateResponse(
|
||||
"modules/peer_review_export/templates/peer_review_export/detail.html",
|
||||
_ctx(request, db, user, **payload),
|
||||
)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("/evidence/{subscription_id}/export.zip")
|
||||
def evidence_export_zip(request: Request, subscription_id: int):
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
user = get_current_user(request, db=db)
|
||||
if not user:
|
||||
return RedirectResponse(url="/login", status_code=303)
|
||||
if not can_view_peer_review_export(db, user):
|
||||
return ui_access_denied()
|
||||
try:
|
||||
payload = build_peer_review_evidence(db, request, user, subscription_id)
|
||||
data = build_peer_review_zip(db, request, user, subscription_id)
|
||||
except ValueError:
|
||||
return ui_access_denied()
|
||||
sub = payload["subscription"]
|
||||
client_name = sub.client.client_name if sub.client else "client"
|
||||
service_name = sub.catalogue.service_name if sub.catalogue else "service"
|
||||
filename = _safe_filename(f"peer_review_{client_name}_{service_name}_{sub.financial_year or 'fy'}_{sub.id}.zip")
|
||||
return StreamingResponse(
|
||||
iter([data]),
|
||||
media_type="application/zip",
|
||||
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
|
||||
)
|
||||
finally:
|
||||
db.close()
|
||||
Reference in New Issue
Block a user