WebcookCmsVoter::supportsClass()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
/**
4
 * This file is part of Webcook security bundle.
5
 *
6
 * See LICENSE file in the root of the bundle. Webcook 
7
 */
8
9
namespace Webcook\Cms\SecurityBundle\Authorization\Voter;
10
11
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
12
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
13
use Doctrine\ORM\EntityManager;
14
15
/**
16
 * Main voter for WebcookCms application.
17
 */
18
class WebcookCmsVoter implements VoterInterface
19
{
20
    /**
21
     * @var View action.
22
     */
23
    const ACTION_VIEW = 'view';
24
25
    /**
26
     * @var Edit action
27
     */
28
    const ACTION_INSERT = 'insert';
29
30
    /**
31
     * @var Edit action
32
     */
33
    const ACTION_EDIT = 'edit';
34
35
    /**
36
     * @var Delete action
37
     */
38
    const ACTION_DELETE = 'delete';
39
40
    /**
41
     * Entity manager.
42
     *
43
     * @var EntityManager
44
     */
45
    private $em;
46
47
    /**
48
     * Class constructor.
49
     *
50
     * @param EntityManager $em
51
     */
52 41
    public function __construct(EntityManager $em)
0 ignored issues
show
Bug introduced by
You have injected the EntityManager via parameter $em. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

Loading history...
53
    {
54 41
        $this->em = $em;
55 41
    }
56
57
    /**
58
     * {@inheritdoc}
59
     *
60
     * @param string $attribute
61
     *
62
     * @return bool
63
     */
64 39
    public function supportsAttribute($attribute)
65
    {
66 39
        return in_array($attribute, array(
67 39
            self::ACTION_VIEW,
68 39
            self::ACTION_INSERT,
69 39
            self::ACTION_EDIT,
70 39
            self::ACTION_DELETE,
71
        ));
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     *
77
     * @param string $class
78
     *
79
     * @return bool
80
     */
81 1
    public function supportsClass($class)
0 ignored issues
show
Unused Code introduced by
The parameter $class is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
82
    {
83 1
        return true;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     *
89
     * @param TokenInterface $token
90
     * @param string         $resource
91
     * @param array          $attributes
92
     *
93
     * @return int
94
     */
95 40
    public function vote(TokenInterface $token, $resource, array $attributes)
96
    {
97 40
        if (1 !== count($attributes)) {
98 1
            throw new \InvalidArgumentException(
99 1
                'Only one attribute is allowed for view, edit or delete.'
100
            );
101
        }
102
103
        // set the attribute to check against
104 39
        $attribute = $attributes[0];
105
106
        // check if the given attribute is covered by this voter
107 39
        if (!$this->supportsAttribute($attribute)) {
108 38
            return VoterInterface::ACCESS_ABSTAIN;
109
        }
110
111 30
        $user = $token->getUser();
112
113 30
        foreach ($user->getRoles() as $role) {
114 29
            $roleResource = $role->getResource($resource);
115 29
            if ($roleResource->isGranted($attribute)) {
116 29
                return VoterInterface::ACCESS_GRANTED;
117
            }
118
        }
119
120 1
        return VoterInterface::ACCESS_DENIED;
121
    }
122
}
123