szopen/simple-access-control

基于描述标签定义的操作的权限检查系统

v1.1.0 2023-09-26 06:57 UTC

This package is auto-updated.

Last update: 2024-09-10 17:26:38 UTC


README

本项目是一个简单的系统,用于检查关于文本标签操作权限。

基本概念是,您可以定义一个描述可能过程的操作,然后可以定义一个权限,允许或拒绝该操作。

<?php
// Defines the action with a label identifier
$productDetailViewAction = new Action('product.detail.view');
// Defines the permission that allow to view the product detail
$canViewProductDetailPermission = new Permission($productDetailViewAction, true);

层次权限

您可以以这样的方式定义操作标签,使其表现得像一个层次结构。基本思想是使用一系列名词,用任意字符串分隔,以创建父子关系。这样,就可以为整个操作家族定义权限。

操作名称解析策略

前面章节中提到的是使用ActionNameParserStrategy实现的,该策略定义了如何解析Action标签并将其分割成一组单独的元素,其序列定义了父子关系的路径。已经定义了两种策略

// Defines the parser strategy
$dotSeparatedParser = new DotSeparatedActionNameParserStrategy(); 
// Defines two action that are related 
$productAction = new Action('product', $dotSeparatedParser);
// `product` is the root
// `detail` is the child of product
// `view` child of detail and nephew of product
$productDetailViewAction = new Action('product.detail.view', $dotSeparatedParser);

这样,可以定义例如,一个授予根product权限的权限,这样拥有此权限的人也将被授予product(例如,product.detail.view)的“子”操作的所有权限,基于决策策略

权限检查策略

使用PermissionCheckerStrategy,可以检查给定的Action是否允许与PermissionsCollection进行比较。已经定义了两种类型的策略

  • Affirmative:只要有权限授予访问权限,就授予访问权限;
  • Unanimous:只有在没有权限拒绝访问的情况下才授予访问权限。
<?php

$permissions = [
    new Permission(new Action('product.detail.view'), true),
    new Permission(new Action('product.detail.edit'), false),
];

$strategy = new AffirmativePermissionCheckerStrategy();
// This returns `true`
$isAllowed = $strategy->canPerformAction(
    new Action('product.detail.view'),
    new PermissionsCollection($permissions)
);

使用层次功能,如果父操作的权限被授予,则使用AffirmativePermissionCheckerStrategy授予子操作

<?php
// Defines the parser strategy
$dotSeparatedParser = new DotSeparatedActionNameParserStrategy(); 

$permissions = [
    new Permission(new Action('product', $dotSeparatedParser), true),
    new Permission(new Action('product.detail.edit', $dotSeparatedParser), false),
];

$strategy = new AffirmativePermissionCheckerStrategy();
// This returns `true`
$isAllowed = $strategy->canPerformAction(
    new Action('product.detail.edit', $dotSeparatedParser),
    new PermissionsCollection($permissions)
);

如果未定义针对操作的权限,则策略将始终拒绝操作。

<?php

$permissions = [
    new Permission(new Action('product.detail.view'), true),
    new Permission(new Action('product.detail.edit'), false),
];

$strategy = new AffirmativePermissionCheckerStrategy();
// This returns `false`
$isAllowed = $strategy->canPerformAction(
    // This action is not associated to any permission in the collection
    new Action('product.add'),
    new PermissionsCollection($permissions)
);

服务

作为常见用例,该包提供了一个UserAuthorizationService,该服务给定一个UserWithPermission和一个Action,能够检查用户是否有权执行该操作。UserWithPermission是辅助接口,您必须实现它以利用此服务。

<?php

final class MyDomainUser implements UserWithPermission
{
    // some code...
    
    public function getPermissions(): PermissionsCollection
    {
        return new PermissionsCollection([
            new Permission(new Action('product.detail.view'), true),
            new Permission(new Action('product.detail.edit'), false),
        ]);
    }
}

然后是服务。

<?php

$user = new MyDomainUser();

$service = new UserAuthorizationService(
    new AffirmativePermissionCheckerStrategy()
);
// This returns `false`
$isAllowed = $service->canUserPerformAction($user, new Action('product.detail.edit'));

测试

要运行所有测试,请执行composer test