jaminv / aclfilter-bundle
Doctrine QueryBuilder 的 ACL 过滤桥
This package is not auto-updated.
Last update: 2024-09-28 20:50:59 UTC
README
此捆绑包允许您设置与 ACL 关联的 Doctrine 查询。这有助于填补 Symfony 当前 ACL 实现的空白。虽然 Symfony ACL 允许您高效地检查特定对象的权限,但它没有有效的方法来构建只返回被授予权限的对象的列表查询。
在 Symfony 的 ACL 下,唯一以这种方式列出资源的方法是逐个测试它们。预缓存可以在一定程度上提高性能,但如果只有几百个有效结果,这远远不是理想的。此系统也不太适合限制/偏移查询。
此捆绑包通过修改使用 QueryBuilder 构建的查询来绕过这个问题,将这些查询与适当的表连接起来,以便在查询执行期间检查 ACL 权限。结果是查询效率非常高,只返回您想要的结果。如计数、限制或偏移等特殊查询选项都将正常工作。
但是,此捆绑包必须直接查询数据库,因此可能存在与 Doctrine 未来版本的兼容性问题或问题。然而,它应该与大多数数据库兼容,并且我能够将四年前实现的代码仅对 Symfony 代码进行很少的更改。没有对 Doctrine 特定代码进行代码更改,因此至少在不久的将来,它应该继续与 Doctrine 版本一起工作。
- 从 rejsmont/LabDB 克隆。
- 仅提取 src/VIB/SecurityBundle 包
- 删除和更改了一些与 ACL 过滤系统无关的文件。
- 重命名为 ACLFilterBundle,以反映单一目的。
- 更新以与 Symfony 3 兼容
- 添加文档
- 添加 AclQuery 服务
AclQuery
我还注意到,Symfony 的 ACL 捆绑包没有一种方法可以通过查询 ACL 来获取有权访问对象的用户/角色的列表。我需要这个功能来为用户提供一个界面来编辑他们对象的权限。因此,我在此捆绑包中添加了 AclQuery 服务来处理此功能。
与 AclFilter 服务一样,AclQuery 依赖于直接对数据库的 SQL 查询,因此可能与某些数据库存在一些兼容性问题。唯一的替代方案是为每个 ACL 数据库表设置 Doctrine 实体,这通常是不希望的。
安装
Composer 安装
composer require jaminv/aclfilter-bundle
或编辑 composer.json
# /composer.json
"require": {
...
"jaminv/aclfilter-bundle": "dev-master"
},
注册捆绑包
# /app/AppKernel.php
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = [
...
new jaminv\ACLFilterBundle\jaminvACLFilterBundle(),
new AppBundle\AppBundle(),
];
...
用法
基本用法
设置基本查询
$em = $this->getDoctrine->getManager();
$builder = em->getRepository('AppBundle:SomeTable')->getQueryBuilder('a');
$builder->select('a')
->where("a.somefield = 'value'");
将 AclFilter 应用到查询
$aclfilter = $this->get('jaminv.aclfilter');
$query = $aclfilter->apply($builder->getQuery(), array('EDIT'), $this->getUser(), 'a');
$result = $query->getResult();
AclFilter 将修改查询,使其只返回具有当前用户编辑权限的对象的结果。
AclQuery 用法
使用 AclQuery 列出有权访问对象的用户/角色可以一行完成
$result = $this->get('jaminv.aclquery')->queryAcl("AppBundle\\Entity\\SomeTable", $id);
结果是可能如下所示的数组
[{"security_identifier":"ROLE_ADMIN","is_username":"0","mask":"32"},
{"security_identifier":"AppBundle\\Entity\\User-username","is_username":"1","mask":"128"}]
数组中的每个条目都有 3 个字段
- security_identifier: (string) 安全标识符,通常为 "AppBundle\Entity\User-" 或 "ROLE_"
- is_username: (boolean) 如果安全标识符是按其用户名识别的用户,则为 1。否则为 0,这应表示它是一个角色。
- mask: (int) 该用户的权限掩码。与 MaskBuilder 掩码进行比较;如果此数字大于 MaskBuilder 掩码,则用户具有这些权限。
在上面的示例中,掩码值表明用户“username”已被授予所有者(OWNER)权限,而角色ROLE_ADMIN已被授予主(MASTER)权限。
AclQuery::queryAcl还接受第三个可选参数,即字段名称。这可以用来执行字段级别权限的相同操作。请注意,如果您不包括此参数,查询将仅返回对象级别的权限而不会返回字段级别的权限。同样,使用此参数将仅返回字段级别的权限。
建议您在将此查询的结果返回给用户之前检查用户是否有对对象的授权(GRANT)权限。AclQuery服务不会明确执行此操作。
AclQuery服务目前不遍历角色层次结构或对象祖先。它仅返回直接对象身份与安全身份的关系。目前没有计划添加此功能,因为当前的使用案例(向用户显示编辑权限)仅适用于直接关系。