10 de setembro de 2011  //  27 Comentários  //  Categorias: CakePHP, Plugins, Tutoriais

Utilizando o Plugin ACL Caching no CakePHP 1.3



Utilizar ACL no CakePHP é essencial para qualquer sistema. Contudo, conforme vamos nos aprofundamos, verificamos algumas falhas e começamos a personaliza-lo a nossa maneira. Neste tutorial quero compartilhar um plugin que desenvolvi para utiliza-lo em meus projetos e aposto que você vai gostar de usa-lo também.

ACL Caching

ACL_Caching é um plugin que estende as funcionalidades do AclComponente, com algumas funções diferenciadas, porém, o aspecto mais positivo é o ganho de performance

Desvantagem

  • Carrega todas as permissões no login, sendo necessário realizar logout caso queria que novas definições de acesso entrem em vigor. Contudo, esta desvantagem pode ser “revertida” pela função especial checkDB() presente no plugin.

A View que define as permissões de acesso do sistema, utiliza sistema de permissão Action/Action, ou seja, você não conseguirá permitir o Controller Usurarios para automaticamente liberar todas as Actions pertencente a ele. Contudo, o ACL_Caching apenas não define as permissões desta forma, portanto, você pode se desejar continuar utilizando este sistema de permissão.

Vantagens

  • Carrega todas as permissões no login, evitando excessos de consultas no banco;
  • Pode ser chamado pelo Controller ou View;
  • Conta com funções especiais como: checkIfOne(), checkIfAll() e checkDB();
  • Conta com o Helper Acl_HTML que exibe links apenas para os usuários com permissão.

Compatibilidade

  • Compatível com CakePHP v 1.3

Instalação

Em novos projetos

Se você esta ainda desenvolvendo o seu projeto, recomendo que você siga este tutorial: Controle de acesso a nível grupo/usuário no CakePHP 1.3 + ACL + Caching.

Caso o seu projeto já esteja em produção, continue este mesmo tutorial.

Download

Antes de iniciar, baixe o ACL_Caching. Copie os arquivos para a pasta /app/plugins/acl_caching ou em outro diretório para plugins do CakePHP.

Se preferir, utilize o git:
git clone https://github.com/pedroelsner/acl_caching.git

Configurações

Você pode substituir o ACL pelo ACL_Caching com segurança em sua aplicação. Para evitar problemas e transtorno de alterações de códigos, este plugin responde pelo comando $this->AclCaching ou $this->Acl, garantindo assim o funcionamento imediato do plugin após a instalação e configuração.

É importante ressaltar que você deve substituir o Acl pelo Acl_Caching em sua aplicação.

Basta alterar as seguinte variáveis em seu app_controler.php e tudo estará funcionando de forma “automágica”:

Vamos ver os parâmetros de configurações do componente:

  • contain Se você definir o recursive de todos os Models como -1, configure está opção como true;
  • model Informe o model responsável pelos grupos dos usuário;
  • primaryKey Informe o nome do campo;
  • displayField Informe o nome do campo;
  • foreignKey Informe o nome do campo que consta na tabela de usuários.

Definições de acesso

O ACL_Caching identifica as definições de acesso como sendo action/action, ou seja, você não consegue permitir o Controller Usuarios e por consequência todas as Actions dele – como acontece no funcionamento normal do Acl.

Portanto, você pode apagar todas as definições do banco e cria-las rapidamente novamente, ou, acessar a página de definições e “corrigir” o que estiver “errado”…

Acesse a url http://seusite.com/admin/acl_caching/acl/ e defina as permissões de acesso para os grupos cadastrados. Uma tela parecida com está será exibida:

Utilização

Você pode chamar as funções do Acl_Plugin nos controllers utilizando $this->Acl ou $this->AclCaching, pode também chama-las nas views através das variáveis $Acl ou $AclCaching.

Funções especiais

check()

Esta função verifica se o usuário logado tem permissão de acesso para a url informada.

Note que o primeiro parâmetro referente ao ARO (usuário/grupo) não foi informado – fixado como null. Isto acontece porque está função verifica SOMENTE a permissão do usuário logado.

