diff --git a/src/Symfony/Security/ResourceAccessChecker.php b/src/Symfony/Security/ResourceAccessChecker.php index e12087a3a7..657245fd69 100644 --- a/src/Symfony/Security/ResourceAccessChecker.php +++ b/src/Symfony/Security/ResourceAccessChecker.php @@ -13,6 +13,7 @@ namespace ApiPlatform\Symfony\Security; +use ApiPlatform\Metadata\Exception\RuntimeException; use ApiPlatform\Metadata\ResourceAccessCheckerInterface; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; use Symfony\Component\ExpressionLanguage\Node\NameNode; @@ -50,6 +51,14 @@ public function isGranted(string $resourceClass, string $expression, array $extr public function usesObjectVariable(string $expression, array $variables = []): bool { + if (null === $this->tokenStorage || null === $this->authenticationTrustResolver) { + throw new RuntimeException('The "symfony/security" library must be installed to use the "security" attribute.'); + } + + if (null === $this->expressionLanguage) { + throw new RuntimeException('The "symfony/expression-language" library must be installed to use the "security" attribute.'); + } + return $this->hasObjectVariable($this->expressionLanguage->parse($expression, array_keys($this->getVariables($variables)))->getNodes()->toArray()); } diff --git a/tests/Symfony/Security/ResourceAccessCheckerTest.php b/tests/Symfony/Security/ResourceAccessCheckerTest.php index aa124b1449..a8aa66f7e4 100644 --- a/tests/Symfony/Security/ResourceAccessCheckerTest.php +++ b/tests/Symfony/Security/ResourceAccessCheckerTest.php @@ -13,6 +13,7 @@ namespace ApiPlatform\Tests\Symfony\Security; +use ApiPlatform\Metadata\Exception\RuntimeException; use ApiPlatform\Symfony\Security\ResourceAccessChecker; use ApiPlatform\Tests\Fixtures\Serializable; use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Dummy; @@ -82,6 +83,32 @@ public function testExpressionLanguageNotInstalled(): void $checker->isGranted(Dummy::class, 'is_granted("ROLE_ADMIN")'); } + public function testUsesObjectVariableThrowsWhenSecurityComponentNotAvailable(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The "symfony/security" library must be installed to use the "security" attribute.'); + + $checker = new ResourceAccessChecker($this->prophesize(ExpressionLanguage::class)->reveal()); + $checker->usesObjectVariable('user == object.owner'); + } + + public function testUsesObjectVariableThrowsWhenExpressionLanguageNotInstalled(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('The "symfony/expression-language" library must be installed to use the "security" attribute.'); + + $authenticationTrustResolverProphecy = $this->prophesize(AuthenticationTrustResolverInterface::class); + $tokenStorageProphecy = $this->prophesize(TokenStorageInterface::class); + $tokenProphecy = $this->prophesize(TokenInterface::class); + $tokenProphecy->willImplement(Serializable::class); + $tokenProphecy->getUser()->willReturn(null); + $tokenProphecy->getRoleNames()->willReturn([]); + $tokenStorageProphecy->getToken()->willReturn($tokenProphecy->reveal()); + + $checker = new ResourceAccessChecker(null, $authenticationTrustResolverProphecy->reveal(), null, $tokenStorageProphecy->reveal()); + $checker->usesObjectVariable('user == object.owner'); + } + public function testWithoutAuthenticationToken(): void { $expressionLanguageProphecy = $this->prophesize(ExpressionLanguage::class);