Skip to content
Snippets Groups Projects
Commit 2b13a20f authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

Intégration de la gestion des privilèges et des droits.

parent 87b6f3a7
Branches
Tags
No related merge requests found
Showing
with 1484 additions and 236 deletions
......@@ -2,6 +2,7 @@
namespace UnicaenAuth;
use UnicaenAuth\Guard\PrivilegeController;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
......@@ -23,6 +24,8 @@ class Module implements ConfigProviderInterface, ServiceProviderInterface
return include __DIR__ . '/config/module.config.php';
}
/**
*
* @return array
......@@ -42,14 +45,18 @@ class Module implements ConfigProviderInterface, ServiceProviderInterface
];
}
/**
* This method is called once the MVC bootstrapping is complete,
* after the "loadModule.post" event, once $application->bootstrap() is called.
*
* @param EventInterface $e
*
* @see BootstrapListenerInterface
*/
public function onBootstrap(\Zend\EventManager\EventInterface $e) /* @var \Zend\Mvc\MvcEvent $e */
public function onBootstrap(\Zend\EventManager\EventInterface $e)
/* @var \Zend\Mvc\MvcEvent $e */
{
$application = $e->getApplication();
/* @var $services \Zend\ServiceManager\ServiceManager */
......@@ -57,11 +64,11 @@ class Module implements ConfigProviderInterface, ServiceProviderInterface
// transmission des ACL aux aides de vue de navigation
try {
$authorizeService = $services->get('BjyAuthorize\Service\Authorize'); /* @var $authorizeService \BjyAuthorize\Service\Authorize */
$authorizeService = $services->get('BjyAuthorize\Service\Authorize');
/* @var $authorizeService \BjyAuthorize\Service\Authorize */
\Zend\View\Helper\Navigation::setDefaultAcl($authorizeService->getAcl());
\Zend\View\Helper\Navigation::setDefaultRole($authorizeService->getIdentity());
}
catch (\Zend\ServiceManager\Exception\ServiceNotFoundException $snfe) {
} catch (\Zend\ServiceManager\Exception\ServiceNotFoundException $snfe) {
// pas de module BjyAuthorize : pas d'ACL
}
......@@ -107,11 +114,13 @@ class Module implements ConfigProviderInterface, ServiceProviderInterface
],
],
],
]
],
]);
}
}
/**
*
* @return array
......@@ -127,9 +136,45 @@ class Module implements ConfigProviderInterface, ServiceProviderInterface
$form = new \ZfcUser\Form\Login(null, $options);
$form->setInputFilter(new \ZfcUser\Form\LoginFilter($options));
$form->get('identity')->setLabel("Username");
return $form;
},
],
];
}
/**
* Retourne le menu de navigation (à placer où vous voulez)!!
*
* @return array
*/
static public function getDroitsNavigation($label=null, $title=null)
{
if (!$label) $label = "Droits d'accès";
if (!$title) $title = "Gestion des droits d'accès";
return [
'label' => $label,
'title' => $title,
'route' => 'droits',
'resource' => PrivilegeController::getResourceId('UnicaenAuth\Controller\Droits','index'),
'pages' => [
'roles' => [
'label' => "Rôles",
'title' => "Gestion des rôles",
'route' => 'droits/roles',
'resource' => PrivilegeController::getResourceId('UnicaenAuth\Controller\Droits','roles'),
'withtarget' => true,
],
'privileges' => [
'label' => "Privilèges",
'title' => "Gestion des privilèges",
'route' => 'droits/privileges',
'resource' => PrivilegeController::getResourceId('UnicaenAuth\Controller\Droits','privileges'),
'withtarget' => true,
],
],
];
}
}
\ No newline at end of file
<?php
use UnicaenAuth\Provider\Privilege\Privileges;
$settings = [
'entity_manager_name' => 'doctrine.entitymanager.orm_default', // nom du gestionnaire d'entités à utiliser
/**
* Fournisseurs d'identité.
*/
'identity_providers' => [
300 => 'UnicaenAuth\Provider\Identity\Basic', // en 1er
200 => 'UnicaenAuth\Provider\Identity\Db', // en 2e
100 => 'UnicaenAuth\Provider\Identity\Ldap', // en 3e
100 => 'UnicaenAuth\Provider\Identity\Ldap', // en 3e @deprecated
],
];
$zfcuserSettings = [
return [
'zfcuser' => [
/**
* Enable registration
* Allows users to register through the website.
......@@ -69,9 +75,8 @@ $zfcuserSettings = [
'user_entity_class' => 'UnicaenAuth\Entity\Db\User',
// telling ZfcUserDoctrineORM to skip the entities it defines
'enable_default_entities' => false,
];
$bjyauthorize = [
],
'bjyauthorize' => [
/* this module uses a meta-role that inherits from any roles that should
* be applied to the active user. the identity provider tells us which
* roles the "identity role" should inherit from.
......@@ -101,10 +106,7 @@ $bjyauthorize = [
* NB: si le rôle par défaut 'guest' est fourni ici, il ne sera pas ajouté en double dans les ACL.
* NB: si la connexion à la base échoue, ce n'est pas bloquant!
*/
'UnicaenAuth\Provider\Role\DbRole' => [
'object_manager' => 'doctrine.entitymanager.orm_default',
'role_entity_class' => 'UnicaenAuth\Entity\Db\Role',
],
'UnicaenAuth\Provider\Role\DbRole' => [],
/**
* Fournit le rôle correspondant à l'identifiant de connexion de l'utilisateur.
* Cela est utile lorsque l'on veut gérer les habilitations d'un utilisateur unique
......@@ -113,6 +115,14 @@ $bjyauthorize = [
'UnicaenAuth\Provider\Role\Username' => [],
],
'rule_providers' => [
//'UnicaenAuth\Provider\Rule\PrivilegeRuleProvider' => [],
],
'resource_providers' => [
'UnicaenAuth\Service\Privilege' => [],
],
// strategy service name for the strategy listener to be used when permission-related errors are detected
// 'unauthorized_strategy' => 'BjyAuthorize\View\RedirectionStrategy',
'unauthorized_strategy' => 'UnicaenAuth\View\RedirectionStrategy',
......@@ -138,12 +148,38 @@ $bjyauthorize = [
['controller' => 'UnicaenApp\Controller\Application', 'action' => 'refresh-session', 'roles' => []],
['controller' => 'UnicaenAuth\Controller\Utilisateur', 'action' => 'selectionner-profil', 'roles' => []],
],
'UnicaenAuth\Guard\PrivilegeController' => [
[
'controller' => 'UnicaenAuth\Controller\Droits',
'action' => ['index'],
'privileges' => [
Privileges::DROIT_ROLE_VISUALISATION,
Privileges::DROIT_PRIVILEGE_VISUALISATION,
],
],
[
'controller' => 'UnicaenAuth\Controller\Droits',
'action' => ['roles'],
'privileges' => [Privileges::DROIT_ROLE_VISUALISATION],
],
[
'controller' => 'UnicaenAuth\Controller\Droits',
'action' => ['privileges'],
'privileges' => [Privileges::DROIT_PRIVILEGE_VISUALISATION],
],
[
'controller' => 'UnicaenAuth\Controller\Droits',
'action' => ['role-edition', 'role-suppression'],
'privileges' => [Privileges::DROIT_ROLE_EDITION],
],
[
'controller' => 'UnicaenAuth\Controller\Droits',
'action' => ['privileges-modifier'],
'privileges' => [Privileges::DROIT_PRIVILEGE_EDITION],
],
],
],
],
];
return [
'zfcuser' => $zfcuserSettings,
'bjyauthorize' => $bjyauthorize,
'unicaen-auth' => $settings,
'doctrine' => [
'driver' => [
......@@ -170,41 +206,6 @@ return [
],
],
],
'service_manager' => [
'aliases' => [
'Zend\Authentication\AuthenticationService' => 'zfcuser_auth_service',
],
'invokables' => [
'unicaen-auth_user_service' => 'UnicaenAuth\Service\User',
'UnicaenAuth\Authentication\Storage\Db' => 'UnicaenAuth\Authentication\Storage\Db',
'UnicaenAuth\Authentication\Storage\Ldap' => 'UnicaenAuth\Authentication\Storage\Ldap',
'UnicaenAuth\View\RedirectionStrategy' => 'UnicaenAuth\View\RedirectionStrategy',
'authUserContext' => 'UnicaenAuth\Service\UserContext',
],
'abstract_factories' => [
'UnicaenAuth\Authentication\Adapter\AbstractFactory',
],
'factories' => [
'unicaen-auth_module_options' => 'UnicaenAuth\Options\ModuleOptionsFactory',
'zfcuser_auth_service' => 'UnicaenAuth\Authentication\AuthenticationServiceFactory',
'UnicaenAuth\Authentication\Storage\Chain' => 'UnicaenAuth\Authentication\Storage\ChainServiceFactory',
'UnicaenAuth\Provider\Identity\Chain' => 'UnicaenAuth\Provider\Identity\ChainServiceFactory',
'UnicaenAuth\Provider\Identity\Ldap' => 'UnicaenAuth\Provider\Identity\LdapServiceFactory',
'UnicaenAuth\Provider\Identity\Db' => 'UnicaenAuth\Provider\Identity\DbServiceFactory',
'UnicaenAuth\Provider\Identity\Basic' => 'UnicaenAuth\Provider\Identity\BasicServiceFactory',
'UnicaenAuth\Provider\Role\Config' => 'UnicaenAuth\Provider\Role\ConfigServiceFactory',
'UnicaenAuth\Provider\Role\DbRole' => 'UnicaenAuth\Provider\Role\DbRoleServiceFactory',
'UnicaenAuth\Provider\Role\Username' => 'UnicaenAuth\Provider\Role\UsernameServiceFactory',
],
'initializers' => [
'UnicaenAuth\Service\UserAwareInitializer',
],
],
'controllers' => [
'invokables' => [
'UnicaenAuth\Controller\Utilisateur' => 'UnicaenAuth\Controller\UtilisateurController',
],
],
'view_manager' => [
'template_map' => [
'error/403' => __DIR__ . '/../view/error/403.phtml',
......@@ -295,6 +296,80 @@ return [
],
],
],
'droits' => [
'type' => 'Literal',
'options' => [
'route' => '/droits',
'defaults' => [
'__NAMESPACE__' => 'UnicaenAuth\Controller',
'controller' => 'Droits',
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'roles' => [
'type' => 'Segment',
'may_terminate' => true,
'options' => [
'route' => '/roles',
'defaults' => [
'action' => 'roles',
],
],
'child_routes' => [
'edition' => [
'type' => 'Segment',
'may_terminate' => true,
'options' => [
'route' => '/edition[/:role]',
'constraints' => [
'role' => '[0-9]*',
],
'defaults' => [
'action' => 'role-edition',
],
],
],
'suppression' => [
'type' => 'Segment',
'may_terminate' => true,
'options' => [
'route' => '/suppression/:role',
'constraints' => [
'role' => '[0-9]*',
],
'defaults' => [
'action' => 'role-suppression',
],
],
],
],
],
'privileges' => [
'type' => 'Literal',
'may_terminate' => true,
'options' => [
'route' => '/privileges',
'defaults' => [
'action' => 'privileges',
],
],
'child_routes' => [
'modifier' => [
'type' => 'Segment',
'may_terminate' => true,
'options' => [
'route' => '/modifier',
'defaults' => [
'action' => 'privileges-modifier',
],
],
],
],
],
],
],
],
],
// All navigation-related configuration is collected in the 'navigation' key
......@@ -318,6 +393,57 @@ return [
],
],
],
'service_manager' => [
'aliases' => [
'Zend\Authentication\AuthenticationService' => 'zfcuser_auth_service',
'UnicaenAuth\Privilege\PrivilegeProvider' => 'UnicaenAuth\Service\Privilege',
'unicaen-auth_user_service' => 'UnicaenAuth\Service\User', // pour la compatibilité
'authUserContext' => 'UnicaenAuth\Service\UserContext', // pour la compatibilité
],
'invokables' => [
'UnicaenAuth\Authentication\Storage\Db' => 'UnicaenAuth\Authentication\Storage\Db',
'UnicaenAuth\Authentication\Storage\Ldap' => 'UnicaenAuth\Authentication\Storage\Ldap',
'UnicaenAuth\View\RedirectionStrategy' => 'UnicaenAuth\View\RedirectionStrategy',
'UnicaenAuth\Service\UserContext' => 'UnicaenAuth\Service\UserContext',
'UnicaenAuth\Service\User' => 'UnicaenAuth\Service\User',
'UnicaenAuth\Service\Privilege' => 'UnicaenAuth\Service\PrivilegeService',
'UnicaenAuth\Service\CategoriePrivilege' => 'UnicaenAuth\Service\CategoriePrivilegeService',
'UnicaenAuth\Service\Role' => 'UnicaenAuth\Service\RoleService',
],
'abstract_factories' => [
'UnicaenAuth\Authentication\Adapter\AbstractFactory',
],
'factories' => [
'unicaen-auth_module_options' => 'UnicaenAuth\Options\ModuleOptionsFactory',
'zfcuser_auth_service' => 'UnicaenAuth\Authentication\AuthenticationServiceFactory',
'UnicaenAuth\Authentication\Storage\Chain' => 'UnicaenAuth\Authentication\Storage\ChainServiceFactory',
'UnicaenAuth\Provider\Identity\Chain' => 'UnicaenAuth\Provider\Identity\ChainServiceFactory',
'UnicaenAuth\Provider\Identity\Ldap' => 'UnicaenAuth\Provider\Identity\LdapServiceFactory',
'UnicaenAuth\Provider\Identity\Db' => 'UnicaenAuth\Provider\Identity\DbServiceFactory',
'UnicaenAuth\Provider\Identity\Basic' => 'UnicaenAuth\Provider\Identity\BasicServiceFactory',
'UnicaenAuth\Provider\Role\Config' => 'UnicaenAuth\Provider\Role\ConfigServiceFactory',
'UnicaenAuth\Provider\Role\DbRole' => 'UnicaenAuth\Provider\Role\DbRoleServiceFactory',
'UnicaenAuth\Provider\Role\Username' => 'UnicaenAuth\Provider\Role\UsernameServiceFactory',
'BjyAuthorize\Service\Authorize' => 'UnicaenAuth\Service\AuthorizeServiceFactory', // surcharge!!!
],
'initializers' => [
'UnicaenAuth\Service\UserAwareInitializer',
],
],
'controllers' => [
'invokables' => [
'UnicaenAuth\Controller\Utilisateur' => 'UnicaenAuth\Controller\UtilisateurController',
'UnicaenAuth\Controller\Droits' => 'UnicaenAuth\Controller\DroitsController',
],
],
'form_elements' => [
'invokables' => [
'UnicaenAuth\Form\Droits\Role' => 'UnicaenAuth\Form\Droits\RoleForm',
],
],
'view_helpers' => [
'factories' => [
......
......@@ -16,6 +16,11 @@ $settings = [
* (i.e. créer un compte dans la table des utilisateurs).
*/
'enable_registration' => false,
/**
* Nom du gestionnaire d'entités doctrine qui sera utilisé pour accéder à la base de données des rôles,
* utilisateurs et privilèges.
*/
//'entity_manager_name' => 'doctrine.entitymanager.orm_default',
];
/**
......
......@@ -9,6 +9,7 @@ CREATE TABLE user (
UNIQUE INDEX `unique_username` (`username` ASC)
) ENGINE=InnoDB DEFAULT CHARACTER SET = utf8 COLLATE = utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `user_role` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`role_id` VARCHAR(64) NOT NULL,
......@@ -21,6 +22,7 @@ CREATE TABLE IF NOT EXISTS `user_role` (
CONSTRAINT `fk_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `user_role` (`id`) ON DELETE SET NULL
) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 COLLATE = utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `user_role_linker` (
`user_id` INT(11) NOT NULL,
`role_id` INT(11) NOT NULL,
......@@ -53,6 +55,7 @@ CREATE TABLE IF NOT EXISTS privilege (
CONSTRAINT fk_categorie_id FOREIGN KEY (categorie_id) REFERENCES categorie_privilege (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET = utf8 COLLATE = utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS role_privilege (
role_id INT(11) NOT NULL,
privilege_id INT(11) NOT NULL,
......@@ -63,8 +66,25 @@ CREATE TABLE IF NOT EXISTS role_privilege (
CONSTRAINT fk_rp_privilege_id FOREIGN KEY (privilege_id) REFERENCES privilege (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARACTER SET = utf8 COLLATE = utf8_unicode_ci;
-- Données
INSERT INTO `user_role` (`id`, `role_id`, `is_default`, `parent_id`) VALUES
(1, 'Standard', 1, NULL),
(2, 'Gestionnaire', 0, 1),
(3, 'Super-gestionnaire', 0, 2),
(4, 'Administrateur de l''application', 0, 3);
(4, 'Administrateur', 0, 3);
INSERT INTO `categorie_privilege` (`id`, `code`, `libelle`, `ordre`) VALUES
(1, 'droit', 'Gestion des droits', 1);
INSERT INTO `privilege` (`id`, `categorie_id`, `code`, `libelle`, `ordre`) VALUES
(1, 1, 'role-visualisation', 'Rôles - Visualisation', 1),
(2, 1, 'role-edition', 'Rôles - Édition', 2),
(3, 1, 'privilege-visualisation', 'Privilèges - Visualisation', 3),
(4, 1, 'privilege-edition', 'Privilèges - Édition', 4);
INSERT INTO `role_privilege` (`role_id`, `privilege_id`) VALUES
(4, 1),
(4, 2),
(4, 3),
(4, 4);
\ No newline at end of file
CREATE TABLE "USER"
CREATE TABLE USER
( "ID" NUMBER(*,0) NOT NULL ENABLE,
"USERNAME" VARCHAR2(255 CHAR),
"EMAIL" VARCHAR2(255 CHAR),
......@@ -8,7 +8,7 @@ CREATE TABLE "USER"
CONSTRAINT "USER_USERNAME_UN" UNIQUE ("USERNAME")
);
CREATE TABLE "USER_ROLE"
CREATE TABLE USER_ROLE
( "ID" NUMBER(*,0) NOT NULL ENABLE,
"ROLE_ID" VARCHAR2(64 CHAR) NOT NULL ENABLE,
"IS_DEFAULT" NUMBER(38,0) NOT NULL ENABLE,
......@@ -19,7 +19,7 @@ CREATE TABLE "USER_ROLE"
);
CREATE INDEX "USER_ROLE_PARENT__IDX" ON "USER_ROLE" ("PARENT_ID");
CREATE TABLE "OSE"."USER_ROLE_LINKER"
CREATE TABLE USER_ROLE_LINKER
( "USER_ID" NUMBER(*,0) NOT NULL ENABLE,
"ROLE_ID" NUMBER(*,0) NOT NULL ENABLE,
CONSTRAINT "USER_ROLE_LINKER_PK" PRIMARY KEY ("USER_ID", "ROLE_ID")
......@@ -27,4 +27,3 @@ CREATE TABLE "OSE"."USER_ROLE_LINKER"
CONSTRAINT "USER_ROLE_USER_ROLE_FK" FOREIGN KEY ("ROLE_ID") REFERENCES "USER_ROLE" ("ID") ON DELETE CASCADE ENABLE
);
CREATE INDEX "USER_ROLE_LINKER_ROLE_IDX" ON "USER_ROLE_LINKER" ("ROLE_ID");
CREATE INDEX "USER_ROLE_LINKER_USER_IDX" ON "USER_ROLE_LINKER" ("USER_ID");
\ No newline at end of file
<?php
namespace UnicaenAuth\Assertion;
use Zend\Mvc\MvcEvent;
use Zend\Permissions\Acl\Acl;
use Zend\Permissions\Acl\Assertion\AssertionInterface;
use Zend\Permissions\Acl\Resource\ResourceInterface;
use Zend\Permissions\Acl\Role\RoleInterface;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
/**
* Description of AbstractAssertion
*
* @author Laurent LÉCLUSE <laurent.lecluse at unicaen.fr>
*/
abstract class AbstractAssertion implements AssertionInterface, ServiceLocatorAwareInterface
{
use ServiceLocatorAwareTrait;
/**
* !!!! Pour éviter l'erreur "Serialization of 'Closure' is not allowed"... !!!!
*
* @return array
*/
public function __sleep()
{
return [];
}
/**
* Returns true if and only if the assertion conditions are met
*
* This method is passed the ACL, Role, Resource, and privilege to which the authorization query applies. If the
* $role, $this->resource, or $privilege parameters are null, it means that the query applies to all Roles, Resources, or
* privileges, respectively.
*
* @param Acl $acl
* @param RoleInterface $role
* @param ResourceInterface $resource
* @param string $privilege
*
* @return bool
*/
public final function assert(Acl $acl, RoleInterface $role = null, ResourceInterface $resource = null, $privilege = null)
{
switch (true) {
case $this->detectPrivilege($resource):
return $this->assertPrivilege($acl, $role, ltrim(strstr($resource, '/'), '/'), $privilege);
case $this->detectController($resource):
$resource = (string)$resource;
$spos = strpos($resource, '/') + 1;
$dpos = strrpos($resource, ':') + 1;
$controller = substr($resource, $spos, $dpos - $spos - 1);
$action = substr($resource, $dpos);
return $this->assertController($acl, $role, $controller, $action, $privilege);
case $this->detectEntity($resource):
return $this->assertEntity($acl, $role, $resource, $privilege);
default:
return $this->assertOther($acl, $role, $resource, $privilege);
}
}
/**
*
* @param string $resource
*
* @return boolean
*/
private function detectPrivilege($resource = null)
{
if ($resource instanceof ResourceInterface) $resource = $resource->getResourceId();
return is_string($resource) && 0 === strpos($resource, 'privilege/');
}
/**
*
* @param Acl $acl
* @param RoleInterface $role
* @param string $privilege
* @param string $subPrivilege
*
* @return boolean
*/
protected function assertPrivilege(Acl $acl, RoleInterface $role = null, $privilege = null, $subPrivilege = null)
{
return true;
}
/**
*
* @param string $resource
*
* @return boolean
*/
private function detectController($resource = null)
{
if ($resource instanceof ResourceInterface) $resource = $resource->getResourceId();
return 0 === strpos($resource, 'controller/');
}
/**
*
* @param Acl $acl
* @param RoleInterface $role
* @param string $controller
* @param string $action
* @param string $privilege
*
* @return boolean
*/
protected function assertController(Acl $acl, RoleInterface $role = null, $controller = null, $action = null, $privilege = null)
{
return true;
}
/**
*
* @param string $resource
*
* @return boolean
*/
private function detectEntity($resource = null)
{
return
is_object($resource)
&& method_exists($resource, 'getId');
}
/**
*
* @param Acl $acl
* @param RoleInterface $role
* @param ResourceInterface $entity
* @param string $privilege
*
* @return boolean
*/
protected function assertEntity(Acl $acl, RoleInterface $role = null, ResourceInterface $entity = null, $privilege = null)
{
return true;
}
/**
*
* @param Acl $acl
* @param RoleInterface $role
* @param ResourceInterface $entity
* @param string $privilege
*
* @return boolean
*/
protected function assertOther(Acl $acl, RoleInterface $role = null, ResourceInterface $entity = null, $privilege = null)
{
return true;
}
/**
*
* @return MvcEvent
*/
protected function getMvcEvent()
{
$application = $this->getServiceLocator()->get('Application');
return $application->getMvcEvent();
}
}
\ No newline at end of file
<?php
namespace UnicaenAuth\Controller;
use UnicaenAuth\Entity\Db\Privilege;
use UnicaenAuth\Entity\Db\Role;
use UnicaenAuth\Form\Droits\Traits\RoleFormAwareTrait;
use UnicaenAuth\Service\Traits\PrivilegeServiceAwareTrait;
use UnicaenAuth\Service\Traits\RoleServiceAwareTrait;
use Zend\Form\Form;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
/**
* Description of DroitsController
*
*
* @author Laurent LÉCLUSE <laurent.lecluse at unicaen.fr>
*/
class DroitsController extends AbstractActionController
{
use RoleServiceAwareTrait;
use RoleFormAwareTrait;
use PrivilegeServiceAwareTrait;
/**
*
* @return type
*/
public function indexAction()
{
return [];
}
public function rolesAction()
{
$roles = $this->getServiceRole()->getList();
return compact('roles');
}
public function roleEditionAction()
{
$roleId = $this->params()->fromRoute('role');
$role = $this->getServiceRole()->get($roleId);
$errors = [];
$form = $this->getFormDroitsRole();
if (empty($role)) {
$title = 'Création d\'un nouveau rôle';
$role = $this->getServiceRole()->newEntity();
$form->setObject($role);
} else {
$title = 'Édition du rôle';
$form->bind($role);
}
$form->setAttribute('action', $this->url()->fromRoute(null, [], [], true));
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
try {
$this->getServiceRole()->save($role);
$form->get('id')->setValue($role->getId()); // transmet le nouvel ID
} catch (\Exception $e) {
$errors[] = $e->getMessage();
}
}
}
return compact('form', 'title', 'errors');
}
public function roleSuppressionAction()
{
$roleId = $this->params()->fromRoute('role');
$role = $this->getServiceRole()->get($roleId);
$title = "Suppression du rôle";
$form = $this->getFormSupprimer();
$errors = [];
if ($this->getRequest()->isPost()) {
try {
$this->getServiceRole()->delete($role);
} catch (\Exception $e) {
$errors[] = $e->getMessage();
}
}
return compact('role', 'title', 'form', 'errors');
}
public function privilegesAction()
{
$ps = $this->getServicePrivilege()->getList();
$privileges = [];
foreach ($ps as $privilege) {
$categorie = $privilege->getCategorie();
if (!isset($privileges[$categorie->getCode()])) {
$privileges[$categorie->getCode()] = [
'categorie' => $categorie,
'privileges' => [],
];
}
$privileges[$categorie->getCode()]['privileges'][] = $privilege;
}
$roles = $this->getServiceRole()->getList();
return compact('privileges', 'roles');
}
public function privilegesModifierAction()
{
$roleId = $this->params()->fromPost('role');
$role = $this->getServiceRole()->get($roleId);
$privilegeId = $this->params()->fromPost('privilege');
$privilege = $this->getServicePrivilege()->get($privilegeId);
$action = $this->params()->fromPost('action');
switch ($action) {
case 'accorder':
$this->getServicePrivilege()->addRole($privilege,$role);
break;
case 'refuser':
$this->getServicePrivilege()->removeRole($privilege,$role);
break;
}
$viewModel = new ViewModel();
$viewModel->setVariables(compact('role', 'privilege'))
->setTerminal(true);
return $viewModel;
}
public function getFormSupprimer()
{
$form = new Form();
$form->add([
'name' => 'id',
'type' => 'Hidden',
]);
$form->add([
'name' => 'submit',
'type' => 'Submit',
'attributes' => [
'value' => 'Je confirme la suppression',
],
]);
$form->setAttribute('action', $this->url()->fromRoute(null, [], [], true));
return $form;
}
}
\ No newline at end of file
<?php
namespace UnicaenAuth\Entity\Db;
use Doctrine\ORM\Mapping as ORM;
/**
*
* @ORM\Entity
* @ORM\Table(name="categorie_privilege")
*/
class CategoriePrivilege
{
/**
* @var int
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
* @ORM\Column(name="code", type="string", length=150, unique=false, nullable=false)
*/
private $code;
/**
* @var string
* @ORM\Column(name="libelle", type="string", length=200, unique=false, nullable=false)
*/
private $libelle;
/**
* @var int
* @ORM\Column(name="ordre", type="integer", unique=false, nullable=false)
*/
private $ordre;
/**
* @var \Doctrine\Common\Collections\Collection
* @ORM\OneToMany(targetEntity="Privilege", mappedBy="categorie")
*/
private $privilege;
/**
* Constructor
*/
public function __construct()
{
$this->privilege = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Set code
*
* @param string $code
*
* @return Privilege
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get code
*
* @return string
*/
public function getCode()
{
return $this->code;
}
/**
* Set libelle
*
* @param string $libelle
*
* @return Privilege
*/
public function setLibelle($libelle)
{
$this->libelle = $libelle;
return $this;
}
/**
* Get libelle
*
* @return string
*/
public function getLibelle()
{
return $this->libelle;
}
/**
*
* @return integer
*/
function getOrdre()
{
return $this->ordre;
}
/**
*
* @param integer $ordre
*
* @return \Application\Entity\Db\Privilege
*/
function setOrdre($ordre)
{
$this->ordre = $ordre;
return $this;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add privilege
*
* @param Privilege $privilege
*
* @return Privilege
*/
public function addPrivilege(Privilege $privilege)
{
$this->privilege[] = $privilege;
return $this;
}
/**
* Remove privilege
*
* @param Privilege $privilege
*/
public function removePrivilege(Privilege $privilege)
{
$this->privilege->removeElement($privilege);
}
/**
* Get privilege
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getPrivilege()
{
return $this->privilege;
}
/**
* @return string
*/
public function __toString()
{
return $this->getLibelle();
}
}
<?php
namespace UnicaenAuth\Entity\Db;
use UnicaenAuth\Provider\Privilege\Privileges;
use Zend\Permissions\Acl\Resource\ResourceInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* Privilege
*
* @ORM\Entity
* @ORM\Table(name="privilege")
*/
abstract class AbstractPrivilege implements ResourceInterface
class Privilege implements ResourceInterface
{
/**
* @var int
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
* @ORM\Column(name="code", type="string", length=150, unique=false, nullable=false)
*/
private $code;
/**
* @var string
* @ORM\Column(name="libelle", type="string", length=200, unique=false, nullable=false)
*/
private $libelle;
/**
*
* @var integer
* @var int
* @ORM\Column(name="ordre", type="integer", unique=false, nullable=false)
*/
private $ordre;
/**
* @var integer
*/
private $id;
/**
* @var \UnicaenApp\Entity\Db\CategoriePrivilege
* @var CategoriePrivilege
* @ORM\ManyToOne(targetEntity="CategoriePrivilege", inversedBy="privilege")
* @ORM\JoinColumn(name="categorie_id", referencedColumnName="id")
*/
private $categorie;
/**
* @var \Doctrine\Common\Collections\Collection
* @ORM\ManyToMany(targetEntity="UnicaenAuth\Entity\Db\Role",cascade={"all"})
* @ORM\JoinTable(
* name="role_privilege",
* joinColumns={@ORM\JoinColumn(name="privilege_id", referencedColumnName="id", onDelete="cascade")},
* inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id", onDelete="cascade")}
*
* )
*/
private $role;
......@@ -129,7 +147,7 @@ abstract class AbstractPrivilege implements ResourceInterface
*
* @param integer $ordre
*
* @return \Application\Entity\Db\Privilege
* @return self
*/
function setOrdre($ordre)
{
......@@ -155,11 +173,11 @@ abstract class AbstractPrivilege implements ResourceInterface
/**
* Set categorie
*
* @param \Application\Entity\Db\CategoriePrivilege $categorie
* @param CategoriePrivilege $categorie
*
* @return Privilege
* @return self
*/
public function setCategorie(\Application\Entity\Db\CategoriePrivilege $categorie = null)
public function setCategorie(CategoriePrivilege $categorie = null)
{
$this->categorie = $categorie;
......@@ -171,7 +189,7 @@ abstract class AbstractPrivilege implements ResourceInterface
/**
* Get categorie
*
* @return \Application\Entity\Db\CategoriePrivilege
* @return CategoriePrivilege
*/
public function getCategorie()
{
......@@ -183,13 +201,13 @@ abstract class AbstractPrivilege implements ResourceInterface
/**
* Add role
*
* @param \Application\Entity\Db\Role $role
* @param Role $role
*
* @return Privilege
* @return self
*/
public function addRole(\Application\Entity\Db\Role $role)
public function addRole(Role $role)
{
$this->Role[] = $role;
$this->role->add($role);
return $this;
}
......@@ -199,9 +217,9 @@ abstract class AbstractPrivilege implements ResourceInterface
/**
* Remove role
*
* @param \Application\Entity\Db\Role $role
* @param Role $role
*/
public function removeRole(\Application\Entity\Db\Role $role)
public function removeRole(Role $role)
{
$this->role->removeElement($role);
}
......@@ -220,23 +238,6 @@ abstract class AbstractPrivilege implements ResourceInterface
/**
* @deprecated
* @todo à voir si cela sert à quelque chose ou non !!
* @return array
*/
public function getRoleCodes()
{
$result = [];
foreach ($this->role as $role) {
/* @var $role Role */
$result[] = $role->getRoleId();
}
return $result;
}
/**
* @return string
*/
......@@ -252,6 +253,6 @@ abstract class AbstractPrivilege implements ResourceInterface
*/
public function getResourceId()
{
return sprintf('privilege/%s', $this->getFullCode());
return Privileges::getResource($this);
}
}
......@@ -35,9 +35,9 @@ class Role implements HierarchicalRoleInterface
/**
* @var boolean
* @ORM\Column(name="is_default", type="boolean", nullable=false)
* @ORM\Column(name="is_default", type="boolean", nullable=true)
*/
protected $isDefault;
protected $isDefault = false;
/**
* @var Role
......
<?php
namespace UnicaenAuth\Form\Droits;
use UnicaenAuth\Entity\Db\Role;
use UnicaenAuth\Service\Traits\RoleServiceAwareTrait;
use Zend\Form\Form;
use UnicaenApp\Util;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
use Zend\Stdlib\Hydrator\HydratorInterface;
/**
* Description of RoleForm
*
* @author Laurent LECLUSE <laurent.lecluse at unicaen.fr>
*/
class RoleForm extends Form implements ServiceLocatorAwareInterface
{
use ServiceLocatorAwareTrait;
use RoleServiceAwareTrait;
public function init()
{
$hydrator = new RoleFormHydrator;
$hydrator->setServiceRole( $this->getServiceRole() );
$this->setHydrator($hydrator);
$this->add([
'type' => 'Text',
'name' => 'role-id',
'options' => [
'label' => 'Nom',
],
]);
$this->add([
'type' => 'Text',
'name' => 'ldap-filter',
'options' => [
'label' => 'Filtre LDAP',
],
]);
$this->add([
'type' => 'Select',
'name' => 'parent',
'options' => [
'label' => 'Parent',
'empty_option' => '- Aucun -',
'value_options' => Util::collectionAsOptions($this->getServiceRole()->getList()),
],
]);
$this->add([
'name' => 'id',
'type' => 'Hidden',
]);
$this->add([
'name' => 'submit',
'type' => 'Submit',
'attributes' => [
'value' => 'Enregistrer',
'class' => 'btn btn-primary',
],
]);
}
/**
* Should return an array specification compatible with
* {@link Zend\InputFilter\Factory::createInputFilter()}.
*
* @return array
*/
public function getInputFilterSpecification()
{
return [
'role-id' => [
'required' => true,
],
'ldap-filter' => [
'required' => false,
],
'parent' => [
'required' => false,
],
];
}
}
/**
* Class RoleFormHydrator
*
* @package UnicaenAuth\Form\Droits
* @author Laurent LÉCLUSE <laurent.lecluse at unicaen.fr>
*/
class RoleFormHydrator implements HydratorInterface
{
use RoleServiceAwareTrait;
/**
* @param array $data
* @param Role $object
*
* @return object
*/
public function hydrate(array $data, $object)
{
$object->setRoleId($data['role-id']);
$object->setLdapFilter($data['ldap-filter'] ?: null);
$object->setParent($this->getServiceRole()->get($data['parent']));
return $object;
}
/**
* @param Role $object
*
* @return array
*/
public function extract($object)
{
$data = [
'id' => $object->getId(),
'role-id' => $object->getRoleId(),
'ldap-filter' => $object->getLdapFilter(),
'parent' => $object->getParent() ? $object->getParent()->getId() : null,
];
return $data;
}
}
\ No newline at end of file
<?php
namespace UnicaenAuth\Form\Droits\Traits;
use UnicaenAuth\Form\Droits\RoleForm;
use RuntimeException;
/**
* Description of RoleFormAwareTrait
*
* @author UnicaenCode
*/
trait RoleFormAwareTrait
{
/**
* @var RoleForm
*/
private $formDroitsRole;
/**
* @param RoleForm $formDroitsRole
*
* @return self
*/
public function setFormDroitsRole(RoleForm $formDroitsRole)
{
$this->formDroitsRole = $formDroitsRole;
return $this;
}
/**
* @return RoleForm
* @throws RuntimeException
*/
public function getFormDroitsRole()
{
if (empty($this->formDroitsRole)) {
if (!method_exists($this, 'getServiceLocator')) {
throw new RuntimeException('La classe ' . get_class($this) . ' n\'a pas accès au ServiceLocator.');
}
$serviceLocator = $this->getServiceLocator();
if (method_exists($serviceLocator, 'getServiceLocator')) {
$serviceLocator = $serviceLocator->getServiceLocator();
}
$this->formDroitsRole = $serviceLocator->get('FormElementManager')->get('UnicaenAuth\Form\Droits\Role');
}
return $this->formDroitsRole;
}
}
\ No newline at end of file
<?php
namespace UnicaenAuth\Guard;
use BjyAuthorize\Guard\Controller;
use Zend\ServiceManager\ServiceLocatorInterface;
use UnicaenAuth\Provider\Privilege\PrivilegeProviderAwareTrait;
use UnicaenApp\Traits\SessionContainerTrait;
/**
* Description of ControllerGuard
*
* @author Laurent LECLUSE <laurent.lecluse at unicaen.fr>
*/
class PrivilegeController extends Controller
{
use PrivilegeProviderAwareTrait;
use SessionContainerTrait;
public function __construct(array $rules, ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
parent::__construct($this->privilegesToRoles($rules), $serviceLocator);
}
protected function privilegesToRoles(array $rules)
{
// $session = $this->getSessionContainer();
// if (! isset($session->rules)){
$pr = $this->getPrivilegeProvider()->getPrivilegesRoles();
foreach ($rules as $index => $rule) {
if (isset($rule['privileges'])) {
$rolesCount = 0;
$privileges = (array)$rule['privileges'];
$rule['roles'] = isset($rule['roles']) ? (array)$rule['roles'] : [];
foreach ($pr as $privilege => $roles) {
if (in_array($privilege, $privileges)) {
$rolesCount += count($roles);
$rule['roles'] = array_unique(array_merge($rule['roles'], $roles));
}
}
unset($rule['privileges']);
if (0 < count($rule['roles'])) {
$rules[$index] = $rule;
}else{
unset($rules[$index]);
}
}
}
return $rules;
// $session->rules = $rules;
// }
// return $session->rules;
}
/**
* Pour récupérer le serviceLocator depuis les traits de service
*
* @return ServiceLocatorInterface
*/
protected function getServiceLocator()
{
return $this->serviceLocator;
}
public static function getResourceId($controller, $action = null)
{
if (isset($action)) {
return sprintf('controller/%s:%s', $controller, strtolower($action));
}
return sprintf('controller/%s', $controller);
}
}
\ No newline at end of file
......@@ -23,18 +23,29 @@ class ModuleOptions extends \ZfcUser\Options\ModuleOptions
*/
protected $cas = [];
/**
* @var string
*/
protected $entityManagerName = 'doctrine.entitymanager.orm_default';
/**
* set usernames allowed to make usurpation
*
* @param array $usurpationAllowedUsernames
*
* @return ModuleOptions
*/
public function setUsurpationAllowedUsernames(array $usurpationAllowedUsernames = [])
{
$this->usurpationAllowedUsernames = $usurpationAllowedUsernames;
return $this;
}
/**
* get usernames allowed to make usurpation
*
......@@ -45,19 +56,25 @@ class ModuleOptions extends \ZfcUser\Options\ModuleOptions
return $this->usurpationAllowedUsernames;
}
/**
* Spécifie si l'utilisateur authentifié doit être enregistré dans la base
* de données de l'appli
*
* @param bool $flag
*
* @return ModuleOptions
*/
public function setSaveLdapUserInDatabase($flag = true)
{
$this->saveLdapUserInDatabase = (bool)$flag;
return $this;
}
/**
* Retourne la valeur du flag spécifiant si l'utilisateur authentifié doit être
* enregistré dans la base de données de l'appli
......@@ -69,18 +86,24 @@ class ModuleOptions extends \ZfcUser\Options\ModuleOptions
return $this->saveLdapUserInDatabase;
}
/**
* set cas connection params
*
* @param array $cas
*
* @return ModuleOptions
*/
public function setCas(array $cas = [])
{
$this->cas = $cas;
return $this;
}
/**
* get cas connection params
*
......@@ -90,4 +113,30 @@ class ModuleOptions extends \ZfcUser\Options\ModuleOptions
{
return $this->cas;
}
/**
* @return string
*/
public function getEntityManagerName()
{
return $this->entityManagerName;
}
/**
* @param string $entityManagerName
*
* @return ModuleOptions
*/
public function setEntityManagerName($entityManagerName)
{
$this->entityManagerName = $entityManagerName;
return $this;
}
}
\ No newline at end of file
<?php
namespace UnicaenAuth\Options\Traits;
use UnicaenAuth\Options\ModuleOptions;
use RuntimeException;
/**
* Description of ModuleOptionsAwareTrait
*
* @author Laurent LÉCLUSE <laurent.lecluse at unicaen.fr>
*/
trait ModuleOptionsAwareTrait
{
/**
* @var ModuleOptions
*/
private $moduleOptions;
/**
* @param ModuleOptions $moduleOptions
*
* @return self
*/
public function setModuleOptions(ModuleOptions $moduleOptions)
{
$this->moduleOptions = $moduleOptions;
return $this;
}
/**
* @return ModuleOptions
* @throws RuntimeException
*/
public function getModuleOptions()
{
if (empty($this->moduleOptions)) {
if (!method_exists($this, 'getServiceLocator')) {
throw new RuntimeException('La classe ' . get_class($this) . ' n\'a pas accès au ServiceLocator.');
}
$serviceLocator = $this->getServiceLocator();
if (method_exists($serviceLocator, 'getServiceLocator')) {
$serviceLocator = $serviceLocator->getServiceLocator();
}
$this->moduleOptions = $serviceLocator->get('unicaen-auth_module_options');
}
return $this->moduleOptions;
}
}
\ No newline at end of file
......@@ -41,8 +41,8 @@ class Chain implements ProviderInterface, ServiceLocatorAwareInterface, EventMan
*/
public function getIdentityRoles()
{
$selectedIdentityRole = $this->getSelectedIdentityRole();
$allRoles = $this->getAllIdentityRoles();
$selectedIdentityRole = $this->getSelectedIdentityRole();
$roles = $selectedIdentityRole ? [$selectedIdentityRole] : $allRoles;
return $roles;
......
......@@ -3,6 +3,11 @@ namespace UnicaenAuth\Provider\Identity;
use BjyAuthorize\Provider\Identity\AuthenticationIdentityProvider;
use BjyAuthorize\Provider\Role\ProviderInterface;
use UnicaenApp\Entity\Ldap\People;
use UnicaenAuth\Entity\Db\Role;
use UnicaenAuth\Service\Traits\RoleServiceAwareTrait;
use Zend\Ldap\Ldap;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
use ZfcUser\Entity\UserInterface;
use Traversable;
......@@ -16,8 +21,17 @@ use Traversable;
*
* @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
*/
class Db extends AuthenticationIdentityProvider implements ChainableProvider
class Db extends AuthenticationIdentityProvider implements ChainableProvider, \BjyAuthorize\Provider\Identity\ProviderInterface
{
use RoleServiceAwareTrait;
/**
* @var Ldap
*/
private $ldap;
/**
* {@inheritDoc}
*/
......@@ -26,17 +40,26 @@ class Db extends AuthenticationIdentityProvider implements ChainableProvider
$event->addRoles($this->getIdentityRoles());
}
/**
* {@inheritDoc}
*/
public function getIdentityRoles()
{
if (!($identity = $this->authService->getIdentity())) {
if (!($idArray = $this->authService->getIdentity())) {
return [$this->defaultRole];
}
if (is_array($identity) && isset($identity['db'])) {
$identity = $identity['db'];
$ldapDn = null;
$identity = null;
if (is_array($idArray)) {
if (isset($idArray['ldap']) && $idArray['ldap'] instanceof People) {
$ldapDn = $idArray['ldap']->getDn();
}
if (isset($idArray['db'])) {
$identity = $idArray['db'];
}
}
if ($identity instanceof ProviderInterface) {
......@@ -44,8 +67,7 @@ class Db extends AuthenticationIdentityProvider implements ChainableProvider
if ($roles instanceof Traversable) {
$roles = iterator_to_array($roles);
}
}
else {
} else {
$roles = [];
}
......@@ -53,6 +75,61 @@ class Db extends AuthenticationIdentityProvider implements ChainableProvider
$roles[] = $identity->getUsername();
}
/* Injection des rôles par filtre LDAP */
$ldapRoles = $this->getServiceRole()->getList();
foreach ($ldapRoles as $role) {
if ($role->getLdapFilter() && !in_array($role, $roles)) {
if ($this->roleMatches($role, $ldapDn)) {
$roles[] = $role;
}
}
}
return $roles;
}
/**
* @param Role $role
* @param string $dn
*
* @return bool
*/
protected function roleMatches(Role $role, $dn)
{
try {
return 1 === $this->getLdap()->count($role->getLdapFilter(), $dn, Ldap::SEARCH_SCOPE_SUB);
} catch (\Zend\Ldap\Exception\LdapException $e) {
return false;
}
}
/**
* Returns the LDAP Object
*
* @return Ldap
*/
public function getLdap()
{
return $this->ldap;
}
/**
* Set an Ldap connection
*
* @param Ldap $ldap
*
* @return self
*/
public function setLdap(Ldap $ldap)
{
$this->ldap = $ldap;
return $this;
}
}
\ No newline at end of file
......@@ -2,6 +2,8 @@
namespace UnicaenAuth\Provider\Identity;
use UnicaenApp\Options\ModuleOptions;
use Zend\Ldap\Ldap;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
......@@ -18,9 +20,17 @@ class DbServiceFactory implements FactoryInterface
public function createService(ServiceLocatorInterface $serviceLocator)
{
$user = $serviceLocator->get('zfcuser_user_service');
$config = $serviceLocator->get('BjyAuthorize\Config');
$identityProvider = new Db($user->getAuthService());
$unicaenAppOptions = $serviceLocator->get('unicaen-app_module_options');
/* @var $unicaenAppOptions ModuleOptions */
$ldap = new Ldap($unicaenAppOptions->getLdap()['connection']['default']['params']);
$identityProvider->setLdap($ldap);
$identityProvider->setServiceRole($serviceLocator->get('UnicaenAuth\Service\Role'));
$config = $serviceLocator->get('BjyAuthorize\Config');
$identityProvider->setDefaultRole($config['default_role']);
$identityProvider->setAuthenticatedRole($config['authenticated_role']);
......
......@@ -14,6 +14,7 @@ use ZfcUser\Entity\UserInterface;
* - L'identité authentifiée est fournie par le service d'authentification.
*
* @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
* @deprecated
*/
class Ldap extends AuthenticationIdentityProvider implements ChainableProvider
{
......
......@@ -15,6 +15,7 @@ class LdapServiceFactory implements FactoryInterface
{
/**
* {@inheritDoc}
* @deprecated
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment