Zend_Acl 和动态 Assert
我试图在我的 Zend 代码中暗示一些动态断言,并且一直在使用 [Ralph Schindler][1] 的文章,但我无法让它工作。我想做的是在 de Acl 中制定一个“允许”规则,检查登录的人是否实际上是 UserContent 的所有者。
我有一个 User 类和一个 UserContent 类(删除了所有不必要的位):
class User implements Zend_Acl_Role_Interface {
private $_roleId;
public function getRoleId() { return $this->_roleId; }
}
class UserContent implements Zend_Acl_Resource_Interface {
private $_resourceId;
private $_userId;
public function getResourceId() { return $this->_resourceId; }
public function getUserId() { return $this->_userId; }
}
现在在我的 Acl 类 My_Acl 中,我定义了一个“成员”角色、一个“usercontent”资源和一个“编辑”权限,并且想要创建以下允许规则:
$this->allow('member', 'usercontent', 'edit', new My_Acl_Assert_IsOwner());
其中 Assert 实现了类 Zend_Acl_Assert_Interface:
class My_Acl_Assert_IsOwner 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 if the user logged in is owner of the userContent]
}
}
我仍在努力考虑在实际的断言方法中放入什么内容。
假设我以会员身份登录(所以我的 $_roleId='member'),并且想要检查是否允许我编辑 UserContent 的一部分,如下所示:
$userContentMapper = new Application_Model_Mapper_UserContent();
$userContent = $userContentMapper->find(123);
if ($this->isAllowed($userContent, 'delete')) echo "You are allowed to delete this";
在断言方法中我想添加一些内容就像:
$resource->getUserId();
但这给了我错误消息*调用未定义的方法 Zend_Acl_Resource::getUserId()*。奇怪的是,如果我测试资源是否是 UserContent 的实例,我会得到确认:将以下行添加到资产方法中:
if ($resource instanceof UserContent) echo "True!";
我确实得到了 true。出了什么问题?
为了进行测试,我向 UserContent 类添加了一个额外的公共变量 OwnerId,定义如下:
private $_id;
public $ownerId;
public function setId($id) {$this->_id = $id; $this->ownerId = $id;
现在,如果我将 $resource->ownerId 添加到断言方法中,我不会收到任何错误消息,它只是从类中读取值。出了什么问题? $resource是UserContent的一个实例,但是我不能调用方法getUserId,但是我可以调用公共变量$ownerId??
[1] http://ralphschindler.com/2009/ 08/13/动态断言-for-zend_acl-in-zf
I'm trying to imply some dynamic assertions into my Zend code and have been using an article by [Ralph Schindler][1] but I couldn't get it to work. What I wanna do is make an "allow" rule in de Acl that checks if the person logged in is actually the owner of a piece of UserContent.
I have the a User class and a UserContent class (deleted all the unneccessary bits):
class User implements Zend_Acl_Role_Interface {
private $_roleId;
public function getRoleId() { return $this->_roleId; }
}
class UserContent implements Zend_Acl_Resource_Interface {
private $_resourceId;
private $_userId;
public function getResourceId() { return $this->_resourceId; }
public function getUserId() { return $this->_userId; }
}
Now in my Acl class My_Acl I have defined a 'member' role, a 'usercontent' resource and a 'edit' privilege, and would like to create the following allow rule:
$this->allow('member', 'usercontent', 'edit', new My_Acl_Assert_IsOwner());
where the Assert implements the class Zend_Acl_Assert_Interface:
class My_Acl_Assert_IsOwner 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 if the user logged in is owner of the userContent]
}
}
where I'm still struggling with what to put in the actual assert method.
Let's say I am logged in as a member (so my $_roleId='member'), and want to check if I'm allowed to edit a piece of UserContent, something like this:
$userContentMapper = new Application_Model_Mapper_UserContent();
$userContent = $userContentMapper->find(123);
if ($this->isAllowed($userContent, 'delete')) echo "You are allowed to delete this";
In the assert method I would like to put something like:
$resource->getUserId();
but this gives me the error messages *Call to undefined method Zend_Acl_Resource::getUserId()*. Strange, cos if I test if the resource is an instance of the UserContent I get a confirmation: adding the following line to the asset method:
if ($resource instanceof UserContent) echo "True!";
I get a true indeed. What goes wrong?
For a test I have added an extra public variable ownerId to the UserContent class, definied as follows:
private $_id;
public $ownerId;
public function setId($id) {$this->_id = $id; $this->ownerId = $id;
Now if I add $resource->ownerId to the assert method, I get no error message, it simply reads the value from the class. What is going wrong? $resource is an instance of UserContent, but I can't call the method getUserId, but I can call the public variable $ownerId??
[1] http://ralphschindler.com/2009/08/13/dynamic-assertions-for-zend_acl-in-zf
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如 @pieter 指出的,acl 规则是在应用程序内的另一个位置调用的,这就是为什么当您检查资源是否是 UserContent 的实例时,它会回显 True。
您声明的 acl 规则正在检查“编辑”权限:
$this->allow('member', 'usercontent', 'edit', new My_Acl_Assert_IsOwner());
但是当您'重新测试“删除”权限:
if ($this->isAllowed($userContent, 'delete')) echo "您可以删除this";
尝试将其添加到您的 acl:
$this->allow('member', 'usercontent', 'delete', new My_Acl_Assert_IsOwner());
As @pieter pointed out, the acl rule is being called in another place within your app which is why when you check that the resource is an instance of UserContent it is echoing True.
The acl rule you declare is checking for an "edit" privilege:
$this->allow('member', 'usercontent', 'edit', new My_Acl_Assert_IsOwner());
but when you're testing for a "delete" privilege:
if ($this->isAllowed($userContent, 'delete')) echo "You are allowed to delete this";
Try adding this to your acl:
$this->allow('member', 'usercontent', 'delete', new My_Acl_Assert_IsOwner());