Skip to content

Commit

Permalink
Authorization
Browse files Browse the repository at this point in the history
  • Loading branch information
wingman007 committed Jul 29, 2013
1 parent 970cf03 commit a7e52b2
Show file tree
Hide file tree
Showing 22 changed files with 1,818 additions and 4 deletions.
50 changes: 50 additions & 0 deletions config/autoload/acl.global.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
// http://p0l0.binware.org/index.php/2012/02/18/zend-framework-2-authentication-acl-using-eventmanager/
// First I created an extra config for ACL (could be also in module.config.php, but I prefer to have it in a separated file)
return array(
'acl' => array(
'roles' => array(
'guest' => null,
'member' => 'guest'
),
'resources' => array(
'allow' => array(
//- 'user' => array(
//- 'login' => 'guest',
//- 'all' => 'member'
//- )
'CsnUser\Controller\UserDoctrineSimpleAuthorizationAcl' => array(
// 'all' => 'guest',
'index' => 'guest',
'create' => 'member'
),
'CsnUser\Controller\UserDoctrinePureAcl' => array(
'all' => 'member',
),
'Application\Controller\Index' => array(
'all' => 'guest'
),
'Auth\Controller\Index' => array(
// 'index' => 'guest',
// 'all' => 'member',
'all' => 'guest'
),
'zfcuser' => array( // zg-commoms ZfcUser
// 'index' => 'guest',
// 'all' => 'member',
'all' => 'guest'
),
'Auth\Controller\Hello' => array(
'all' => 'guest'
),
'Auth\Controller\FormTests' => array(
'all' => 'guest'
),
'AuthDoctrine\Controller\Index' => array(
'all' => 'guest'
// 'all' => 'member',
),
)
)
)
);
7 changes: 7 additions & 0 deletions config/autoload/global.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
// added for Authorization. Without this each time we have to create a new instance.
'aliases' => array( // !!! aliases not alias
'Zend\Authentication\AuthenticationService' => 'my_auth_service',
),
'invokables' => array(
'my_auth_service' => 'Zend\Authentication\AuthenticationService',
),
),
);
Expand Down
27 changes: 27 additions & 0 deletions fmi_user_roles.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--
-- Table structure for table `user_roles`
--

