Symfony ParamConverter Weirdness - PullRequest
       5

Symfony ParamConverter Weirdness

0 голосов
/ 04 октября 2018

В рамках процесса входа в систему / авторизации моего приложения Symfony 4 у меня есть определитель событий, определенный для определения набора групп, к которым у текущего пользователя есть доступ.Это выполняется при каждом запросе:

class DatabaseUserAuthenticationListener {
    ... //constructor and private vars

    public function onKernelController(FilterControllerEvent $event)  {
        if ($this->authToken && $this->authToken->getUser() !== "anon.")  {
            $databaseUser = $this->authToken->getUser();
            $user = $databaseUser->getUser();
            $groups = $this->groupDAO->getUserTree($user);
            $privileges = $this->privilegeDAO->getUserPrivileges($user);
            $groups->addPrivileges($privileges);

            $this->authToken->setAttribute("groupTree", null);
            $this->authToken->setAttribute("groupTree", $groups);
        }
    }
}

Он зарегистрирован здесь как сервис:

App\Utility\Security\DatabaseUserAuthenticationListener:
    tags:
        - { name: kernel.event_listener , event: kernel.controller }

По сути, это загрузка набора групп, к которым у пользователя есть доступ,и затем заполнение этих групп привилегиями, которые пользователь может сделать для каждой группы.

Это создает объект GroupTree, который выглядит примерно так:

GroupTree {#444 ▼
  #nodeList: array:9 [▶]
  #rootNodes: array:2 [▶]
  -parents: array:9 [▶]
}

nodeList показывает всесписок узлов в плоском массиве.rootNodes имеет все узлы в формате дерева.Если я dump($groups) прямо перед тем, как позвонить setAttribute, я получу нечто подобное в nodeList:

#nodeList: array:9 [▼
  14 => GroupNode {#445 ▼
    -privileges: array:1 [▼
      "VIEW_GROUP" => Privilege {#454 ▶}
    ]
    #nodeId: 14
    #nodeObject: Group {#435 ▶}
    #children: array:2 [▶]
    #parent: null
  }
  15 => GroupNode {#446 ▶}
  ...
  25 => GroupNode {#453 ▶}
]

Это плоский массив GroupNode объектов.Каждый GroupNode объект имеет массив Privilege объектов, который представляет то, что текущий пользователь может делать с Группой.

Я также должен заявить, что дерево построено путем вызова addNode(GroupNode $node), поэтому это невозможнодобавить что-то кроме GroupNode к этому дереву.

Вот Weiedness

У меня есть ParamConverter, который должен принять идентификатор, переданный контроллером, и посмотретьподнимите id в контексте текущего пользователя (то есть GroupTree, который я только что поместил в AuthToken) и верните , что GroupNode (в комплекте с привилегиями пользователя), если оно есть в дереве.

class GroupConverter implements ParamConverterInterface {
    private $groupTree;

    public function __construct(TokenStorageInterface $tokenStorage) {
        if ($tokenStorage->getToken() instanceof UsernamePasswordToken)  {
            $token = $tokenStorage->getToken();
            //I'm setting the groupTree from the UserToken
            $this->groupTree = $token->hasAttribute("groupTree")  ?  $token->getAttribute("groupTree")  :  null;
        }
    }

    public function apply(Request $request, ParamConverter $configuration)  {
        $name = $configuration->getName();
        if ($this->groupTree  &&  $this->groupTree->keyExists($request->get("id")))  {
            //I'm looking at the id passed in by the controller and using it to look up the GroupNode object in from the tree.
            $object = $this->groupTree->getItem($request->get("id"));
        }  else  {
            throw new NotFoundHttpException("Group not found!");
        }

        $request->attributes->set($name, $object);

        return true;
    }

    public function supports(ParamConverter $configuration) {
        if ($configuration->getClass() === "App\\Model\\Objects\\GroupNode")  {
            return true;
        }

        return false;
    }
}

Вот странная часть: Единственный раз, когда я возвращаю объект GroupNode, это когда я прохожу в одном из корневых узлов.Во всех других случаях я получаю что-то, кажущееся случайным ... иногда bool, иногда string, иногда array.Очень странно.

Если бы я был dump($this->groupTree) сразу после того, как я установил его в конструкторе выше, вот что я получаю в nodeList (groupTree то же самое):

#nodeList: array:9 [▼
  14 => GroupNode {#249 ▶}
  15 => "18"
  18 => 1
  19 => GroupNode {#243 ▶}
  20 => "21"
  21 => array:2 [▶]
  22 => 0
  24 => []
  25 => 0
]

14 и 19 (по совпадению?) Оказались корнями.

Итак, чтобы подвести итог проблемы:

  1. GroupTree объекты не могут есть что-то кроме GroupNode объектов в nodeList ... и все же это есть.
  2. каждый раз Я проверяю объект GroupTree прямо перед тем, как добавить его в качестве атрибута кМой токен пользователя в моем Слушателе, это правильно.Кроме того, это only место, где установлен этот атрибут.Тем не менее, каждый раз, когда я проверяю этот атрибут на токене аутентификации, из моего класса GroupConverter (который, предположительно) после вызова слушателя, он искажается.

Так что мои вопросы широкие игенерал:

WTH может быть причиной этого?Я делаю что-то явно не так?Правильно ли я понимаю порядок, в котором эти вещи происходят (и действительно ли это имеет значение)?

Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...