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

时间:2019-03-27 18:31:39

标签: symfony sonata

当当前用户不是当前对象的所有者,但确实具有ADMIN角色来编辑它时,我想用表单删除某些操作,例如“删除”。

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

我目前使用在Admin类中使用的投票器,例如:

/*
hello_world

Gabriel Staples
www.ElectricRCAircraftGuy.com
27 Mar. 2019 

Examples of how to compile & run:
- NB: c90 requires C-style comments (slash star, star slash) and does NOT work with modern
      C++-style // comments!
  C:
    gcc -Wall -o hello_world hello_world.c && ./hello_world
    gcc -Wall -std=c90 -o hello_world hello_world.c && ./hello_world
    gcc -Wall -std=c99 -o hello_world hello_world.c && ./hello_world
    gcc -Wall -std=c11 -o hello_world hello_world.c && ./hello_world
  C++:
    g++ -Wall -o hello_world hello_world.c && ./hello_world
    g++ -Wall -std=c++98 -o hello_world hello_world.c && ./hello_world
    g++ -Wall -std=c++03 -o hello_world hello_world.c && ./hello_world
    g++ -Wall -std=c++11 -o hello_world hello_world.c && ./hello_world


*/

// #include <stdio.h>   // for printf
#include <stdbool.h> // for `true` and `false`

#ifdef __cplusplus
extern "C" {
#endif
int printf ( const char * format, ... ); // a hacky alternative to including stdio.h above! 
#ifdef __cplusplus
}
#endif

int main(void)
{
    printf("Hello World\n");
    printf("`true == 1`? = %i, `true == 1`? = %s\n", true, (true == 1 ? "true" : "false"));

    return 0;
}

我在这里检查自己的逻辑。但是我不知道如何使用我的选民删除删除动作。

我首先尝试使用自己的逻辑删除对configureRoutes的操作,但未成功。另外,我读到由于缓存问题,这是一个错误的选择。

1 个答案:

答案 0 :(得分: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.twig复制/粘贴到templates/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();
        }
    }