Se você deseja pegar a permissão de outro usuário, utilize a função checkDB().

checkIfOne()

Esta função verifica se o usuário logado tem permissão de acesso em pelo menos UMA url.

Note que o primeiro parâmetro referente ao ARO (usuário/grupo) não foi informado – fixado como null. Isto acontece porque está função verifica SOMENTE a permissão do usuário logado.

Se você deseja pegar a permissão de outro usuário, utilize a função checkDB().

checkIfAll()

Esta função verifica se o usuário logado tem permissão de acesso em TODAS as urls.

Note que o primeiro parâmetro referente ao ARO (usuário/grupo) não foi informado – fixado como null. Isto acontece porque está função verifica SOMENTE a permissão do usuário logado.

Se você deseja pegar a permissão de outro usuário, utilize a função checkDB().

checkDB()

Está função é utilizada para verificar a permissão de acesso de um determinado usuário a uma url específica, verificando diretamente no banco de dados.

Sendo assim, como o plugin grava as permissões de acesso em uma variável de sessão no login, você pode utiliza-la para forçar o sistema a utilizar o banco de dados para verificar a permissão de acesso.

forceAllow()

Quando utilizamos Auth ou ACL, para podermos liberar o acesso a todas as Actions do sistema usamos a função $this->Auth->allow('*'). Agora, utilizando o plugin ACL_Caching usaremos $this->AclCaching->forceAllow().

Chamando está função, desativamos todo o sistema de permissão, liberando acesso a todas as Actions do sistema e exibindo todos os links do Helper Acl_HTML:

flushCache()

Apaga a sessão que armazena as permissões de acesso. O plugin automaticamente carrega todas as permissões quando a função check() for solicitada.

Helper Acl_Html

Este Helper foi desenvolvido simplesmente para ocultar links que os usuário não tenham permissão para acessar. =]

Vamos supor que temos o link ‘Adicionar novo Post’ e desejamos mostra-lo apenas para usuários com permissão para cadastrar, então usaremos o Helper Acl_Html ao invés do Html.

Haverá situação que você deseja exibir apenas o texto ‘Adicionar novo Post’ se o usuário não tiver permissão de acesso (ao invés de não exibir nada). Para isso, usamos a opção show definida como true.

Conclusão

O plugin ACL_Caching foi desenvolvido devido as necessidades que encontrei em meus projetos. Contudo, ele está longe do ideal e eu já tenho algumas novas funções para implementa-lo. Você pode participar enviando sugestões.

Espero que ele ajude você, tanto quanto tem me ajudado. ^^’

Termos de busca

Quer copiar esse post no seu site? Você pode!

Segundo a licença da Creative Commons 3.0 (CC BY SA 3.0) você pode copiar e distribuir esse conteúdo desde que faça menção ao autor original, para isso é só copiar esse código no final do artigo quando for publicá-lo em seu site:

