forked from yvv/decision
Compartimentation : isolation stricte des données par espace de travail
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Ajout clause else IS NULL sur tous les endpoints list (protocols, decisions, mandates, documents, groups, votes) — sans X-Organization → données globales seulement, jamais le contenu d'un autre espace - _get_protocol/_get_decision/_get_mandate : org_id propagé à tous les endpoints GET/PUT/DELETE/advance/assign/revoke/steps → 404 si UUID d'un autre espace - votes.py : list_vote_sessions filtre via JOIN VotingProtocol.organization_id - groups.py : suppression _org_id_from_header() mort, create_group assigne organization_id correctement Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -37,8 +37,10 @@ router = APIRouter()
|
||||
# ── Helpers ─────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
async def _get_mandate(db: AsyncSession, mandate_id: uuid.UUID) -> Mandate:
|
||||
result = await db.execute(
|
||||
async def _get_mandate(
|
||||
db: AsyncSession, mandate_id: uuid.UUID, org_id: uuid.UUID | None = None
|
||||
) -> Mandate:
|
||||
stmt = (
|
||||
select(Mandate)
|
||||
.options(
|
||||
selectinload(Mandate.steps),
|
||||
@@ -47,6 +49,11 @@ async def _get_mandate(db: AsyncSession, mandate_id: uuid.UUID) -> Mandate:
|
||||
)
|
||||
.where(Mandate.id == mandate_id)
|
||||
)
|
||||
if org_id is not None:
|
||||
stmt = stmt.where(Mandate.organization_id == org_id)
|
||||
else:
|
||||
stmt = stmt.where(Mandate.organization_id.is_(None))
|
||||
result = await db.execute(stmt)
|
||||
mandate = result.scalar_one_or_none()
|
||||
if mandate is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Mandat introuvable")
|
||||
@@ -80,6 +87,8 @@ async def list_mandates(
|
||||
|
||||
if org_id is not None:
|
||||
stmt = stmt.where(Mandate.organization_id == org_id)
|
||||
else:
|
||||
stmt = stmt.where(Mandate.organization_id.is_(None))
|
||||
if mandate_type is not None:
|
||||
stmt = stmt.where(Mandate.mandate_type == mandate_type)
|
||||
if status_filter is not None:
|
||||
@@ -111,7 +120,7 @@ async def create_mandate(
|
||||
await db.commit()
|
||||
await db.refresh(mandate)
|
||||
|
||||
mandate = await _get_mandate(db, mandate.id)
|
||||
mandate = await _get_mandate(db, mandate.id, org_id)
|
||||
return _mandate_out(mandate)
|
||||
|
||||
|
||||
@@ -119,8 +128,9 @@ async def create_mandate(
|
||||
async def get_mandate(
|
||||
id: uuid.UUID,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
org_id: uuid.UUID | None = Depends(get_active_org_id),
|
||||
) -> MandateOut:
|
||||
mandate = await _get_mandate(db, id)
|
||||
mandate = await _get_mandate(db, id, org_id)
|
||||
return _mandate_out(mandate)
|
||||
|
||||
|
||||
@@ -130,14 +140,15 @@ async def update_mandate(
|
||||
payload: MandateUpdate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
identity: DuniterIdentity = Depends(get_current_identity),
|
||||
org_id: uuid.UUID | None = Depends(get_active_org_id),
|
||||
) -> MandateOut:
|
||||
mandate = await _get_mandate(db, id)
|
||||
mandate = await _get_mandate(db, id, org_id)
|
||||
|
||||
for field, value in payload.model_dump(exclude_unset=True).items():
|
||||
setattr(mandate, field, value)
|
||||
|
||||
await db.commit()
|
||||
mandate = await _get_mandate(db, mandate.id)
|
||||
mandate = await _get_mandate(db, mandate.id, org_id)
|
||||
return _mandate_out(mandate)
|
||||
|
||||
|
||||
@@ -146,8 +157,9 @@ async def delete_mandate(
|
||||
id: uuid.UUID,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
identity: DuniterIdentity = Depends(get_current_identity),
|
||||
org_id: uuid.UUID | None = Depends(get_active_org_id),
|
||||
) -> None:
|
||||
mandate = await _get_mandate(db, id)
|
||||
mandate = await _get_mandate(db, id, org_id)
|
||||
|
||||
if mandate.status != "draft":
|
||||
raise HTTPException(
|
||||
@@ -168,8 +180,9 @@ async def add_step(
|
||||
payload: MandateStepCreate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
identity: DuniterIdentity = Depends(get_current_identity),
|
||||
org_id: uuid.UUID | None = Depends(get_active_org_id),
|
||||
) -> MandateStepOut:
|
||||
mandate = await _get_mandate(db, id)
|
||||
mandate = await _get_mandate(db, id, org_id)
|
||||
|
||||
step = MandateStep(mandate_id=mandate.id, **payload.model_dump())
|
||||
db.add(step)
|
||||
@@ -183,8 +196,9 @@ async def add_step(
|
||||
async def list_steps(
|
||||
id: uuid.UUID,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
org_id: uuid.UUID | None = Depends(get_active_org_id),
|
||||
) -> list[MandateStepOut]:
|
||||
mandate = await _get_mandate(db, id)
|
||||
mandate = await _get_mandate(db, id, org_id)
|
||||
return [MandateStepOut.model_validate(s) for s in mandate.steps]
|
||||
|
||||
|
||||
@@ -196,13 +210,14 @@ async def advance_mandate_endpoint(
|
||||
id: uuid.UUID,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
identity: DuniterIdentity = Depends(get_current_identity),
|
||||
org_id: uuid.UUID | None = Depends(get_active_org_id),
|
||||
) -> MandateAdvanceOut:
|
||||
try:
|
||||
mandate = await advance_mandate(id, db)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc))
|
||||
|
||||
mandate = await _get_mandate(db, mandate.id)
|
||||
mandate = await _get_mandate(db, mandate.id, org_id)
|
||||
out = _mandate_out(mandate)
|
||||
return MandateAdvanceOut(
|
||||
**out.model_dump(),
|
||||
@@ -216,13 +231,14 @@ async def assign_mandatee_endpoint(
|
||||
payload: MandateAssignRequest,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
identity: DuniterIdentity = Depends(get_current_identity),
|
||||
org_id: uuid.UUID | None = Depends(get_active_org_id),
|
||||
) -> MandateOut:
|
||||
try:
|
||||
mandate = await assign_mandatee(id, payload.mandatee_id, db)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc))
|
||||
|
||||
mandate = await _get_mandate(db, mandate.id)
|
||||
mandate = await _get_mandate(db, mandate.id, org_id)
|
||||
return _mandate_out(mandate)
|
||||
|
||||
|
||||
@@ -231,13 +247,14 @@ async def revoke_mandate_endpoint(
|
||||
id: uuid.UUID,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
identity: DuniterIdentity = Depends(get_current_identity),
|
||||
org_id: uuid.UUID | None = Depends(get_active_org_id),
|
||||
) -> MandateOut:
|
||||
try:
|
||||
mandate = await revoke_mandate(id, db)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc))
|
||||
|
||||
mandate = await _get_mandate(db, mandate.id)
|
||||
mandate = await _get_mandate(db, mandate.id, org_id)
|
||||
return _mandate_out(mandate)
|
||||
|
||||
|
||||
@@ -251,6 +268,7 @@ async def create_vote_session_for_step_endpoint(
|
||||
step_id: uuid.UUID,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
identity: DuniterIdentity = Depends(get_current_identity),
|
||||
org_id: uuid.UUID | None = Depends(get_active_org_id),
|
||||
) -> VoteSessionOut:
|
||||
try:
|
||||
session = await create_vote_session_for_step(id, step_id, db)
|
||||
|
||||
Reference in New Issue
Block a user