- Ya
- 15 Agosti 2026, 02:58 UTC
- Mwandishi
- Kamo
- Ahadi ya
- 09ea51a
ImagingController checked ImageAccessLevelType and nothing else, and DocumentController checked only that a session existed. Access level is a real control but an orthogonal one: it decides WHICH documents a caller may touch, while CREATE / EDIT / DELETE_DOCUMENTS and MANAGE_STORAGE decide whether the caller may perform the verb at all. All four gated nothing anywhere until now, and VIEW_DOCUMENTS was enforced only by navRegistry hiding the app in the browser. 27 gates here plus 2 in DocumentController, all through hasRightApplied, which reads the end of the waterfall — the security model attached to the organization's branch type, then roles, department, job title, member overrides, FORCE rules and closure. The gate asks what the organization configured and re-derives none of it. Fails closed: hasRightApplied throws when the member row is gone, and an unresolvable caller is refused. /api/docs/open/{imgId} takes EDIT_DOCUMENTS rather than VIEW_DOCUMENTS. It hands back a Docs session, and that session writes through WopiController.putFile, which authenticates the token issued here rather than the member — its caller is Docs, not a browser. This is where edit access is really granted; gating it on "may view" would let anyone who can see a document rewrite it. Reading without editing is the download and stream endpoints. backfill-thumbnails takes MANAGE_STORAGE. It required only a session, having been anonymous until someone noticed APIService relays /api/docs/** without gateway auth, and it reads every tenant's document bytes. The shares/* sub-API is left alone: it is already governed by the enforced SHARE_DOCS_* rights and a second gate risks over-restricting it. No seeding, deliberately. DELETE_DOCUMENTS and MANAGE_STORAGE are granted to the Administrator role only in all 14 organizations while VIEW/CREATE/EDIT go to 28 of 42 roles; 14 members can delete today because nothing checks and will stop. That is the configuration taking effect for the first time. Seeding to preserve today's behaviour would overwrite the decision everywhere, which is the opposite of the point. A right that is differentially granted carries intent; one nobody holds at all does not. Two test fixtures now grant the new rights. ImagingIssuedDocumentGuardTest mocks MemberRightsAppliedService and Mockito's default false turned all 15 cases into 403s; ImagingDownloadAuditTest passed a null that failed closed before reaching the auditor. The Docstor feeding LegalIssuedDocumentAccess still denies — those tests are about a caller holding no HR right, and merging the two would have quietly destroyed what they check.