对kohana的acl模块进行技术调研,主要是对AACL/deputy/bonafide3个开源项目进行调研,调研结果如下:


1 AACL

https://github.com/banks/aacl


1.1 总结:
AACL:权限操作与权限检查的统一入口
初始化:遍历查找AACL_Resource的实现类,并调用acl_actions()等来获得rule的属性
AACL_Resource : 资源接口,资源有id+action+condition,检查对资源的权限时,都要检查这些属性
Model_AACL_Rule : 保存权限信息,role + AACL_Resource的3个属性,检查用户对资源的权限时,就要查询该用户所有的rule,并检查rule中的资源是否匹配目标资源(即 user -> role -> resource)


1.2 AACL_Resource:资源的接口,代表资源
有两个实现
1 Controller_AACL:资源是controller,id返回controller名,action返回controller的action,condition在类中自定义

2 Sprig_AACL : 资源是model,id返回model名+id,action返回增删改查,condition在类中自定义


/**
 * 资源接口
 */
interface AACL_Resource
{
/**
 * 资源id
 */
public function acl_id();
/**
 * 资源动作
 */
public function acl_actions($return_current = FALSE);
/**
 * 资源的条件
 */
public function acl_conditions(Model_User $user = NULL, $condition = NULL);
/**
 * 获得资源实例
 */
public static function acl_instance($class_name);
} // End  AACL_Resource

1.3 Model_AACL_Rule : 规则的model,表示的是权限的规则,有以下字段:
1 role:用户的角色
2 resource : 资源
3 action : 资源的操作
4 condition : 资源的条件

其中
Model_AACL_Rule::allows_access_to(AACL_Resource $resource, $action)
用于检查rule是否有规定对resource的权限

1.4 AACL:负责权限赋予+废除+检查的统一入口

AACL::grant($role, $resource, $action, $condition)
赋予role对resource的权限:直接创建aacl_rule对象

AACL::revoke($role, $resource, $action, $condition)
废除role对resource的权限:直接删除aacl_rule对象

AACL::check(AACL_Resource $resource, $action)
检查当前user是否对resource有权限

其中他会找到该user的所有role,然后找到role的所有rule,然后逐一调用Model_AACL_Rule::allows_access_to(AACL_Resource $resource, $action)来检查当前用户是否对资源有权限


2 deputy

https://github.com/morgan/kohana-deputy


2.1 role 角色,包含角色名 + 允许访问的url资源 + 禁止访问的url资源

2.1.1 数据结构 { name : { allow : [], deny : []} }
$roles['user'] = array
(
    'allow' => array
    (
        'forum/thread/*'
    ),
    'deny'  => array
    (
        'forum/thread/delete'
    )
);
$roles['editor'] = array
(
    'forum/post',
    'forum/thread/*'
);
Deputy::instance()->set_roles($roles);

2.1.2 检查权限
$deputy = Deputy::instance();
// Outputs "TRUE"
var_export($deputy->allowed('forum/thread/edit'));
// Outputs "FALSE"
var_export($deputy->allowed('forum/thread/delete'));

2.2 resource 资源,包含url + 其他属性(如title + meta)

2.2.1 数据结构,如下
$config = array
(
    'uri'       => 'forum',
    'title'     => 'Forum',
    'visible'   => TRUE,
    'override'  => NULL,
    'meta'      => array('key' => 'value', 'class' => 'p_w_picpath_dashboard')
);
$resource = Deputy_Resource::factory($config);
// Outputs "Thread"
echo $resource->title();
// Outputs "forum/thread"
echo $resource->uri();
// Outputs "TRUE"
var_export($resource->is_visible());

3 bonafide

https://github.com/shadowhand/bonafide

Kohana_Bonafide_ACL:权限的入口类,包含权限设置与查询

3.1 resource,包含name + action数组
数据结构: { name : [ action1, action2 ] }
// Add a "users" resource
$acl->resource('users');
// Add a "news" resource
$acl->resource('news');
// Add a "latest" resource with inherits from "news"
$acl->resource('latest', 'news');

3. 2 role,包含name + permission数组
数据结构: { name : { permissions : [] } }
// Add a "guest" role
$acl->role('guest');
// Add a "member" role that inherits from "guest"
$acl->role('member', 'guest');
// Add a "admin" role
$acl->role('admin');

有role的继承,就是将parent_role中的permission复制过来

3.3 permission,是3维数组:role -> action -> resource
数据结构: { role : { action : { resource : true } } } 如 $this->_permissions[$role][$action][$resource] = (bool) $access;

// Allow "admin" to access everything
$acl->permission('admin', NULL, NULL, TRUE);

3.4 例子
//设置资源权限
$acl = Bonafide::acl('blog')
// Blog has posts and comments
->resource('post', array('add', 'publish', 'delete', 'edit', 'view'))
->resource('comment', array('add', 'approve', 'delete', 'view'))
// Guest
->role('guest')
// Can view anything; add comments
->allow('guest', 'view')
->allow('guest', 'add', 'comment')
// Author, has all the guest roles
->role('author', 'guest')
// Can also add posts; approve comments
->allow('author', 'add', 'post')
->allow('author', 'approve', 'comment')
// Publisher, has all the author roles
->role('publisher', 'author')
// Can also publish anything; edit posts; delete comments
->allow('publisher', 'publish')
->allow('publisher', 'edit', 'post')
->allow('publisher', 'delete', 'comment')
// Administrator, not inherited
->role('admin')
// Can do anything, except publish
->allow('admin')
->deny('admin', 'publish');
//查询资源
// Does this resource have the action?
$can = $this->acl->can($action, $resource);
//查询权限
// Is this action allowed?
$allowed = $this->acl->allowed($role, $action, $resource);
注:
另外一个基于zend acl的项目跟这个的设计思路类似
https://github.com/synapsestudios/kohana-acl
zend acl介绍
http://framework.zend.com/manual/1.12/zh/zend.acl.introduction.html