diff --git a/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/FilterExpressionFunctionProvider.php b/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/FilterExpressionFunctionProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..54bb2809bd6ec206bc7647a3c89ec6e9ae86a44d --- /dev/null +++ b/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/FilterExpressionFunctionProvider.php @@ -0,0 +1,40 @@ +<?php + +declare(strict_types=1); + +namespace Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionFunctionProviders; + +use Symfony\Component\ExpressionLanguage\ExpressionFunction; +use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; + +class FilterExpressionFunctionProvider implements ExpressionFunctionProviderInterface +{ + /** @var ExpressionLanguage */ + private $expressionLanguage; + + public function __construct(ExpressionLanguage $expressionLanguage) + { + $this->expressionLanguage = $expressionLanguage; + } + + public function getFunctions(): array + { + return [ + new ExpressionFunction('filter', + function (string $iterableName, string $expression): string { + return sprintf('filter(%s, %s)', $iterableName, $expression); + }, + function ($arguments, iterable $iterable, string $expression): array { + $filteredResult = []; + foreach ($iterable as $key => $value) { + if ($this->expressionLanguage->evaluate($expression, ['key' => $key, 'value' => $value])) { + $filteredResult[] = $value; + } + } + + return $filteredResult; + }), + ]; + } +} diff --git a/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/MapExpressionFunctionProvider.php b/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/MapExpressionFunctionProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..e1d7b00b9e6550b4029ad377fc78c44b8d88c69f --- /dev/null +++ b/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/MapExpressionFunctionProvider.php @@ -0,0 +1,38 @@ +<?php + +declare(strict_types=1); + +namespace Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionFunctionProviders; + +use Symfony\Component\ExpressionLanguage\ExpressionFunction; +use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; + +class MapExpressionFunctionProvider implements ExpressionFunctionProviderInterface +{ + /** @var ExpressionLanguage */ + private $expressionLanguage; + + public function __construct(ExpressionLanguage $expressionLanguage) + { + $this->expressionLanguage = $expressionLanguage; + } + + public function getFunctions(): array + { + return [ + new ExpressionFunction('map', + function (string $iterableName, string $expression): string { + return sprintf('map(%s, %s)', $iterableName, $expression); + }, + function ($arguments, iterable $iterable, string $expression): array { + $transformedResult = []; + foreach ($iterable as $key => $value) { + $transformedResult[$key] = $this->expressionLanguage->evaluate($expression, ['key' => $key, 'value' => $value]); + } + + return $transformedResult; + }), + ]; + } +} diff --git a/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/PhpArrayExpressionFunctionProvider.php b/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/PhpArrayExpressionFunctionProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..db907caf10e149bbaa79d6a3a59e3f09afcaac5d --- /dev/null +++ b/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/PhpArrayExpressionFunctionProvider.php @@ -0,0 +1,20 @@ +<?php + +declare(strict_types=1); + +namespace Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionFunctionProviders; + +use Symfony\Component\ExpressionLanguage\ExpressionFunction; +use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; + +class PhpArrayExpressionFunctionProvider implements ExpressionFunctionProviderInterface +{ + public function getFunctions(): array + { + return [ + ExpressionFunction::fromPhp('count'), + ExpressionFunction::fromPhp('implode'), + ExpressionFunction::fromPhp('explode'), + ]; + } +} diff --git a/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/PhpNumericExpressionFunctionProvider.php b/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/PhpNumericExpressionFunctionProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..ca7ec435016cdccba9b01bdbc9147aef772247e6 --- /dev/null +++ b/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/PhpNumericExpressionFunctionProvider.php @@ -0,0 +1,22 @@ +<?php + +declare(strict_types=1); + +namespace Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionFunctionProviders; + +use Symfony\Component\ExpressionLanguage\ExpressionFunction; +use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; + +class PhpNumericExpressionFunctionProvider implements ExpressionFunctionProviderInterface +{ + public function getFunctions(): array + { + return [ + ExpressionFunction::fromPhp('ceil'), + ExpressionFunction::fromPhp('floor'), + ExpressionFunction::fromPhp('round'), + ExpressionFunction::fromPhp('max'), + ExpressionFunction::fromPhp('min'), + ]; + } +} diff --git a/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/PhpStringExpressionFunctionProvider.php b/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/PhpStringExpressionFunctionProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..1412dafde6c9ec83d42a62a2d86505437c692073 --- /dev/null +++ b/src/Authorization/ExpressionLanguage/ExpressionFunctionProviders/PhpStringExpressionFunctionProvider.php @@ -0,0 +1,22 @@ +<?php + +declare(strict_types=1); + +namespace Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionFunctionProviders; + +use Symfony\Component\ExpressionLanguage\ExpressionFunction; +use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; + +class PhpStringExpressionFunctionProvider implements ExpressionFunctionProviderInterface +{ + public function getFunctions(): array + { + return [ + ExpressionFunction::fromPhp('str_starts_with'), + ExpressionFunction::fromPhp('str_ends_with'), + ExpressionFunction::fromPhp('substr'), + ExpressionFunction::fromPhp('strpos'), + ExpressionFunction::fromPhp('strlen'), + ]; + } +} diff --git a/src/Authorization/ExpressionLanguage/ExpressionLanguage.php b/src/Authorization/ExpressionLanguage/ExpressionLanguage.php new file mode 100644 index 0000000000000000000000000000000000000000..a997ab81e79679de981405f1c2921d713ed13b33 --- /dev/null +++ b/src/Authorization/ExpressionLanguage/ExpressionLanguage.php @@ -0,0 +1,29 @@ +<?php + +declare(strict_types=1); + +namespace Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage; + +use Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionFunctionProviders\FilterExpressionFunctionProvider; +use Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionFunctionProviders\MapExpressionFunctionProvider; +use Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionFunctionProviders\PhpArrayExpressionFunctionProvider; +use Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionFunctionProviders\PhpNumericExpressionFunctionProvider; +use Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionFunctionProviders\PhpStringExpressionFunctionProvider; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\ExpressionLanguage\ExpressionLanguage as SymfonyExpressionLanguage; + +class ExpressionLanguage extends SymfonyExpressionLanguage +{ + public function __construct(CacheItemPoolInterface $cache = null, array $providers = []) + { + $providers = array_merge([ + new FilterExpressionFunctionProvider($this), + new MapExpressionFunctionProvider($this), + new PhpArrayExpressionFunctionProvider(), + new PhpNumericExpressionFunctionProvider(), + new PhpStringExpressionFunctionProvider(), + ], $providers); + + parent::__construct($cache, $providers); + } +} diff --git a/src/Authorization/UserAuthorizationChecker.php b/src/Authorization/UserAuthorizationChecker.php index dda9986cd2ec49ade81a1f5186ee76095fcdb3c1..ba961d690af8aeb59e236b00fbdb97e98c2d5610 100644 --- a/src/Authorization/UserAuthorizationChecker.php +++ b/src/Authorization/UserAuthorizationChecker.php @@ -4,8 +4,8 @@ declare(strict_types=1); namespace Dbp\Relay\CoreBundle\Authorization; +use Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionLanguage; use Dbp\Relay\CoreBundle\Helpers\Tools; -use Symfony\Component\ExpressionLanguage\ExpressionLanguage; class UserAuthorizationChecker {