EasyCorp / EasyAdminBundle

EasyAdmin is a fast, beautiful and modern admin generator for Symfony applications.
MIT License
3.99k stars 1.01k forks source link

custom action with voter hides action on dropdown but you can still perform the action by copying the link #6279

Closed budzik closed 3 weeks ago

budzik commented 3 weeks ago

Describe the bug Can someone confirm that? is this a bug or am I doing something wrong? The code is shortened, the same voter works correctly for the default EA actions like NEW, EDIT or DETAILS. Got error performing default EA actions copying the link on account !ROLE_ADMIN obraz

custom action - is not visible on index list (good) but i can perform that action on user without permission copying a link (got nice green success flash message)

// TournamentVoter

namespace App\Security\Voter\Tournament;

use App\Entity\Tournament\Tournament;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Bundle\SecurityBundle\Security;

class TournamentVoter extends Voter
{

public const MAKE_SERIES = 'TOURNAMENT_MAKE_SERIES';

public function __construct(private Security $security)
{
}

protected function supports(string $attribute, mixed $subject): bool
{
    return in_array($attribute, [self::MAKE_SERIES])
        && $subject instanceof Tournament;
}

protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
    $user = $token->getUser();

    if (!$user instanceof UserInterface) {
        return false;
    }

    switch ($attribute) {

        case self::MAKE_SERIES:
            if (
                (in_array("ROLE_ADMIN", $user->getRoles()))
            )
            {
                return true;
            }
            break;

    }

    return false;
}

}

//TournamentCrudController

#[\Override]
public function configureActions(Actions $actions): Actions
{

    $makeSeries = Action::new('Clone series', 'Klonuj serię')->linkToCrudAction('makeSeries');

    return $actions
        ->add(Crud::PAGE_INDEX, $makeSeries)->setPermission($makeSeries, TournamentVoter::MAKE_SERIES)
    ;
}

public function makeSeries(AdminUrlGenerator $adminUrlGenerator)
{

    $this->addFlash('success', 'Success');

    $url = $adminUrlGenerator
        ->setAction(Action::INDEX)
        ->generateUrl();

    return $this->redirect($url);

}

To Reproduce Symfony 7.0.6, EA 4.10.0

budzik commented 3 weeks ago
#[IsGranted('ROLE_ADMIN')]
public function makeSeries(AdminUrlGenerator $adminUrlGenerator)
{
...
$this->denyAccessUnlessGranted('TOURNAMENT_MAKE_SERIES', $entity);