Skip to content

[DX] Rendre plus léger l'appel à AuthorizationHelperInterface pour récolter la liste de Scope et des Center "reachables" par l'utilisateur courant

Le problème

On a très fréquemment besoin d'une liste des Scope et des Center qui sont accessibles par un utilisateur. On utilise pour cela AuthorizationHelperInterface.

Cette méthode prend en argument:

  • l'utilisateur pour lequel on doit retirer la liste des scopes / center
  • le droit
  • et une liste de centre

A l'usage, il faut utiliser Security::getUser() pour retirer l'utilisateur courant, et CenterResolverManager sur un objet pour retirer les centres associés.

Ca donne:

class MyService {
    public function __construct(
    Security $security,
    AuthorizationHelperInterface $authorizationHelper,
    CenterResolverManagerInterface $centerResolverManagerInterface
    ) {
        //...
    }

    public function myMethod()
    {
        $authorizationHelper->getReachableScopes($this->security->getUser(), SomethingVoter::CREATE, $this->centerREsolverManagerInterface->resolveCenters($entity));

        $authorizationHelper->getReachableCenters($this->security->getUser(), SomethingVoter::CREATE);
    }
}

Le problème:

  • 3 dépendances à injecter
  • code lourd

Proposition de solution

class MyService {
    public function __construct(
    AuthorizationHelperInterface $authorizationHelper
    ) {
        //...
    }

    public function myMethod()
    {
        $authorizationHelper->getReachableScopesForCurrent(SomethingVoter::CREATE, $entity);

        $authorizationHelper->getReachableCentersForCurrent(SomethingVoter::CREATE);

        // or for another user:
        $authorizationHelper->getReachableScopes($anotherUser, SomethingVoter::CREATE, $entity);
    }
}

Remplacer le troisième argument de getReachableCenters par quelque chose qui est résolvable vers un centre

La signature serait donc:

interface AuthorizationHelperInterface
{
    /**
     * @param array|Center|Center[]|HasCenterInterface|hasCentersInterface $centerOrCenterResolvable
     */
    public function getReachableScopes(UserInterface $user, string $role, $centerOrCenterResolvable): array;
}

Créer des méthodes qui s'appliquerait au currentUser (utilisateur connecté)

On garderait les autres méthodes, pour les situations où on a besoin de connaitre les droits d'un autre user:

interface AuthorizationHelperInterface
{
    /**
     * Get reachable Centers for the given user, role,
     * and optionnaly Scope.
     *
     * @return Center[]
     */
    public function getReachableCentersForCurrent(string $role, ?Scope $scope = null): array;

    /**
     * @param array|Center|Center[]|HasCenterInterface|HasCentersInterface $centerOrResolvable
     */
    public function getReachableScopesForCurrent(string $role, $centerOrResolvable): array;

    /**
     * Get reachable Centers for the given user, role,
     * and optionnaly Scope.
     *
     * @return Center[]
     */
    public function getReachableCenters(UserInterface $user, string $role, ?Scope $scope = null): array;

    /**
     * @param array|Center|Center[]|HasCenterInterface|HasCentersInterface $centerOrResolvable
     */
    public function getReachableScopes(UserInterface $user, string $role, $centerOrResolvable): array;

}