store encrypted content

This commit is contained in:
Julien Fastré 2024-12-20 21:23:02 +01:00
parent c65f1d495d
commit 0c628c39db
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
4 changed files with 104 additions and 16 deletions

View File

@ -31,7 +31,7 @@ class StoredObjectManager implements StoredObjectManagerInterface
ParameterBagInterface $parameterBag,
private readonly KeyGenerator $keyGenerator,
) {
$this->baseDir = $parameterBag->get('chill_doc_store')['local_storage']['base_dir'];
$this->baseDir = $parameterBag->get('chill_doc_store')['local_storage']['storage_path'];
$this->filesystem = new Filesystem();
}
@ -65,9 +65,7 @@ class StoredObjectManager implements StoredObjectManagerInterface
return false;
}
$path = $this->buildPath($version->getFilename());
return $this->filesystem->exists($path);
return $this->existsContent($version->getFilename());
}
public function read(StoredObject|StoredObjectVersion $document): string
@ -78,15 +76,7 @@ class StoredObjectManager implements StoredObjectManagerInterface
throw StoredObjectManagerException::storedObjectDoesNotContainsVersion();
}
$path = $this->buildPath($version->getFilename());
if (!file_exists($path)) {
throw StoredObjectManagerException::unableToFindDocumentOnDisk($path);
}
if (false === $content = file_get_contents($path)) {
throw StoredObjectManagerException::unableToReadDocumentOnDisk($path);
}
$content = $this->readContent($version->getFilename());
if (!$this->isVersionEncrypted($version)) {
return $content;
@ -134,7 +124,29 @@ class StoredObjectManager implements StoredObjectManagerInterface
throw StoredObjectManagerException::unableToEncryptDocument((string) openssl_error_string());
}
$fullPath = $this->buildPath($version->getFilename());
$this->writeContent($version->getFilename(), $encryptedContent);
return $version;
}
public function readContent(string $filename): string
{
$path = $this->buildPath($filename);
if (!file_exists($path)) {
throw StoredObjectManagerException::unableToFindDocumentOnDisk($path);
}
if (false === $content = file_get_contents($path)) {
throw StoredObjectManagerException::unableToReadDocumentOnDisk($path);
}
return $content;
}
public function writeContent(string $filename, string $encryptedContent): void
{
$fullPath = $this->buildPath($filename);
$dir = Path::getDirectory($fullPath);
if (!$this->filesystem->exists($dir)) {
@ -146,8 +158,13 @@ class StoredObjectManager implements StoredObjectManagerInterface
if (false === $result) {
throw StoredObjectManagerException::unableToStoreDocumentOnDisk();
}
}
return $version;
public function existsContent(string $filename): bool
{
$path = $this->buildPath($filename);
return $this->filesystem->exists($path);
}
private function buildPath(string $filename): string

View File

@ -0,0 +1,69 @@
<?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\Driver\LocalStorage\StoredObjectManager;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
/**
* Controller to deal with local storage operation.
*/
final readonly class StoredObjectContentToLocalStorageController
{
public function __construct(
private StoredObjectManager $storedObjectManager,
) {}
#[Route('/public/stored-object/post', name: 'chill_docstore_storedobject_post', methods: ['POST'])]
public function postContent(Request $request): Response
{
$prefix = $request->query->get('prefix', '');
if ('' === $prefix) {
throw new BadRequestHttpException('prefix parameter is missing');
}
$keyFiles = $request->files->keys();
foreach ($keyFiles as $keyFile) {
/** @var UploadedFile $file */
$file = $request->files->get($keyFile);
$this->storedObjectManager->writeContent($keyFile, $file->getContent());
}
return new Response(status: Response::HTTP_NO_CONTENT);
}
#[Route('/public/stored-object/operate', name: 'chill_docstore_stored_object_operate', methods: ['GET', 'HEAD'])]
public function contentOperate(Request $request): Response
{
$objectName = $request->query->get('object_name', '');
if ('' === $objectName) {
throw new BadRequestHttpException('object name parameter is missing');
}
if (!$this->storedObjectManager->existsContent($objectName)) {
throw new NotFoundHttpException('object does not exists on disk');
}
return match ($request->getMethod()) {
'GET' => new Response($this->storedObjectManager->readContent($objectName)),
'HEAD' => new Response(''),
};
}
}

View File

@ -15,6 +15,7 @@ use Chill\DocStoreBundle\AsyncUpload\Driver\LocalStorage\TempUrlLocalStorageGene
use Chill\DocStoreBundle\AsyncUpload\Driver\OpenstackObjectStore\ConfigureOpenstackObjectStorageCommand;
use Chill\DocStoreBundle\AsyncUpload\Driver\OpenstackObjectStore\TempUrlOpenstackGenerator;
use Chill\DocStoreBundle\AsyncUpload\TempUrlGeneratorInterface;
use Chill\DocStoreBundle\Controller\StoredObjectContentToLocalStorageController;
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
@ -31,6 +32,7 @@ class StorageConfigurationCompilerPass implements CompilerPassInterface
private const SERVICES_LOCAL_STORAGE = [
\Chill\DocStoreBundle\AsyncUpload\Driver\LocalStorage\StoredObjectManager::class,
TempUrlLocalStorageGenerator::class,
StoredObjectContentToLocalStorageController::class,
];
public function process(ContainerBuilder $container)

View File

@ -153,7 +153,7 @@ class StoredObjectManagerTest extends TestCase
private function buildStoredObjectManager(): StoredObjectManager
{
return new StoredObjectManager(
new ParameterBag(['chill_doc_store' => ['local_storage' => ['base_dir' => '/tmp/chill-local-storage-test']]]),
new ParameterBag(['chill_doc_store' => ['local_storage' => ['storage_path' => '/tmp/chill-local-storage-test']]]),
new KeyGenerator(),
);
}