Implement StoredObject permissions in AsyncUploadVoter.php

This commit is contained in:
Julie Lenaerts 2024-07-02 15:35:41 +02:00
parent a9f4f8c973
commit 3262a1dd02
9 changed files with 21 additions and 14 deletions

View File

@ -127,7 +127,7 @@ final readonly class TempUrlOpenstackGenerator implements TempUrlGeneratorInterf
];
$url = $url.'?'.\http_build_query($args);
$signature = new SignedUrl(strtoupper($method), $url, $expires);
$signature = new SignedUrl(strtoupper($method), $url, $expires, $object_name);
$this->event_dispatcher->dispatch(
new TempUrlGenerateEvent($signature)

View File

@ -21,6 +21,7 @@ readonly class SignedUrl
#[Serializer\Groups(['read'])]
public string $url,
public \DateTimeImmutable $expires,
public string $object_name,
) {}
#[Serializer\Groups(['read'])]

View File

@ -12,6 +12,8 @@ declare(strict_types=1);
namespace Chill\DocStoreBundle\Security\Authorization;
use Chill\DocStoreBundle\AsyncUpload\SignedUrl;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Repository\StoredObjectRepository;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
@ -22,6 +24,7 @@ final class AsyncUploadVoter extends Voter
public function __construct(
private readonly Security $security,
private readonly StoredObjectRepository $storedObjectRepository
) {}
protected function supports($attribute, $subject): bool
@ -36,13 +39,12 @@ final class AsyncUploadVoter extends Voter
return false;
}
//TODO get the StoredObject from the SignedUrl
/* match($subject->method) {
'GET' => $this->security->isGranted('SEE', $storedObject),
'PUT' => $this->security->isGranted('EDIT', $storedObject),
'POST' => $this->security->isGranted('ROLE_USER') || $this->security->isGranted('ROLE_ADMIN')
};*/
$storedObject = $this->storedObjectRepository->findOneBy(['filename' => $subject->object_name]);
return $this->security->isGranted('ROLE_USER') || $this->security->isGranted('ROLE_ADMIN');
return match($subject->method) {
'GET' => $this->security->isGranted(StoredObjectRoleEnum::SEE->value, $storedObject),
'PUT' => $this->security->isGranted(StoredObjectRoleEnum::EDIT->value, $storedObject),
default => $this->security->isGranted('ROLE_USER') || $this->security->isGranted('ROLE_ADMIN')
};
}
}

View File

@ -122,7 +122,8 @@ class TempUrlOpenstackGeneratorTest extends TestCase
$signedUrl = new SignedUrl(
'GET',
'https://objectstore.example/v1/my_account/container/object?temp_url_sig=0aeef353a5f6e22d125c76c6ad8c644a59b222ba1b13eaeb56bf3d04e28b081d11dfcb36601ab3aa7b623d79e1ef03017071bbc842fb7b34afec2baff895bf80&temp_url_expires=1702043543',
\DateTimeImmutable::createFromFormat('U', '1702043543')
\DateTimeImmutable::createFromFormat('U', '1702043543'),
$objectName
);
foreach ($baseUrls as $baseUrl) {

View File

@ -35,7 +35,7 @@ class AsyncUploadExtensionTest extends KernelTestCase
{
$generator = $this->prophesize(TempUrlGeneratorInterface::class);
$generator->generate(Argument::in(['GET', 'POST']), Argument::type('string'), Argument::any())
->will(fn (array $args): SignedUrl => new SignedUrl($args[0], 'https://object.store.example/container/'.$args[1], new \DateTimeImmutable('1 hours')));
->will(fn (array $args): SignedUrl => new SignedUrl($args[0], 'https://object.store.example/container/'.$args[1], new \DateTimeImmutable('1 hours'), $args[1]));
$urlGenerator = $this->prophesize(UrlGeneratorInterface::class);
$urlGenerator->generate('async_upload.generate_url', Argument::type('array'))

View File

@ -87,7 +87,8 @@ class AsyncUploadControllerTest extends TestCase
return new SignedUrl(
$method,
'https://object.store.example',
new \DateTimeImmutable('1 hour')
new \DateTimeImmutable('1 hour'),
$object_name
);
}
};

View File

@ -38,7 +38,8 @@ class SignedUrlNormalizerTest extends KernelTestCase
$signedUrl = new SignedUrl(
'GET',
'https://object.store.example/container/object',
\DateTimeImmutable::createFromFormat('U', '1700000')
\DateTimeImmutable::createFromFormat('U', '1700000'),
'object'
);
$actual = self::$normalizer->normalize($signedUrl, 'json', [AbstractNormalizer::GROUPS => ['read']]);

View File

@ -202,7 +202,8 @@ final class StoredObjectManagerTest extends TestCase
$response = new SignedUrl(
'PUT',
'https://example.com/'.$storedObject->getFilename(),
new \DateTimeImmutable('1 hours')
new \DateTimeImmutable('1 hours'),
$storedObject->getFilename()
);
$tempUrlGenerator = $this->createMock(TempUrlGeneratorInterface::class);

View File

@ -43,7 +43,7 @@ class AsyncFileExistsValidatorTest extends ConstraintValidatorTestCase
$generator = $this->prophesize(TempUrlGeneratorInterface::class);
$generator->generate(Argument::in(['GET', 'HEAD']), Argument::type('string'), Argument::any())
->will(fn (array $args): SignedUrl => new SignedUrl($args[0], 'https://object.store.example/container/'.$args[1], new \DateTimeImmutable('1 hours')));
->will(fn (array $args): SignedUrl => new SignedUrl($args[0], 'https://object.store.example/container/'.$args[1], new \DateTimeImmutable('1 hours'), $args[1]));
return new AsyncFileExistsValidator($generator->reveal(), $client);
}