diff --git a/src/bundle/Controller/SiteAccess/SiteAccessController.php b/src/bundle/Controller/SiteAccess/SiteAccessController.php new file mode 100644 index 0000000000..e64880c4be --- /dev/null +++ b/src/bundle/Controller/SiteAccess/SiteAccessController.php @@ -0,0 +1,46 @@ +siteAccessResolvers = $siteAccessResolvers; + } + + /** + * @throws \Psr\Container\ContainerExceptionInterface + * @throws \Psr\Container\NotFoundExceptionInterface + */ + public function loadForLocation(Request $request, Location $location): SiteAccessesList + { + $resolverType = $request->query->get('resolver_type', 'non_admin'); + + try { + /** @var \Ibexa\AdminUi\Siteaccess\SiteaccessResolverInterface $siteAccessResolver */ + $siteAccessResolver = $this->siteAccessResolvers->get($resolverType); + } catch (NotFoundExceptionInterface $e) { + throw new BadRequestException($e->getMessage(), $e->getCode(), $e); + } + + return new SiteAccessesList($siteAccessResolver->getSiteAccessesListForLocation($location)); + } +} diff --git a/src/bundle/Resources/config/routing_rest.yaml b/src/bundle/Resources/config/routing_rest.yaml index 20113ea6d4..4282977378 100644 --- a/src/bundle/Resources/config/routing_rest.yaml +++ b/src/bundle/Resources/config/routing_rest.yaml @@ -137,3 +137,14 @@ ibexa.rest.content_type.load_field_definitions_from_expression: methods: [POST] options: expose: true + +# +# Site Access +# + +ibexa.rest.site_access.load_for_location: + path: /site-access/by-location/{locationId} + controller: 'Ibexa\Bundle\AdminUi\Controller\SiteAccess\SiteAccessController::loadForLocation' + methods: [GET] + options: + expose: true diff --git a/src/bundle/Resources/config/services/controllers.yaml b/src/bundle/Resources/config/services/controllers.yaml index ab509005ec..e86dba98e0 100644 --- a/src/bundle/Resources/config/services/controllers.yaml +++ b/src/bundle/Resources/config/services/controllers.yaml @@ -265,3 +265,13 @@ services: $fieldsByExpressionService: '@Ibexa\Contracts\AdminUi\ContentType\ContentTypeFieldsByExpressionServiceInterface' tags: - controller.service_arguments + + Ibexa\Bundle\AdminUi\Controller\SiteAccess\SiteAccessController: + parent: Ibexa\Rest\Server\Controller + autowire: true + arguments: + $siteAccessResolvers: !tagged_locator + tag: 'ibexa.site_access.resolver' + index_by: type + tags: + - controller.service_arguments diff --git a/src/bundle/Resources/config/services/rest.yaml b/src/bundle/Resources/config/services/rest.yaml index 0cbc65fd13..98ebcdb3d3 100644 --- a/src/bundle/Resources/config/services/rest.yaml +++ b/src/bundle/Resources/config/services/rest.yaml @@ -108,3 +108,10 @@ services: parent: Ibexa\Contracts\Rest\Output\ValueObjectVisitor tags: - { name: ibexa.rest.output.value_object.visitor, type: Ibexa\AdminUi\REST\Value\ContentType\FieldDefinitionInfoList } + # + # Site Accesses + # + Ibexa\AdminUi\REST\Output\ValueObjectVisitor\SiteAccess\SiteAccessesListVisitor: + parent: Ibexa\Contracts\Rest\Output\ValueObjectVisitor + tags: + - { name: ibexa.rest.output.value_object.visitor, type: Ibexa\AdminUi\REST\Value\SiteAccess\SiteAccessesList } diff --git a/src/bundle/Resources/config/services/siteaccess.yaml b/src/bundle/Resources/config/services/siteaccess.yaml index 5490a7045e..53e73436aa 100644 --- a/src/bundle/Resources/config/services/siteaccess.yaml +++ b/src/bundle/Resources/config/services/siteaccess.yaml @@ -18,6 +18,8 @@ services: Ibexa\AdminUi\Siteaccess\NonAdminSiteaccessResolver: arguments: $siteAccessGroups: '%ibexa.site_access.groups%' + tags: + - { name: 'ibexa.site_access.resolver', type: 'non_admin' } Ibexa\AdminUi\Siteaccess\AdminSiteaccessPreviewVoter: arguments: diff --git a/src/lib/REST/Output/ValueObjectVisitor/SiteAccess/SiteAccessesListVisitor.php b/src/lib/REST/Output/ValueObjectVisitor/SiteAccess/SiteAccessesListVisitor.php new file mode 100644 index 0000000000..e99007336a --- /dev/null +++ b/src/lib/REST/Output/ValueObjectVisitor/SiteAccess/SiteAccessesListVisitor.php @@ -0,0 +1,37 @@ +startObjectElement('SiteAccessesList'); + $visitor->setHeader('Content-Type', $generator->getMediaType('SiteAccessesList')); + + $generator->startList('values'); + foreach ($data->getSiteAccesses() as $siteAccess) { + $generator->startObjectElement('SiteAccess'); + + $generator->valueElement('name', $siteAccess->name); + + $generator->endObjectElement('SiteAccess'); + } + $generator->endList('values'); + + $generator->endObjectElement('SiteAccessesList'); + } +} diff --git a/src/lib/REST/Value/SiteAccess/SiteAccessesList.php b/src/lib/REST/Value/SiteAccess/SiteAccessesList.php new file mode 100644 index 0000000000..bd8ab6d1de --- /dev/null +++ b/src/lib/REST/Value/SiteAccess/SiteAccessesList.php @@ -0,0 +1,33 @@ +siteAccesses = $siteAccesses; + } + + /** + * @return \Ibexa\Core\MVC\Symfony\SiteAccess[] + */ + public function getSiteAccesses(): array + { + return $this->siteAccesses; + } +} diff --git a/tests/integration/REST/GetSiteAccessesListTest.php b/tests/integration/REST/GetSiteAccessesListTest.php new file mode 100644 index 0000000000..0c41e8c682 --- /dev/null +++ b/tests/integration/REST/GetSiteAccessesListTest.php @@ -0,0 +1,57 @@ +getIbexaTestCore()->setAdministratorUser(); + + $this->loginAsUser( + $this->createUserWithPolicies( + 'editor', + [ + 'user/login' => [], + 'content/read' => [], + 'content/versionread' => [], + ] + ) + ); + } + + protected static function getEndpointsToTest(): iterable + { + foreach (self::REQUIRED_FORMATS as $format) { + yield new EndpointRequestDefinition( + 'GET', + '/api/ibexa/v2/site-access/by-location/2?resolver_type=non_admin', + 'SiteAccessesList', + "application/vnd.ibexa.api.SiteAccessesList+$format", + ['HTTP_X-SiteAccess' => 'admin'], + null, + null, + 'SiteAccessesList' + ); + } + } +} diff --git a/tests/integration/Resources/REST/Schemas/SiteAccessesList.json b/tests/integration/Resources/REST/Schemas/SiteAccessesList.json new file mode 100644 index 0000000000..c99d90396c --- /dev/null +++ b/tests/integration/Resources/REST/Schemas/SiteAccessesList.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "SiteAccessesList": { + "type": "object", + "properties": { + "_media-type": { + "type": "string" + }, + "values": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "_media-type": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "_media-type", + "name" + ] + } + ] + } + }, + "required": [ + "_media-type", + "values" + ] + } + }, + "required": [ + "SiteAccessesList" + ] +} diff --git a/tests/integration/Resources/REST/Schemas/SiteAccessesList.xsd b/tests/integration/Resources/REST/Schemas/SiteAccessesList.xsd new file mode 100644 index 0000000000..0210f9c2a2 --- /dev/null +++ b/tests/integration/Resources/REST/Schemas/SiteAccessesList.xsd @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/integration/Resources/REST/Snapshots/SiteAccessesList.json b/tests/integration/Resources/REST/Snapshots/SiteAccessesList.json new file mode 100644 index 0000000000..fbf576070d --- /dev/null +++ b/tests/integration/Resources/REST/Snapshots/SiteAccessesList.json @@ -0,0 +1,27 @@ +{ + "SiteAccessesList": { + "_media-type": "application/vnd.ibexa.api.SiteAccessesList+json", + "values": [ + { + "_media-type": "application/vnd.ibexa.api.SiteAccess+json", + "name": "__default_site_access__" + }, + { + "_media-type": "application/vnd.ibexa.api.SiteAccess+json", + "name": "__second_site_access__" + }, + { + "_media-type": "application/vnd.ibexa.api.SiteAccess+json", + "name": "ger" + }, + { + "_media-type": "application/vnd.ibexa.api.SiteAccess+json", + "name": "eng" + }, + { + "_media-type": "application/vnd.ibexa.api.SiteAccess+json", + "name": "ku6\"H" + } + ] + } +} diff --git a/tests/integration/Resources/REST/Snapshots/SiteAccessesList.xml b/tests/integration/Resources/REST/Snapshots/SiteAccessesList.xml new file mode 100644 index 0000000000..c03df4e75e --- /dev/null +++ b/tests/integration/Resources/REST/Snapshots/SiteAccessesList.xml @@ -0,0 +1,18 @@ + + + + __default_site_access__ + + + __second_site_access__ + + + ger + + + eng + + + ku6"H + +