mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-13 22:04:23 +00:00
122 lines
5.0 KiB
PHP
122 lines
5.0 KiB
PHP
<?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\AsyncUpload\TempUrlGeneratorInterface;
|
|
use Chill\DocStoreBundle\Entity\StoredObject;
|
|
use Chill\DocStoreBundle\Entity\StoredObjectVersion;
|
|
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
|
|
use Chill\MainBundle\Entity\User;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
|
use Symfony\Component\Routing\Annotation\Route;
|
|
use Symfony\Component\Security\Core\Security;
|
|
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
|
use Symfony\Component\Serializer\SerializerInterface;
|
|
|
|
final readonly class AsyncUploadController
|
|
{
|
|
public function __construct(
|
|
private TempUrlGeneratorInterface $tempUrlGenerator,
|
|
private SerializerInterface $serializer,
|
|
private Security $security,
|
|
private LoggerInterface $chillLogger,
|
|
) {}
|
|
|
|
#[Route(path: '/api/1.0/doc-store/async-upload/temp_url/{uuid}/generate/post', name: 'chill_docstore_asyncupload_getsignedurlpost')]
|
|
public function getSignedUrlPost(Request $request, StoredObject $storedObject): JsonResponse
|
|
{
|
|
if (!$this->security->isGranted(StoredObjectRoleEnum::EDIT->value, $storedObject)) {
|
|
throw new AccessDeniedHttpException('not able to edit the given stored object');
|
|
}
|
|
|
|
// we create a dummy version, to generate a filename
|
|
$version = $storedObject->registerVersion();
|
|
|
|
$p = $this->tempUrlGenerator
|
|
->generatePost(
|
|
$request->query->has('expires_delay') ? $request->query->getInt('expires_delay') : null,
|
|
$request->query->has('submit_delay') ? $request->query->getInt('submit_delay') : null,
|
|
object_name: $version->getFilename()
|
|
);
|
|
|
|
$this->chillLogger->notice('[Privacy Event] a request to upload a document has been generated', [
|
|
'doc_uuid' => $storedObject->getUuid(),
|
|
]);
|
|
|
|
return new JsonResponse(
|
|
$this->serializer->serialize($p, 'json', [AbstractNormalizer::GROUPS => ['read']]),
|
|
Response::HTTP_OK,
|
|
[],
|
|
true
|
|
);
|
|
}
|
|
|
|
#[Route(path: '/api/1.0/doc-store/async-upload/temp_url/{uuid}/generate/{method}', name: 'chill_docstore_asyncupload_getsignedurlget', requirements: ['method' => 'get|head'])]
|
|
public function getSignedUrlGet(Request $request, StoredObject $storedObject, string $method): JsonResponse
|
|
{
|
|
if (!$this->security->isGranted(StoredObjectRoleEnum::SEE->value, $storedObject)) {
|
|
throw new AccessDeniedHttpException('not able to read the given stored object');
|
|
}
|
|
|
|
// we really want to be sure that there are no other method than get or head:
|
|
if (!in_array($method, ['get', 'head'], true)) {
|
|
throw new AccessDeniedHttpException('Only methods get and head are allowed');
|
|
}
|
|
|
|
if ($request->query->has('version')) {
|
|
$filename = $request->query->get('version');
|
|
|
|
$storedObjectVersion = $storedObject->getVersions()->findFirst(fn (int $index, StoredObjectVersion $version): bool => $version->getFilename() === $filename);
|
|
|
|
if (null === $storedObjectVersion) {
|
|
// we are here in the case where the version is not stored into the database
|
|
// as the version is prefixed by the stored object prefix, we just have to check that this prefix
|
|
// is the same. It means that the user had previously the permission to "SEE_AND_EDIT" this stored
|
|
// object with same prefix that we checked before
|
|
if (!str_starts_with($filename, $storedObject->getPrefix())) {
|
|
throw new AccessDeniedHttpException('not able to match the version with the same filename');
|
|
}
|
|
}
|
|
} else {
|
|
$filename = $storedObject->getCurrentVersion()->getFilename();
|
|
}
|
|
|
|
$p = $this->tempUrlGenerator->generate(
|
|
$method,
|
|
$filename,
|
|
$request->query->has('expires_delay') ? $request->query->getInt('expires_delay') : null
|
|
);
|
|
|
|
$user = $this->security->getUser();
|
|
$userId = match ($user instanceof User) {
|
|
true => $user->getId(),
|
|
false => $user->getUserIdentifier(),
|
|
};
|
|
|
|
$this->chillLogger->notice('[Privacy Event] a request to see a document has been granted', [
|
|
'doc_uuid' => $storedObject->getUuid()->toString(),
|
|
'user_id' => $userId,
|
|
]);
|
|
|
|
return new JsonResponse(
|
|
$this->serializer->serialize($p, 'json', [AbstractNormalizer::GROUPS => ['read']]),
|
|
Response::HTTP_OK,
|
|
[],
|
|
true
|
|
);
|
|
}
|
|
}
|