DROP TABLE IF EXISTS `user_roles`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `user_roles` (
`usrl_id` int(11) NOT NULL AUTO_INCREMENT,
`usrl_name` varchar(50) NOT NULL,
PRIMARY KEY (`usrl_id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COMMENT='The System Roles. Who can see and do what';
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `user_roles`
--

LOCK TABLES `user_roles` WRITE;
/*!40000 ALTER TABLE `user_roles` DISABLE KEYS */;
INSERT INTO `user_roles` VALUES (1,'Public'),(2,'Prospect'),(3,'Member'),(4,'Admin');
/*!40000 ALTER TABLE `user_roles` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `user_tree_type_values`
--
8 changes: 6 additions & 2 deletions module/Auth/src/Auth/Controller/IndexController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function loginAction()
$form = new AuthForm();
$form->get('submit')->setValue('Login');
$messages = null;

$request = $this->getRequest();
if ($request->isPost()) {
$authFormFilters = new Auth();
Expand All @@ -53,7 +53,9 @@ public function loginAction()
;

$auth = new AuthenticationService();

// or prepare in the globa.config.php and get it from there
// $auth = $this->getServiceLocator()->get('Zend\Authentication\AuthenticationService');
// $sm->setService('Zend\Authentication\AuthenticationService', $auth); // You can set the service here but will be loaded only if this action called.
$result = $auth->authenticate($authAdapter);

switch ($result->getCode()) {
Expand Down Expand Up @@ -88,6 +90,8 @@ public function loginAction()
public function logoutAction()
{
$auth = new AuthenticationService();
// or prepare in the globa.config.php and get it from there
// $auth = $this->getServiceLocator()->get('Zend\Authentication\AuthenticationService');

if ($auth->hasIdentity()) {
$identity = $auth->getIdentity();
Expand Down
60 changes: 59 additions & 1 deletion module/CsnUser/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace CsnUser;

// for Acl
use CsnUser\Acl\Acl;

class Module
{
public function getConfig()
Expand All @@ -18,5 +21,60 @@ public function getAutoloaderConfig()
),
),
);
}
}

// FOR Authorization
public function onBootstrap(\Zend\EventManager\EventInterface $e) // use it to attach event listeners
{
$application = $e->getApplication();
$em = $application->getEventManager();
$em->attach('route', array($this, 'onRoute'), -100);
}

// WORKING the main engine for ACL
public function onRoute(\Zend\EventManager\EventInterface $e) // Event manager of the app
{
$application = $e->getApplication();
$routeMatch = $e->getRouteMatch();
$sm = $application->getServiceManager();
$auth = $sm->get('Zend\Authentication\AuthenticationService');
$config = $sm->get('Config');
$acl = new Acl($config);
// everyone is guest untill it gets logged in
$role = Acl::DEFAULT_ROLE; // The default role is guest $acl
if ($auth->hasIdentity()) {
$usr = $auth->getIdentity();
$usrl_id = $usr->usrl_id; // Use a view to get the name of the role
// TODO we don't need that if the names of the roles are comming from the DB
switch ($usrl_id) {
case 1 :
$role = Acl::DEFAULT_ROLE; // guest
break;
case 2 :
$role = 'member';
break;
default :
$role = Acl::DEFAULT_ROLE; // guest
break;
}
}
$controller = $routeMatch->getParam('controller');
$action = $routeMatch->getParam('action');

if (!$acl->hasResource($controller)) {
throw new \Exception('Resource ' . $controller . ' not defined');
}

if (!$acl->isAllowed($role, $controller, $action)) {
$url = $e->getRouter()->assemble(array(), array('name' => 'home'));
$response = $e->getResponse();

$response->getHeaders()->addHeaderLine('Location', $url);
// The HTTP response status code 302 Found is a common way of performing a redirection.
// http://en.wikipedia.org/wiki/HTTP_302
$response->setStatusCode(302);
$response->sendHeaders();
exit;
}
}
}
7 changes: 6 additions & 1 deletion module/CsnUser/config/module.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@

'CsnUser\Controller\UserDoctrineDbal' => 'CsnUser\Controller\UserDoctrineDbalController',
'CsnUser\Controller\UserDoctrineSeparatedForm' => 'CsnUser\Controller\UserDoctrineSeparatedFormController',
'CsnUser\Controller\UserDoctrine' => 'CsnUser\Controller\UserDoctrineController',
'CsnUser\Controller\UserDoctrine' => 'CsnUser\Controller\UserDoctrineController', // the final form

// Authorization
'CsnUser\Controller\UserDoctrineSimpleAuthorization' => 'CsnUser\Controller\UserDoctrineSimpleAuthorizationController',
'CsnUser\Controller\UserDoctrineSimpleAuthorizationAcl' => 'CsnUser\Controller\UserDoctrineSimpleAuthorizationAclController',
'CsnUser\Controller\UserDoctrinePureAcl' => 'CsnUser\Controller\UserDoctrinePureAclController',
),
),
'router' => array(
Expand Down
129 changes: 129 additions & 0 deletions module/CsnUser/src/CsnUser/Acl/Acl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php
/**
* File for Acl Class
*
* @category User
* @package User_Acl
* @author Marco Neumann <webcoder_at_binware_dot_org>
* @copyright Copyright (c) 2011, Marco Neumann
* @license http://binware.org/license/index/type:new-bsd New BSD License
* http://p0l0.binware.org/index.php/2012/02/18/zend-framework-2-authentication-acl-using-eventmanager/
*/

/**
* @namespace
*/
namespace CsnUser\Acl;
// namespace User\Acl;

/**
* @uses Zend\Acl\Acl
* @uses Zend\Acl\Role\GenericRole
* @uses Zend\Acl\Resource\GenericResource
*/
use Zend\Permissions\Acl\Acl as ZendAcl,
Zend\Permissions\Acl\Role\GenericRole as Role,
Zend\Permissions\Acl\Resource\GenericResource as Resource;
// use Zend\Acl\Acl as ZendAcl,
// Zend\Acl\Role\GenericRole as Role,
// Zend\Acl\Resource\GenericResource as Resource;

/**
* Class to handle Acl
*
* This class is for loading ACL defined in a config
*
* @category User
* @package User_Acl
* @copyright Copyright (c) 2011, Marco Neumann
* @license http://binware.org/license/index/type:new-bsd New BSD License
*/
class Acl extends ZendAcl {
/**
* Default Role
*/
const DEFAULT_ROLE = 'guest';

/**
* Constructor
*
* @param array $config
* @return void
* @throws \Exception
*/
public function __construct($config)
{
if (!isset($config['acl']['roles']) || !isset($config['acl']['resources'])) {
throw new \Exception('Invalid ACL Config found');
}

$roles = $config['acl']['roles'];
if (!isset($roles[self::DEFAULT_ROLE])) {
$roles[self::DEFAULT_ROLE] = '';
}

$this->_addRoles($roles)
->_addResources($config['acl']['resources']);
}

/**
* Adds Roles to ACL
*
* @param array $roles
* @return User\Acl
*/
protected function _addRoles($roles)
{
foreach ($roles as $name => $parent) {
if (!$this->hasRole($name)) {
if (empty($parent)) {
$parent = array();
} else {
$parent = explode(',', $parent);
}

$this->addRole(new Role($name), $parent);
}
}

return $this;
}

/**
* Adds Resources to ACL
*
* @param $resources
* @return User\Acl
* @throws \Exception
*/
protected function _addResources($resources)
{
foreach ($resources as $permission => $controllers) {
foreach ($controllers as $controller => $actions) {
if ($controller == 'all') {
$controller = null;
} else {
if (!$this->hasResource($controller)) {
$this->addResource(new Resource($controller));
}
}

foreach ($actions as $action => $role) {
if ($action == 'all') {
$action = null;
}

if ($permission == 'allow') {
$this->allow($role, $controller, $action);
} elseif ($permission == 'deny') {
$this->deny($role, $controller, $action);
} else {
throw new \Exception('No valid permission defined: ' . $permission);
}
}
}
}

return $this;
}
}
Loading

0 comments on commit a7e52b2

Please sign in to comment.