These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | /* |
||
6 | * This file is part of the Sonata Project package. |
||
7 | * |
||
8 | * (c) Thomas Rabaix <[email protected]> |
||
9 | * |
||
10 | * For the full copyright and license information, please view the LICENSE |
||
11 | * file that was distributed with this source code. |
||
12 | */ |
||
13 | |||
14 | namespace Sonata\AdminBundle\Util; |
||
15 | |||
16 | use Sonata\AdminBundle\Admin\AdminInterface; |
||
17 | use Sonata\AdminBundle\Security\Handler\SecurityHandlerInterface; |
||
18 | use Symfony\Component\Form\Form; |
||
19 | use Symfony\Component\Security\Acl\Domain\Acl; |
||
20 | |||
21 | /** |
||
22 | * AdminObjectAclData holds data manipulated by {@link AdminObjectAclManipulator}. |
||
23 | * |
||
24 | * @final since sonata-project/admin-bundle 3.52 |
||
25 | * |
||
26 | * @author Kévin Dunglas <[email protected]> |
||
27 | */ |
||
28 | class AdminObjectAclData |
||
29 | { |
||
30 | /** |
||
31 | * @var array Permissions managed only by a OWNER |
||
32 | */ |
||
33 | protected static $ownerPermissions = ['MASTER', 'OWNER']; |
||
34 | |||
35 | /** |
||
36 | * @var AdminInterface |
||
37 | */ |
||
38 | protected $admin; |
||
39 | |||
40 | /** |
||
41 | * @var object |
||
42 | */ |
||
43 | protected $object; |
||
44 | |||
45 | /** |
||
46 | * @var \Traversable Users to set ACL for |
||
47 | */ |
||
48 | protected $aclUsers; |
||
49 | |||
50 | /** |
||
51 | * @var \Traversable Roles to set ACL for |
||
52 | */ |
||
53 | protected $aclRoles; |
||
54 | |||
55 | /** |
||
56 | * @var array Cache of masks |
||
57 | */ |
||
58 | protected $masks; |
||
59 | |||
60 | /** |
||
61 | * @var Form |
||
62 | */ |
||
63 | protected $aclUsersForm; |
||
64 | |||
65 | /** |
||
66 | * @var Form |
||
67 | */ |
||
68 | protected $aclRolesForm; |
||
69 | |||
70 | /** |
||
71 | * @var Acl |
||
72 | */ |
||
73 | protected $acl; |
||
74 | |||
75 | /** |
||
76 | * @var string |
||
77 | */ |
||
78 | protected $maskBuilderClass; |
||
79 | |||
80 | /** |
||
81 | * @param object $object |
||
82 | * @param string $maskBuilderClass |
||
83 | */ |
||
84 | public function __construct( |
||
85 | AdminInterface $admin, |
||
86 | $object, |
||
87 | \Traversable $aclUsers, |
||
88 | $maskBuilderClass, |
||
89 | ?\Traversable $aclRoles = null |
||
90 | ) { |
||
91 | $this->admin = $admin; |
||
92 | $this->object = $object; |
||
93 | $this->aclUsers = $aclUsers; |
||
94 | $this->aclRoles = (null === $aclRoles) ? new \ArrayIterator() : $aclRoles; |
||
95 | $this->maskBuilderClass = $maskBuilderClass; |
||
96 | |||
97 | $this->updateMasks(); |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * Gets admin. |
||
102 | * |
||
103 | * @return AdminInterface |
||
104 | */ |
||
105 | public function getAdmin() |
||
106 | { |
||
107 | return $this->admin; |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * Gets object. |
||
112 | * |
||
113 | * @return object |
||
114 | */ |
||
115 | public function getObject() |
||
116 | { |
||
117 | return $this->object; |
||
118 | } |
||
119 | |||
120 | /** |
||
121 | * Gets ACL users. |
||
122 | * |
||
123 | * @return \Traversable |
||
124 | */ |
||
125 | public function getAclUsers() |
||
126 | { |
||
127 | return $this->aclUsers; |
||
128 | } |
||
129 | |||
130 | /** |
||
131 | * Gets ACL roles. |
||
132 | * |
||
133 | * @return \Traversable |
||
134 | */ |
||
135 | public function getAclRoles() |
||
136 | { |
||
137 | return $this->aclRoles; |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * Sets ACL. |
||
142 | * |
||
143 | * @return AdminObjectAclData |
||
144 | */ |
||
145 | public function setAcl(Acl $acl) |
||
146 | { |
||
147 | $this->acl = $acl; |
||
148 | |||
149 | return $this; |
||
150 | } |
||
151 | |||
152 | /** |
||
153 | * Gets ACL. |
||
154 | * |
||
155 | * @return Acl |
||
156 | */ |
||
157 | public function getAcl() |
||
158 | { |
||
159 | return $this->acl; |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * Gets masks. |
||
164 | * |
||
165 | * @return array |
||
166 | */ |
||
167 | public function getMasks() |
||
168 | { |
||
169 | return $this->masks; |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * Sets form. |
||
174 | * |
||
175 | * NEXT_MAJOR: remove this method. |
||
176 | * |
||
177 | * @return AdminObjectAclData |
||
178 | * |
||
179 | * @deprecated since sonata-project/admin-bundle 3.0. Use setAclUsersForm() instead |
||
180 | */ |
||
181 | public function setForm(Form $form) |
||
182 | { |
||
183 | @trigger_error( |
||
0 ignored issues
–
show
|
|||
184 | 'setForm() is deprecated since version 3.0 and will be removed in 4.0. ' |
||
185 | .'Use setAclUsersForm() instead.', |
||
186 | E_USER_DEPRECATED |
||
187 | ); |
||
188 | |||
189 | return $this->setAclUsersForm($form); |
||
190 | } |
||
191 | |||
192 | /** |
||
193 | * Gets form. |
||
194 | * |
||
195 | * NEXT_MAJOR: remove this method. |
||
196 | * |
||
197 | * @return Form |
||
198 | * |
||
199 | * @deprecated since sonata-project/admin-bundle version 3.0. Use getAclUsersForm() instead |
||
200 | */ |
||
201 | public function getForm() |
||
202 | { |
||
203 | @trigger_error( |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||
204 | 'getForm() is deprecated since version 3.0 and will be removed in 4.0. ' |
||
205 | .'Use getAclUsersForm() instead.', |
||
206 | E_USER_DEPRECATED |
||
207 | ); |
||
208 | |||
209 | return $this->getAclUsersForm(); |
||
210 | } |
||
211 | |||
212 | /** |
||
213 | * Sets ACL users form. |
||
214 | * |
||
215 | * @return AdminObjectAclData |
||
216 | */ |
||
217 | public function setAclUsersForm(Form $form) |
||
218 | { |
||
219 | $this->aclUsersForm = $form; |
||
220 | |||
221 | return $this; |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * Gets ACL users form. |
||
226 | * |
||
227 | * @return Form |
||
228 | */ |
||
229 | public function getAclUsersForm() |
||
230 | { |
||
231 | return $this->aclUsersForm; |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * Sets ACL roles form. |
||
236 | * |
||
237 | * @return AdminObjectAclData |
||
238 | */ |
||
239 | public function setAclRolesForm(Form $form) |
||
240 | { |
||
241 | $this->aclRolesForm = $form; |
||
242 | |||
243 | return $this; |
||
244 | } |
||
245 | |||
246 | /** |
||
247 | * Gets ACL roles form. |
||
248 | * |
||
249 | * @return Form |
||
250 | */ |
||
251 | public function getAclRolesForm() |
||
252 | { |
||
253 | return $this->aclRolesForm; |
||
254 | } |
||
255 | |||
256 | /** |
||
257 | * Gets permissions. |
||
258 | * |
||
259 | * @return array |
||
260 | */ |
||
261 | public function getPermissions() |
||
262 | { |
||
263 | return $this->admin->getSecurityHandler()->getObjectPermissions(); |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
Sonata\AdminBundle\Secur...ecurityHandlerInterface as the method getObjectPermissions() does only exist in the following implementations of said interface: Sonata\AdminBundle\Secur...dler\AclSecurityHandler .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
264 | } |
||
265 | |||
266 | /** |
||
267 | * Get permissions that the current user can set. |
||
268 | * |
||
269 | * @return array |
||
270 | */ |
||
271 | public function getUserPermissions() |
||
272 | { |
||
273 | $permissions = $this->getPermissions(); |
||
274 | |||
275 | if (!$this->isOwner()) { |
||
276 | foreach (self::$ownerPermissions as $permission) { |
||
277 | $key = array_search($permission, $permissions, true); |
||
278 | if (false !== $key) { |
||
279 | unset($permissions[$key]); |
||
280 | } |
||
281 | } |
||
282 | } |
||
283 | |||
284 | return $permissions; |
||
285 | } |
||
286 | |||
287 | public function getOwnerPermissions() |
||
288 | { |
||
289 | return self::$ownerPermissions; |
||
290 | } |
||
291 | |||
292 | /** |
||
293 | * Tests if the current user has the OWNER right. |
||
294 | * |
||
295 | * @return bool |
||
296 | */ |
||
297 | public function isOwner() |
||
298 | { |
||
299 | // Only a owner can set MASTER and OWNER ACL |
||
300 | return $this->admin->isGranted('OWNER', $this->object); |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * Gets security handler. |
||
305 | * |
||
306 | * @return SecurityHandlerInterface |
||
307 | */ |
||
308 | public function getSecurityHandler() |
||
309 | { |
||
310 | return $this->admin->getSecurityHandler(); |
||
311 | } |
||
312 | |||
313 | /** |
||
314 | * @return array |
||
315 | */ |
||
316 | public function getSecurityInformation() |
||
317 | { |
||
318 | return $this->admin->getSecurityHandler()->buildSecurityInformation($this->admin); |
||
319 | } |
||
320 | |||
321 | /** |
||
322 | * Cache masks. |
||
323 | */ |
||
324 | protected function updateMasks() |
||
325 | { |
||
326 | $permissions = $this->getPermissions(); |
||
327 | |||
328 | $reflectionClass = new \ReflectionClass(new $this->maskBuilderClass()); |
||
329 | $this->masks = []; |
||
330 | foreach ($permissions as $permission) { |
||
331 | $this->masks[$permission] = $reflectionClass->getConstant('MASK_'.$permission); |
||
332 | } |
||
333 | } |
||
334 | } |
||
335 |
If you suppress an error, we recommend checking for the error condition explicitly: