Commit cc5ed43e authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Tests unitaires et améliorations/refactorisations.

parent e257996a
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
namespace UnicaenAuth\Authentication\Storage; namespace UnicaenAuth\Authentication\Storage;
use Zend\Authentication\Storage\StorageInterface; use Zend\Authentication\Storage\StorageInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\EventManager\EventManagerInterface; use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\EventManagerAwareInterface; use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManager; use Zend\EventManager\EventManager;
...@@ -16,8 +14,6 @@ use Zend\EventManager\EventManager; ...@@ -16,8 +14,6 @@ use Zend\EventManager\EventManager;
* Exemples de sources disponibles : * Exemples de sources disponibles :
* - Ldap (annuaire LDAP) * - Ldap (annuaire LDAP)
* - Db (table des utilisateurs en base de données) * - Db (table des utilisateurs en base de données)
*
*
* *
* @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr> * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
* @see ChainEvent * @see ChainEvent
...@@ -25,18 +21,13 @@ use Zend\EventManager\EventManager; ...@@ -25,18 +21,13 @@ use Zend\EventManager\EventManager;
* @see Ldap * @see Ldap
* @see Db * @see Db
*/ */
class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventManagerAwareInterface class Chain implements StorageInterface, EventManagerAwareInterface
{ {
/** /**
* @var StorageInterface * @var StorageInterface
*/ */
protected $storage; protected $storage;
/**
* @var ServiceLocatorInterface
*/
protected $serviceLocator;
/** /**
* @var EventManagerInterface * @var EventManagerInterface
*/ */
...@@ -47,6 +38,11 @@ class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventMana ...@@ -47,6 +38,11 @@ class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventMana
*/ */
protected $event; protected $event;
/**
* @var array
*/
protected $resolvedIdentity;
/** /**
* Returns true if and only if storage is empty * Returns true if and only if storage is empty
* *
...@@ -68,12 +64,23 @@ class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventMana ...@@ -68,12 +64,23 @@ class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventMana
*/ */
public function read() public function read()
{ {
if (null !== $this->resolvedIdentity) {
return $this->resolvedIdentity;
}
$e = $this->getEvent(); $e = $this->getEvent();
$this->getEventManager()->trigger('read', $e); $this->getEventManager()->trigger('read', $e);
$identity = $e->getContents(); $identity = $e->getContents();
return $identity; if ($identity) {
$this->resolvedIdentity = $identity;
}
else {
$this->resolvedIdentity = null;
}
return $this->resolvedIdentity;
} }
/** /**
...@@ -131,28 +138,6 @@ class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventMana ...@@ -131,28 +138,6 @@ class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventMana
return $this; 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 * Inject an EventManager instance
* *
......
...@@ -25,7 +25,6 @@ class ChainServiceFactory implements FactoryInterface ...@@ -25,7 +25,6 @@ class ChainServiceFactory implements FactoryInterface
); );
$chain = new Chain(); $chain = new Chain();
$chain->setServiceLocator($serviceLocator);
foreach ($storages as $priority => $name) { foreach ($storages as $priority => $name) {
$storage = $serviceLocator->get($name); $storage = $serviceLocator->get($name);
......
...@@ -7,7 +7,9 @@ use Zend\ServiceManager\ServiceManager; ...@@ -7,7 +7,9 @@ use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface; use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\Exception\ServiceNotFoundException; use Zend\ServiceManager\Exception\ServiceNotFoundException;
use Zend\Authentication\Exception\InvalidArgumentException; use Zend\Authentication\Exception\InvalidArgumentException;
use ZfcUser\Authentication\Storage\Db as DbStorage; use Zend\Authentication\Storage\Session;
use Zend\Authentication\Storage\StorageInterface;
use ZfcUser\Mapper\UserInterface as UserMapper;
/** /**
* Db authentication storage. * Db authentication storage.
...@@ -17,9 +19,14 @@ use ZfcUser\Authentication\Storage\Db as DbStorage; ...@@ -17,9 +19,14 @@ use ZfcUser\Authentication\Storage\Db as DbStorage;
class Db implements ChainableStorage, ServiceManagerAwareInterface class Db implements ChainableStorage, ServiceManagerAwareInterface
{ {
/** /**
* @var DbStorage * @var StorageInterface
*/ */
protected $delegate; protected $storage;
/**
* @var UserMapper
*/
protected $mapper;
/** /**
* @var mixed * @var mixed
...@@ -27,47 +34,60 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface ...@@ -27,47 +34,60 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
protected $resolvedIdentity; protected $resolvedIdentity;
/** /**
* Writes $contents to storage * @var ServiceManager
*
* @param mixed $contents
* @throws \Zend\Authentication\Exception\InvalidArgumentException If writing $contents to storage is impossible
* @return void
*/ */
public function write(ChainEvent $e) protected $serviceManager;
{
$contents = $e->getParam('contents');
$this->resolvedIdentity = null;
$this->getDelegate()->write($contents);
}
/** /**
* Returns the contents of storage * Returns the contents of storage
* *
* Behavior is undefined when storage is empty. * Behavior is undefined when storage is empty.
* *
* @params ChainEvent $e
* @throws InvalidArgumentException If reading contents from storage is impossible * @throws InvalidArgumentException If reading contents from storage is impossible
* @return \ZfcUser\Entity\UserInterface * @return void
*/ */
public function read(ChainEvent $e) public function read(ChainEvent $e)
{ {
$identity = $this->findIdentity(); if (!$this->resolvedIdentity) {
$identity = $this->findIdentity();
if ($identity) {
$this->resolvedIdentity = $identity;
}
else {
$this->resolvedIdentity = null;
}
}
$e->addContents('db', $identity); $e->addContents('db', $this->resolvedIdentity);
}
/**
* Writes $contents to storage
*
* @params ChainEvent $e
* @throws \Zend\Authentication\Exception\InvalidArgumentException If writing $contents to storage is impossible
* @return void
*/
public function write(ChainEvent $e)
{
$contents = $e->getParam('contents');
return $identity; $this->resolvedIdentity = null;
$this->getStorage()->write($contents);
} }
/** /**
* Clears contents from storage * Clears contents from storage
* *
* @params ChainEvent $e
* @throws \Zend\Authentication\Exception\InvalidArgumentException If clearing contents from storage is impossible * @throws \Zend\Authentication\Exception\InvalidArgumentException If clearing contents from storage is impossible
* @return void * @return void
*/ */
public function clear(ChainEvent $e) public function clear(ChainEvent $e)
{ {
$this->resolvedIdentity = null; $this->resolvedIdentity = null;
$this->getDelegate()->getStorage()->clear(); $this->getStorage()->clear();
} }
/** /**
...@@ -76,8 +96,16 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface ...@@ -76,8 +96,16 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
*/ */
protected function findIdentity() protected function findIdentity()
{ {
$id = $this->getStorage()->read();
// si on obtient autre chose qu'un scalaire, l'utilisateur a déjà été
// recherché/trouvé dans la base de données
if ($id && !is_scalar($id)) {
return $id;
}
/** /**
* 1ere tentative (mécanisme standard du module ZfcUser) : * 1ere tentative :
* *
* Recherche dans la base de données de l'utilisateur dont l'id correspond à ce qui * Recherche dans la base de données de l'utilisateur dont l'id correspond à ce qui
* est stoqué en session. * est stoqué en session.
...@@ -85,19 +113,16 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface ...@@ -85,19 +113,16 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
* NB: En cas de problème de connexion ou de service 'zfcuser_user_mapper' introuvable, * NB: En cas de problème de connexion ou de service 'zfcuser_user_mapper' introuvable,
* cela signifie sans doute que l'application n'utilise pas de table des utilisateurs. * cela signifie sans doute que l'application n'utilise pas de table des utilisateurs.
*/ */
try { if (is_int($id) || is_scalar($id)) {
$identity = $this->getDelegate()->read(); try {
} $identity = $this->getMapper()->findById($id);
catch (PDOException $pdoe) { }
$identity = null; catch (PDOException $pdoe) {
} $identity = null;
catch (ServiceNotFoundException $e) { }
$identity = null; catch (ServiceNotFoundException $e) {
} $identity = null;
// si on obtient autre chose qu'un scalaire, l'utilisateur a déjà été }
// recherché/trouvé dans la base de données
if ($identity && !is_scalar($identity)) {
return $identity;
} }
/** /**
...@@ -109,10 +134,9 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface ...@@ -109,10 +134,9 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
* NB: En cas de problème de connexion ou de service 'zfcuser_user_mapper' introuvable, * NB: En cas de problème de connexion ou de service 'zfcuser_user_mapper' introuvable,
* cela signifie sans doute que l'application n'utilise pas de table des utilisateurs. * cela signifie sans doute que l'application n'utilise pas de table des utilisateurs.
*/ */
$username = $this->getDelegate()->getStorage()->read(); if (is_string($id)) {
if (is_string($username)) {
try { try {
$identity = $this->getDelegate()->getMapper()->findByUsername($username); $identity = $this->getMapper()->findByUsername($id);
} }
catch (PDOException $pdoe) { catch (PDOException $pdoe) {
$identity = null; $identity = null;
...@@ -122,14 +146,58 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface ...@@ -122,14 +146,58 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
} }
} }
if ($identity) { return $identity;
$this->resolvedIdentity = $identity; }
}
else { /**
$this->resolvedIdentity = null; * getStorage
*
* @return StorageInterface
*/
public function getStorage()
{
if (null === $this->storage) {
$this->setStorage(new Session());
} }
return $this->storage;
return $this->resolvedIdentity; }
/**
* setStorage
*
* @param StorageInterface $storage
* @access public
* @return Db
*/
public function setStorage(StorageInterface $storage)
{
$this->storage = $storage;
return $this;
}
/**
* getMapper
*
* @return UserMapper
*/
public function getMapper()
{
if (null === $this->mapper) {
$this->mapper = $this->getServiceManager()->get('zfcuser_user_mapper');
}
return $this->mapper;
}
/**
* setMapper
*
* @param UserMapper $mapper
* @return Db
*/
public function setMapper(UserMapper $mapper = null)
{
$this->mapper = $mapper;
return $this;
} }
/** /**
...@@ -146,21 +214,11 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface ...@@ -146,21 +214,11 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
* Set service manager instance * Set service manager instance
* *
* @param ServiceManager $locator * @param ServiceManager $locator
* @return void * @return self
*/ */
public function setServiceManager(ServiceManager $serviceManager) public function setServiceManager(ServiceManager $serviceManager)
{ {
$this->serviceManager = $serviceManager; $this->serviceManager = $serviceManager;
} return $this;
/**
* @return DbStorage
*/
protected function getDelegate()
{
if (null === $this->delegate) {
$this->delegate = $this->getServiceManager()->get('ZfcUser\Authentication\Storage\Db');
}
return $this->delegate;
} }
} }
\ No newline at end of file
...@@ -43,17 +43,6 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface ...@@ -43,17 +43,6 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface
*/ */
protected $serviceManager; protected $serviceManager;
/**
* Returns true if and only if storage is empty
*
* @throws InvalidArgumentException If it is impossible to determine whether storage is empty
* @return boolean
*/
public function isEmpty()
{
return $this->getStorage()->isEmpty();
}
/** /**
* Returns the contents of storage * Returns the contents of storage
* *
...@@ -84,7 +73,15 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface ...@@ -84,7 +73,15 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface
$identity = $this->getStorage()->read(); $identity = $this->getStorage()->read();
if (is_scalar($identity)) { if (is_scalar($identity)) {
$identity = $this->getMapper()->findOneByUsername($identity); try {
$identity = $this->getMapper()->findOneByUsername($identity);
}
catch (\Zend\Ldap\Exception\LdapException $exc) {
$identity = null;
}
catch (\UnicaenApp\Exception $exc) {
$identity = null;
}
} }
if ($identity) { if ($identity) {
...@@ -168,7 +165,7 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface ...@@ -168,7 +165,7 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface
* @param LdapPeopleMapper $mapper * @param LdapPeopleMapper $mapper
* @return Ldap * @return Ldap
*/ */
public function setMapper(LdapPeopleMapper $mapper) public function setMapper(LdapPeopleMapper $mapper = null)
{ {
$this->mapper = $mapper; $this->mapper = $mapper;
return $this; return $this;
...@@ -188,7 +185,7 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface ...@@ -188,7 +185,7 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface
* Set service manager instance * Set service manager instance
* *
* @param ServiceManager $locator * @param ServiceManager $locator
* @return void * @return self
*/ */
public function setServiceManager(ServiceManager $serviceManager) public function setServiceManager(ServiceManager $serviceManager)
{ {
...@@ -199,7 +196,7 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface ...@@ -199,7 +196,7 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface
/** /**
* @param ModuleOptions $options * @param ModuleOptions $options
*/ */
public function setOptions(ModuleOptions $options) public function setOptions(ModuleOptions $options = null)
{ {
$this->options = $options; $this->options = $options;
return $this; return $this;
......
<?php
namespace UnicaenAuth\Authentication\Storage;
use UnicaenAuth\Entity\Ldap\PeopleAdapter;
use UnicaenAuth\Options\ModuleOptions;
use Zend\Authentication\Exception\InvalidArgumentException;
use Zend\Authentication\Storage;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use ZfcUser\Entity\UserInterface;
/**
* Ldap/Db mixin authentification storage.
*
* @see Ldap
* @see Db
* @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
*/
class LdapDb implements Storage\StorageInterface, ServiceManagerAwareInterface
{
/**
* @var ServiceManager
*/
protected $serviceManager;
/**
* @var Ldap
*/
protected $ldapStorage;
/**
* @var Db
*/
protected $dbStorage;
/**
* @var ModuleOptions
*/
protected $options;
/**
* Returns true if and only if storage is empty
*
* @throws InvalidArgumentException If it is impossible to determine whether storage is empty
* @return boolean
*/
public function isEmpty()
{
if ($this->getLdapStorage()->isEmpty() && $this->getDbStorage()->isEmpty()) {
return true;
}
return false;
}
/**
* Returns the contents of storage
*
* Behavior is undefined when storage is empty.
*
* @throws InvalidArgumentException If reading contents from storage is impossible
* @return UserInterface
*/