Skip to content

Instantly share code, notes, and snippets.

@awartoft
Created September 16, 2012 12:36
Show Gist options
  • Save awartoft/3732248 to your computer and use it in GitHub Desktop.
Save awartoft/3732248 to your computer and use it in GitHub Desktop.
<?php
/**
* @author Antoine Hedgecock <[email protected]>
* @author Jonas Eriksson <[email protected]>
*
* @copyright PMG Media Group AB
*/
namespace Acl;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Application;
use User\Entity\User as UserEntity;
use ExceptionManager\Exception\AccessDeniedException;
use ExceptionManager\Exception\UnauthorizedRequestException;
/**
* @category Acl
*/
class Module
{
/**
* @param MvcEvent $e
*/
public function onBootstrap(MvcEvent $e)
{
$evm = $e->getApplication()->getEventManager();
// Attach some events
$evm->attach(MvcEvent::EVENT_ROUTE, array($this, 'initiateAcl'), -1000);
$evm->attach(MvcEvent::EVENT_ROUTE, array($this, 'queryAcl'), -1000);
}
/**
* @param \Zend\Mvc\MvcEvent $e
*/
public function initiateAcl(MvcEvent $e)
{
// initiate the acl
$acl = new \Zend\Permissions\Acl\Acl();
// Get the service manager
$sm = $e->getApplication()->getServiceManager();
// save the acl to the service manager
$sm->setService('acl', $acl);
#
# Setup the roles
#
$acl->addRole('guest');
$acl->addRole('user', 'guest');
$acl->addRole('accountant', 'user');
$acl->addRole('technician', 'user');
$acl->addRole('owner', array('accountant', 'technician'));
$acl->addRole('administrator');
#
# Setup the resources
#
$acl->addResource('authorized');
$acl->addResource('unauthorized');
#
# Setup the permissions
#
// Allow the administrator do everything
$acl->allow('administrator');
// Deny the guest from doing everything!
$acl->deny('guest');
// then allow him access to unauthorized stuff
$acl->allow('guest', 'unauthorized');
}
/**
* @param \Zend\Mvc\MvcEvent $e
*/
public function queryAcl(MvcEvent $e)
{
// Get the service manager
$sm = $e->getApplication()->getServiceManager();
/**
* Get the acl
*
* @var $acl \Zend\Permissions\Acl\Acl
*/
$acl = $sm->get('acl');
/**
* Get the current user
*
* @var $user \User\Entity\User
*/
$user = $sm->get('user.service.authentication')->getIdentity();
// Current route match
$routeMatch = $e->getRouteMatch();
// Don't query when no route match is found
if ($routeMatch !== null) {
$resource = $routeMatch->getParam('acl_resource');
$privilege = $routeMatch->getParam('acl_privilege');
if ($resource == null) {
$sm->get('logger')->warn(
sprintf(
'No acl_resource has been specified for route with name: %s',
$routeMatch->getMatchedRouteName()
)
);
// Don't do anything
return;
}
// Failed authentication
if (! $acl->isAllowed($user, $resource, $privilege)) {
// If the user is not authorized then we should respond with a 401
if ($user->getRoleId() == UserEntity::ROLE_GUEST) {
$exception = new UnauthorizedRequestException();
} else {
$exception = new AccessDeniedException();
}
$e->setParam('user', $user);
$e->setParam('route', $routeMatch->getMatchedRouteName());
$e->setParam('exception', $exception);
$e->setError(Application::ERROR_EXCEPTION);
$e->getApplication()->getEventManager()->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $e);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment