hoa/acl

此包已被废弃,不再维护。未建议替代包。

Hoa\Acl 库。

1.17.05.02 2017-05-02 12:24 UTC

README

Hoa

Build status Code coverage Packagist License

Hoa 是一套 模块化可扩展结构化 的 PHP 库。
此外,Hoa 致力于成为工业和研究世界的桥梁。

Hoa\Acl

Help on IRC Help on Gitter Documentation Board

此库允许创建和操作访问控制列表 (ACL)。ACL 的角色如下:

  • ,包含零个或多个用户,有零个或多个权限和拥有零个或多个服务。一个组可以从其他组继承权限。用户和服务不能继承。如果一个组拥有一个服务,这是一个共享服务,因为多个用户可以访问它。
  • 用户,可以拥有零个或多个服务,可以属于零个或多个组。
  • 权限,类似于权利。一个组持有零个或多个权限,可以用作允许或拒绝访问。
  • 服务,是一个文档、一个资源,用户想要访问的东西。

尽管其名称中包含“列表”一词,但底层结构是一个图(请参阅 Hoa\Graph 库),其中顶点(即节点)是组。

了解更多.

安装

使用 Composer,要将此库包含在依赖项中,您需要要求 hoa/acl

$ composer require hoa/acl '~1.0'

有关更多安装说明,请参阅 源代码页面

测试

在运行测试套件之前,必须安装开发依赖项

$ composer install

然后,运行所有测试套件

$ vendor/bin/hoa test:run

有关更多信息,请参阅 贡献者指南

快速使用

作为快速概述,我们提出了以下角色:

  • 组:访客、买家、编辑、管理员
  • 用户:匿名访客、登录访客、产品编辑、博客编辑
  • 权限:阅读、写入、购买
  • 服务:产品、博客页面

基本上,有 2 个服务:一个产品和博客页面。它可以看起来像一个小的商店。访客可以是登录的或未登录的。如果已登录,则可以购买产品。商店可以由编辑管理,具有不同的角色:一个用于产品,一个用于博客。因此,我们有 4 个组:访客、买家、编辑和管理员。

创建 ACL

我们首先创建所有角色,为清晰起见,将它们分别放在变量中

$groupVisitor       = new Hoa\Acl\Group('group_visitor');
$groupBuyer         = new Hoa\Acl\Group('group_buyer');
$groupEditor        = new Hoa\Acl\Group('group_editor');
$groupAdministrator = new Hoa\Acl\Group('group_administrator');

$userAnonymousVisitor = new Hoa\Acl\User('user_visitor_anonymous');
$userLoggedVisitor    = new Hoa\Acl\User('user_visitor_logged');
$userProductEditor    = new Hoa\Acl\User('user_editor_product');
$userBlogEditor       = new Hoa\Acl\User('user_editor_blog');

$permissionRead  = new Hoa\Acl\Permission('permission_read');
$permissionWrite = new Hoa\Acl\Permission('permission_write');
$permissionBuy   = new Hoa\Acl\Permission('permission_buy');

$serviceProduct  = new Hoa\Acl\Service('service_product');
$serviceBlogPage = new Hoa\Acl\Service('service_blog_page');

然后,我们将它们组合起来:我们创建一个 ACL 实例,在用户和组上添加服务,在组上添加用户,在 ACL 实例中添加组,最后在组上添加权限。

// Create an ACL instance.
$acl = new Hoa\Acl();

// Add services to users and groups.
// The visitor group shares the product and the blog page services.
$groupVisitor->addServices([$serviceProduct, $serviceBlogPage]);
// The buyer group shares the product and the blog page services (reminder:
// Services are not inherited).
$groupBuyer->addServices([$serviceProduct, $serviceBlogPage]);
// The product editor user owns the product service.
$userProductEditor->addServices([$serviceProduct]);
// The blog editor user owns the blog page service.
$userBlogEditor->addServices([$serviceBlogPage]);

// Add users to groups.
// The visitor group contains one anonymous visitor user.
$groupVisitor->addUsers([$userAnonymousVisitor]);
// The buyer group contains one logged visitor user.
$groupBuyer->addUsers([$userLoggedVisitor]);
// The editor group contains two users: Product editor and blog editor.
$groupEditor->addUsers([$userProductEditor, $userBlogEditor]);

// Add groups to the ACL instance.
$acl->addGroup($groupVisitor);
// The buy group inherits permissions from the visitor group.
$acl->addGroup($groupBuyer, [$groupVisitor]);
$acl->addGroup($groupEditor);
// The administrator group inherits permissions from the editor group.
$acl->addGroup($groupAdministrator, [$groupEditor]);

// Add permissions.
// The visitor group has permission to read.
$acl->allow($groupVisitor, [$permissionRead]);
// The buy group has permission to buy.
$acl->allow($groupBuyer, [$permissionBuy]);
// The editor group has permission to read and write.
$acl->allow($groupEditor, [$permissionRead, $permissionWrite])

请注意,用户和服务在组之间不会继承。

查询ACL

现在我们的ACL已经构建,我们可以通过例如使用isAllowed方法来查询它。此方法至少需要两个参数:一个用户和一个权限。它检查用户是否拥有某个权限。此外,还可以提供一个服务,然后它将检查用户是否在特定服务上拥有某个权限。让我们看看一些例子。

  • 匿名访客是否有权阅读产品?是的。
$acl->isAllowed($userAnonymousVisitor, $permissionRead, $serviceProduct) // true
  • 匿名访客是否有权购买产品?不。
$acl->isAllowed($userAnonymousVisitor, $permissionBuy, $serviceProduct) // false
  • 已登录访客是否有权阅读产品?是的。
$acl->isAllowed($userLoggedVisitor, $permissionRead, $serviceProduct) // true
  • 已登录访客是否有权购买产品?是的。
$acl->isAllowed($userLoggedVisitor, $permissionBuy, $serviceProduct) // true
  • 已登录访客是否有权写入(任何服务)?不。
$acl->isAllowed($userLoggedVisitor, $permissionWrite) // false
  • 产品编辑是否有权购买(任何服务)?不。
$acl->isAllowed($userProductEditor, $permissionBuy) // false
  • 产品编辑是否有权写入(任何服务)?是的。
$acl->isAllowed($userProductEditor, $permissionWrite) // true
  • 博客编辑是否有权写入(任何服务)?是的。
$acl->isAllowed($userBlogEditor, $permissionWrite) // true
  • 产品编辑是否有权写入博客页面?不。
$acl->isAllowed($userProductEditor, $permissionWrite, $serviceBlogPage) // false
  • 博客编辑是否有权写入博客页面?是的。
$acl->isAllowed($userBlogEditor, $permissionWrite, $serviceBlogPage) // true

使用用户、权限和服务对象有时可能很麻烦。因此,我们可以使用它们各自的ID。因此,可以这样写

$acl->isAllowed('user_editor_blog', 'permission_write', 'service_blog_page') // true

使用特定断言进行更精简的查询

可能发生ACL,包括用户、权限、服务和组,无法表达所有您的约束。这就是为什么可以提供一个断言的原因。

断言必须实现Hoa\Acl\Assertable接口并期望实现assert方法。它将接收$userId$permissionId和可选的$serviceId数据。此assert方法必须计算出一个布尔值,该值将用作isAllowed方法的最后一步。

想象以下场景,如果一个登录用户在购物袋中的物品数量大于X的情况下,M分钟后才允许购买另一个产品。

class DoNotBuyThatMuch implements Hoa\Acl\Assertable
{
    public function assert($userId, $permissionId, $serviceId)
    {
        $shoppingBag = getShoppingBagOf($userId);

        return
            X < $shoppingBag->getAmount() &&
            time() + M * 60 > $shoppingBag->getCheckoutTime();
    }
}

$acl->isAllowed(
    $userLoggedVisitor,
    $permissionBuy,
    $serviceProduct,
    new DoNotBuyThatMuch()
);

显然,断言体可能很复杂,而这个库并没有解决断言聚合或类似问题。然而,Hoa\Ruler库完美地填补了这一角色,您可能需要考虑它。

文档

Hoa\Acl的骇客手册包含有关如何使用此库及其工作方式的详细信息。

要本地生成文档,请执行以下命令

$ composer require --dev hoa/devtools
$ vendor/bin/hoa devtools:documentation --open

更多文档可以在项目网站上找到:hoa-project.net

获取帮助

主要有两种方法可以获取帮助

贡献

你想贡献吗?谢谢!一个详细的贡献指南解释了你需要知道的一切。

许可证

Hoa遵循新BSD许可证(BSD-3-Clause)。请参阅LICENSE以获取详细信息。