Coverage for app/routers/tasks.py: 93.33%
30 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-25 15:51 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-25 15:51 +0000
1"""
2Tasks Router
4Read-only access to task information for a deployment. Tasks are created by the
5deployment flow itself; this router exposes status and details so the frontend
6can render progress.
8Every endpoint enforces ``ensure_deployment_access`` (to prevent IDOR) plus
9``ensure_deployment_owner_view``, so only the deployment creator, teachers, and
10admins can read task logs — which contain Terraform outputs, IPs, and worker
11stack traces. Members get a 403 even though they can read deployment metadata.
12"""
14from uuid import UUID
16from fastapi import APIRouter, Depends, HTTPException, status
17from sqlalchemy.orm import Session
19from app.crud import deployments as crud_deployments
20from app.crud import tasks as crud_tasks
21from app.database import get_db
22from app.models import User
23from app.schemas import TaskResponse
24from app.utils.keycloak_auth import get_current_user_keycloak
25from app.utils.permissions import ensure_deployment_access, ensure_deployment_owner_view
27router = APIRouter()
30@router.get("/deployment/{deployment_id}", response_model=list[TaskResponse])
31def get_deployment_tasks(
32 deployment_id: UUID,
33 db: Session = Depends(get_db),
34 current_user: User = Depends(get_current_user_keycloak),
35):
36 """List all tasks for a deployment the caller has owner-access to."""
37 deployment = crud_deployments.get_deployment(db, deployment_id)
38 if not deployment:
39 raise HTTPException(
40 status_code=status.HTTP_404_NOT_FOUND,
41 detail="Deployment not found",
42 )
43 ensure_deployment_access(deployment, current_user, db)
44 ensure_deployment_owner_view(deployment, current_user)
45 return crud_tasks.get_tasks(db, deployment_id=deployment_id)
48@router.get("/{task_id}", response_model=TaskResponse)
49def get_task(
50 task_id: UUID,
51 db: Session = Depends(get_db),
52 current_user: User = Depends(get_current_user_keycloak),
53):
54 """Fetch a single task; only the deployment owner-view sees it."""
55 task = crud_tasks.get_task(db, task_id)
56 if not task:
57 raise HTTPException(
58 status_code=status.HTTP_404_NOT_FOUND,
59 detail="Task not found",
60 )
61 deployment = crud_deployments.get_deployment(db, task.deploymentId)
62 if not deployment:
63 raise HTTPException(
64 status_code=status.HTTP_404_NOT_FOUND,
65 detail="Deployment for task not found",
66 )
67 ensure_deployment_access(deployment, current_user, db)
68 ensure_deployment_owner_view(deployment, current_user)
69 return task