Skip to content

Commit e25cfde

Browse files
reypmalanpoulain
authored andcommitted
Fixed dependency issue when SecurityBundle is not installed (#3149)
* Fixed dependency issue when SecurityBundle is not installed * Fix tests * Move condition in SecurityPostDenormalizeStage
1 parent 0f91a71 commit e25cfde

File tree

5 files changed

+74
-4
lines changed

5 files changed

+74
-4
lines changed

src/Bridge/Symfony/Bundle/Resources/config/graphql.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@
5353

5454
<service id="api_platform.graphql.resolver.stage.security" class="ApiPlatform\Core\GraphQl\Resolver\Stage\SecurityStage" public="false">
5555
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
56-
<argument type="service" id="api_platform.security.resource_access_checker" />
56+
<argument type="service" id="api_platform.security.resource_access_checker" on-invalid="ignore" />
5757
</service>
5858

5959
<service id="api_platform.graphql.resolver.stage.security_post_denormalize" class="ApiPlatform\Core\GraphQl\Resolver\Stage\SecurityPostDenormalizeStage" public="false">
6060
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
61-
<argument type="service" id="api_platform.security.resource_access_checker" />
61+
<argument type="service" id="api_platform.security.resource_access_checker" on-invalid="ignore" />
6262
</service>
6363

6464
<service id="api_platform.graphql.resolver.stage.serialize" class="ApiPlatform\Core\GraphQl\Resolver\Stage\SerializeStage" public="false">

src/GraphQl/Resolver/Stage/SecurityPostDenormalizeStage.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ final class SecurityPostDenormalizeStage implements SecurityPostDenormalizeStage
3030
private $resourceMetadataFactory;
3131
private $resourceAccessChecker;
3232

33-
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, ResourceAccessCheckerInterface $resourceAccessChecker)
33+
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, ?ResourceAccessCheckerInterface $resourceAccessChecker)
3434
{
3535
$this->resourceMetadataFactory = $resourceMetadataFactory;
3636
$this->resourceAccessChecker = $resourceAccessChecker;
@@ -44,6 +44,7 @@ public function __invoke(string $resourceClass, string $operationName, array $co
4444
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
4545

4646
$isGranted = $resourceMetadata->getGraphqlAttribute($operationName, 'security_post_denormalize', null, true);
47+
4748
if (null === $isGranted) {
4849
// Backward compatibility
4950
$isGranted = $resourceMetadata->getGraphqlAttribute($operationName, 'access_control', null, true);
@@ -52,6 +53,10 @@ public function __invoke(string $resourceClass, string $operationName, array $co
5253
}
5354
}
5455

56+
if (null !== $isGranted && null === $this->resourceAccessChecker) {
57+
throw new \LogicException('Cannot check security expression when SecurityBundle is not installed. Try running "composer require symfony/security-bundle".');
58+
}
59+
5560
if (null === $isGranted || $this->resourceAccessChecker->isGranted($resourceClass, (string) $isGranted, $context['extra_variables'])) {
5661
return;
5762
}

src/GraphQl/Resolver/Stage/SecurityStage.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ final class SecurityStage implements SecurityStageInterface
3030
private $resourceMetadataFactory;
3131
private $resourceAccessChecker;
3232

33-
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, ResourceAccessCheckerInterface $resourceAccessChecker)
33+
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, ?ResourceAccessCheckerInterface $resourceAccessChecker)
3434
{
3535
$this->resourceMetadataFactory = $resourceMetadataFactory;
3636
$this->resourceAccessChecker = $resourceAccessChecker;
@@ -44,6 +44,11 @@ public function __invoke(string $resourceClass, string $operationName, array $co
4444
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
4545

4646
$isGranted = $resourceMetadata->getGraphqlAttribute($operationName, 'security', null, true);
47+
48+
if (null !== $isGranted && null === $this->resourceAccessChecker) {
49+
throw new \LogicException('Cannot check security expression when SecurityBundle is not installed. Try running "composer require symfony/security-bundle".');
50+
}
51+
4752
if (null === $isGranted || $this->resourceAccessChecker->isGranted($resourceClass, (string) $isGranted, $context['extra_variables'])) {
4853
return;
4954
}

tests/GraphQl/Resolver/Stage/SecurityPostDenormalizeStageTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,34 @@ public function testNotGranted(): void
115115
'extra_variables' => $extraVariables,
116116
]);
117117
}
118+
119+
public function testNoSecurityBundleInstalled(): void
120+
{
121+
$this->securityPostDenormalizeStage = new SecurityPostDenormalizeStage($this->resourceMetadataFactoryProphecy->reveal(), null);
122+
123+
$operationName = 'item_query';
124+
$resourceClass = 'myResource';
125+
$isGranted = 'not_granted';
126+
$resourceMetadata = (new ResourceMetadata())->withGraphql([
127+
$operationName => ['security_post_denormalize' => $isGranted],
128+
]);
129+
$this->resourceMetadataFactoryProphecy->create($resourceClass)->willReturn($resourceMetadata);
130+
131+
$this->expectException(\LogicException::class);
132+
133+
($this->securityPostDenormalizeStage)($resourceClass, 'item_query', []);
134+
}
135+
136+
public function testNoSecurityBundleInstalledNoExpression(): void
137+
{
138+
$this->securityPostDenormalizeStage = new SecurityPostDenormalizeStage($this->resourceMetadataFactoryProphecy->reveal(), null);
139+
140+
$resourceClass = 'myResource';
141+
$resourceMetadata = new ResourceMetadata();
142+
$this->resourceMetadataFactoryProphecy->create($resourceClass)->willReturn($resourceMetadata);
143+
144+
$this->resourceAccessCheckerProphecy->isGranted(Argument::any())->shouldNotBeCalled();
145+
146+
($this->securityPostDenormalizeStage)($resourceClass, 'item_query', []);
147+
}
118148
}

tests/GraphQl/Resolver/Stage/SecurityStageTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,34 @@ public function testNotGranted(): void
9696
'extra_variables' => $extraVariables,
9797
]);
9898
}
99+
100+
public function testNoSecurityBundleInstalled(): void
101+
{
102+
$this->securityStage = new SecurityStage($this->resourceMetadataFactoryProphecy->reveal(), null);
103+
104+
$operationName = 'item_query';
105+
$resourceClass = 'myResource';
106+
$isGranted = 'not_granted';
107+
$resourceMetadata = (new ResourceMetadata())->withGraphql([
108+
$operationName => ['security' => $isGranted],
109+
]);
110+
$this->resourceMetadataFactoryProphecy->create($resourceClass)->willReturn($resourceMetadata);
111+
112+
$this->expectException(\LogicException::class);
113+
114+
($this->securityStage)($resourceClass, 'item_query', []);
115+
}
116+
117+
public function testNoSecurityBundleInstalledNoExpression(): void
118+
{
119+
$this->securityStage = new SecurityStage($this->resourceMetadataFactoryProphecy->reveal(), null);
120+
121+
$resourceClass = 'myResource';
122+
$resourceMetadata = new ResourceMetadata();
123+
$this->resourceMetadataFactoryProphecy->create($resourceClass)->willReturn($resourceMetadata);
124+
125+
$this->resourceAccessCheckerProphecy->isGranted(Argument::any())->shouldNotBeCalled();
126+
127+
($this->securityStage)($resourceClass, 'item_query', []);
128+
}
99129
}

0 commit comments

Comments
 (0)