Skip to content

Commit 35a531b

Browse files
fregataaclaude
andcommitted
feat(BA-5765): add RBAC-enforced VFolder purge mutation
Add PurgeVFolderV2RBACAction (SingleEntityActionProcessor + RBAC). Adapter purge() routes to RBAC path; bulk_purge() stays on legacy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0135927 commit 35a531b

3 files changed

Lines changed: 18 additions & 8 deletions

File tree

changes/11165.feature.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add RBAC-enforced VFolder purge v2 mutation with SingleEntityActionProcessor.

src/ai/backend/manager/api/adapters/vfolder.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,12 +411,9 @@ async def restore(self, vfolder_id: UUID) -> RestoreVFolderPayload:
411411
return RestoreVFolderPayload(id=vfolder_id)
412412

413413
async def purge(self, vfolder_id: UUID) -> PurgeVFolderPayload:
414-
"""Permanently delete a vfolder."""
415-
me = current_user()
416-
if me is None:
417-
raise UnreachableError("User context is not available")
418-
action = PurgeVFolderV2Action(user_id=me.user_id, vfolder_id=vfolder_id)
419-
await self._processors.vfolder.purge_v2.wait_for_complete(action)
414+
"""Permanently delete a vfolder. RBAC enforced."""
415+
action = PurgeVFolderV2RBACAction(vfolder_id=vfolder_id)
416+
await self._processors.vfolder.purge_v2_rbac.wait_for_complete(action)
420417
return PurgeVFolderPayload(id=vfolder_id)
421418

422419
async def deploy(

tests/component/vfolder_v2/test_vfolder_mutation.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
"""Component tests for v2 VFolder RBAC-enforced delete and restore mutations via SDK.
1+
"""Component tests for v2 VFolder RBAC-enforced delete, restore, and purge mutations via SDK.
22
3-
Exercises delete and restore mutations through the real HTTP server +
3+
Exercises delete, restore, and purge mutations through the real HTTP server +
44
V2ClientRegistry SDK.
55
"""
66

@@ -225,3 +225,15 @@ async def test_superadmin_trash_then_restore(
225225
await admin_v2_registry.vfolder.delete(project_vfolder.id)
226226
payload = await admin_v2_registry.vfolder.restore(project_vfolder.id)
227227
assert payload.id == project_vfolder.id
228+
229+
230+
class TestPurgeVFolderRBAC:
231+
"""POST /v2/vfolders/{id}/purge -- SingleEntityActionProcessor RBAC."""
232+
233+
async def test_regular_user_denied(
234+
self,
235+
user_v2_registry: V2ClientRegistry,
236+
project_vfolder: ProjectVFolderFixtureData,
237+
) -> None:
238+
with pytest.raises(PermissionDeniedError):
239+
await user_v2_registry.vfolder.purge(project_vfolder.id)

0 commit comments

Comments
 (0)