Symfony Voter i role

W ostatnim wpisie przybliżyłam temat Votera. Jeśli jeszcze go nie czytałeś, to sprawdź. Bez poprzedniego wpisu ciężej będzie Ci zrozumieć ten. Dlatego zapraszam Cię do przeczytania podstawowych informacji o Symfony Voter, a potem powrót tutaj. Jeśli jednak znasz Votery lub przeczytałeś poprzedni tekst, to zapraszam Cię po poznania użycia voterów, które jest mniej popularne. Chciałabym Ci pokazać jak Symfony Voter i role mogą ze sobą współpracować i uzupełniać się wzajemnie.

Symfony Voter i role

Działanie Votera na podstawie roli nie różni się niczym od zwykłego Votera. Również sprawdzany jest metodą is_granted() zarówno w adnotacji, jak i kodzie php czy plikach twig. Różnica jest taka, że w pierwszym przykładzie $attribute był definiowany w Voterze jako akcja, do której jest dopuszczany user. W poniższym przykładzie nie opieramy się już na tego typu constach a na zbiorze ról i Voter również traktujemy jako odrębną rolę z bardziej skomplikowaną logiką niż standarowe role.

Zdecydowałam się na opisanie tego przypadku mimo tak małych różnic, ponieważ nigdzie nie zdnalazłam podobnych przykładów wykorzystania Votera a uważam, że ma ono duzo zalet. Jest łatwiejsze w  utrzymaniu oraz bardziej czytelne.

Przykład 

<?php

namespace Backend\UserBundle;

/**
 * Class Roles
 */
final class Roles
{
    const CAN_EDIT_POST = 'CAN_EDIT_POST';
}

Powyżej jest przykładowa klasa zawierająca zestaw constów odpowiadających rolom. Poniżej to kod samego Votera, który weryfikuje $attribute będący identyfikatorem roli.

<?php

use Backend\UserBundle\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\PostManagerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;

/**
 * Class CanEditPostVoter
 */
class CanEditPostVoter extends Voter
{
    /**
     * {@inheritdoc}
     */
    protected function supports($attribute, $subject)
    {
        return Roles::CAN_EDIT_POST === $attribute && $subject instanceof Post;
    }

    /**
     * {@inheritdoc}
     */
    protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
    {
        $user = $token->getUser();

        if (!$subject instanceof Post) {
            return false;
        }

        if ($user->getId() === $subject->getAuthorId()) {
            return true;
        }

    }
}

Oto przykład wywołania Votera w formie adnotacji do akcji. Wygląda on bardzo podobnie do weryfikacji klasy, różni się jedynie metodą is_granted. W przypadku weryfikacji roli sprawdzilibyśmy ja metodą has_role().

<?php

class PostController extends Controller
{
     
     /**
     * @Security("is_granted('CAN_EDIT_POST', post)")
     *
     * @param Post          $post
     * @param Request       $request
     * @return Response
     */
    public function editAction(Post $post, Request $request)
    {
        ...
    }
}

Mam nadzieję, że ten przykład był przydatny. Co sądzisz o takim użyciu Votera? Lepsze od standardowego, a może gorsze? Napisz w komentarzu, co o tym sądzisz!

Poprzedni artykułSymfony Voter
Następny artykuł15 pomysłów na prezent dla programisty

Podobne posty

Jestem programistką, która lubi mieć ręce pełne roboty. Do życia potrzebuje komputera z internetem i kubka gorącej kawy. Więcej na stronie o mnie.

Comments

ZOSTAW ODPOWIEDŹ

Please enter your comment!
Please enter your name here