Passed
Pull Request — master (#7)
by Yonel Ceruto
09:02
created

RolesDefinitionExtension::buildConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
3
/*******************************************************************************
4
 *  This file is part of the GraphQL Bundle package.
5
 *
6
 *  (c) YnloUltratech <[email protected]>
7
 *
8
 *  For the full copyright and license information, please view the LICENSE
9
 *  file that was distributed with this source code.
10
 ******************************************************************************/
11
12
namespace Ynlo\GraphQLBundle\Definition\Extension;
13
14
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
15
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
16
use Ynlo\GraphQLBundle\Definition\ExecutableDefinitionInterface;
17
use Ynlo\GraphQLBundle\Definition\FieldsAwareDefinitionInterface;
18
use Ynlo\GraphQLBundle\Definition\Registry\Endpoint;
19
20
class RolesDefinitionExtension extends AbstractDefinitionExtension
21
{
22
    /**
23
     * @var bool[]
24
     */
25
    private $definitionVisited = [];
26
27
    private $authorizationChecker;
28
29
    public function __construct(AuthorizationCheckerInterface $authorizationChecker)
30
    {
31
        $this->authorizationChecker = $authorizationChecker;
32
    }
33
34
    /**
35
     * {@inheritDoc}
36
     */
37
    public function buildConfig(ArrayNodeDefinition $root): void
38
    {
39
        $root
40
            ->info('List of roles for queries and mutations')
41
            ->prototype('scalar')
42
            ->end();
43
    }
44
45
    /**
46
     * {@inheritDoc}
47
     */
48
    public function configureEndpoint(Endpoint $endpoint): void
49
    {
50
        $endpoint->setQueries($this->secureDefinitions($endpoint->allQueries(), $endpoint));
51
        $endpoint->setMutations($this->secureDefinitions($endpoint->allMutations(), $endpoint));
52
    }
53
54
    /**
55
     * @param ExecutableDefinitionInterface[]     $definitions
56
     * @param Endpoint                            $endpoint
57
     * @param FieldsAwareDefinitionInterface|null $parent
58
     *
59
     * @return ExecutableDefinitionInterface[]
60
     */
61
    private function secureDefinitions(array $definitions, Endpoint $endpoint, FieldsAwareDefinitionInterface $parent = null): array
62
    {
63
        $secureDefinitions = [];
64
        foreach ($definitions as $definition) {
65
            $key = spl_object_hash($definition);
66
            if (isset($this->definitionVisited[$key])) {
67
                continue;
68
            }
69
            $this->definitionVisited[$key] = true;
70
71
            $type = $endpoint->hasType($definition->getType()) ? $endpoint->getType($definition->getType()): null;
72
73
            if (($roles = $definition->getRoles()) && !$this->authorizationChecker->isGranted($roles)) {
0 ignored issues
show
Bug introduced by
The method getRoles() does not exist on Ynlo\GraphQLBundle\Defin...ableDefinitionInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Ynlo\GraphQLBundle\Defin...ableDefinitionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
            if (($roles = $definition->/** @scrutinizer ignore-call */ getRoles()) && !$this->authorizationChecker->isGranted($roles)) {
Loading history...
74
                if ($parent) {
75
                    $parent->removeField($definition->getName());
76
                }
77
78
                continue;
79
            }
80
81
            $secureDefinitions[] = $definition;
82
83
            if ($type instanceof FieldsAwareDefinitionInterface && $fieldDefinitions = $type->getFields()) {
84
                $this->secureDefinitions($fieldDefinitions, $endpoint, $type);
85
            }
86
        }
87
88
        return $secureDefinitions;
89
    }
90
}
91