Passed
Push — master ( 319fcb...7a107a )
by Rafael
04:41
created

AccessControlListener   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 59
Duplicated Lines 0 %

Test Coverage

Coverage 66.67%

Importance

Changes 0
Metric Value
wmc 10
dl 0
loc 59
c 0
b 0
f 0
ccs 18
cts 27
cp 0.6667
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A onSubmitMutation() 0 8 3
A __construct() 0 3 1
B preReadField() 0 22 5
A getSubscribedEvents() 0 5 1
1
<?php
2
/*******************************************************************************
3
 *  This file is part of the GraphQL Bundle package.
4
 *
5
 *  (c) YnloUltratech <[email protected]>
6
 *
7
 *  For the full copyright and license information, please view the LICENSE
8
 *  file that was distributed with this source code.
9
 ******************************************************************************/
10
11
namespace Ynlo\GraphQLBundle\EventListener\GraphQL;
12
13
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
14
use Ynlo\GraphQLBundle\Events\GraphQLEvents;
15
use Ynlo\GraphQLBundle\Events\GraphQLFieldEvent;
16
use Ynlo\GraphQLBundle\Events\GraphQLMutationEvent;
17
use Ynlo\GraphQLBundle\Exception\GraphQL\ForbiddenFieldException;
18
use Ynlo\GraphQLBundle\Exception\GraphQL\ForbiddenObjectException;
19
use Ynlo\GraphQLBundle\Exception\GraphQL\SecurityException;
20
use Ynlo\GraphQLBundle\Security\Authorization\AccessControlChecker;
21
22
class AccessControlListener implements EventSubscriberInterface
23
{
24
    /**
25
     * @var AccessControlChecker
26
     */
27
    protected $accessControlChecker;
28
29
    /**
30
     * @param AccessControlChecker $accessControlChecker
31
     */
32 22
    public function __construct(AccessControlChecker $accessControlChecker)
33
    {
34 22
        $this->accessControlChecker = $accessControlChecker;
35 22
    }
36
37
    /**
38
     * {@inheritDoc}
39
     */
40 1
    public static function getSubscribedEvents()
41
    {
42
        return [
43 1
            GraphQLEvents::POST_READ_FIELD => 'preReadField',
44 1
            GraphQLEvents::MUTATION_SUBMITTED => 'onSubmitMutation',
45
        ];
46
    }
47
48 8
    public function onSubmitMutation(GraphQLMutationEvent $event)
49
    {
50 8
        $operation = $event->getContext()->getDefinition();
51 8
        if ($this->accessControlChecker->isControlled($operation)
52 8
            && !$this->accessControlChecker->isGranted($operation, $event->getFormEvent()->getData())
53
        ) {
54
            $message = $this->accessControlChecker->getMessage($operation) ?? 'Access Denied';
55
            throw new SecurityException($message);
56
        }
57 8
    }
58
59 22
    public function preReadField(GraphQLFieldEvent $event)
60
    {
61
        //check firstly if the user have rights to read the object
62 22
        $object = $event->getInfo()->getObject();
63 22
        if ($this->accessControlChecker->isControlled($object)
64 22
            && !$this->accessControlChecker->isGranted($object, $event->getRoot())
65
        ) {
66
            throw new ForbiddenObjectException(
67
                $event->getInfo()->getObject(),
68
                $this->accessControlChecker->getMessage($object)
69
            );
70
        }
71
72
        //check then if the user have rights to read the field
73 22
        $field = $event->getInfo()->getField();
74 22
        if ($this->accessControlChecker->isControlled($field)
75 22
            && !$this->accessControlChecker->isGranted($field, $event->getRoot())
76
        ) {
77
            throw new ForbiddenFieldException(
78
                $event->getInfo()->getObject(),
79
                $event->getInfo()->getField(),
80
                $this->accessControlChecker->getMessage($field)
81
            );
82
        }
83 22
    }
84
}
85