fix(security) : harden ROLE_CLIENT isolation + tighten cross-module contracts
Findings from the post-migration code review. The arrival of ROLE_CLIENT exposed internal endpoints still guarded only by IS_AUTHENTICATED_FULLY (or no security), reachable by a client. Verified by re-running a multi-role smoke test (client -> 403, internal roles -> 200). Security (closed real client-isolation holes): - TaskDocumentDownloadController: add ownership check (admin all / client only own clientTicket docs / user only task-linked docs) — the custom download bypassed the cloistered provider. - Share browse/download/search/status controllers: IS_AUTHENTICATED_FULLY -> ROLE_USER (SMB share is internal). - User Get/GetCollection: add security ROLE_USER (was exposing the internal directory to clients). - BookStackLink GetCollection/Post/Delete: IS_AUTHENTICATED_FULLY -> ROLE_USER. Contracts / robustness: - TaskInterface gains getProject(): ?ProjectInterface; TimeTracking export controller/service drop concrete cross-module entities for repo interfaces. - Shared MCP Serializer signatures widened to the contracts (user/projectRef/ taskRef/tags/users); project()/userFull()/etc. kept concrete (use getters outside the contracts). - RecurrenceHandler: null-guard before findMaxNumberByProjectForUpdate(). 180 tests green, cs-fixer clean, routes unchanged.
This commit is contained in:
@@ -39,10 +39,12 @@ use Symfony\Component\Serializer\Attribute\Groups;
|
||||
normalizationContext: ['groups' => ['me:read']],
|
||||
),
|
||||
new Get(
|
||||
security: "is_granted('ROLE_USER')",
|
||||
normalizationContext: ['groups' => ['user:list']],
|
||||
),
|
||||
new GetCollection(
|
||||
paginationEnabled: false,
|
||||
security: "is_granted('ROLE_USER')",
|
||||
normalizationContext: ['groups' => ['user:list']],
|
||||
),
|
||||
new Post(security: "is_granted('ROLE_ADMIN')", processor: UserPasswordHasherProcessor::class),
|
||||
|
||||
Reference in New Issue
Block a user