diff --git a/src/Http/Controllers/Api/ApiFilterAutocompleteController.php b/src/Http/Controllers/Api/ApiFilterAutocompleteController.php index 1322c0326..d74eecc6e 100644 --- a/src/Http/Controllers/Api/ApiFilterAutocompleteController.php +++ b/src/Http/Controllers/Api/ApiFilterAutocompleteController.php @@ -11,6 +11,8 @@ class ApiFilterAutocompleteController extends Controller { public function index(string $globalFilter, EntityKey $entityKey, string $filterHandlerKey): array { + $this->authorizationManager->check('entity', $entityKey); + $entity = $this->entityManager->entityFor($entityKey); if ($entity instanceof SharpDashboardEntity) { diff --git a/src/Http/Controllers/Api/ApiFormAutocompleteController.php b/src/Http/Controllers/Api/ApiFormAutocompleteController.php index 17ad9b99c..2ddf98a38 100644 --- a/src/Http/Controllers/Api/ApiFormAutocompleteController.php +++ b/src/Http/Controllers/Api/ApiFormAutocompleteController.php @@ -16,7 +16,7 @@ class ApiFormAutocompleteController extends Controller public function index(string $globalFilter, EntityKey $entityKey, string $autocompleteFieldKey) { - $fieldContainer = $this->getFieldContainer($entityKey); + $fieldContainer = $this->getFieldContainer($entityKey, isUpdate: false); $field = $fieldContainer->findFieldByKey($autocompleteFieldKey); if ($field === null) { diff --git a/src/Http/Controllers/Api/ApiFormRefreshController.php b/src/Http/Controllers/Api/ApiFormRefreshController.php index f06eb0664..b9ab7f3ea 100644 --- a/src/Http/Controllers/Api/ApiFormRefreshController.php +++ b/src/Http/Controllers/Api/ApiFormRefreshController.php @@ -11,7 +11,7 @@ class ApiFormRefreshController extends Controller public function update(string $globalFilter, EntityKey $entityKey) { - $fieldContainer = $this->getFieldContainer($entityKey); + $fieldContainer = $this->getFieldContainer($entityKey, isUpdate: false); return response()->json([ 'form' => [ diff --git a/src/Http/Controllers/Api/ApiFormUploadController.php b/src/Http/Controllers/Api/ApiFormUploadController.php index c60c8d4e0..5cd973d5c 100644 --- a/src/Http/Controllers/Api/ApiFormUploadController.php +++ b/src/Http/Controllers/Api/ApiFormUploadController.php @@ -16,8 +16,9 @@ class ApiFormUploadController extends Controller public function store(string $globalFilter, EntityKey $entityKey, string $uploadFieldKey, FileUtil $fileUtil) { - $field = $this->getFieldContainer($entityKey) - ->findFieldByKey($uploadFieldKey); + $container = $this->getFieldContainer($entityKey, isUpdate: true); + + $field = $container->findFieldByKey($uploadFieldKey); if ($field instanceof SharpFormEditorField) { $field = $field->uploadsConfig(); diff --git a/src/Http/Controllers/Api/Commands/ApiDashboardCommandController.php b/src/Http/Controllers/Api/Commands/ApiDashboardCommandController.php index 244a4c4f1..b9f0ab480 100644 --- a/src/Http/Controllers/Api/Commands/ApiDashboardCommandController.php +++ b/src/Http/Controllers/Api/Commands/ApiDashboardCommandController.php @@ -20,6 +20,8 @@ public function __construct( public function show(string $globalFilter, string $entityKey, string $commandKey) { + $this->authorizationManager->check('entity', $entityKey); + $dashboard = $this->entityManager->entityFor($entityKey)->getViewOrFail(); $dashboard->buildDashboardConfig(); $dashboard->initQueryParams(request()->query()); @@ -35,6 +37,8 @@ public function show(string $globalFilter, string $entityKey, string $commandKey public function update(string $globalFilter, string $entityKey, string $commandKey) { + $this->authorizationManager->check('entity', $entityKey); + $dashboard = $this->entityManager->entityFor($entityKey)->getViewOrFail(); $dashboard->buildDashboardConfig(); $dashboard->initQueryParams(request()->input('query')); diff --git a/src/Http/Controllers/Api/Commands/ApiEntityListEntityCommandController.php b/src/Http/Controllers/Api/Commands/ApiEntityListEntityCommandController.php index 607f96280..1d1f3b501 100644 --- a/src/Http/Controllers/Api/Commands/ApiEntityListEntityCommandController.php +++ b/src/Http/Controllers/Api/Commands/ApiEntityListEntityCommandController.php @@ -20,6 +20,8 @@ public function __construct( public function show(string $globalFilter, string $entityKey, string $commandKey) { + $this->authorizationManager->check('entity', $entityKey); + $list = $this->entityManager->entityFor($entityKey)->getListOrFail(); $list->buildListConfig(); $list->initQueryParams(request()->query()); @@ -35,6 +37,8 @@ public function show(string $globalFilter, string $entityKey, string $commandKey public function update(string $globalFilter, string $entityKey, string $commandKey) { + $this->authorizationManager->check('entity', $entityKey); + $list = $this->entityManager->entityFor($entityKey)->getListOrFail(); $list->buildListConfig(); $list->initQueryParams(request()->input('query')); diff --git a/src/Http/Controllers/Api/Commands/ApiEntityListEntityStateController.php b/src/Http/Controllers/Api/Commands/ApiEntityListEntityStateController.php index d8650f556..f49cd2de7 100644 --- a/src/Http/Controllers/Api/Commands/ApiEntityListEntityStateController.php +++ b/src/Http/Controllers/Api/Commands/ApiEntityListEntityStateController.php @@ -12,6 +12,8 @@ class ApiEntityListEntityStateController extends Controller public function update(string $globalFilter, string $entityKey, mixed $instanceId) { + $this->authorizationManager->check('entity', $entityKey); + $list = $this->entityManager->entityFor($entityKey)->getListOrFail(); $list->buildListConfig(); $list->initQueryParams(request()->input('query')); diff --git a/src/Http/Controllers/Api/Commands/ApiEntityListInstanceCommandController.php b/src/Http/Controllers/Api/Commands/ApiEntityListInstanceCommandController.php index 3bcd08d8e..aebcf4b94 100644 --- a/src/Http/Controllers/Api/Commands/ApiEntityListInstanceCommandController.php +++ b/src/Http/Controllers/Api/Commands/ApiEntityListInstanceCommandController.php @@ -20,6 +20,8 @@ public function __construct( public function show(string $globalFilter, string $entityKey, string $commandKey, mixed $instanceId) { + $this->authorizationManager->check('entity', $entityKey); + $list = $this->entityManager->entityFor($entityKey)->getListOrFail(); $list->buildListConfig(); $list->initQueryParams(request()->query()); @@ -38,6 +40,8 @@ public function show(string $globalFilter, string $entityKey, string $commandKey */ public function update(string $globalFilter, string $entityKey, string $commandKey, mixed $instanceId) { + $this->authorizationManager->check('entity', $entityKey); + $list = $this->entityManager->entityFor($entityKey)->getListOrFail(); $list->buildListConfig(); $list->initQueryParams(request()->input('query')); diff --git a/src/Http/Controllers/Api/Commands/ApiShowEntityStateController.php b/src/Http/Controllers/Api/Commands/ApiShowEntityStateController.php index d45c45305..dcd4b8b2e 100644 --- a/src/Http/Controllers/Api/Commands/ApiShowEntityStateController.php +++ b/src/Http/Controllers/Api/Commands/ApiShowEntityStateController.php @@ -13,6 +13,8 @@ class ApiShowEntityStateController extends Controller public function update(string $globalFilter, string $entityKey, mixed $instanceId = null) { + $this->authorizationManager->check('view', $entityKey, $instanceId); + $showPage = $this->getShowPage($entityKey, $instanceId); $stateHandler = $showPage->entityStateHandler(); diff --git a/src/Http/Controllers/Api/Commands/ApiShowInstanceCommandController.php b/src/Http/Controllers/Api/Commands/ApiShowInstanceCommandController.php index 3c31e499e..cba1f0618 100644 --- a/src/Http/Controllers/Api/Commands/ApiShowInstanceCommandController.php +++ b/src/Http/Controllers/Api/Commands/ApiShowInstanceCommandController.php @@ -21,6 +21,8 @@ public function __construct( public function show(string $globalFilter, string $entityKey, string $commandKey, mixed $instanceId = null) { + $this->authorizationManager->check('view', $entityKey, $instanceId); + $showPage = $this->getShowPage($entityKey, $instanceId); $commandHandler = $this->getInstanceCommandHandler($showPage, $commandKey, $instanceId); @@ -33,6 +35,8 @@ public function show(string $globalFilter, string $entityKey, string $commandKey public function update(string $globalFilter, string $entityKey, string $commandKey, mixed $instanceId = null) { + $this->authorizationManager->check('view', $entityKey, $instanceId); + $showPage = $this->getShowPage($entityKey, $instanceId); $commandHandler = $this->getInstanceCommandHandler($showPage, $commandKey, $instanceId); diff --git a/src/Http/Controllers/Api/HandlesFieldContainer.php b/src/Http/Controllers/Api/HandlesFieldContainer.php index 65ef1e8d5..0d641b761 100644 --- a/src/Http/Controllers/Api/HandlesFieldContainer.php +++ b/src/Http/Controllers/Api/HandlesFieldContainer.php @@ -19,17 +19,21 @@ trait HandlesFieldContainer use HandlesEntityCommand; use HandlesInstanceCommand; - private function getFieldContainer(EntityKey $entityKey): SharpFormEditorEmbed|Command|SharpForm + private function getFieldContainer(EntityKey $entityKey, bool $isUpdate): SharpFormEditorEmbed|Command|SharpForm { $requestFieldContainerData = RequestFieldContainerData::from(request()->query()); if ($requestFieldContainerData->embed_key) { + $this->authorizationManager->check('entity', $entityKey); + return $this->getEmbedFromKey($requestFieldContainerData->embed_key); } $entity = $this->entityManager->entityFor($entityKey); if ($commandKey = $requestFieldContainerData->entity_list_command_key) { + $this->authorizationManager->check('entity', $entityKey); + if ($requestFieldContainerData->instance_id) { return $this->getInstanceCommandHandler( $entity->getListOrFail(), @@ -45,6 +49,8 @@ private function getFieldContainer(EntityKey $entityKey): SharpFormEditorEmbed|C } if ($commandKey = $requestFieldContainerData->show_command_key) { + $this->authorizationManager->check('view', $entityKey, $requestFieldContainerData->instance_id); + return $this->getInstanceCommandHandler( $entity->getShowOrFail(), $commandKey, @@ -53,12 +59,28 @@ private function getFieldContainer(EntityKey $entityKey): SharpFormEditorEmbed|C } if ($commandKey = $requestFieldContainerData->dashboard_command_key) { + $this->authorizationManager->check('entity', $entityKey); + return $this->getDashboardCommandHandler( $entity->getViewOrFail(), $commandKey ); } + if ($requestFieldContainerData->instance_id !== null || $entity->isSingle()) { + if ($isUpdate) { + $this->authorizationManager->check('update', $entityKey, $requestFieldContainerData->instance_id); + } else { + $this->authorizationManager->check('view', $entityKey, $requestFieldContainerData->instance_id); + } + } else { + if ($isUpdate) { + $this->authorizationManager->check('create', $entityKey); + } else { + $this->authorizationManager->check('entity', $entityKey); + } + } + return $entity->getFormOrFail($entityKey->multiformKey()); } } diff --git a/src/Http/Controllers/Api/Requests/EditorUploadFormRequest.php b/src/Http/Controllers/Api/Requests/EditorUploadFormRequest.php index 85196ec1f..d32444efb 100644 --- a/src/Http/Controllers/Api/Requests/EditorUploadFormRequest.php +++ b/src/Http/Controllers/Api/Requests/EditorUploadFormRequest.php @@ -15,6 +15,6 @@ public function rules(): array protected function prepareForValidation() { - $this->merge($this->get('data')); + $this->merge($this->input('data')); } } diff --git a/tests/Http/Api/ApiFormAutocompleteControllerTest.php b/tests/Http/Api/ApiFormAutocompleteControllerTest.php index 9cfd32254..08ad7e655 100644 --- a/tests/Http/Api/ApiFormAutocompleteControllerTest.php +++ b/tests/Http/Api/ApiFormAutocompleteControllerTest.php @@ -3,11 +3,13 @@ use Code16\Sharp\EntityList\Commands\EntityCommand; use Code16\Sharp\EntityList\Commands\InstanceCommand; use Code16\Sharp\EntityList\Commands\SingleInstanceCommand; +use Code16\Sharp\Exceptions\SharpInvalidConfigException; use Code16\Sharp\Form\Fields\SharpFormAutocompleteRemoteField; use Code16\Sharp\Form\Fields\SharpFormEditorField; use Code16\Sharp\Form\Fields\SharpFormListField; use Code16\Sharp\Form\Fields\SharpFormTextField; use Code16\Sharp\Tests\Fixtures\Entities\PersonEntity; +use Code16\Sharp\Tests\Fixtures\Entities\SinglePersonEntity; use Code16\Sharp\Tests\Fixtures\Sharp\PersonForm; use Code16\Sharp\Tests\Fixtures\Sharp\PersonList; use Code16\Sharp\Tests\Fixtures\Sharp\PersonShow; @@ -379,7 +381,7 @@ public function buildFormFields(FieldsContainer $formFields): void 'entityKey' => 'person', 'autocompleteFieldKey' => 'autocomplete_field', ])); -})->throws(\Code16\Sharp\Exceptions\SharpInvalidConfigException::class); +})->throws(SharpInvalidConfigException::class); it('fails if field is not a remote autocomplete field', function () { $this->withoutExceptionHandling(); @@ -399,7 +401,7 @@ public function buildFormFields(FieldsContainer $formFields): void 'entityKey' => 'person', 'autocompleteFieldKey' => 'name', ])); -})->throws(\Code16\Sharp\Exceptions\SharpInvalidConfigException::class); +})->throws(SharpInvalidConfigException::class); it('validates that the sent remote endpoint is the same that was defined in the autocomplete field', function () { $this->withoutExceptionHandling(); @@ -427,7 +429,7 @@ public function buildFormFields(FieldsContainer $formFields): void 'endpoint' => '/another/endpoint', 'search' => 'my search', ]); -})->throws(\Code16\Sharp\Exceptions\SharpInvalidConfigException::class); +})->throws(SharpInvalidConfigException::class); it('allows the defined endpoint to have a querystring', function () { $this->withoutExceptionHandling(); @@ -602,7 +604,7 @@ public function buildFormFields(FieldsContainer $formFields): void 'endpoint' => 'https://google.fr', 'search' => 'my search', ]); -})->throws(\Code16\Sharp\Exceptions\SharpInvalidConfigException::class); +})->throws(SharpInvalidConfigException::class); it('allows internal remote endpoint with a querystring', function () { $this->withoutExceptionHandling(); @@ -829,7 +831,9 @@ protected function executeSingle(array $data): array {} }); it('allows to call an functional endpoint for a remote autocomplete field in an InstanceCommand of a SingleShow', function () { - fakeShowFor('person', new class() extends PersonSingleShow + sharp()->config()->declareEntity(SinglePersonEntity::class); + + fakeShowFor(SinglePersonEntity::class, new class() extends PersonSingleShow { public function getInstanceCommands(): ?array { @@ -866,7 +870,7 @@ protected function executeSingle(array $data): array {} $this ->postJson(route('code16.sharp.api.form.autocomplete.index', [ - 'entityKey' => 'person', + 'entityKey' => 'single-person', 'autocompleteFieldKey' => 'autocomplete_field', 'show_command_key' => 'my-command', 'endpoint' => '/my/endpoint', diff --git a/tests/Http/Api/ApiFormUploadControllerTest.php b/tests/Http/Api/ApiFormUploadControllerTest.php index af882cdfa..84409d02c 100644 --- a/tests/Http/Api/ApiFormUploadControllerTest.php +++ b/tests/Http/Api/ApiFormUploadControllerTest.php @@ -191,6 +191,8 @@ public function updateContent(array $data = []): array } it('allows to upload a file in an embed', function () { + sharp()->config()->declareEntity(PersonEntity::class); + $this ->postJson( route('code16.sharp.api.form.upload', [