diff --git a/src/Authorization/AuthorizationService.php b/src/Authorization/AuthorizationService.php new file mode 100644 index 0000000000000000000000000000000000000000..ba739c3808baed991623b093b248583ea64b513d --- /dev/null +++ b/src/Authorization/AuthorizationService.php @@ -0,0 +1,11 @@ +<?php + +declare(strict_types=1); + +namespace Dbp\Relay\ProxyBundle\Authorization; + +use Dbp\Relay\CoreBundle\Authorization\AbstractAuthorizationService; + +class AuthorizationService extends AbstractAuthorizationService +{ +} diff --git a/src/DataPersister/ProxyDataPersister.php b/src/DataPersister/ProxyDataPersister.php index a8f16ea5da366637d73192eff01b65bdb2de3634..5b71901265d342214e8d521dbe128b2290a7ce6d 100644 --- a/src/DataPersister/ProxyDataPersister.php +++ b/src/DataPersister/ProxyDataPersister.php @@ -7,6 +7,7 @@ namespace Dbp\Relay\ProxyBundle\DataPersister; use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface; use Dbp\Relay\CoreBundle\Helpers\Tools; use Dbp\Relay\CoreBundle\ProxyApi\ProxyDataEvent; +use Dbp\Relay\ProxyBundle\Authorization\AuthorizationService; use Dbp\Relay\ProxyBundle\Entity\ProxyData; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -17,9 +18,13 @@ class ProxyDataPersister extends AbstractController implements ContextAwareDataP /** @var EventDispatcherInterface */ private $eventDispatcher; - public function __construct(EventDispatcherInterface $eventDispatcher) + /** @var AuthorizationService */ + private $authorizationService; + + public function __construct(EventDispatcherInterface $eventDispatcher, AuthorizationService $authorizationService) { $this->eventDispatcher = $eventDispatcher; + $this->authorizationService = $authorizationService; } public function supports($data, array $context = []): bool @@ -33,7 +38,6 @@ class ProxyDataPersister extends AbstractController implements ContextAwareDataP public function persist($data, array $context = []): ProxyData { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY'); - $this->denyAccessUnlessGranted('ROLE_SCOPE_API-PROXY'); if ($data instanceof ProxyData) { if (Tools::isNullOrEmpty($data->getNamespace())) { @@ -41,6 +45,8 @@ class ProxyDataPersister extends AbstractController implements ContextAwareDataP } elseif (Tools::isNullOrEmpty($data->getFunctionName())) { throw new BadRequestException('parameter functionName must not be null nor empty'); } else { + $this->authorizationService->denyAccessUnlessIsGranted('CALL_FUNCTION', $data); + $proxyDataEvent = new ProxyDataEvent($data); $this->eventDispatcher->dispatch($proxyDataEvent, ProxyDataEvent::NAME.'.'.$data->getNamespace()); diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 3bbc6cb9d608fd0b6ff59f06c3dccb8ad9cd0783..42fba6a3bc5cc56844f38bf044c86167d14d0a01 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -4,15 +4,37 @@ declare(strict_types=1); namespace Dbp\Relay\ProxyBundle\DependencyInjection; +use Dbp\Relay\CoreBundle\Authorization\UserAuthorizationChecker; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; class Configuration implements ConfigurationInterface { + public const AUTHORIZATON_NODE = 'authorization'; + public const CALL_FUNCTION_RIGHT = 'CALL_FUNCTION'; + public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('dbp_relay_proxy'); + $treeBuilder->getRootNode() + ->children() + ->arrayNode(self::AUTHORIZATON_NODE) + ->addDefaultsIfNotSet() + ->children() + ->arrayNode(UserAuthorizationChecker::RIGHTS_CONFIG_ATTRIBUTE) + ->children() + ->scalarNode(self::CALL_FUNCTION_RIGHT) + ->info('The (boolean) expression checking whether the current user may call the requested function. Available parameters: user, subject (of type ProxyData)') + ->example('user.get("CALL_PROXY_FUNCTIONS") === true || subject.getNamespace() === "public"') + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + return $treeBuilder; } } diff --git a/src/DependencyInjection/DbpRelayProxyExtension.php b/src/DependencyInjection/DbpRelayProxyExtension.php index 6601dfb0a00b4832ad2255a2649378167aa7ac58..efef44fe74618f68f5c0bd176a85da758dde8e9a 100644 --- a/src/DependencyInjection/DbpRelayProxyExtension.php +++ b/src/DependencyInjection/DbpRelayProxyExtension.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Dbp\Relay\ProxyBundle\DependencyInjection; use Dbp\Relay\CoreBundle\Extension\ExtensionTrait; +use Dbp\Relay\ProxyBundle\Authorization\AuthorizationService; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; @@ -32,5 +33,8 @@ class DbpRelayProxyExtension extends ConfigurableExtension new FileLocator(__DIR__.'/../Resources/config') ); $loader->load('services.yaml'); + + $definition = $container->getDefinition(AuthorizationService::class); + $definition->addMethodCall('setConfig', [$mergedConfig['authorization']]); } } diff --git a/src/Entity/ProxyData.php b/src/Entity/ProxyData.php index fc4ad84343279991f2392ae4f217835e9488b8d8..c416ccb0c40769cd6b682e038773c80558dcedf6 100644 --- a/src/Entity/ProxyData.php +++ b/src/Entity/ProxyData.php @@ -13,7 +13,7 @@ use Symfony\Component\Serializer\Annotation\Groups; * @ApiResource( * collectionOperations={ * "post" = { - * "security" = "is_granted('IS_AUTHENTICATED_FULLY') and is_granted('ROLE_SCOPE_API-PROXY')", + * "security" = "is_granted('IS_AUTHENTICATED_FULLY')", * "path" = "/proxy/proxydata", * "openapi_context" = { * "tags" = {"Proxy"}, diff --git a/src/Resources/config/services.yaml b/src/Resources/config/services.yaml index 555defc0a137a50f259ba5f72fd2f5548162ccf4..7ac04798ab6c8344049466f3e3157b26ffb279bb 100644 --- a/src/Resources/config/services.yaml +++ b/src/Resources/config/services.yaml @@ -1,4 +1,8 @@ services: + Dbp\Relay\ProxyBundle\Authorization\AuthorizationService: + autowire: true + autoconfigure: true + Dbp\Relay\ProxyBundle\DataProvider\: resource: '../../DataProvider' autowire: true