ACL - Sonata Admin + Sonata User

38 views
Skip to first unread message

Cassiano Tartari

unread,
Feb 7, 2013, 6:17:34 AM2/7/13
to symfony-pt
Bom dia pessoal!

    Estou usando o conjunto em suas últimas versões. Porém estou com algumas dúvidas com relação ao ACL. Estou criando as hierarquias de usuários e grupos porém uma coisa que eu queria é que um usuário do tipo STAFF só conseguisse editar os objetos criados por ele. Por exemplo, tenho um usuário root, um usuário criado pelo root e por esse usuário mais 2. O problema é que na listagem de usuários o usuário criado pelo root pode editar seu "pai". E queria que esse usuário só pudesse editar a si mesmo e seus "filhos". Alguém poderia me ajudar a configurar isso?

Valeu!

Cassiano Tartari.

Raphael

unread,
Feb 7, 2013, 8:02:14 AM2/7/13
to symfo...@googlegroups.com
Eu normalmente adiciono um condicional nos métodos edit e update. Algo da seguinte forma:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

<?php

    /**
     * Displays a form to edit an existing Item entity.
     *
     */
    public function editAction($id)
    {
        $em = $this->getDoctrine()->getManager();
        
        $conditions = array(
            'id' => $id
        );

        if (false === $this->get('security.context')->isGranted('ROLE_SUPER_ADMIN')) {
            $conditions['userAdmin'] = $em->getReference('AcmeUserBundle:UserAdmin', $this->getUser()->getId());
        }

        $entity = $em->getRepository('AcmeBundle:Item')
                ->findOneBy($conditions);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find item entity.');
        }

2013/2/7 Cassiano Tartari <cassian...@gmail.com>

--
Você está recebendo esta mensagem porque se inscreveu no grupo "Symfony Brasil" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para symfony-pt+...@googlegroups.com.
Para postar neste grupo, envie um e-mail para symfo...@googlegroups.com.
Visite este grupo em http://groups.google.com/group/symfony-pt?hl=pt-BR.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
 
 



--
Raphael Almeida Araújo
Homepage: http://sites.google.com/site/raphoxaraujo

Cassiano Tartari

unread,
Feb 7, 2013, 11:31:34 AM2/7/13
to symfony-pt
Primeiramente muito obrigado Raphael,

Mas como principiante no Symfony não consegui adaptar nem entender muito bem como funciona o teu código.

Tentei adaptar o seu código no meu CRUDController (UserAdminController) da minha UserAdmin class sem muito sucesso.

Depois de muito pesquisar achei uma solução que admito que ainda não parei para interpretá-la mas que aparentemente faz o que quero, o usuário só pode realizar ações sobre os usuários criado por ele mesmo. Só falta adaptar o código para ele poder se editar também.

Segue o código que vai dentro da mina UserAdmin que estende Sonata\AdminBundle\Admin\Admin

public function createQuery($context = 'list') {
        if(!$this->isGranted('ROLE_SUPER_ADMIN')) {
            $user = $this->getConfigurationPool()->getContainer()->get('security.context')->getToken()->getUser();
            $qb = $this->createObjectsByMaskQuery($user, $this->getClass());
            return new ProxyQuery($qb);
        }
        else {
            $query = $this->getModelManager()->createQuery($this->getClass());
            return $query;
        }
    }

    public function createObjectsByMaskQuery($user, $class, $mask = MaskBuilder::MASK_OWNER) {
        $rsm = new ResultSetMapping;
        $rsm->addScalarResult('object_identifier', 'object_identifier');

        $em = $this->getModelManager($class)->getEntityManager($class);

        $query = $em->createNativeQuery('
            SELECT oid.object_identifier
                FROM
                    acl_security_identities sid
                JOIN
                    acl_entries e ON (e.security_identity_id = sid.id)
                JOIN
                    acl_object_identities oid ON (
                        e.class_id = oid.class_id
                        AND e.object_identity_id IS NOT NULL
                        AND e.object_identity_id = oid.id)
                JOIN
                    acl_classes c ON oid.class_id = c.id
                WHERE
                    c.class_type LIKE :class
                    AND e.mask & :mask
                    AND sid.identifier LIKE :username', $rsm);

        $query->setParameter('class', addslashes($class));
        $query->setParameter('mask', $mask);
        $query->setParameter('username', addslashes(get_class($user)) . '-' . $user->getUsername());

        $result = array();
        foreach ($query->getResult() as $i => $row) {
            $result[] = $row['object_identifier'];
        }

        if (!count($result)) {
            $result = array();
            $result[] = 0;
        }

        $qb = $em->getRepository($class)->createQueryBuilder('c');
        $qb->where($qb->expr()->in('c.id', $result));

        return $qb;
    }


Cassiano Valle Tartari
MSc. Computer Engineer

Tel: +55.48.84474818
Email: fal...@cassianotartari.eng.br
Site: http://www.cassianotartari.eng.br

QR Code


2013/2/7 Raphael <raphox...@gmail.com>

Raphael

unread,
Feb 7, 2013, 11:46:39 AM2/7/13
to symfo...@googlegroups.com
No seu caso ai a função 'createQuery' é gerado pelo bundle de administração. Ela é responsável por tratar os filtros e ordenações do CRUD. Então realmente vc precisa alterá-la. Eu não utilizei esse bundle, mas esse outro método 'createObjectsByMaskQuery' parece ser um método criado pelo usuário e é ele que pega o usuário da sessão e faz a consulta com base no nome do usuario quando não é um super admin.

Eu só não entendi a parte de mask ('MaskBuilder::MASK_OWNER'), mas isso pq eu não conheço o bundle.

2013/2/7 Cassiano Tartari <cassian...@gmail.com>

Cassiano Tartari

unread,
Feb 7, 2013, 2:26:58 PM2/7/13
to symfony-pt
Até da pra entender o código desse método, consegui adicionar a possibilidade do usuário se editar também adicionando somente a linha em destaque abaixo:

        $result[] = $this->securityContext->getToken()->getUser()->getId();

Cassiano Tartari

unread,
Feb 7, 2013, 2:29:19 PM2/7/13
to symfony-pt
Só pra deixar completo aqui, a variável securityContext eu obtenho assim:

    /**
     * Security Context
     * @var \Symfony\Component\Security\Core\SecurityContextInterface
     */
    protected $securityContext;

    public function setSecurityContext(SecurityContextInterface $securityContext) {
        $this->securityContext = $securityContext;
    }


E tenho o security.context injetado no service

Cassiano Valle Tartari
MSc. Computer Engineer

Tel: +55.48.84474818
Email: fal...@cassianotartari.eng.br
Site: http://www.cassianotartari.eng.br

QR Code


2013/2/7 Cassiano Tartari <cassian...@gmail.com>
Reply all
Reply to author
Forward
0 new messages