0

親を一覧表示しながら、いくつかの子エンティティの acl エントリを確認したいと考えています。

それが現在の設定です:

Gallery (parent)
    Gallerycategory (child)
    Gallerylanguage (child)
  • すべてのユーザーグループには独自の役割があります。
  • Gallerycategory または Gallerylanguage を作成するときに、このエンティティにアクセスできるすべてのグループのリストを作成します。
  • チェックすると、グループはGallerycategory -> ROLE_(Usergroup)関係の ACL で VIEW エントリを取得します。

ここで、自分のギャラリーを一覧表示したい場合、許可された Gallerycategory または Gallerylanguage のエントリだけが表示されるはずです。

それを達成するための最良の方法は何ですか?リポジトリに入り、現在のユーザーを確認しますか?

4

2 に答える 2

0

@develth が説明した方法論に基づいて、正確な問題を解決する Symfony バンドルを公開しました。

https://github.com/GoDisco/AclTreeBundle

AclTreeバンドルを使用すると、ACL アクセス許可のエンティティ間に階層関係を作成できます。

于 2014-12-01T11:48:27.127 に答える
0

私はそれを理解したと思います。

まず、AclChildEntityInterfaceという新しいインターフェイスを作成しました。ものすごく単純:

interface AclChildEntityInterface{ 
    public function getAclChildren(); 
}

子 ACL / ACE をチェックしたいすべてのエンティティはそれを実装し、子エンティティを取得する関数の配列を返します。

class Gallery implements AclChildEntityInterface
{
    public function getAclChildren(){
        return array(
            'mediacategories' => 'getMediacategories',
            'medialanguages' => 'getMedialanguages',
        );
    }
}

注:配列値は、現在のエンティティ クラスの関数として存在する必要があります。

その後、次を拡張する新しい AclVoter を作成しましたSymfony\Component\Security\Acl\Voter\AclVoter

クラスはほぼ同じですが、投票機能の動作を変更しただけです

catch (AclNotFoundException $noAcl)

use Symfony\Component\Security\Acl\Voter\AclVoter as BaseVoter;
...
use Develth\Prodcut\GalleryBundle\Entity\AclChildEntityInterface;

class MediaAclVoter extends BaseVoter
{
    ...
    public function vote(TokenInterface $token, $object, array $attributes)
    {
        ...
        } catch (AclNotFoundException $noAcl) {
            if (null !== $this->logger) {
                $this->logger->debug('No ACL found for the object identity. Voting to deny access.');
            }

            // Check if entity has childs to check
            if($object instanceof AclChildEntityInterface){
                $entityChilds = $object->getAclChildren();
                foreach ($entityChilds as $child) {
                    $childEntites = call_user_func( array($object,$child) );
                    foreach ($childEntites as $childEntity) {
                        $mapping =  $childEntity->getName();
                        $oid = $this->objectIdentityRetrievalStrategy->getObjectIdentity($childEntity);
                        try{
                            $acl = $this->aclProvider->findAcl($oid, $sids);
                            if($acl->isGranted($masks, $sids, false)){
                                // Has permission to view. show it. 
                                return self::ACCESS_GRANTED;
                            }
                        }catch(AclNotFoundException $noAcl){
                            // No ACL for this entity. Ignore
                        }catch(NoAceFoundException $noAce){
                            // No ACE for this entity. Ignore because other could have.
                        }
                    }
                }
            }

            return self::ACCESS_DENIED;
        } catch (NoAceFoundException $noAce) {
           ...

}    

そこで何が起こるの?

現在のエンティティの ACL が見つからない場合は、以前に作成された AclChildEntityInterface のインスタンスかどうかを確認します。すべての childAcl を取得してチェックしACCESS_GRANTED、ACE が見つかった場合は を返します。

しかし、まだ気に入らない点がいくつかあり、改善される可能性があると思います。

実装する Entity クラスで、次のAclChildEntityInterfaceようなことをしたい:

public function getAclChildren(){
    return array(
        'mediacategories' => $this->mediacategories,
        'medialanguages' => $this->medialanguages,
    );
 }

または get メソッドに関するものです。

しかし、投票者のそれらにアクセスしたい場合、私は常にメイン エンティティ メディアを所有者として PersistentCollection を取得するため、それらに直接アクセスすることはできません。それが私が使用する理由call_user_funkです。

改善に感謝します!

于 2013-01-10T14:13:17.917 に答える