fix(authz): invalidate role cache on change

This commit is contained in:
Edouard Vanbelle
2026-07-06 23:01:37 +02:00
parent 79f4792709
commit f7deb7aaf4
7 changed files with 134 additions and 10 deletions
@@ -249,6 +249,20 @@ impl DriveManagementService {
.set_role(caller_id, subject, role, resource, expires_at)
.await?;
// Drop the entire drive-role cache for this drive so the new
// grant is visible on the very next `check` — without this, a
// caller that gets Owner via `POST /api/drives/{id}/members`
// then immediately acts on drive content (WebDAV cross-drive
// MOVE, admin-driven cleanup, drive management) hits the
// stale "no role for this subject on this drive" entry
// seeded at some earlier `check`. TTL rescues eventually,
// but the storage_cleanup_check.sh drain pattern hits this
// race within a single test-second and fails on `authz.denied`
// for admin's cascade to files inside.
self.authz
.invalidate_drive_role_cache_for_drive(drive_id)
.await;
// D6 §11: canonical `drive.member_added` audit event covers
// every successful membership write (add + role-refresh, since
// the underlying `set_role` is UPSERT — distinguishing the two
@@ -312,6 +326,15 @@ impl DriveManagementService {
self.authz.clear_role(subject, resource).await?;
// Mirror of `set_member_role`'s cache invalidation: after
// clearing a role we MUST drop the `drive_role_cache` entries
// targeting this drive, otherwise the just-removed subject's
// former role stays visible until TTL expires. Same anti-drift
// reason as the sibling add path above.
self.authz
.invalidate_drive_role_cache_for_drive(drive_id)
.await;
// D6 §11: canonical `drive.member_removed` audit event covers
// every successful removal (owner-driven or admin bypass).
// `via_admin` replaces the separate