ketysek
ketysek

Reputation: 1219

Symfony2 voter issue

I've got a problem with my custom Voter. If the user has a specific role (for ex. 'ROLE_USER'), the voter will let him do the action. I'll try to leave in vote method only ACCESS_DENIED, but without success. It seems that the symfony is ignoring my custom Voter

ItemVoter.php

class ItemVoter implements VoterInterface 
{
    const ROLE_ADMIN = 'ROLE_ADMIN';
    const ROLE_MANAGER = 'ROLE_MANAGER';
    const ROLE_USER = 'ROLE_USER';

    public function supportsAttribute($attribute) {
        return in_array($attribute, array(
            self::ROLE_ADMIN,
            self::ROLE_MANAGER,
            self::ROLE_USER,
        ));
    }

    public function supportsClass($class) {
       $supportedClass = 'Cvut\Fit\BiWt2\InventoryBundle\Entity\Item';

       return $supportedClass === $class || is_subclass_of($class, $supportedClass);
    }

    public function vote(TokenInterface $token, $item, array $attributes) {
        /*
        if (!$this->supportsClass(get_class($item))) {
            return VoterInterface::ACCESS_ABSTAIN;
        }

        $attribute = $attributes[0];
        $user = $token->getUser();

        if (!$this->supportsAttribute($attribute)) {
            return VoterInterface::ACCESS_ABSTAIN;
        }
        */
        /*
        switch($attribute) {
            case 'ROLE_USER':
                if($user->getId() === $item->getPerson()->getId()) {
                    return VoterInterface::ACCESS_GRANTED;
                }
                break;
            case 'ROLE_MANAGER':
                if($user->getId === $item->getOrganizationalUnit()->getSuperiorUnit()) {
                    //return VoterInterface::ACCESS_GRANTED;
                }
                break;
            case 'ROLE ADMIN':
                //return VoterInterface::ACCESS_GRANTED;
                break;
        }*/

        return VoterInterface::ACCESS_DENIED;
    }
}

services.yml

security.access.item_voter:
    class:  'Cvut\Fit\BiWt2\InventoryBundle\Security\Authorization\Voter\ItemVoter'
    tags:
      - { name: security.voter }

use in a controller

$item = $itemService->getItem($id);
    $roles = $this->getUser()->getRoles();
    if (false === $this->get('security.context')->isGranted($roles[0]->getRole(), $item)) {
        throw new AccessDeniedException('Unauthorised access!');
    }

Every user has only 1 role (role[0] is guaranteed)

Upvotes: 0

Views: 252

Answers (1)

szecsikecso
szecsikecso

Reputation: 301

Might you missed to read the last section of the Specific Voter documentation: http://symfony.com/doc/current/cookbook/security/voters.html#changing-the-access-decision-strategy Changing the Access Decision Strategy.

This code in your security.yml file:

# app/config/security.yml
security:
    access_decision_manager:
        # strategy can be: affirmative, unanimous or consensus
        strategy: unanimous
        # only grant access if none of the voters has denied access

Has to solve your problem, and activate ItemVoter.

Upvotes: 2

Related Questions