From 2278816a088592fa1ad339d50d2a7ee72ef498b2 Mon Sep 17 00:00:00 2001 From: Tobias Gross-Vogt Date: Wed, 2 Oct 2024 09:09:22 +0200 Subject: [PATCH] add ROLE_USER policy for authorization --- CHANGELOG.md | 2 ++ src/Authorization/AuthorizationService.php | 14 ++++++++++++++ src/DependencyInjection/Configuration.php | 9 +++++++-- ...pRelayBlobConnectorCampusonlineDmsExtension.php | 4 ++++ src/Entity/Document.php | 4 +++- src/Rest/CreateDocumentController.php | 1 + src/Rest/CreateDocumentVersionController.php | 1 + src/Rest/DocumentProvider.php | 13 +++++++++---- src/Rest/DocumentVersionInfoProvider.php | 12 ++++++------ src/Rest/FileProcessor.php | 13 +++++++++---- src/Rest/FileProvider.php | 13 +++++++++---- src/Rest/GetDocumentVersionContentController.php | 5 ++++- 12 files changed, 69 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96a62e0..2ad029a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Add ROLE_USER policy to configure who is granted access to the API + ## v0.1.2 * Integrate Blob File API diff --git a/src/Authorization/AuthorizationService.php b/src/Authorization/AuthorizationService.php index 0965d52..6954081 100644 --- a/src/Authorization/AuthorizationService.php +++ b/src/Authorization/AuthorizationService.php @@ -4,8 +4,22 @@ namespace Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Authorization; +use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\DependencyInjection\Configuration; use Dbp\Relay\CoreBundle\Authorization\AbstractAuthorizationService; +use Dbp\Relay\CoreBundle\Exception\ApiError; +use Symfony\Component\HttpFoundation\Response; class AuthorizationService extends AbstractAuthorizationService { + public function denyAccessUnlessHasRoleUser(): void + { + if (!$this->hasRoleUser()) { + throw ApiError::withDetails(Response::HTTP_FORBIDDEN); + } + } + + public function hasRoleUser(): bool + { + return $this->isGranted(Configuration::ROLE_USER); + } } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index e172f38..18b20e0 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -4,16 +4,21 @@ namespace Dbp\Relay\BlobConnectorCampusonlineDmsBundle\DependencyInjection; +use Dbp\Relay\CoreBundle\Authorization\AuthorizationConfigDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; class Configuration implements ConfigurationInterface { + public const ROLE_USER = 'ROLE_USER'; + public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('dbp_relay_blob_connector_campusonline_dms'); - - // append your config definition here + $treeBuilder->getRootNode() + ->append(AuthorizationConfigDefinition::create() + ->addPolicy(self::ROLE_USER, 'false', 'Returns true if the current user is authorized to use the API') + ->getNodeDefinition()); return $treeBuilder; } diff --git a/src/DependencyInjection/DbpRelayBlobConnectorCampusonlineDmsExtension.php b/src/DependencyInjection/DbpRelayBlobConnectorCampusonlineDmsExtension.php index 35964c9..b821cbd 100644 --- a/src/DependencyInjection/DbpRelayBlobConnectorCampusonlineDmsExtension.php +++ b/src/DependencyInjection/DbpRelayBlobConnectorCampusonlineDmsExtension.php @@ -4,6 +4,7 @@ namespace Dbp\Relay\BlobConnectorCampusonlineDmsBundle\DependencyInjection; +use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Authorization\AuthorizationService; use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Service\DocumentService; use Dbp\Relay\CoreBundle\Extension\ExtensionTrait; use Symfony\Component\Config\FileLocator; @@ -27,5 +28,8 @@ public function loadInternal(array $mergedConfig, ContainerBuilder $container): $definition = $container->getDefinition(DocumentService::class); $definition->addMethodCall('setConfig', [$mergedConfig]); + + $definition = $container->getDefinition(AuthorizationService::class); + $definition->addMethodCall('setConfig', [$mergedConfig]); } } diff --git a/src/Entity/Document.php b/src/Entity/Document.php index 87243eb..ab9a99f 100644 --- a/src/Entity/Document.php +++ b/src/Entity/Document.php @@ -30,7 +30,7 @@ provider: DocumentProvider::class ), new Get( - uriTemplate: '/co-dp-dms-adapter-d3/api/version/{uid}', + uriTemplate: '/co-dp-dms-adapter-d3/api/documents/version/{uid}', outputFormats: [ 'octet_stream' => 'application/octet-stream', 'jsonproblem' => 'application/problem+json', @@ -38,6 +38,7 @@ controller: GetDocumentVersionContentController::class, openapiContext: [ 'tags' => ['Campusonline DMS'], + 'summary' => 'Retrieves the file content for a BlobConnectorCampusonlineDmsDocumentVersionInfo resource', 'responses' => [ '200' => [ 'content' => [ @@ -122,6 +123,7 @@ controller: CreateDocumentVersionController::class, openapiContext: [ 'tags' => ['Campusonline DMS'], + 'summary' => 'Creates a new version for a BlobConnectorCampusonlineDmsDocument resource', 'requestBody' => [ 'content' => [ 'application/octet-stream' => [ diff --git a/src/Rest/CreateDocumentController.php b/src/Rest/CreateDocumentController.php index 53097b9..91f7302 100644 --- a/src/Rest/CreateDocumentController.php +++ b/src/Rest/CreateDocumentController.php @@ -26,6 +26,7 @@ public function __construct( public function __invoke(Request $request): Document { $this->requireAuthentication(); + $this->authorizationService->denyAccessUnlessHasRoleUser(); $name = $request->request->get('name'); // TODO: validate name $documentType = $request->request->get('documentType'); // TODO: validate document type diff --git a/src/Rest/CreateDocumentVersionController.php b/src/Rest/CreateDocumentVersionController.php index 84f044b..9b66585 100644 --- a/src/Rest/CreateDocumentVersionController.php +++ b/src/Rest/CreateDocumentVersionController.php @@ -24,6 +24,7 @@ public function __construct( public function __invoke(Request $request, string $uid): ?Document { $this->requireAuthentication(); + $this->authorizationService->denyAccessUnlessHasRoleUser(); $uploadedFile = $request->files->get('content'); // TODO: validate uploaded file diff --git a/src/Rest/DocumentProvider.php b/src/Rest/DocumentProvider.php index 43bc895..5980f86 100644 --- a/src/Rest/DocumentProvider.php +++ b/src/Rest/DocumentProvider.php @@ -4,6 +4,7 @@ namespace Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Rest; +use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Authorization\AuthorizationService; use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Entity\Document; use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Service\DocumentService; use Dbp\Relay\CoreBundle\Rest\AbstractDataProvider; @@ -15,11 +16,10 @@ class DocumentProvider extends AbstractDataProvider { protected static string $identifierName = 'uid'; - private DocumentService $documentService; - - public function __construct(DocumentService $placeService) + public function __construct( + private readonly DocumentService $documentService, + private readonly AuthorizationService $authorizationService) { - $this->documentService = $placeService; } protected function getItemById(string $id, array $filters = [], array $options = []): ?Document @@ -31,4 +31,9 @@ protected function getPage(int $currentPageNumber, int $maxNumItemsPerPage, arra { throw new \RuntimeException('not available'); } + + protected function isCurrentUserGrantedOperationAccess(int $operation): bool + { + return $this->authorizationService->hasRoleUser(); + } } diff --git a/src/Rest/DocumentVersionInfoProvider.php b/src/Rest/DocumentVersionInfoProvider.php index 21952fa..29678e9 100644 --- a/src/Rest/DocumentVersionInfoProvider.php +++ b/src/Rest/DocumentVersionInfoProvider.php @@ -4,6 +4,7 @@ namespace Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Rest; +use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Authorization\AuthorizationService; use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Entity\DocumentVersionInfo; use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Service\DocumentService; use Dbp\Relay\CoreBundle\Rest\AbstractDataProvider; @@ -15,11 +16,10 @@ class DocumentVersionInfoProvider extends AbstractDataProvider { protected static string $identifierName = 'uid'; - private DocumentService $documentService; - - public function __construct(DocumentService $placeService) + public function __construct( + private readonly DocumentService $documentService, + private readonly AuthorizationService $authorizationService) { - $this->documentService = $placeService; } protected function getItemById(string $id, array $filters = [], array $options = []): ?DocumentVersionInfo @@ -32,8 +32,8 @@ protected function getPage(int $currentPageNumber, int $maxNumItemsPerPage, arra throw new \RuntimeException('not available'); } - protected function isUserGrantedOperationAccess(int $operation): bool + protected function isCurrentUserGrantedOperationAccess(int $operation): bool { - return $this->isAuthenticated(); + return $this->authorizationService->hasRoleUser(); } } diff --git a/src/Rest/FileProcessor.php b/src/Rest/FileProcessor.php index 216d8d6..01ef2c6 100644 --- a/src/Rest/FileProcessor.php +++ b/src/Rest/FileProcessor.php @@ -4,6 +4,7 @@ namespace Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Rest; +use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Authorization\AuthorizationService; use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Entity\File; use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Service\DocumentService; use Dbp\Relay\CoreBundle\Rest\AbstractDataProcessor; @@ -12,11 +13,10 @@ class FileProcessor extends AbstractDataProcessor { protected static string $identifierName = 'uid'; - private DocumentService $documentService; - - public function __construct(DocumentService $placeService) + public function __construct( + private readonly DocumentService $documentService, + private readonly AuthorizationService $authorizationService) { - $this->documentService = $placeService; } protected function addItem(mixed $data, array $filters): File @@ -32,4 +32,9 @@ protected function replaceItem(mixed $identifier, mixed $data, mixed $previousDa return $this->documentService->replaceFile($identifier, $data); } + + protected function isCurrentUserGrantedOperationAccess(int $operation): bool + { + return $this->authorizationService->hasRoleUser(); + } } diff --git a/src/Rest/FileProvider.php b/src/Rest/FileProvider.php index 5501f24..ebe0907 100644 --- a/src/Rest/FileProvider.php +++ b/src/Rest/FileProvider.php @@ -4,6 +4,7 @@ namespace Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Rest; +use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Authorization\AuthorizationService; use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Entity\File; use Dbp\Relay\BlobConnectorCampusonlineDmsBundle\Service\DocumentService; use Dbp\Relay\CoreBundle\Rest\AbstractDataProvider; @@ -15,11 +16,10 @@ class FileProvider extends AbstractDataProvider { protected static string $identifierName = 'uid'; - private DocumentService $documentService; - - public function __construct(DocumentService $placeService) + public function __construct( + private readonly DocumentService $documentService, + private readonly AuthorizationService $authorizationService) { - $this->documentService = $placeService; } protected function getItemById(string $id, array $filters = [], array $options = []): ?File @@ -31,4 +31,9 @@ protected function getPage(int $currentPageNumber, int $maxNumItemsPerPage, arra { throw new \RuntimeException('not available'); } + + protected function isCurrentUserGrantedOperationAccess(int $operation): bool + { + return $this->authorizationService->hasRoleUser(); + } } diff --git a/src/Rest/GetDocumentVersionContentController.php b/src/Rest/GetDocumentVersionContentController.php index 804c29c..76886b2 100644 --- a/src/Rest/GetDocumentVersionContentController.php +++ b/src/Rest/GetDocumentVersionContentController.php @@ -21,11 +21,14 @@ public function __construct( { } + /** + * @throws \Exception + */ public function __invoke(Request $request, string $uid): Response { $this->requireAuthentication(); + $this->authorizationService->denyAccessUnlessHasRoleUser(); - // TODO: get blob file with given version and return its content return $this->documentService->getDocumentVersionBinaryFileResponse($uid); } }