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) |
|
|
|
|
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) |
|
|
|
|
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
|
|
|
|
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:If that code throws an exception and the
EntityManager
is closed. Any other code which depends on the same instance of theEntityManager
during this request will fail.On the other hand, if you instead inject the
ManagerRegistry
, thegetManager()
method guarantees that you will always get a usable manager instance.