<p>Artigo originalmente publicado em <em>10 de setembro de 2011</em> por <strong><a href="http://pedroelsner.com/" title="Pedro Elsner, Profissional de TI - São Paulo">Pedro Elsner</a></strong>: <a href="http://pedroelsner.com/2011/09/utilizando-o-plugin-acl-caching-no-cakephp/" title="Utilizando o Plugin ACL Caching no CakePHP 1.3">Utilizando o Plugin ACL Caching no CakePHP 1.3</a></p>
A não menção ao autor original da obra implicará em cópia e/ou distribuição ilegal de propriedade intelectual, o que é crime segundo a Lei n.º 9.610.
  • Neto Basilio

    Parabéns pelo trabalho!!!

  • Obrigado Neto.

  • Daniel Pakuschewski

    Cara fico muito bacana o plugin, vou dar uma testada nele em um próximo projeto.

  • Amigo, eu não consegui fazer aparecer os links.
    O primeiro acesso q faço no admin, aparece a msg:
    “Undefined offset: 0 [APPpluginsacl_cachingcontrollerscomponentsacl_caching.php, line 315]”
    e
    “Invalid argument supplied for foreach() [APPpluginsacl_cachingcontrollerscomponentsacl_caching.php, line 315]”

    Daí qdo atualizo o erro some, porém os links não aparecem sob hipótese alguma.
    Eu já dei as permissões no /acl_caching/acl/ e meus links estão assim:
                            if ($AclCaching->check(null, array(‘controller’ =>’pages’, ‘action’ =>’admin_index’))){
                                echo $this->Html->link(‘Pages’,array( ‘controller’=>’pages’, ‘action’=>’admin_index’, ‘admin’=>true));
                            }
                            if ($AclCaching->check(null, array(‘controller’ =>’grupos’, ‘action’ =>’admin_index’))){
                                echo $this->Html->link(‘Grupos’,array( ‘controller’=>’grupos’, ‘action’=>’admin_index’, ‘admin’=>true));
                            }

    e
    AclHtml->link(
                          __(‘Grupos’, true),
                          array(
                            ‘controller’ => ‘grupos’,
                            ‘action’     => ‘admin_index’,
                            ‘admin’      => true
                          )
                        )?>

    Mas não aparecem, exceto quando eu descomento a $this->AclCaching->forceAllow();

    Pode me ajudar?

  • Fala Marcelo, beleza? ^^

    Ainda hoje vou realizar a instação de uma nova aplicação e ver se tenho o mesmo problema. Te retorno logo em seguida.

    Abraços!

  • Eu coloquei a opção: array( ‘show’ => true ) no link, e aparece agora o texto sem link… porém eu verifiquei e meu usuários tem as permissões.
    Fiz um teste, coloquei 2 link com permissão e 2 sem, porém aparecem todos como texto, sem link.

    Não sei o que pode ser, tentei analizar as funções do seu plugin, porém não encontrei nada.
    Esse offset aí é estranho, é como se o Auth não estivesse sendo chamado.

  • Baaaah, num acredito.
    Cara, eu tava viajando…. eu segui o seu tutorial desde o início, qdo criou apenas o model User, depois pulei pro model Groups e esqueci de adicionar o belongsTo group na model User… aff
    Agora deu certinho, funcionando perfeitamente!!!
    Obrigado pela atenção cara!!

    Excelente plugin e excelente profissional!

  • hehe acontece! ^^

    Analizando seu código, você pode utiliza o helper AclHtml para exibir o link, sem precisar verificar pelo AclCaching->Check

    Veja como usar o helper neste tutorial: http://pedroelsner.com/2011/09/utilizando-o-plugin-acl-caching-no-cakephp/

    Obrigado pelas palavras, qualquer coisa conte comigo!

    Abraços! =]

  • Bah cara, eu falei cedo demais.
    Fui testar novamente, eu vi que na verdade apos eu colocar belongsTo, apenas parou de aparecer o erro de Offset… mas o problema continua: Assim que eu logo, todos os links (permitidos e nao permitidos) sao listados, dai eu dou um refresh na pagina, e todos os links passam a ser apenas texto.
    Nao sei, fiquei sem ideia do q fazer agora.

  • Marcelo, tem um tutorial aqui no site que explica como utilizar e instalar o plugin do zero.

    Olhe as configurações que ele faz e veja se tem alguma coisa faltando.
    Criei uma aplicação teste aqui e esta tudo funcionando perfeiramente:

    Tutorial de utilização: http://pedroelsner.com/2011/07/controle-de-acesso-a-nivel-grupo-usuario-no-cakephp/

  • Tyler Developer

    Pôxa Pedro, você começou humilde lá no iMasters com a gente e já tá esse cara maneiro aí no cake hehehe 🙂

  • Hehehe, estou meio afastado.
    Mas agora em 2012 vou voltar com tudo! xD

  • Vinicius

    Olá Pedro..!!
    estou estudando seu plugin e achei muito interessante..!

    gostaria de saber o seguinte:
    o que signific:
    “ACL_Caching identifica as definições de acesso como sendo action/action”qual a diferença disso para a abordagem do ACL padrão? (do tutorial do book?)

    Agradeço a atenção

    Vinicius

  • Fala Vinicius,

    Siguinifica o seguinte: que você vai precisar atribuir a permissao de acesso de cada action de seu sistema para seu usuário (action/action = action por action) ^^

    O funcionamento padrão do ACL (sem o plugin) identifica que se eu liberar o controller para o usuário X, automaticamente estou liberando todas as actions.

    Veja, a tela de configuração do plugin não permiter liberar um controller para o usuario mas apenas action/action.

    Entretanto, devido a diversos e-mails, a presente versão do plugin no meu respositório do GIT trabalha e identifica a permissão por controller. Portanto se você desejar apenas usar o sistema de cache, continuar controlando as pemissões do seu jeito (não utilizando o painel do plugin) ele irá funcionar sem problemas! =D

    Ainda neste restinho de 2012 devo lançar a versão dele para Cake 2 com várias novidades =DDD

    Abraços!

  • Francis Rodrigues

    Se numa action eu tentar recuperar a id dela com $this->Model->id, gera erro no cache =(

  • Pedro

    Como ficaria esse login sem o seu plugin acl_caching? to tentando usar o cake 2.0 mas o seu so e compativel com o 1.3, e o book tem um exemplo la, mas nao consigo entender esse book, muito superficial.

    Obrigado

  • Pode parecer mentira, mas o preguiçoso aqui ainda nem baixou o cake 2.0 ^^’
    Agora eu não consigo te ajudar. Assim que pintar um novo job pra mim, vou utilizar cake 2.0 e reescrever esse plugin para toda a comunidade =D

  • Guilherme_vpusch

     Esse Plugin é muito bom. agiliza totalmente o cake.
    mas tenho somente um caso.
    Eu tinha dentro de um controller relatorios a action financeiro.
    Apos isso, meses depois foi criado um controller financeiro.
    Sendo assim, ficou no painel permissão para todas as actions do controller financeiro se voce ja tivesse permissão para ver a action financeiro do controler relatorio e eu nao conseguia negar as permissões.

    Outra coisa, o plugin é para usuarios e grupos? pois só consigo setar permissões para grupos, não sei como acessar um painel para um usuario especifico. tem como?

  • Beleza Guilherme?

    1- Você chegou a utilizar o ACL_Extras para atualizar a lista de ACOS da sua aplicação?
    2- Infelizmente nesta versão do plugin apenas é possível atribuir permissão para grupos. (Na versão para Cake2 que estou preparando não será mais assim).

    Abraços!

  • Guilherme_vpusch

    Boa Tarde,

    Como faço para ignorar uma action, posso colocar com _action mas ai nao acesso via url.
    O ForceAllow ignora a acao do painel de permissões? é possivel utilizar ele para uma só função ou ele é global somente?

    O ex:
    Relatorio X –
    Tem um formulario que gera o relatorio. Ja dei permissao ao cliente.
     Tenho que dar permissao a todas outras actions para que relatorio seja acessivel, não seria possivel eu ignorar eles do acl?
    Assim dou permissao somente ao formulario que gera o relatorio e nao as actions que mostram o relatorio.

  • Guilherme_vpusch

     Boa Tarde.

    Existe alguma limitacao de quantidade de acos e aros no acl caching?
    Pois chego uma uma que fomos atualizando as acls, que nao conseguia mais atribuir nenhuma permissao.
    ficava estatico.

  • Guilherme, não existe limites…

  • Pedro, td bom?
    Quando vamos começar a estudar ACL no Cake 2.2, por exemplo?

  • Hehehe
    Estou devendo a atualização do plugin ha um bom tempo..
    Vamos ver Tyler, quem sabe nesse restinho de ano saí xD

  • Ótimo, vou começar a estudar o cake 2, não sei em qual versão está mas pretendo estudar a
    última estável.

  • Pedro estou tentando listar apenas os controllers para criar um painel de gerenciamento, mas não estou conseguindo. Tem alguma idéia?

  • Alex Monte

    Consegui adaptar 99% dele para o CakePhp 2.X

    Uma coisa que eu nao entendo é em q momento ele gera o Auth.Permissions em momenot eh executado o check ?