[PM-42605] refactor: wire PostBulkCollectionAccess into CollectionAuthorizationService - #8268
Conversation
…ionService behind a flag The endpoint authorized ModifyUserAccess and ModifyGroupAccess in one IAuthorizationService call, so both operations had to succeed for the whole collection set. Behind pm-35160-authorization-services it now intersects AuthorizeModifyUserAccessManyAsync and AuthorizeModifyGroupAccessManyAsync, which is the same all-or-nothing decision. Three things stay as they were. The count pre-check still rejects unknown, cross-organization and duplicate ids with a 404, because the service omits those ids rather than failing on them. The collection entities are still fetched, because BulkAddCollectionAccessCommand needs them for event logging and for its default-collection check. An empty request still returns a 404, which needs an explicit guard: the legacy handler fails an empty resource list, while the service returns an empty result that must not be read as authorized.
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE Reviewed the |
🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-42605
Stacked on #8211 (PM-12473). Review that one first — this PR only adds a caller.
📔 Objective
CollectionsController.PostBulkCollectionAccesswas the last place inCollectionsControllerstill usingBulkCollectionAuthorizationHandlerforcollection access. This PR points it at
ICollectionAuthorizationService,which #8211 added, behind the same
pm-35160-authorization-servicesflag.The old call passed both
ModifyUserAccessandModifyGroupAccessto asingle
AuthorizeAsync, so both operations had to succeed across the wholecollection set. The flag-on path intersects
AuthorizeModifyUserAccessManyAsyncand
AuthorizeModifyGroupAccessManyAsync, which is the same all-or-nothingdecision. This also gives those two methods their first caller.
Three things stay as they are:
collection ids with a 404.
ICollectionAuthorizationServiceleaves such idsout of its result rather than failing on them, so removing this check would
turn a rejection into a silent ignore.
BulkAddCollectionAccessCommand.AddAccessAsynctakes the
Collectionentities and needs them for event logging and for itsdefault-collection check. The authorization service resolves the same ids
again, so this request reads collections twice. That is the cost of an
authorization layer that fetches its own data, instead of threading
pre-fetched entities into it — the pattern rejected on [PM-12473] feat: Add CollectionUser authorization handler and delta access endpoint #8075.
handler fails an empty resource list, while the service returns an empty
result, and "every id is authorized" is vacuously true over an empty list.
Without the guard the flag-on path would fail open and reach the command.
No behavior change is expected on either path.
📸 Screenshots
N/A