alexdpy/acl

Acl - Php

0.3.0 2015-10-25 18:39 UTC

This package is not auto-updated.

Last update: 2024-09-14 17:21:30 UTC


README

动态访问控制列表的最简单方法

这个库是 ACL 模型的 PHP 实现。它被设计得非常容易使用。

安装

$ composer require alexdpy/acl

更新数据库模式

您必须创建 acl_permissions 表。
您可以使用终端中的 vendor/bin/acl 命令生成查询输出。

$ vendor/bin/acl schema:get-create-query 

自定义选项包括

  • 权限表名称
  • 请求者列长度
  • 资源列长度

用法

首先,您必须选择一个 DatabaseProvider。
此库支持 DoctrineDbal/ORM (~2.4), CakephpOrm (~3.0), IlluminateDatabase (>4.2) 或原生 PDO (./src/Database/Provider).

如果您使用其他数据库连接库,您必须创建一个实现了 AlexDpy\Acl\Database\Provider\DatabaseProviderInterface 的 DatabaseProvider。

<?php
// example with Doctrine

use AlexDpy\Acl\Database\Provider\DoctrineDbalProvider;
use Doctrine\DBAL\DriverManager;

$connection = DriverManager::getConnection(/* ... */);
$databaseProvider = new DoctrineDbalProvider($connection);

然后,您只需要创建一个 AlexDpy\Acl\Acl 的新实例。

<?php

use AlexDpy\Acl\Acl;

$acl = new Acl($databaseProvider, new PermissionBuffer());

$acl 使用 AclSchema 来了解数据库模式的外观。
如果需要,您可以自定义模式选项。

<?php

use AlexDpy\Acl\Acl;
use AlexDpy\Acl\Database\Schema\AclSchema;

$aclSchema = new AclSchema([
    'permissions_table_name' => 'acl_perm',
    'requester_column_length' => 100,
    'resource_column_length' => 100,
]);

$acl = new Acl(
    $databaseProvider,
    new PermissionBuffer(),
    'AlexDpy\Acl\Mask\BasicMaskBuilder',
    $aclSchema
);

您还可以扩展 AclSchema 并使用您自己的。

isGranted, grant, revoke

以下是场景

给定一个 user("请求者")和一个 post("资源")
user 想要编辑 post
然后我们调用 $acl->isGranted($user, $post, 'EDIT')

$user 必须是 AlexDpy\Acl\Model\RequesterInterface 的实例
$post 必须是 AlexDpy\Acl\Model\ResourceInterface 的实例

<?php

if (!$acl->isGranted($user, $post, 'EDIT')) {
    throw new \Exception('You can not edit this post !');
}
<?php

$acl->grant($user, $post, 'EDIT');
// $user can now edit $post

$acl->revoke($user, $post, 'EDIT');
// $user can not edit $post anymore

请求者和资源

$acl 与 RequesterInterfaceResourceInterface 一起工作。
它们都有一种用于识别其对象的方法。

一切关乎命名约定。您必须注意标识符冲突。
一个不错的选择是使用表示对象的名称前缀和唯一标识符。

<?php

use AlexDpy\Acl\Model\RequesterInterface;

class User implements RequesterInterface
{
    protected $id;
    
    public function getAclRequesterIdentifier()
    {
        return 'user-' . $this->id;
    }
}
<?php

use AlexDpy\Acl\Model\ResourceInterface;

class Post implements ResourceInterface
{
    protected $id;
    
    public function getAclResourceIdentifier()
    {
        return 'post-' . $this->id;
    }
}

当然,您也可以使用任何任意的请求者或任何任意的资源

<?php

use AlexDpy\Acl\Model\Requester;
use AlexDpy\Acl\Model\Resource;

$acl->grant(
    new Requester('user-666'),
    new Resource('post-1337'),
    'VIEW'
);

CascadingRequesterInterface

有时,与请求者和其父级一起工作可能会有用。例如,用户及其安全角色。$acl->isGranted() 将处理所有父级。如果有一个父级被授权,则它将返回 true。

<?php

use AlexDpy\Acl\Model\CascadingRequesterInterface;

class User implements CascadingRequesterInterface
{
    protected $id;
    
    protected $roles;
    
    public function getAclRequesterIdentifier()
    {
        return 'user-' . $this->id;
    }
    
    public function getAclParentsRequester()
    {
        $parents = [];
        
        foreach ($this->roles as $role) {
            $parents[] = new Requester('role-' . $role);
        }
        
        return $parents;
    }
}

MaskBuilder

MaskBuilder 是 AlexDpy\Acl\Mask\MaskBuilderInterface 的实例。
它的作用是关注权限级别。它与位掩码一起工作。
我们提供了一个 BasicMaskBuilder,它有 4 个掩码

const MASK_VIEW = 1;
const MASK_EDIT = 2;
const MASK_CREATE = 4;
const MASK_DELETE = 8;

当您授予请求者 VIEW 和 EDIT 时,存储的掩码将是 3 (MASK_VIEW + MASK_EDIT)。
public function resolveMask($code); 将可读参数转换为整数掩码等效值。
它允许您写入 $acl->grant($user, $post, ['view', 'edit']);$acl->grant($user, $post, 3); 以获得相同的结果。

如果您需要更多和/或不同的掩码,您可以创建自己的 MaskBuilder,扩展 AlexDpy\Acl\Mask\AbstractMaskBuilder
然后

<?php

use AlexDpy\Acl\Acl;

$acl = new Acl($databaseProvider, new PermissionBuffer(), 'My\New\MaskBuilder');

缓存

为了避免无用的数据库请求,$acl 需要 PermissionBuffer。PermissionBuffer 与 DoctrineCache 库一起工作。它需要一个 Doctrine\Common\Cache\CacheProvider

最简单的方法是使用 APC

<?php

use Doctrine\Common\Cache\ApcCache;

$cacheProvider = new ApcCache();
$cacheProvider->setNamespace('acl');

$permissionBuffer = new PermissionBuffer($cacheProvider);
$acl = new Acl($databaseProvider, $permissionBuffer);

@see https://github.com/doctrine/cache

过滤列表

@TODO

许可协议

MIT 协议