Commit 4b79eaa4 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Améliorations importantes : notamment collecte des rôles disponibles et de...

Améliorations importantes : notamment collecte des rôles disponibles et de ceux de l'identité authentifiée.
parent 3548a071
...@@ -112,6 +112,11 @@ class Module implements ConfigProviderInterface, ViewHelperProviderInterface, Se ...@@ -112,6 +112,11 @@ class Module implements ConfigProviderInterface, ViewHelperProviderInterface, Se
) )
)); ));
} }
// $services->get('zfcuser_user_service')->getEventManager()->attach('register', function(\Zend\EventManager\Event $event) {
// var_dump($event->getParams());
// throw new \ZfcUser\Service\Exception\InvalidArgumentException("Test");
// });
} }
/** /**
...@@ -158,16 +163,6 @@ class Module implements ConfigProviderInterface, ViewHelperProviderInterface, Se ...@@ -158,16 +163,6 @@ class Module implements ConfigProviderInterface, ViewHelperProviderInterface, Se
{ {
return array( return array(
'factories' => array( 'factories' => array(
'zfcuser_user_mapper' => function ($sm) {
$config = $sm->get('configuration');
$em = isset($config['doctrine']['connection']['orm_auth']) ?
'doctrine.entitymanager.orm_auth' :
'doctrine.entitymanager.orm_default';
return new \ZfcUserDoctrineORM\Mapper\User(
$sm->get($em),
$sm->get('zfcuser_module_options')
);
},
'unicaen-auth_user_service' => function () { 'unicaen-auth_user_service' => function () {
return new Service\User(); return new Service\User();
}, },
...@@ -176,6 +171,19 @@ class Module implements ConfigProviderInterface, ViewHelperProviderInterface, Se ...@@ -176,6 +171,19 @@ class Module implements ConfigProviderInterface, ViewHelperProviderInterface, Se
$provider = new \UnicaenAuth\Provider\Identity\LdapPeople($authService); $provider = new \UnicaenAuth\Provider\Identity\LdapPeople($authService);
return $provider; return $provider;
}, },
'UnicaenAuth\Provider\Identity\DbUser' => function($sm) {
$authService = $sm->get('zfcuser_auth_service');
$provider = new \UnicaenAuth\Provider\Identity\DbUser($authService);
return $provider;
},
// verrue pour forcer le label de l'identifiant qqsoit l'options 'auth_identity_fields'
'zfcuser_login_form' => function($sm) {
$options = $sm->get('zfcuser_module_options');
$form = new \ZfcUser\Form\Login(null, $options);
$form->setInputFilter(new \ZfcUser\Form\LoginFilter($options));
$form->get('identity')->setLabel("Username");
return $form;
},
), ),
); );
} }
......
...@@ -17,7 +17,7 @@ $zfcuserSettings = array( ...@@ -17,7 +17,7 @@ $zfcuserSettings = array(
* Default value: array containing 'email' * Default value: array containing 'email'
* Accepted values: array containing one or more of: email, username * Accepted values: array containing one or more of: email, username
*/ */
'auth_identity_fields' => array('username'), 'auth_identity_fields' => array('username', 'email'),
/** /**
* Login Redirect Route * Login Redirect Route
* Upon successful login the user will be redirected to the entered route * Upon successful login the user will be redirected to the entered route
...@@ -38,7 +38,7 @@ $zfcuserSettings = array( ...@@ -38,7 +38,7 @@ $zfcuserSettings = array(
* in using their username OR email address. Default is false. * in using their username OR email address. Default is false.
* Accepted values: boolean true or false * Accepted values: boolean true or false
*/ */
'enable_username' => true, 'enable_username' => false,
/** /**
* Enable Display Name * Enable Display Name
* Enables a display name field on the registration form, which is persisted * Enables a display name field on the registration form, which is persisted
...@@ -57,8 +57,13 @@ $zfcuserSettings = array( ...@@ -57,8 +57,13 @@ $zfcuserSettings = array(
200 => 'UnicaenAuth\Authentication\Adapter\Db', // ensuite (si échec d'authentification Ldap) 200 => 'UnicaenAuth\Authentication\Adapter\Db', // ensuite (si échec d'authentification Ldap)
100 => 'UnicaenAuth\Authentication\Adapter\Cas', // ensuite (si échec d'authentification Db) 100 => 'UnicaenAuth\Authentication\Adapter\Cas', // ensuite (si échec d'authentification Db)
), ),
// telling ZfcUser to use our own class
'user_entity_class' => 'UnicaenAuth\Entity\Db\User',
// telling ZfcUserDoctrineORM to skip the entities it defines
'enable_default_entities' => false,
); );
$bjyauthorize = array( $bjyauthorize = array(
/* this module uses a meta-role that inherits from any roles that should /* 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 * be applied to the active user. the identity provider tells us which
...@@ -66,7 +71,7 @@ $bjyauthorize = array( ...@@ -66,7 +71,7 @@ $bjyauthorize = array(
* *
* for ZfcUser, this will be your default identity provider * for ZfcUser, this will be your default identity provider
*/ */
'identity_provider' => 'UnicaenAuth\Provider\Identity\LdapPeople', 'identity_provider' => 'UnicaenAuth\Provider\Identity\Chain',
/* role providers simply provide a list of roles that should be inserted /* role providers simply provide a list of roles that should be inserted
* into the Zend\Acl instance. the module comes with two providers, one * into the Zend\Acl instance. the module comes with two providers, one
...@@ -74,14 +79,24 @@ $bjyauthorize = array( ...@@ -74,14 +79,24 @@ $bjyauthorize = array(
* Zend\Db adapter. * Zend\Db adapter.
*/ */
'role_providers' => array( 'role_providers' => array(
/* here, 'guest' and 'user are defined as top-level roles, with /**
* 'admin' inheriting from user * 2 rôles doivent systématiquement exister dans les ACL :
* - le rôle par défaut 'guest', c'est le rôle de tout utilisateur non authentifié.
* - le rôle 'user', c'est le rôle de tout utilisateur authentifié.
*/ */
'BjyAuthorize\Provider\Role\Config' => array( 'UnicaenAuth\Provider\Role\Config' => array(
'guest' => array(), // rôle par défaut 'guest' => array('name' => "Non authentifié(e)", 'children' => array(
// 'user' => array('children' => array( 'user' => array('name' => "Authentifié(e)")
// 'admin' => array(), )),
// )), ),
/**
* Fournit les rôles issus de la base de données éventuelle de l'appli.
* 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\Db' => array(
'object_manager' => 'doctrine.entitymanager.orm_default',
'role_entity_class' => 'UnicaenAuth\Entity\Db\Role',
), ),
), ),
...@@ -96,16 +111,16 @@ $bjyauthorize = array( ...@@ -96,16 +111,16 @@ $bjyauthorize = array(
* You may omit the 'action' index to allow access to the entire controller * You may omit the 'action' index to allow access to the entire controller
*/ */
'BjyAuthorize\Guard\Controller' => array( 'BjyAuthorize\Guard\Controller' => array(
array('controller' => 'index', 'action' => 'index', 'roles' => array('guest')), array('controller' => 'index', 'action' => 'index', 'roles' => array()),
array('controller' => 'zfcuser', 'roles' => array('guest')), array('controller' => 'zfcuser', 'roles' => array()),
array('controller' => 'Application\Controller\Index', 'roles' => array('guest')), array('controller' => 'Application\Controller\Index', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application:etab', 'roles' => array('guest')), array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'etab', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application:apropos', 'roles' => array('guest')), array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'apropos', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application:contact', 'roles' => array('guest')), array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'contact', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application:plan', 'roles' => array('guest')), array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'plan', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application:mentions-legales', 'roles' => array('guest')), array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'mentions-legales', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application:informatique-et-libertes', 'roles' => array('guest')), array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'informatique-et-libertes', 'roles' => array()),
), ),
), ),
); );
...@@ -115,14 +130,37 @@ return array( ...@@ -115,14 +130,37 @@ return array(
'bjyauthorize' => $bjyauthorize, 'bjyauthorize' => $bjyauthorize,
'unicaen-auth' => $settings, 'unicaen-auth' => $settings,
'doctrine' => array( 'doctrine' => array(
'entitymanager' => array( 'driver' => array(
'orm_auth' => array( // overriding zfc-user-doctrine-orm's config
'connection' => 'orm_auth', 'zfcuser_entity' => array(
'configuration' => 'orm_default' 'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
) 'paths' => array(
__DIR__ . '/../src/UnicaenAuth/Entity/Db'
)
),
'orm_auth_driver' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(
__DIR__ . '/../src/UnicaenAuth/Entity/Db'
)
),
'orm_default' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\DriverChain',
'drivers' => array(
'UnicaenAuth\Entity\Db' => 'zfcuser_entity',
'UnicaenAuth\Entity\Db' => 'orm_auth_driver'
)
),
), ),
), ),
'service_manager' => array( 'service_manager' => array(
'aliases' => array(
'Zend\Authentication\AuthenticationService' => 'zfcuser_auth_service',
),
'invokables' => array(
),
'abstract_factories' => array( 'abstract_factories' => array(
'UnicaenAuth\Authentication\Adapter\AbstractFactory', 'UnicaenAuth\Authentication\Adapter\AbstractFactory',
), ),
...@@ -145,10 +183,16 @@ return array( ...@@ -145,10 +183,16 @@ return array(
}, },
'zfcuser_auth_service' => function (Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) { 'zfcuser_auth_service' => function (Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) {
return new \Zend\Authentication\AuthenticationService( return new \Zend\Authentication\AuthenticationService(
$serviceLocator->get('UnicaenAuth\Authentication\Storage\LdapDb'), $serviceLocator->get('UnicaenAuth\Authentication\Storage\Chain'),
$serviceLocator->get('ZfcUser\Authentication\Adapter\AdapterChain') $serviceLocator->get('ZfcUser\Authentication\Adapter\AdapterChain')
); );
}, },
'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\Role\Config' => 'UnicaenAuth\Provider\Role\ConfigServiceFactory',
'UnicaenAuth\Provider\Role\Db' => 'UnicaenAuth\Provider\Role\DbServiceFactory',
), ),
), ),
'controllers' => array( 'controllers' => array(
......
...@@ -6,24 +6,6 @@ ...@@ -6,24 +6,6 @@
* drop this config file in it and change the values as you wish. * drop this config file in it and change the values as you wish.
*/ */
$settings = array( $settings = array(
/**
* Connexion à la base de donnée d'authentification via Doctrine.
* Décommenter pour spécifier une connexion autre que la connexion principale 'orm_default'.
*/
// 'doctrine' => array(
// 'connection' => array(
// 'orm_auth' => array(
// 'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
// 'params' => array(
// 'host' => 'localhost',
// 'port' => '3306',
// 'user' => 'root',
// 'password' => 'root',
// 'dbname' => 'authdb',
// )
// ),
// ),
// ),
/** /**
* Paramètres de connexion au serveur CAS : * Paramètres de connexion au serveur CAS :
* - pour désactiver l'authentification CAS, le tableau 'cas' doit être vide. * - pour désactiver l'authentification CAS, le tableau 'cas' doit être vide.
...@@ -54,5 +36,4 @@ $settings = array( ...@@ -54,5 +36,4 @@ $settings = array(
*/ */
return array( return array(
'unicaen-auth' => $settings, 'unicaen-auth' => $settings,
'doctrine' => isset($settings['doctrine']) ? $settings['doctrine'] : array(),
); );
\ No newline at end of file
INSERT INTO user_role (role_id, default, parent) CREATE TABLE user (
VALUES ('guest', '1', NULL); id INT(11) NOT NULL AUTO_INCREMENT,
\ No newline at end of file username VARCHAR(255) DEFAULT NULL,
email VARCHAR(255) DEFAULT NULL,
display_name VARCHAR(64) DEFAULT NULL,
password VARCHAR(128) NOT NULL,
state SMALLINT default 1,
PRIMARY KEY (`id`),
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,
`name` VARCHAR(255) NOT NULL,
`is_default` TINYINT(1) NOT NULL DEFAULT 0,
`parent_id` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `unique_role` (`role_id` ASC),
INDEX `idx_parent_id` (`parent_id` ASC),
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,
PRIMARY KEY (`user_id`, `role_id`),
INDEX `idx_role_id` (`role_id` ASC),
INDEX `idx_user_id` (`user_id` ASC),
CONSTRAINT `fk_role_id` FOREIGN KEY (`role_id`) REFERENCES `user_role` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 COLLATE = utf8_unicode_ci;
INSERT INTO user_role (role_id, description, is_default)
VALUES ('guest', 'Invité', 1);
...@@ -14,17 +14,24 @@ class NamedRole extends \BjyAuthorize\Acl\Role ...@@ -14,17 +14,24 @@ class NamedRole extends \BjyAuthorize\Acl\Role
* @var string * @var string
*/ */
protected $roleName; protected $roleName;
/**
* @var string
*/
protected $roleDescription;
/** /**
* @param string|null $roleId * @param string|null $roleId
* @param RoleInterface|string|null $parent * @param RoleInterface|string|null $parent
* @param string $roleName * @param string $roleName
* @param string $roleDescription
*/ */
public function __construct($roleId = null, $parent = null, $roleName = null) public function __construct($roleId = null, $parent = null, $roleName = null, $roleDescription = null)
{ {
parent::__construct($roleId, $parent); parent::__construct($roleId, $parent);
$this->setRoleName($roleName ?: $roleId); $this->setRoleName($roleName ?: $roleId);
$this->setRoleDescription($roleDescription ?: null);
} }
/** /**
...@@ -48,4 +55,26 @@ class NamedRole extends \BjyAuthorize\Acl\Role ...@@ -48,4 +55,26 @@ class NamedRole extends \BjyAuthorize\Acl\Role
$this->roleName = (string) $roleName; $this->roleName = (string) $roleName;
return $this; return $this;
} }
/**
* Retourne la description du rôle.
*
* @return string
*/
public function getRoleDescription()
{
return $this->roleDescription;
}
/**
* Spécifie la description du rôle.
*
* @param string $roleDescription
* @return self
*/
public function setRoleDescription($roleDescription)
{
$this->roleDescription = (string) $roleDescription;
return $this;
}
} }
\ No newline at end of file
<?php
namespace UnicaenAuth\Authentication\Storage;
use Zend\Authentication\Storage\StorageInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManager;
/**
* Implémentation d'une chaîne de responsabilité permettant à plusieurs sources
* de fournir les données sur l'identité authentifiée éventuelle.
*
* Exemples de sources disponibles :
* - Ldap (annuaire LDAP)
* - Db (table des utilisateurs en base de données)
*
*
*
* @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
* @see ChainEvent
* @see \UnicaenAuth\Service\ChainAuthenticationStorageServiceFactory
* @see Ldap
* @see Db
*/
class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventManagerAwareInterface
{
/**
* @var StorageInterface
*/
protected $storage;
/**
* @var ServiceLocatorInterface
*/
protected $serviceLocator;
/**
* @var EventManagerInterface
*/
protected $eventManager;
/**
* @var ChainEvent
*/
protected $event;
/**
* Returns true if and only if storage is empty
*
* @throws \Zend\Authentication\Exception\ExceptionInterface If it is impossible to determine whether storage is empty
* @return bool
*/
public function isEmpty()
{
return $this->getStorage()->isEmpty();
}
/**
* Returns the contents of storage
*
* Behavior is undefined when storage is empty.
*
* @throws \Zend\Authentication\Exception\ExceptionInterface If reading contents from storage is impossible
* @return mixed
*/
public function read()
{
$e = $this->getEvent();
$this->getEventManager()->trigger('read', $e);
$identity = $e->getContents();
return $identity;
}
/**
* Writes $contents to storage
*
* @param mixed $contents
* @throws \Zend\Authentication\Exception\ExceptionInterface If writing $contents to storage is impossible
* @return void
*/
public function write($contents)
{
$this->getStorage()->write($contents);
$e = $this->getEvent();
$e->setParams(compact('contents'));
$this->getEventManager()->trigger('write', $e);
}
/**
* Clears contents from storage
*
* @throws \Zend\Authentication\Exception\ExceptionInterface If clearing contents from storage is impossible
* @return void
*/
public function clear()
{
$this->getStorage()->clear();
$e = $this->getEvent();
$this->getEventManager()->trigger('clear', $e);
}
/**
* getStorage
*
* @return StorageInterface
*/
public function getStorage()
{
if (null === $this->storage) {
$this->setStorage(new \Zend\Authentication\Storage\Session());
}
return $this->storage;
}
/**
* setStorage
*
* @param StorageInterface $storage
* @return self
*/
public function setStorage(StorageInterface $storage)
{
$this->storage = $storage;
return $this;
}
/**
* Set service locator
*
* @param ServiceLocatorInterface $serviceLocator
* @return self
*/
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
return $this;
}
/**
* Get service locator
*
* @return ServiceLocatorInterface
*/
public function getServiceLocator()
{
return $this->serviceLocator;
}
/**
* Inject an EventManager instance
*
* @param EventManagerInterface $eventManager
* @return self
*/
public function setEventManager(EventManagerInterface $eventManager)
{
$eventManager->setIdentifiers(array(
__CLASS__,
get_called_class(),
));
$this->eventManager = $eventManager;
return $this;
}
/**
* Retrieve the event manager
*
* Lazy-loads an EventManager instance if none registered.
*
* @return EventManagerInterface
*/
public function getEventManager()
{
if (null === $this->eventManager) {
$this->eventManager = new EventManager();
}
return $this->eventManager;
}
/**
* @return ChainEvent
*/
public function getEvent()
{
if (null === $this->event) {
$this->event = new ChainEvent();
}
return $this->event;
}
/**
* @param ChainEvent $event
* @return self
*/
public function setEvent(ChainEvent $event)
{
$this->event = $event;
return $this;
}
}
\ No newline at end of file