Add StoredObjectLockApiController and tests for lock removal functionality

- Implemented `StoredObjectLockApiController` with endpoint to remove locks from stored objects.
- Added access control checks and validation for lock existence before removal.
- Wrote `StoredObjectLockApiControllerTest` to cover access denial, lock absence, and successful lock removal scenarios.
- Utilized `MockClock` in test cases to accurately simulate time-based behaviors.
This commit is contained in:
2026-04-14 15:35:22 +02:00
parent a27173ee4a
commit 7b00006943
3 changed files with 170 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\DocStoreBundle\Controller;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
use Chill\DocStoreBundle\Service\Lock\StoredObjectLockManager;
use Symfony\Component\Clock\ClockInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
final readonly class StoredObjectLockApiController
{
public function __construct(
private Security $security,
private StoredObjectLockManager $storedObjectLockManager,
private ClockInterface $clock,
) {}
#[Route('/api/1.0/doc-store/stored-object/{uuid}/lock', name: 'chill_docstore_storedobjectlock_removelock', methods: ['DELETE'])]
public function removeLock(StoredObject $storedObject): Response
{
if (!$this->security->isGranted(StoredObjectRoleEnum::EDIT->value, $storedObject)) {
throw new AccessDeniedHttpException();
}
if (!$this->storedObjectLockManager->hasLock($storedObject)) {
throw new PreconditionFailedHttpException('No lock found for this stored object');
}
$this->storedObjectLockManager->deleteLock($storedObject, $this->clock->now());
return new Response(null, Response::HTTP_NO_CONTENT);
}
}