默认情况下,即使acl规则允许,在断言中返回false也会拒绝访问。我想做的是反过来 - 即在一个断言中返回true,以便在acl规则拒绝它时允许访问。
例如:
class TestAssert implements Zend_Acl_Assert_Interface
{
public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $role = null, Zend_Acl_Resource_Interface $resource = null,
$privilege = null)
{
return true;
}
}
$acl = new Zend_Acl;
$acl->addResource('page');
$acl->addRole('user');
$acl->allow('user', 'page', 'read', new TestAssert);
$acl->isAllowed('user', 'page', 'write');
上面的isAllowed()将返回false,因为我询问的特权在acl规则中是不允许的,因此它没有达到断言的程度。
我想要的是什么?
我想这样做的原因是用户可能拥有所有页面的特定权限,然后是他们创建的页面的一组不同的权限 - 在查询权限时我希望能够判断该页面是否是他们的,如果是,则应用“自己的页面”而不是“页面”的规则。显然,在真实的应用程序中,传递用户和页面对象而不是字符串。
更新:我已经设法通过继承Zend_Acl来做我想做的事。
此类允许为特定角色和资源组合添加回调。当调用isAllowed()时,将运行回调(如果存在)。它在与断言相同的参数中传递(以及parent :: isAllowed()的结果)。此回调的返回值是从isAllowed()返回,除非它是null,在这种情况下使用正常的返回值。
class Acl extends Zend_Acl
{
protected $_callbacks = array();
/**
* Takes into account the callback to determine whether the role is allowed access
*
* @param Zend_Acl_Role_Interface $role
* @param Zend_Acl_Resource_Interface $resource
* @param string $privilege
* @return bool
*/
public function isAllowed($role = null, $resource = null, $privilege = null)
{
$result = parent::isAllowed($role, $resource, $privilege);
$role = $this->getRole($role)->getRoleId();
$resource = $this->get($resource)->getResourceId();
if(isset($this->_callbacks[$role][$resource]))
{
$callbackResult = call_user_func($this->_callbacks[$role][$resource], $this, $role, $resource, $privilege, $result);
}
return isset($callbackResult) ? $callbackResult : $result;
}
/**
* Add a callback for a specific role and resource combination.
* If the callback returns a value, this is used as the return value for isAllowed().
* Otherwise, if the callback returns null, the normal result of isAllowed() will be used.
*
* @param Zend_Acl_Role_Interface $role
* @param Zend_Acl_Resource_Interface $resource
* @param callback $callback
*/
public function addCallback($role, $resource, $callback)
{
$role = $this->getRole($role)->getRoleId();
$resource = $this->get($resource)->getResourceId();
$this->_callbacks[$role][$resource] = $callback;
}
}
用法:
$acl = new Acl;
$acl->addResource('page');
$acl->addRole('user');
$acl->addCallback('user', 'page', function($acl, $role, $resource, $privilege, $result)
{
return true;
});
$acl->allow('user', 'page', array('read'));
$acl->isAllowed('user', 'page', 'edit'); //returns true even though 'edit' is not allowed.
答案 0 :(得分:1)
听起来你想要的东西:
class WriteAssert implements Zend_Acl_Assert_Interface
{
public function assert(Zend_Acl $acl,
Zend_Acl_Role_Interface $role = null,
Zend_Acl_Resource_Interface $resource = null,
$privilege = null)
{
// return whether the user owns the page
}
}
$acl = new Zend_Acl;
$acl->addResource('page');
$acl->addRole('user');
$acl->allow('user', 'page', 'read');
$acl->allow('user', 'page', 'write', new WriteAssert);
$acl->isAllowed('user', 'page', 'write');
在这里,您希望用户能够阅读任何页面,但只能写入自己的页面。