首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Zend ACL动态断言

Zend ACL动态断言
EN

Stack Overflow用户
提问于 2012-07-26 11:57:43
回答 1查看 2.3K关注 0票数 3

我想限制我的用户只编辑/删除他们添加的评论。我在youtube上找到了一个叫intergral30的人的例子,并遵照了他的指示。现在我的管理帐户可以编辑/删除所有内容,但是我的用户无法访问他自己的评论。

下面是代码: Resource

代码语言:javascript
运行
复制
class Application_Model_CommentResource implements Zend_Acl_Resource_Interface{
public $ownerId = null;
public $resourceId = 'comment';

public function getResourceId() {
    return $this->resourceId;
}
}

角色

代码语言:javascript
运行
复制
class Application_Model_UserRole implements Zend_Acl_Role_Interface{
public $role = 'guest';
public $id = null;

public function __construct(){
    $auth = Zend_Auth::getInstance();
    $identity = $auth->getStorage()->read();

    $this->id = $identity->id;
    $this->role = $identity->role;
}

public function getRoleId(){
    return $this->role;
}
}

断言

代码语言:javascript
运行
复制
class Application_Model_CommentAssertion implements Zend_Acl_Assert_Interface
{
public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $user=null,
            Zend_Acl_Resource_Interface $comment=null, $privilege=null){
    // if role is admin, he can always edit a comment
    if ($user->getRoleId() == 'admin') {
        return true;
    }

    if ($user->id != null && $comment->ownerId == $user->id){
        return true;
    } else {
        return false;
    }
}

}

在我的ACL中,我有一个名为setDynemicPermissions的函数,它在访问检查插件的preDispatch方法中被调用。

代码语言:javascript
运行
复制
public function setDynamicPermissions() {
    $this->addResource('comment');
    $this->addResource('post');

    $this->allow('user', 'comment', 'modify', new Application_Model_CommentAssertion());

    $this->allow('admin', 'post', 'modify', new Application_Model_PostAssertion());
}

public function preDispatch(Zend_Controller_Request_Abstract $request) 
{
    $this->_acl->setDynamicPermissions();
}

我从我的注释模型中调用ACL-s isAllowed方法,在该方法中,我返回了一个注释对象列表。

代码语言:javascript
运行
复制
public function getComments($id){
    //loading comments from the DB

    $userRole = new Application_Model_UserRole();
    $commentResource = new Application_Model_CommentResource();

    $comments = array();
    foreach ($res as $comment) {
        $commentResource->ownerId = $comment[userId];

        $commentObj = new Application_Model_Comment();
        $commentObj->setId($comment[id]);
        //setting the data
        $commentObj->setLink('');

        if (Zend_Registry::get('acl')->isAllowed($userRole->getRoleId(), $commentResource->getResourceId(), 'modify')) {
            $commentObj->setLink('<a href="editcomment/id/'.$comment[id].'">Edit</a>'.'<a href="deletecomment/id/'.$comment[id].'">Delete</a>');
        }

        $comments[$comment[id]] = $commentObj;
    }
}

有人能告诉我我做错了什么吗?或者我应该使用什么,如果我想给我的管理员开始一个帖子的权利和其他用户评论他们的权利。每个用户都应该有机会编辑或删除自己的评论,管理员应该拥有所有的权利。

EN

Stack Overflow用户

发布于 2012-07-29 13:08:04

您似乎以错误的方式使用动态断言,因为您仍在将roleId传递给isAllowed()

这些动态断言真正要做的是,获取一个完整的对象并处理它。Zend将通过调用对象上的getResourceId()getRoleId()来确定必须使用哪条规则。

所以你所要做的就是把你的对象而不是字符串传递给isAllowed()

代码语言:javascript
运行
复制
public function getComments($id){
    //loading comments from the DB

    $userRole = new Application_Model_UserRole();
    $commentResource = new Application_Model_CommentResource();

    $comments = array();
    foreach ($res as $comment) {
        $commentResource->ownerId = $comment[userId];

        $commentObj = new Application_Model_Comment();
        $commentObj->setId($comment[id]);
        //setting the data
        $commentObj->setLink('');

        // This line includes the changes
        if (Zend_Registry::get('acl')->isAllowed($userRole, $commentResource, 'modify')) {
            $commentObj->setLink('<a href="editcomment/id/'.$comment[id].'">Edit</a>'.'<a href="deletecomment/id/'.$comment[id].'">Delete</a>');
        }

        $comments[$comment[id]] = $commentObj;
    }
}

但在这里可以做得更好

您不必实现一个完全新的Application_Model_CommentResource,而是可以像这样使用实际的Application_Model_Comment

代码语言:javascript
运行
复制
// we are using your normal Comment class here
class Application_Model_Comment implements Zend_Acl_Resource_Interface {
    public $resourceId = 'comment';

    public function getResourceId() {
        return $this->resourceId;
    }

    // all other methods you have implemented
    // I think there is something like this among them
    public function getOwnerId() {
        return $this->ownerId;
    }
}

然后,断言将使用此对象并检索所有者,将其与实际登录的人进行比较:

代码语言:javascript
运行
复制
class Application_Model_CommentAssertion implements Zend_Acl_Assert_Interface {
    public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $user=null,
        Zend_Acl_Resource_Interface $comment=null, $privilege=null){
    // if role is admin, he can always edit a comment
    if ($user->getRoleId() == 'admin') {
        return true;
    }

    // using the method now instead of ->ownerId, but this totally depends
    // on how one can get the owner in Application_Model_Comment
    if ($user->id != null && $comment->getOwnerId() == $user->id){
        return true;
    } else {
        return false;
    }
}

它的用法如下:

代码语言:javascript
运行
复制
public function getComments($id) {
    //loading comments from the DB

    $userRole = new Application_Model_UserRole();

    $comments = array();
    foreach ($res as $comment) {
        $commentObj = new Application_Model_Comment();
        $commentObj->setId($comment[id]);
        //setting the data
        $commentObj->setLink('');

        // no $commentResource anymore, just pure $comment
        if (Zend_Registry::get('acl')->isAllowed($userRole, $comment, 'modify')) {
            $commentObj->setLink('<a href="editcomment/id/'.$comment[id].'">Edit</a>'.'<a href="deletecomment/id/'.$comment[id].'">Delete</a>');
        }

        $comments[$comment[id]] = $commentObj;
    }
}
票数 5
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11668785

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档