@@ -264,37 +264,66 @@ the same ``getAuthorEmail`` logic you used above:
264
264
265
265
namespace AppBundle\Security;
266
266
267
- use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
267
+ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
268
+ use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
269
+ use Symfony\Component\Security\Core\Authorization\Voter\Voter;
268
270
use Symfony\Component\Security\Core\User\UserInterface;
271
+ use AppBundle\Entity\Post;
269
272
270
- // AbstractVoter class requires Symfony 2.6 or higher version
271
- class PostVoter extends AbstractVoter
273
+ // Voter class requires Symfony 2.8 or higher version
274
+ class PostVoter extends Voter
272
275
{
273
276
const CREATE = 'create';
274
277
const EDIT = 'edit';
275
278
276
- protected function getSupportedAttributes()
279
+ /**
280
+ * @var AccessDecisionManagerInterface
281
+ */
282
+ private $decisionManager;
283
+
284
+ public function __construct(AccessDecisionManagerInterface $decisionManager)
277
285
{
278
- return array(self::CREATE, self::EDIT) ;
286
+ $this->decisionManager = $decisionManager ;
279
287
}
280
288
281
- protected function getSupportedClasses( )
289
+ protected function supports($attribute, $subject )
282
290
{
283
- return array('AppBundle\Entity\Post');
291
+ if (!in_array($attribute, array(self::CREATE, self::EDIT))) {
292
+ return false;
293
+ }
294
+
295
+ if (!$subject instanceof Post) {
296
+ return false;
297
+ }
298
+
299
+ return true;
284
300
}
285
301
286
- protected function isGranted ($attribute, $post, $user = null )
302
+ protected function voteOnAttribute ($attribute, $subject, TokenInterface $token )
287
303
{
304
+ $user = $token->getUser();
305
+ /** @var Post */
306
+ $post = $subject; // $subject must be a Post instance, thanks to the supports method
307
+
288
308
if (!$user instanceof UserInterface) {
289
309
return false;
290
310
}
291
311
292
- if ($attribute === self::CREATE && in_array('ROLE_ADMIN', $user->getRoles(), true)) {
293
- return true;
294
- }
295
-
296
- if ($attribute === self::EDIT && $user->getEmail() === $post->getAuthorEmail()) {
297
- return true;
312
+ switch ($attribute) {
313
+ case self::CREATE:
314
+ // if the user is an admin, allow them to create new posts
315
+ if ($this->decisionManager->decide($token, array('ROLE_ADMIN'))) {
316
+ return true;
317
+ }
318
+
319
+ break;
320
+ case self::EDIT:
321
+ // if the user is the author of the post, allow them to edit the posts
322
+ if ($user->getEmail() === $post->getAuthorEmail()) {
323
+ return true;
324
+ }
325
+
326
+ break;
298
327
}
299
328
300
329
return false;
@@ -310,6 +339,7 @@ To enable the security voter in the application, define a new service:
310
339
# ...
311
340
post_voter :
312
341
class : AppBundle\Security\PostVoter
342
+ arguments : ['@security.access.decision_manager']
313
343
public : false
314
344
tags :
315
345
- { name: security.voter }
@@ -337,7 +367,7 @@ via the even easier shortcut in a controller:
337
367
*/
338
368
public function editAction($id)
339
369
{
340
- $post = // query for the post ...
370
+ $post = ...; // query for the post
341
371
342
372
$this->denyAccessUnlessGranted('edit', $post);
343
373
0 commit comments