2015-04-15 5 views
0

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

Вот мой Exemple:
У меня есть статья и теги, связанные со статьей. Я хочу, чтобы автор статьи мог удалять теги, связанные с этой статьей (только автор статьи может это сделать)

Я думал об использовании избирателей (чтобы убедиться, что пользователь является автором статьи) , но каждый пример, который я нашел в Интернете, показывает избирателей, которые называются либо из ветки, либо из контроллера ... в то время как с возможностью выбора «разрешить-удалить» symfony вызовите метод removeTag ($ tag) из объекта Article. Также я не вижу, как/где я могу позвонить избирателям.

+0

Premising, что я не знаю вашего и я считаю, что этот тип проверки должен применяться всегда до доступа к действию, из которого вы можете «удалить» тег (в контроллере), но чтобы попытаться ответить на ваш конкретный вопрос, что вы думаете о добавлении пользовательского валидатор внутри объекта «Article», а затем вызвать внутри него соответствующего избирателя? Или вы можете вызвать избирателя в контроллере, а затем передать результат в построитель форм, чтобы установить 'allow_delete => false'. В любом случае вы можете добавить пользователю соответствующее сообщение об ошибке. –

+0

@ gp_sflover за помощь. как я могу добавить пользовательский валидатор внутри объекта статьи, а затем позвонить внутри соответствующего избирателя? валидатор не может быть реализован в методе, отличном от get или is ... пока я хочу, чтобы мой чек делался на removeTag или что-то в этом роде ... –

ответ

2

ответ может быть только это:

да вы можете, впрыснуть service.container, где вы хотите и позвонить $this->securityContext->isGranted('delete', $tag);

, но это означает, что вам нужно, чтобы ввести услугу в своих лиц, и это совершенно неправильно ,

Другой способ сделать это внутри слушателя доктрины на событиях preRemove или onFlush, это круто, но почти неправильно, что вы делаете, если избиратель терпит неудачу? если вы выбросите исключение, это нарушит доктрину. Также что происходит, если пользователей нет? причина в том, что в слушателе вы не можете легко вернуть обратную связь пользователю.

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

вместо попробовать это:

  • , если вы используете Symfony формы вы можете сделать одно из этих двух вещей:
    • использовать форму ограничения в качестве службы, впрыснуть здесь контекст безопасности и сделать ваши проверки, если неверно добавить ошибку формы
    • создать пользовательский тип формы в качестве службы с коллекцией как родительский, ввести security.context и, наконец, использовать прослушиватель формы на PRE_SET_DATA, чтобы проверить, что что-то удалено, и проверить, разрешен ли текущий пользователь с isGranted, если проверка не удалась, добавьте ошибку формы
  • если вы делаете что в одном действии (например, АНИ) вам просто нужно проверить с isGranted непосредственно в действии или в веточке
+0

thks Marino для вашего ответа. Не могли бы вы рассказать подробнее о своем первом решении. ** ограничение формы как службы, вводят контекст безопасности ... **, что очень помогло бы мне. –

+0

К сожалению, сегодня у меня нет времени, чтобы написать вам полное решение http://symfony.com/doc/current/cookbook/validation/custom_constraint.html Пойдите с этим, есть объяснение того, как сделать ограничение как услугу. Жесткая часть после этого, вам нужно знать удаленные элементы коллекции, самый простой способ - установить исходную коллекцию внутри валидатора, используя событие формы http://symfony.com/doc/current /cookbook/form/dynamic_form_modification.html –

+0

Другой способ - вычислить набор изменений сущности с помощью доктрины или более легко сохранить удаленные элементы где-нибудь в сущности (перемещение в массиве при вызове removeTag) –