使用自定义策略限制使用Sonata的某些用户的操作

问题描述 投票:0回答:1

当当前用户不是当前对象的所有者但是具有用于编辑它的ADMIN角色时,我想删除一些像表单“DELETE”的操作。

我想将此行为应用于列表(复选框)或编辑对象时。

我目前使用的是在Admin类中使用的选民,如:

protected function configureFormFields(FormMapper $formMapper){
        if($this->isCurrentRoute('edit') && !$this->getConfigurationPool()->getContainer()->get('security.authorization_checker')->isGranted('edit', $this->getSubject()))
            throw new AccessDeniedHttpException();
...
}

我用自己的逻辑检查。但我不知道如何使用我的选民删除删除操作。

我首先尝试使用自己的逻辑删除configureRoutes上的操作,但我没有成功。此外,我读到由于缓存问题,这是一个糟糕的选择。

symfony sonata
1个回答
0
投票

我终于成功了,但我不确定这是最好的解决方案。

我使用管理自己逻辑的voter。在我的管理实体中,我覆盖了“编辑”模板。

class ProjectAdmin extends AbstractAdmin
{
...
public function getTemplate($name)
    {
        switch ($name) {
            case 'edit':
                return 'Sonata/ProjectAdmin/edit.html.twig';
                break;
            default:
                return parent::getTemplate($name);
                break;
        }
    }
...
}

我在templates/Sonata/ProjectAdmin/edit.html.twig创建了我的模板

包含:

{% extends 'SonataAdminBundle:CRUD:base_edit.html.twig' %}

{% use 'SonataExtends/base_edit_form.html.twig' with form as parentForm %}

{% block form %}
    {{ block('parentForm') }}
{% endblock %}

然后我复制/粘贴vendor/sonata-project/admin-bundle/src/Ressources/views/CRUD/base_edit_form.html.twigtemplates/SonataExtends/base_edit_form.html.twig

我替换了块:

 {% if admin.hasRoute('delete') and admin.hasAccess('delete', object) %}
    {{ 'delete_or'|trans({}, 'SonataAdminBundle') }}
    <a class="btn btn-danger" href="{{ admin.generateObjectUrl('delete', object) }}">
    <i class="fa fa-minus-circle" aria-hidden="true"></i> {{ 'link_delete'|trans({}, 'SonataAdminBundle') }}</a>
{% endif %}

打电话给我的选民:

 {% if admin.hasRoute('delete') and is_granted('delete', object) %}
     {{ 'delete_or'|trans({}, 'SonataAdminBundle') }}
     <a class="btn btn-danger" href="{{ admin.generateObjectUrl('delete', object) }}">
     <i class="fa fa-minus-circle" aria-hidden="true"></i> {{ 'link_delete'|trans({}, 'SonataAdminBundle') }}</a>
{% endif %}

唯一的区别是is_granted('delete', object)而不是admin.hasAccess('delete', object)

正如我所说,这可能不是最好的方式,所以谢谢你纠正我。但我没有设法覆盖admin.hasAccess('delete',object)的逻辑。对于其他管理类,我只需要使用我的getTemplate函数来使用这个逻辑。

PS:我还在管理类中添加了此代码来管理删除操作:

 public function preRemove($project){
        if (false === $this->getConfigurationPool()->getContainer()->get('security.authorization_checker')->isGranted('delete', $project)) {
            throw new AccessDeniedHttpException();
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.