Cauan Cabral's.

[Comitiva] Como utilizar controle de permissão no sistema

Cauan Cabral
Cauan Cabral
Posted underCakePHPPHPProjetos

Como escrevi anteriormente, o PHPMS mantém um sistema para gerenciar eventos – desde a divulgação de informações, cadastro de eventos, inscrições, pagamentos, envio de mensagens para inscritos e check-in.

Mas o objetivo deste post não é dizer o que já foi dito, quero iniciar uma série de posts onde vou explicar o funcionamento de alguns recursos dentro do Comitiva, convidando todos os desenvolvedores a opinar sobre implementação e contribuir com o projeto.

O assunto de hoje é controle de acesso, então vamos ao que interessa.

Como funciona o controle de acesso no Comitiva?

Utilizamos o componente Auth do CakePHP para cuidar da autenticação (efetuar login, verificar se o usuário está logado e efetuar logout).
Mas precisávamos ir um pouco além da configuração básica, definindo diferentes opções para diferentes tipos de usuários. Para isso, consideramos duas opções iniciais: usar também o Acl Behavior ou ficar apenas com o AuthComponent e criar diferentes actions para diferentes tipos de usuários.

Como possuímos apenas dois tipos de usuários (admin e participant) decidimos pela que seria mais simples inicialmente – mesmo sabendo que a manutenção no futuro poderia ser mais complicada – que foi criar diferentes actions para os tipos de usuários.

Para criar essa funcionalidade, definimos inicialmente um prefixo para cada tipo de usuário (prefixos ‘admin‘ e ‘participant‘). Em seguida configuramos o AuthComponent desta maneira (código extraído do AppController):

//Configure AuthComponent
$this->Auth->authorize = 'controller';

if( !isset($this->params['prefix']) || !( in_array($this->params['prefix'], Configure::read('Routing.prefixes')) ) )
{
	// all non-prefixed actions are allowed
	$this->Auth->allow('*');
}

Ou seja, toda ação que não tiver prefixo ou o prefixo não estiver definido nas configurações de rota serão públicas (assim é possível, por exemplo, deixar uma página com instruções acessível à qualquer usuário).

Mas como fica essa verificação de tipos no controlador? Como definimos o método de autorização do Auth como ‘controller’, precisamos definir em todos os controladores o método isAuthorized que deve retornar true quando o acesso é aprovado e false caso contrário.
Seguindo a ideia de que cada tipo de usuário possui um prefixo próprio nas ações, nosso método isAuthorized fica desta forma:

if($this->userLogged == TRUE && $this->params['prefix'] == User::get('type'))
{
	return true;
}

return false;

Onde o atributo $this->userLogged pertence a classe AppController e sua função é reduzir chamada ao método $Auth->login() e na segunda parte da condição temos uma comparação entre o prefixo da url acessada e o tipo do usuário – se ambos forem iguais, então o acesso está liberado.

Por fim, devemos criar nossas ações para cada tipo de usuário, onde o prefixo será usado para validar o acesso à aquela ação, veja o exemplo da ação “listar pagamentos”:

// ação exclusiva para admin - tem acesso aos pagamentos de todos os outros usuários
public function admin_index($event_id = null)
{
	$this->Subscription->recursive = 0;
		
	if(is_numeric($event_id))
	{
		$this->paginate = array(
			'conditions' => array(
				'event_id' => $event_id
			)
		);
	}
		
	$this->set(compact('event_id'));
	$this->set('subscriptions', $this->paginate());
}

// ação exclusiva para participant - tem acesso somente aos próprios pagamentos
public function participant_index()
{
	$this->Subscription->recursive = 0;
	$this->set('subscriptions', $this->paginate(array('user_id' => User::get('id'))));
}

Como podem ver, isso permite a criação de diferentes regras de negócio para os diferentes tipos de usuários e embora aumente a quantidade de código “redundante” por repetir alguns procedimentos para todos os tipos de usuários, a leitura e entendimento do código é facilitada – basta ver o prefixo do método (ação) para saber quem terá acesso a ele.

TaggedCakePHPcomitiva


pgModeler – gerando o seu binário

Cauan Cabral
Cauan Cabral

Tem algumas aplicações que são icônicas pra gente – por diversas razões – no meu caso, alguns destes são winamp, mIRC, Macromedia Flash MX, Amarok, Kompare, MySQL Workbench e Gitlab. Outro que conheci e me deixou admirado quando descobri foi o pgModeler, primeiro pela qualidade da aplicação em si que é o mais próximo do […]

Dica Rápida: usando tipos “complexos” com Migrations no Phinx

Cauan Cabral
Cauan Cabral

Essa é uma dica bem curta e realmente rápida pra registrar algo que precisei pesquisar algumas vezes nos últimos anos e sempre me esqueço. Cena: você define uma tabela no seu projeto e gostaria de usar uma coluna com o tipo tsvector (como citei em posts recentes) ou então uuid. Você quer usar as funções […]