【问题标题】:Zend ACL Dynamic AssertionZend ACL 动态断言
【发布时间】:2012-07-26 11:57:43
【问题描述】:

我想限制我的用户仅编辑/删除他们添加的 cmets。我在 youtube 上找到了一个名为 intergral30 的人的示例,并按照他的指示进行操作。现在我的管理员帐户可以编辑/删除所有内容,但我的用户无权访问他自己的评论。

代码如下: 资源

class Application_Model_CommentResource implements Zend_Acl_Resource_Interface{
public $ownerId = null;
public $resourceId = 'comment';

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

角色

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;
}
}

断言

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 方法中调用。

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 方法,在该方法中我返回评论对象列表。

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;
    }
}

谁能告诉我我做错了什么? 或者,如果我想让我的管理员有权开始发帖,而其他用户有权对其发表评论,我应该使用什么。每个用户都应该有机会编辑或删除自己的评论,并且管理员应该拥有所有权限。

【问题讨论】:

    标签: zend-framework dynamic acl assertion


    【解决方案1】:

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

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

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

    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

    // 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;
        }
    }
    

    Assertion 然后会使用这个对象并检索所有者以将其与实际登录的人进行比较:

    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;
        }
    }
    

    而且用法是这样的:

    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;
        }
    }
    

    【讨论】:

    • 那么你告诉我的是将我的commentResource模型的内容移动到我的评论模型中?我明白了吗?顺便说一句,谢谢你的帮助。教导我再次忽略了一些简单的事情,但无法弄清楚是什么。
    • 1) 将CommentResource的内容移动到Comment(包括imlements),2) 传递给isAllowed()时不要使用-&gt;getResourceId()-&gt;getRoleId(),而是真实的对象。 Zend 需要对象动态地检查权限
    猜你喜欢
    • 2014-04-21
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 2019-01-01
    相关资源
    最近更新 更多