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

RolesDefinitionExtension   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
dl 0
loc 69
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
D secureDefinitions() 0 28 9
A configureEndpoint() 0 4 1
A buildConfig() 0 6 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