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:
@@ -81,8 +81,12 @@ final readonly class RecurrenceHandler
|
||||
$newTask->setCalendarEventUid($savedEventUid);
|
||||
|
||||
// Generate task number in transaction
|
||||
$this->entityManager->wrapInTransaction(function () use ($newTask): void {
|
||||
$maxNumber = $this->taskRepository->findMaxNumberByProjectForUpdate($newTask->getProject());
|
||||
$project = $newTask->getProject();
|
||||
if (null === $project) {
|
||||
return;
|
||||
}
|
||||
$this->entityManager->wrapInTransaction(function () use ($newTask, $project): void {
|
||||
$maxNumber = $this->taskRepository->findMaxNumberByProjectForUpdate($project);
|
||||
$newTask->setNumber($maxNumber + 1);
|
||||
$this->entityManager->persist($newTask);
|
||||
$this->entityManager->flush();
|
||||
|
||||
Reference in New Issue
Block a user