2

我想将 ACL 与 Symfony 2 一起使用并将它们加载到我的装置中。

以下代码完美运行,但如果我取消注释,则会array('myprivateroom', 'user1', 'view'),收到以下错误:

[Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException]  ObjectIdentity(1, Acme\RoomBundle\Entity\Room) is already associated with an ACL.

我认为问题就在这里,$acl = $aclProvider-createAcl(ObjectIdentity::fromDomainObject($room));但我不知道如何解决。

public function load(ObjectManager $manager)
{
    $datas = array(
        array('myprivateroom', 'admin', 'owner'),
        //array('myprivateroom', 'user1', 'view'),
        array('mypublicroom', 'user1', 'owner'),
    );

    foreach ($datas as $data) {
        // creating the ACL
        $room = $this->getReference($data[0]);
        $aclProvider = $this->container->get('security.acl.provider');
        $objectIdentity = ObjectIdentity::fromDomainObject($room);
        //problem here when I uncomment array('myprivateroom', 'user1', 'view'),
        $acl = $aclProvider->createAcl(ObjectIdentity::fromDomainObject($room));

        // retrieving the security identity of the user
        $user = $this->getReference($data[1]);
        $securityIdentity = UserSecurityIdentity::fromAccount($user);

        //create mask
        $builder = new MaskBuilder();
        $builder->add($data[2]);
        $mask = $builder->get();

        // grant owner access
        $acl->insertObjectAce($securityIdentity, $mask);
        $aclProvider->updateAcl($acl);
    }
}

谢谢

更新:如果我做 2 个数组,比如

$datas = array(
    array('myprivateroom', 'admin', 'owner'),
    array('mypublicroom', 'user1', 'owner'),
);

$datas2 = array(
    array('myprivateroom', 'user1', 'view'),
);

和 2 foreach 但是,在第二个中,我替换$acl = $aclProvider->createAcl(ObjectIdentity::fromDomainObject($room));$acl = $aclProvider->findAcl($objectIdentity);,它工作得很好,但我认为这不是正确的方法,以下不起作用。

try {
    $acl = $aclProvider->findAcl($objectIdentity);
} catch (AclNotFoundException $e) {
    $acl = $aclProvider->createAcl($objectIdentity);
}
4

2 回答 2

4

我遇到了和你完全一样的问题,我已经这样解决了。

try {
    $acl = $this->get('security.acl.provider')->findAcl($idObjeto);
} catch (\Symfony\Component\Security\Acl\Exception\AclNotFoundException $e) {
    $acl = $this->get('security.acl.provider')->createAcl($idObjeto);
}

我没有很好地解释为什么。唯一不同的是“\Symfony\Component\Security\Acl\Exception\AclNotFoundException”

于 2013-05-15T14:12:39.953 回答
0

我来晚了,但以防有人需要了解您的代码发生了什么。如果你遍历这个数组:

$datas = array(
    array('myprivateroom', 'admin', 'owner'),
    array('myprivateroom', 'user1', 'view'),
    array('mypublicroom', 'user1', 'owner'),
);

你将使用:

 $acl = $aclProvider->createAcl(ObjectIdentity::fromDomainObject($room));

在第一个和第二个循环上。它将尝试创建访问控制列表 (ACL)'myprivateroom'两次。这就是为什么它会抛出一个错误,说你已经有了这个 Room 实体的列表。

ObjectIdentity(1, Acme\RoomBundle\Entity\Room) is already associated with an ACL

解决它的一个好方法是尝试它是否有 ACL,如果没有则创建它(@JGrinon 提供的答案)。否则,您可以将数据组织在多维数组中并循环遍历它:

// PHP array but you could use a JSON array to be clearer
$datas = array(
    array('myprivateroom',
        array(
            array('admin', 'owner'),
            array('user1', 'view1')
        )
    ),
    array('mypublicroom',
        array(
            array('user1', 'owner'),
        )
    ),
);

// Call ACL Provider service before the loop
$aclProvider = $this->container->get('security.acl.provider');

// Loop through the array
foreach ($datas as $data) {
    // Get the room name
    $room = $this->getReference($data[0]);
    $objectIdentity = ObjectIdentity::fromDomainObject($room);
    // The list is created only once for each room
    $acl = $aclProvider->createAcl(ObjectIdentity::fromDomainObject($room));

    // Loop through the list of users and associated rights
    $list = $this->getReference($data[1]);
    foreach ($list as $row) {
        // Retrieving the security identity of the user
        $user = $row[0];
        $securityIdentity = UserSecurityIdentity::fromAccount($user);

        // Create Mask
        $builder = new MaskBuilder();
        $builder->add($row[1]);
        $mask = $builder->get();

        // Grant access
        $acl->insertObjectAce($securityIdentity, $mask);
    };

    // Update Access Control List
    $aclProvider->updateAcl($acl);
}

希望这可以帮助 ;)

于 2016-06-09T00:18:38.837 回答