feat(rbac): enforce procurement write restrictions and support supervisor role in SSO
This commit is contained in:
@@ -3,6 +3,7 @@ from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.auth import require_role
|
||||
from app.db.engine import get_db
|
||||
from app.models.procurement import (
|
||||
ItemDecision,
|
||||
@@ -26,6 +27,7 @@ from app.utils.errors import ConflictError, NotFoundError, ValidationError
|
||||
from app.utils.pagination import paginate, sort_query
|
||||
|
||||
router = APIRouter(prefix="/quotes/{quote_id}/termsheets", tags=["termsheets"])
|
||||
_procurement_writer = require_role("admin", "procurement_manager")
|
||||
|
||||
|
||||
async def _quote_or_404(db: AsyncSession, quote_id) -> Quote:
|
||||
@@ -80,7 +82,12 @@ async def list_termsheets(
|
||||
|
||||
|
||||
@router.post("", status_code=201)
|
||||
async def create_termsheet(quote_id, payload: TermsheetCreate, db: AsyncSession = Depends(get_db)):
|
||||
async def create_termsheet(
|
||||
quote_id,
|
||||
payload: TermsheetCreate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_auth=Depends(_procurement_writer),
|
||||
):
|
||||
async with db.begin():
|
||||
quote = await _quote_or_404(db, quote_id)
|
||||
if quote.status != "offered":
|
||||
@@ -110,7 +117,11 @@ async def get_termsheet(
|
||||
|
||||
@router.patch("/{termsheet_id}")
|
||||
async def update_termsheet(
|
||||
quote_id, termsheet_id, payload: TermsheetUpdate, db: AsyncSession = Depends(get_db)
|
||||
quote_id,
|
||||
termsheet_id,
|
||||
payload: TermsheetUpdate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_auth=Depends(_procurement_writer),
|
||||
):
|
||||
ts = await _termsheet_or_404(db, quote_id, termsheet_id)
|
||||
if ts.status != "offered":
|
||||
@@ -127,7 +138,11 @@ async def update_termsheet(
|
||||
|
||||
@router.patch("/{termsheet_id}/status")
|
||||
async def update_termsheet_status(
|
||||
quote_id, termsheet_id, payload: TermsheetStatusUpdate, db: AsyncSession = Depends(get_db)
|
||||
quote_id,
|
||||
termsheet_id,
|
||||
payload: TermsheetStatusUpdate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_auth=Depends(_procurement_writer),
|
||||
):
|
||||
async with db.begin():
|
||||
ts = await _termsheet_or_404(db, quote_id, termsheet_id)
|
||||
@@ -139,7 +154,12 @@ async def update_termsheet_status(
|
||||
|
||||
|
||||
@router.delete("/{termsheet_id}")
|
||||
async def delete_termsheet(quote_id, termsheet_id, db: AsyncSession = Depends(get_db)):
|
||||
async def delete_termsheet(
|
||||
quote_id,
|
||||
termsheet_id,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_auth=Depends(_procurement_writer),
|
||||
):
|
||||
ts = await _termsheet_or_404(db, quote_id, termsheet_id)
|
||||
quote = await _quote_or_404(db, quote_id)
|
||||
if quote.status != "offered":
|
||||
|
||||
Reference in New Issue
Block a user