mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-01 20:43:49 +00:00
Refactor backend for getting signed url
This commit is contained in:
@@ -15,7 +15,7 @@ use Chill\DocStoreBundle\AsyncUpload\SignedUrl;
|
||||
use Chill\DocStoreBundle\AsyncUpload\SignedUrlPost;
|
||||
use Chill\DocStoreBundle\AsyncUpload\TempUrlGeneratorInterface;
|
||||
use Chill\DocStoreBundle\Controller\AsyncUploadController;
|
||||
use Chill\DocStoreBundle\Security\Authorization\AsyncUploadVoter;
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
@@ -34,46 +34,165 @@ class AsyncUploadControllerTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
public function testGenerateWhenUserIsNotGranted(): void
|
||||
public function testGetSignedUrlPost(): void
|
||||
{
|
||||
$this->expectException(AccessDeniedHttpException::class);
|
||||
$controller = $this->buildAsyncUploadController(false);
|
||||
$storedObject = new StoredObject();
|
||||
$security = $this->prophesize(Security::class);
|
||||
$security->isGranted('SEE_AND_EDIT', $storedObject)->willReturn(true)->shouldBeCalled();
|
||||
|
||||
$controller->getSignedUrl('POST', new Request());
|
||||
}
|
||||
$controller = new AsyncUploadController(
|
||||
$this->buildTempUrlGenerator(),
|
||||
$this->buildSerializer(),
|
||||
$security->reveal(),
|
||||
new NullLogger(),
|
||||
);
|
||||
|
||||
public function testGeneratePost(): void
|
||||
{
|
||||
$controller = $this->buildAsyncUploadController(true);
|
||||
$actual = $controller->getSignedUrlPost(new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800]), $storedObject);
|
||||
|
||||
$actual = $controller->getSignedUrl('POST', new Request());
|
||||
$decodedActual = json_decode($actual->getContent(), true, JSON_THROW_ON_ERROR, JSON_THROW_ON_ERROR);
|
||||
|
||||
self::assertArrayHasKey('method', $decodedActual);
|
||||
self::assertEquals('POST', $decodedActual['method']);
|
||||
}
|
||||
|
||||
public function testGenerateGet(): void
|
||||
public function testGetSignedUrlGetSimpleScenarioHappy(): void
|
||||
{
|
||||
$controller = $this->buildAsyncUploadController(true);
|
||||
$storedObject = new StoredObject();
|
||||
$storedObject->registerVersion();
|
||||
$security = $this->prophesize(Security::class);
|
||||
$security->isGranted('SEE', $storedObject)->willReturn(true)->shouldBeCalled();
|
||||
|
||||
$controller = new AsyncUploadController(
|
||||
$this->buildTempUrlGenerator(),
|
||||
$this->buildSerializer(),
|
||||
$security->reveal(),
|
||||
new NullLogger(),
|
||||
);
|
||||
|
||||
$actual = $controller->getSignedUrlGet(new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800]), $storedObject, 'get');
|
||||
|
||||
$actual = $controller->getSignedUrl('GET', new Request(['object_name' => 'abc']));
|
||||
$decodedActual = json_decode($actual->getContent(), true, JSON_THROW_ON_ERROR, JSON_THROW_ON_ERROR);
|
||||
|
||||
self::assertArrayHasKey('method', $decodedActual);
|
||||
self::assertEquals('GET', $decodedActual['method']);
|
||||
}
|
||||
|
||||
private function buildAsyncUploadController(
|
||||
bool $isGranted,
|
||||
): AsyncUploadController {
|
||||
$tempUrlGenerator = new class () implements TempUrlGeneratorInterface {
|
||||
public function generatePost(?int $expire_delay = null, ?int $submit_delay = null, int $max_file_count = 1): SignedUrlPost
|
||||
public function testGetSignedUrlGetSimpleScenarioNotAuthorized(): void
|
||||
{
|
||||
$this->expectException(AccessDeniedHttpException::class);
|
||||
|
||||
$storedObject = new StoredObject();
|
||||
$storedObject->registerVersion();
|
||||
$security = $this->prophesize(Security::class);
|
||||
$security->isGranted('SEE', $storedObject)->willReturn(false)->shouldBeCalled();
|
||||
|
||||
$controller = new AsyncUploadController(
|
||||
$this->buildTempUrlGenerator(),
|
||||
$this->buildSerializer(),
|
||||
$security->reveal(),
|
||||
new NullLogger(),
|
||||
);
|
||||
|
||||
$controller->getSignedUrlGet(new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800]), $storedObject, 'get');
|
||||
}
|
||||
|
||||
public function testGetSignedUrlGetForSpecificVersionOfTheStoredObjectStoredInDatabase(): void
|
||||
{
|
||||
$storedObject = new StoredObject();
|
||||
$version = $storedObject->registerVersion();
|
||||
// we add a version to be sure that the we do not get the last one
|
||||
$storedObject->registerVersion();
|
||||
|
||||
$security = $this->prophesize(Security::class);
|
||||
$security->isGranted('SEE', $storedObject)->willReturn(true)->shouldBeCalled();
|
||||
|
||||
$controller = new AsyncUploadController(
|
||||
$this->buildTempUrlGenerator(),
|
||||
$this->buildSerializer(),
|
||||
$security->reveal(),
|
||||
new NullLogger(),
|
||||
);
|
||||
|
||||
$actual = $controller->getSignedUrlGet(
|
||||
new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800, 'version' => $version->getFilename()]),
|
||||
$storedObject,
|
||||
'get'
|
||||
);
|
||||
|
||||
$decodedActual = json_decode($actual->getContent(), true, JSON_THROW_ON_ERROR, JSON_THROW_ON_ERROR);
|
||||
|
||||
self::assertArrayHasKey('method', $decodedActual);
|
||||
self::assertEquals('GET', $decodedActual['method']);
|
||||
self::assertArrayHasKey('object_name', $decodedActual);
|
||||
self::assertEquals($version->getFilename(), $decodedActual['object_name']);
|
||||
}
|
||||
|
||||
public function testGetSignedUrlGetForSpecificVersionOfTheStoredObjectNotYetStoredInDatabase(): void
|
||||
{
|
||||
$storedObject = new StoredObject();
|
||||
$storedObject->registerVersion();
|
||||
// we generate a valid name
|
||||
$version = $storedObject->getPrefix().'/some-version';
|
||||
|
||||
$security = $this->prophesize(Security::class);
|
||||
$security->isGranted('SEE', $storedObject)->willReturn(true)->shouldBeCalled();
|
||||
|
||||
$controller = new AsyncUploadController(
|
||||
$this->buildTempUrlGenerator(),
|
||||
$this->buildSerializer(),
|
||||
$security->reveal(),
|
||||
new NullLogger(),
|
||||
);
|
||||
|
||||
$actual = $controller->getSignedUrlGet(
|
||||
new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800, 'version' => $version]),
|
||||
$storedObject,
|
||||
'get'
|
||||
);
|
||||
|
||||
$decodedActual = json_decode($actual->getContent(), true, JSON_THROW_ON_ERROR, JSON_THROW_ON_ERROR);
|
||||
|
||||
self::assertArrayHasKey('method', $decodedActual);
|
||||
self::assertEquals('GET', $decodedActual['method']);
|
||||
self::assertArrayHasKey('object_name', $decodedActual);
|
||||
self::assertEquals($version, $decodedActual['object_name']);
|
||||
}
|
||||
|
||||
public function testGetSignedUrlGetForSpecificVersionNotBelongingToTheStoreObject(): void
|
||||
{
|
||||
$this->expectException(AccessDeniedHttpException::class);
|
||||
|
||||
$storedObject = new StoredObject();
|
||||
$storedObject->registerVersion();
|
||||
// we generate a random version
|
||||
$version = 'something/else';
|
||||
|
||||
$security = $this->prophesize(Security::class);
|
||||
$security->isGranted('SEE', $storedObject)->willReturn(true)->shouldBeCalled();
|
||||
|
||||
$controller = new AsyncUploadController(
|
||||
$this->buildTempUrlGenerator(),
|
||||
$this->buildSerializer(),
|
||||
$security->reveal(),
|
||||
new NullLogger(),
|
||||
);
|
||||
|
||||
$controller->getSignedUrlGet(
|
||||
new Request(query: ['expires_delay' => 10, 'submit_delay' => 1800, 'version' => $version]),
|
||||
$storedObject,
|
||||
'get'
|
||||
);
|
||||
}
|
||||
|
||||
public function buildTempUrlGenerator(): TempUrlGeneratorInterface
|
||||
{
|
||||
return new class () implements TempUrlGeneratorInterface {
|
||||
public function generatePost(?int $expire_delay = null, ?int $submit_delay = null, int $max_file_count = 1, ?string $object_name = null): SignedUrlPost
|
||||
{
|
||||
return new SignedUrlPost(
|
||||
'https://object.store.example',
|
||||
new \DateTimeImmutable('1 hour'),
|
||||
'abc',
|
||||
$object_name ?? 'abc',
|
||||
150,
|
||||
1,
|
||||
1800,
|
||||
@@ -86,27 +205,25 @@ class AsyncUploadControllerTest extends TestCase
|
||||
public function generate(string $method, string $object_name, ?int $expire_delay = null): SignedUrl
|
||||
{
|
||||
return new SignedUrl(
|
||||
$method,
|
||||
strtoupper($method),
|
||||
'https://object.store.example',
|
||||
new \DateTimeImmutable('1 hour'),
|
||||
$object_name
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private function buildSerializer(): SerializerInterface
|
||||
{
|
||||
$serializer = $this->prophesize(SerializerInterface::class);
|
||||
$serializer->serialize(Argument::type(SignedUrl::class), 'json', Argument::type('array'))
|
||||
->will(fn (array $args): string => json_encode(['method' => $args[0]->method], JSON_THROW_ON_ERROR, 3));
|
||||
->will(fn (array $args): string => json_encode(
|
||||
['method' => $args[0]->method, 'object_name' => $args[0]->object_name],
|
||||
JSON_THROW_ON_ERROR,
|
||||
3
|
||||
));
|
||||
|
||||
$security = $this->prophesize(Security::class);
|
||||
$security->isGranted(AsyncUploadVoter::GENERATE_SIGNATURE, Argument::type(SignedUrl::class))
|
||||
->willReturn($isGranted);
|
||||
|
||||
return new AsyncUploadController(
|
||||
$tempUrlGenerator,
|
||||
$serializer->reveal(),
|
||||
$security->reveal(),
|
||||
new NullLogger()
|
||||
);
|
||||
return $serializer->reveal();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user