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
)
));
}
// $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
{
return 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 () {
return new Service\User();
},
......@@ -176,6 +171,19 @@ class Module implements ConfigProviderInterface, ViewHelperProviderInterface, Se
$provider = new \UnicaenAuth\Provider\Identity\LdapPeople($authService);
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(
* Default value: array containing 'email'
* Accepted values: array containing one or more of: email, username
*/
'auth_identity_fields' => array('username'),
'auth_identity_fields' => array('username', 'email'),
/**
* Login Redirect Route
* Upon successful login the user will be redirected to the entered route
......@@ -38,7 +38,7 @@ $zfcuserSettings = array(
* in using their username OR email address. Default is false.
* Accepted values: boolean true or false
*/
'enable_username' => true,
'enable_username' => false,
/**
* Enable Display Name
* Enables a display name field on the registration form, which is persisted
......@@ -57,8 +57,13 @@ $zfcuserSettings = array(
200 => 'UnicaenAuth\Authentication\Adapter\Db', // ensuite (si échec d'authentification Ldap)
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(
/* 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
......@@ -66,7 +71,7 @@ $bjyauthorize = array(
*
* 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
* into the Zend\Acl instance. the module comes with two providers, one
......@@ -74,14 +79,24 @@ $bjyauthorize = array(
* Zend\Db adapter.
*/
'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(
'guest' => array(), // rôle par défaut
// 'user' => array('children' => array(
// 'admin' => array(),
// )),
'UnicaenAuth\Provider\Role\Config' => array(
'guest' => array('name' => "Non authentifié(e)", 'children' => array(
'user' => array('name' => "Authentifié(e)")
)),
),
/**
* 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(
* You may omit the 'action' index to allow access to the entire controller
*/
'BjyAuthorize\Guard\Controller' => array(
array('controller' => 'index', 'action' => 'index', 'roles' => array('guest')),
array('controller' => 'zfcuser', 'roles' => array('guest')),
array('controller' => 'Application\Controller\Index', 'roles' => array('guest')),
array('controller' => 'index', 'action' => 'index', 'roles' => array()),
array('controller' => 'zfcuser', 'roles' => array()),
array('controller' => 'Application\Controller\Index', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application:etab', 'roles' => array('guest')),
array('controller' => 'UnicaenApp\Controller\Application:apropos', 'roles' => array('guest')),
array('controller' => 'UnicaenApp\Controller\Application:contact', 'roles' => array('guest')),
array('controller' => 'UnicaenApp\Controller\Application:plan', 'roles' => array('guest')),
array('controller' => 'UnicaenApp\Controller\Application:mentions-legales', 'roles' => array('guest')),
array('controller' => 'UnicaenApp\Controller\Application:informatique-et-libertes', 'roles' => array('guest')),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'etab', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'apropos', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'contact', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'plan', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'mentions-legales', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'informatique-et-libertes', 'roles' => array()),
),
),
);
......@@ -115,14 +130,37 @@ return array(
'bjyauthorize' => $bjyauthorize,
'unicaen-auth' => $settings,
'doctrine' => array(
'entitymanager' => array(
'orm_auth' => array(
'connection' => 'orm_auth',
'configuration' => 'orm_default'
)
'driver' => array(
// overriding zfc-user-doctrine-orm's config
'zfcuser_entity' => array(
'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(
'aliases' => array(
'Zend\Authentication\AuthenticationService' => 'zfcuser_auth_service',
),
'invokables' => array(
),
'abstract_factories' => array(
'UnicaenAuth\Authentication\Adapter\AbstractFactory',
),
......@@ -145,10 +183,16 @@ return array(
},
'zfcuser_auth_service' => function (Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) {
return new \Zend\Authentication\AuthenticationService(
$serviceLocator->get('UnicaenAuth\Authentication\Storage\LdapDb'),
$serviceLocator->get('UnicaenAuth\Authentication\Storage\Chain'),
$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(
......
......@@ -6,24 +6,6 @@
* drop this config file in it and change the values as you wish.
*/
$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 :
* - pour désactiver l'authentification CAS, le tableau 'cas' doit être vide.
......@@ -54,5 +36,4 @@ $settings = array(
*/
return array(
'unicaen-auth' => $settings,
'doctrine' => isset($settings['doctrine']) ? $settings['doctrine'] : array(),
);
\ No newline at end of file
INSERT INTO user_role (role_id, default, parent)
VALUES ('guest', '1', NULL);
\ No newline at end of file
CREATE TABLE user (
id INT(11) NOT NULL AUTO_INCREMENT,
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
* @var string
*/
protected $roleName;
/**
* @var string
*/
protected $roleDescription;
/**
* @param string|null $roleId
* @param RoleInterface|string|null $parent
* @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);
$this->setRoleName($roleName ?: $roleId);
$this->setRoleDescription($roleDescription ?: null);
}
/**
......@@ -48,4 +55,26 @@ class NamedRole extends \BjyAuthorize\Acl\Role
$this->roleName = (string) $roleName;
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
<?php
namespace UnicaenAuth\Authentication\Storage;
use Zend\EventManager\Event;
/**
* Événement propagé dans la chaîne de responsabilité {@see Chain},
* utilisé pour collecter les diverses données concernant l'identité authentifiée.
*
* Exemples de données collectées :
* - <code>array('ldap' => object(UnicaenApp\Entity\Ldap\People), 'db' => object(UnicaenAuth\Entity\Db\User))</code>
* - <code>array('ldap' => object(UnicaenApp\Entity\Ldap\People), 'db' => null)</code>
* - <code>array('ldap' => null, 'db' => object(UnicaenAuth\Entity\Db\User))</code>
* - <code>array('ldap' => null, 'db' => null)</code>
*
* @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
* @see Chain
*/
class ChainEvent extends Event
{
/**
* @var array
*/
protected $contents = array();
/**
* 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 getContents()
{
return $this->contents;
}
/**
* Writes $contents to storage
*
* @param mixed $contents
* @throws \Zend\Authentication\Exception\ExceptionInterface If writing $contents to storage is impossible
* @return void
*/
public function addContents($key, $contents)
{
$this->contents[$key] = $contents;
}
/**
* Clears contents from storage
*
* @throws \Zend\Authentication\Exception\ExceptionInterface If clearing contents from storage is impossible
* @return void
*/
public function clearContents()
{
$this->contents = array();
}
}
\ No newline at end of file
<?php
namespace UnicaenAuth\Authentication\Storage;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
/**