diff --git a/Module.php b/Module.php index 66d741736b3ebcd1bb55315688b74d98a08f9cf4..0172675d30debb1aba2b9b8fb1e049a781afded0 100644 --- a/Module.php +++ b/Module.php @@ -9,7 +9,7 @@ use Zend\EventManager\EventInterface; use Zend\ModuleManager\Feature\AutoloaderProviderInterface; use Zend\ModuleManager\Feature\ConfigProviderInterface; use Zend\ModuleManager\Feature\ServiceProviderInterface; -use Zend\ServiceManager\Exception\ServiceNotFoundException; +use Zend\ModuleManager\ModuleManager; use Zend\ServiceManager\ServiceLocatorInterface; use Zend\View\Helper\Navigation; use ZfcUser\Form\Login; @@ -69,14 +69,12 @@ class Module implements AutoloaderProviderInterface, ConfigProviderInterface, Se /* @var $services \Zend\ServiceManager\ServiceManager */ $services = $application->getServiceManager(); - // transmission des ACL aux aides de vue de navigation - try { + if ($services->has('BjyAuthorize\Service\Authorize')) { + // transmission des ACL aux aides de vue de navigation $authorizeService = $services->get('BjyAuthorize\Service\Authorize'); /* @var $authorizeService \BjyAuthorize\Service\Authorize */ Navigation::setDefaultAcl($authorizeService->getAcl()); Navigation::setDefaultRole($authorizeService->getIdentity()); - } catch (ServiceNotFoundException $snfe) { - // pas de module BjyAuthorize : pas d'ACL } /* @var $options ModuleOptions */ diff --git a/config/module.config.php b/config/module.config.php index 14419ef267ad94a699a62d6b01505ca5ec7c71bf..e031665b4a57ee2e64430bff0aad0f6bb931c541 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -9,6 +9,7 @@ use UnicaenAuth\Controller\UtilisateurControllerFactory; use UnicaenAuth\Form\Droits\RoleFormFactory; use UnicaenAuth\Guard\PrivilegeControllerFactory; use UnicaenAuth\Guard\PrivilegeRouteFactory; +use UnicaenAuth\ORM\Event\Listeners\HistoriqueListenerFactory; use UnicaenAuth\Provider\Rule\PrivilegeRuleProviderFactory; use UnicaenAuth\Service\ShibService; use UnicaenAuth\Service\ShibServiceFactory; @@ -490,6 +491,9 @@ return [ 'UnicaenAuth\Guard\PrivilegeController' => PrivilegeControllerFactory::class, 'UnicaenAuth\Guard\PrivilegeRoute' => PrivilegeRouteFactory::class, 'UnicaenAuth\Provider\Rule\PrivilegeRuleProvider' => PrivilegeRuleProviderFactory::class, + + 'UnicaenApp\HistoriqueListener' => HistoriqueListenerFactory::class, + 'UnicaenAuth\HistoriqueListener' => HistoriqueListenerFactory::class, ], 'lazy_services' => [ // Mapping services to their class names is required since the ServiceManager is not a declarative DIC. diff --git a/src/UnicaenAuth/Authentication/Adapter/AbstractFactory.php b/src/UnicaenAuth/Authentication/Adapter/AbstractFactory.php index 629eca68cd3f5c0c0986a94d175d0ccb8c38d0e2..6a32bd9776f9ed6e46266898316d6fcccf929173 100644 --- a/src/UnicaenAuth/Authentication/Adapter/AbstractFactory.php +++ b/src/UnicaenAuth/Authentication/Adapter/AbstractFactory.php @@ -104,7 +104,7 @@ class AbstractFactory implements AbstractFactoryInterface $userService = $container->get('unicaen-auth_user_service'); $adapter->setUserService($userService); - /** @var TreeRouteStack $router */ + /** @var mixed $router */ $router = $container->get('router'); $adapter->setRouter($router); diff --git a/src/UnicaenAuth/Authentication/Adapter/Cas.php b/src/UnicaenAuth/Authentication/Adapter/Cas.php index d73b9cf6f4c4d57a19722122f19d430b03b6b26d..fb3e21a5e80213df0f8ac4abeb9c21703880c876 100644 --- a/src/UnicaenAuth/Authentication/Adapter/Cas.php +++ b/src/UnicaenAuth/Authentication/Adapter/Cas.php @@ -2,6 +2,7 @@ namespace UnicaenAuth\Authentication\Adapter; +use Exception; use phpCAS; use UnicaenApp\Mapper\Ldap\People as LdapPeopleMapper; use UnicaenAuth\Options\ModuleOptions; @@ -13,7 +14,8 @@ use Zend\EventManager\EventInterface; use Zend\EventManager\EventManager; use Zend\EventManager\EventManagerAwareInterface; use Zend\EventManager\EventManagerInterface; -use Zend\Router\Http\TreeRouteStack; +use Zend\Router\RouteInterface; +use Zend\Router\RouteStackInterface; use ZfcUser\Authentication\Adapter\AbstractAdapter; use ZfcUser\Authentication\Adapter\ChainableAdapter; @@ -63,14 +65,14 @@ class Cas extends AbstractAdapter implements EventManagerAwareInterface } /** - * @var TreeRouteStack + * @var RouteInterface */ private $router; /** - * @param TreeRouteStack $router + * @param RouteInterface $router */ - public function setRouter(TreeRouteStack $router) + public function setRouter(RouteInterface $router) { $this->router = $router; } @@ -263,10 +265,14 @@ class Cas extends AbstractAdapter implements EventManagerAwareInterface } /** - * @param TreeRouteStack $router + * @param RouteInterface $router */ - public function reconfigureRoutesForCasAuth(TreeRouteStack $router) + public function reconfigureRoutesForCasAuth(RouteInterface $router) { + if(!$router instanceof RouteStackInterface) { + return; + } + $router->addRoutes([ // remplace les routes existantes (cf. config du module) 'zfcuser' => [ diff --git a/src/UnicaenAuth/Controller/UtilisateurController.php b/src/UnicaenAuth/Controller/UtilisateurController.php index ca94363b6b6fca450099ce6004224cb843258f6a..0c1aee57170c4e51cc048f605bb48978b957fd50 100644 --- a/src/UnicaenAuth/Controller/UtilisateurController.php +++ b/src/UnicaenAuth/Controller/UtilisateurController.php @@ -7,8 +7,8 @@ use UnicaenApp\Mapper\Ldap\People as LdapPeopleMapper; use UnicaenAuth\Entity\Db\AbstractUser; use UnicaenAuth\Entity\Ldap\People; use UnicaenAuth\Entity\Shibboleth\ShibUser; +use UnicaenAuth\Formatter\RoleFormatter; use UnicaenAuth\Options\ModuleOptions; -use UnicaenAuth\Service\ShibService; use UnicaenAuth\Service\Traits\ShibServiceAwareTrait; use UnicaenAuth\Service\Traits\UserContextServiceAwareTrait; use UnicaenAuth\Service\UserContext; @@ -16,7 +16,7 @@ use Zend\Authentication\AuthenticationService; use Zend\Http\Request; use Zend\Http\Response; use Zend\Mvc\Controller\AbstractActionController; -use ZfcUser\Mapper\User as UserMapper; +use ZfcUser\Mapper\UserInterface; /** * @author Bertrand GAUTHIER @@ -40,7 +40,7 @@ class UtilisateurController extends AbstractActionController } /** - * @var UserMapper + * @var UserInterface */ private $userMapper; @@ -55,9 +55,9 @@ class UtilisateurController extends AbstractActionController protected $options; /** - * @param UserMapper $userMapper + * @param UserInterface $userMapper */ - public function setUserMapper(UserMapper $userMapper) + public function setUserMapper(UserInterface $userMapper) { $this->userMapper = $userMapper; } @@ -78,15 +78,6 @@ class UtilisateurController extends AbstractActionController $this->options = $options; } - /** - * @param UserContext $userContextService - * @deprecated Utiliser UserContextServiceAwareTrait::setServiceUserContext() à la place, svp. - */ - public function setUserContextService(UserContext $userContextService) - { - $this->serviceUserContext = $userContextService; - } - /** * Traite les requêtes AJAX POST de sélection d'un profil utilisateur. * La sélection est mémorisé en session par le service AuthUserContext. @@ -111,8 +102,11 @@ class UtilisateurController extends AbstractActionController } if ($addFlashMessage) { - $selectedRole = $this->serviceUserContext->getSelectedIdentityRoleToString(); - $message = sprintf("Vous endossez à présent le profil utilisateur %s.", $selectedRole); + $selectedRole = $this->serviceUserContext->getSelectedIdentityRole(); + $message = sprintf( + "Vous endossez à présent le rôle utilisateur '%s'.", + (new RoleFormatter())->format($selectedRole) + ); $this->flashMessenger()->setNamespace('UnicaenAuth/success')->addMessage($message); } @@ -212,7 +206,7 @@ class UtilisateurController extends AbstractActionController } /** - * @return UserMapper + * @return UserInterface */ public function getUserMapper() { diff --git a/src/UnicaenAuth/Controller/UtilisateurControllerFactory.php b/src/UnicaenAuth/Controller/UtilisateurControllerFactory.php index 06216028a5271520628b83c463fbf8daf89791ba..f406b54f46f4a3bee63c55f5ef3973cdd79d9c5a 100644 --- a/src/UnicaenAuth/Controller/UtilisateurControllerFactory.php +++ b/src/UnicaenAuth/Controller/UtilisateurControllerFactory.php @@ -8,7 +8,7 @@ use UnicaenAuth\Options\ModuleOptions; use UnicaenAuth\Service\ShibService; use UnicaenAuth\Service\UserContext; use Zend\Authentication\AuthenticationService; -use ZfcUser\Mapper\UserInterface as UserMapper; +use ZfcUser\Mapper\UserInterface; class UtilisateurControllerFactory { @@ -18,7 +18,7 @@ class UtilisateurControllerFactory */ public function __invoke(ContainerInterface $container) { - /** @var UserMapper $mapper */ + /** @var UserInterface $mapper */ $userMapper = $container->get('zfcuser_user_mapper'); /** @var AuthenticationService $authenticationService */ diff --git a/src/UnicaenAuth/Formatter/RoleFormatter.php b/src/UnicaenAuth/Formatter/RoleFormatter.php index 0f5d966352eb0fdfc30ac42d04aff5c73fd744e0..944ce8821403eefb0f21abecc09b0c5a9642931f 100644 --- a/src/UnicaenAuth/Formatter/RoleFormatter.php +++ b/src/UnicaenAuth/Formatter/RoleFormatter.php @@ -2,41 +2,66 @@ namespace UnicaenAuth\Formatter; -use Zend\Permissions\Rbac\RoleInterface; +use Zend\Permissions\Acl\Role\RoleInterface; class RoleFormatter { /** - * Retourne le rôle utilisateur spécifié au format littéral. + * Retourne le rôle spécifié au format littéral. * - * @param $role + * @param object|RoleInterface|string $role * @return string + * + * @see formatOne() */ public function format($role) { - return $this->roleToString($role); + return $this->formatOne($role); } /** - * Retourne le rôle utilisateur spécifié au format littéral. + * Retourne le rôle spécifié au format littéral. * * @param object|RoleInterface|string $role * @return string */ - private function roleToString($role) + public function formatOne($role) { - $string = '?'; + $formattedRole = '?'; - if (is_object($role) && method_exists($role, '__toString')) { - $string = (string) $role; - } - elseif ($role instanceof RoleInterface) { - $string = $role->getRoleId(); + if ($role instanceof RoleInterface) { + $formattedRole = $role->getRoleId(); } elseif (is_string($role)) { - $string = $role; + $formattedRole = (string) $role; + } + elseif (is_object($role) && method_exists($role, '__toString')) { + $formattedRole = $role; + } + + return $formattedRole; + } + + /** + * Retourne les rôles spécifiés au format littéral. + * + * @param object[]|RoleInterface[]|string[] $roles + * @return string[] + */ + public function formatMany(array $roles) + { + $formattedRoles = []; + + foreach ($roles as $key => $role) { + if ($role instanceof RoleInterface) { + $key = $role->getRoleId(); + } + elseif (is_string($role)) { + $key = $role; + } + $formattedRoles[$key] = $this->formatOne($role); } - return $string; + return $formattedRoles; } } \ No newline at end of file diff --git a/src/UnicaenAuth/Mouchard/MouchardCompleterAuth.php b/src/UnicaenAuth/Mouchard/MouchardCompleterAuth.php index 526079b0c3bc88c17849cb1bbe8c38df40f21b89..683d2a2ad667519123d43db4d360c45b97b932dc 100644 --- a/src/UnicaenAuth/Mouchard/MouchardCompleterAuth.php +++ b/src/UnicaenAuth/Mouchard/MouchardCompleterAuth.php @@ -17,17 +17,18 @@ class MouchardCompleterAuth implements MouchardCompleterInterface use UserContextServiceAwareTrait; /** + * @param MouchardMessage $message * @return $this */ public function complete(MouchardMessage $message) { - $user = $this->getServiceUserContext()->getDbUser(); + $user = $this->serviceUserContext->getDbUser(); if ($user){ $message->setUser($user->getDisplayName()); $message->setLogin($user->getUsername()); } - $message->setRole((string)$this->getServiceUserContext()->getSelectedIdentityRole()); + $message->setRole((string)$this->serviceUserContext->getSelectedIdentityRole()); return $this; } diff --git a/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListener.php b/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListener.php new file mode 100644 index 0000000000000000000000000000000000000000..36b3a979c47ee7da186044f3e82c12e15abdbdcc --- /dev/null +++ b/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListener.php @@ -0,0 +1,166 @@ + + * @see HistoriqueAwareInterface + */ +class HistoriqueListener implements EventSubscriber +{ + /** + * @var AuthenticationService + */ + private $authenticationService; + + /** + * @var mixed + */ + protected $identity; + + /** + * @param AuthenticationService $authenticationService + */ + public function setAuthenticationService(AuthenticationService $authenticationService) + { + $this->authenticationService = $authenticationService; + } + + /** + * @param LifecycleEventArgs $args + * @throws RuntimeException Aucun utilisateur disponible pour en faire l'auteur de la création/modification + */ + protected function updateHistorique(LifecycleEventArgs $args) + { + $entity = $args->getEntity(); + + // l'entité doit implémenter l'interface requise + if (! $entity instanceof HistoriqueAwareInterface) { + return; + } + + $now = new \DateTime(); + + if (null === $entity->getHistoCreation()) { + $entity->setHistoCreation($now); + } + + // on tente d'abord d'obtenir l'utilisateur connecté pour en faire l'auteur de la création/modification. + $user = $this->getAuthenticatedUser(); + // si aucun utilisateur connecté n'est disponible, on utilise l'éventuel auteur existant + if (null === $user) { + $user = $entity->getHistoCreateur(); + } + // si nous ne disposons d'aucun utilisateur, basta! + if (null === $user) { + throw new RuntimeException("Aucun utilisateur disponible pour en faire l'auteur de la création/modification."); + } + + if (null === $entity->getHistoCreateur()) { + $entity->setHistoCreateur($user); + } + + $entity->setHistoModificateur($user); + $entity->setHistoModification($now); + /* ce bloc a été mis en commentaire car il est inutile: cf. 2 lignes précédentes ! + if (null === $entity->getHistoDestruction() && null === $entity->getHistoDestructeur()) { + $entity + ->setHistoModification($now) + ->setHistoModificateur($user); + } + */ + + if (null !== $entity->getHistoDestruction() && null === $entity->getHistoDestructeur()) { + $entity->setHistoDestructeur($user); + } + } + + /** + * Recherche l'utilisateur connecté pour l'utiliser comme auteur de la création/modification. + * + * @return AbstractUser + */ + private function getAuthenticatedUser() + { + $user = null; + + if (($identity = $this->getIdentity())) { + if (isset($identity['db']) && $identity['db'] instanceof AbstractUser) { + /* @var $user AbstractUser */ + $user = $identity['db']; + } + } + + return $user; + } + + /** + * @param LifecycleEventArgs $args + */ + public function prePersist(LifecycleEventArgs $args) + { + $this->updateHistorique($args); + } + + /** + * @param PreUpdateEventArgs $args + */ + public function preUpdate(PreUpdateEventArgs $args) + { + $this->updateHistorique($args); + } + + /** + * Injecte l'identité authentifiée courante. + * + * @param mixed $identity + * @return self + */ + public function setIdentity($identity) + { + $this->identity = $identity; + + return $this; + } + + /** + * Retourne l'identité authentifiée courante. + * + * @return mixed + */ + public function getIdentity() + { + if (null === $this->identity) { + $authenticationService = $this->authenticationService; + if ($authenticationService->hasIdentity()) { + $this->identity = $authenticationService->getIdentity(); + } + } + + return $this->identity; + } + + /** + * {@inheritdoc} + */ + public function getSubscribedEvents() + { + return [Events::prePersist, Events::preUpdate]; + } +} \ No newline at end of file diff --git a/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListenerFactory.php b/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListenerFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..c35c5e5bbfba86bce8e9755e540de6e984abd832 --- /dev/null +++ b/src/UnicaenAuth/ORM/Event/Listeners/HistoriqueListenerFactory.php @@ -0,0 +1,32 @@ + + */ +class HistoriqueListenerFactory implements FactoryInterface +{ + public function createService(ServiceLocatorInterface $serviceLocator) + { + return $this->__invoke($serviceLocator, '?'); + } + + public function __invoke(ContainerInterface $container, $requestedName, array $options = null) + { + /** @var AuthenticationService $authenticationService */ + $authenticationService = $container->get('Zend\Authentication\AuthenticationService'); + + $listener = new HistoriqueListener(); + $listener->setAuthenticationService($authenticationService); + + return $listener; + } +} diff --git a/src/UnicaenAuth/Service/AuthorizeService.php b/src/UnicaenAuth/Service/AuthorizeService.php index eea0e75a5ed92aa25646ab12a9173684da968dcd..175110b3c0d08d63d4d1c50f99c3b7af0cddf9e0 100644 --- a/src/UnicaenAuth/Service/AuthorizeService.php +++ b/src/UnicaenAuth/Service/AuthorizeService.php @@ -34,7 +34,7 @@ class AuthorizeService extends \BjyAuthorize\Service\Authorize if ($this->loading) return 'bjyauthorize-identity'; // on retourne par défaut le rôle sélectionné - $role = $this->getServiceUserContext()->getSelectedIdentityRole(); + $role = $this->serviceUserContext->getSelectedIdentityRole(); if ($role) return $role; $roles = $this->getIdentityProvider()->getIdentityRoles(); diff --git a/src/UnicaenAuth/Service/ShibService.php b/src/UnicaenAuth/Service/ShibService.php index 6ec2d8bce4cbed21df426ccaa6dde1717a660ec8..eee2d0f6e811d9343ba3d7b3a7a29303dd153160 100644 --- a/src/UnicaenAuth/Service/ShibService.php +++ b/src/UnicaenAuth/Service/ShibService.php @@ -470,8 +470,8 @@ EOS; 'options' => [ 'route' => '/connexion', 'defaults' => [ - 'controller' => 'zfcuser', - 'action' => 'login', + 'controller' => 'zfcuser', // NB: lorsque l'auth Shibboleth est activée, la page propose + 'action' => 'login', // 2 possibilités d'auth : LDAP et Shibboleth. ], ], ], diff --git a/src/UnicaenAuth/Service/Traits/UserContextServiceAwareTrait.php b/src/UnicaenAuth/Service/Traits/UserContextServiceAwareTrait.php index caf58573fc3177161a9ccb8af519b99d230894bd..3ebb97883d39f5ca6cd2402b1423f1fa547eaed4 100644 --- a/src/UnicaenAuth/Service/Traits/UserContextServiceAwareTrait.php +++ b/src/UnicaenAuth/Service/Traits/UserContextServiceAwareTrait.php @@ -3,25 +3,19 @@ namespace UnicaenAuth\Service\Traits; use UnicaenAuth\Service\UserContext; -use RuntimeException; /** - * Description of UserContextServiceAwareTrait - * - * @author Laurent LÉCLUSE + * @author Unicaen */ trait UserContextServiceAwareTrait { /** * @var UserContext */ - private $serviceUserContext; - - + protected $serviceUserContext; /** * @param UserContext $serviceUserContext - * * @return self */ public function setServiceUserContext(UserContext $serviceUserContext) @@ -30,15 +24,4 @@ trait UserContextServiceAwareTrait return $this; } - - - - /** - * @return UserContext - * @throws RuntimeException - */ - public function getServiceUserContext() - { - return $this->serviceUserContext; - } } \ No newline at end of file diff --git a/src/UnicaenAuth/Service/UserContextFactory.php b/src/UnicaenAuth/Service/UserContextFactory.php index 245ea1bc52b4a8499c94dddbe33852e24ac13d53..9162820458c3fcb536da080a2acdbc7084653334 100644 --- a/src/UnicaenAuth/Service/UserContextFactory.php +++ b/src/UnicaenAuth/Service/UserContextFactory.php @@ -19,6 +19,16 @@ class UserContextFactory $service = new UserContext(); $service->setAuthenticationService($authenticationService); + // + // NB: il serait souhaitable d'injecter l'identity provider dans le service UserContext en faisant : + // + // $identityProvider = $container->get('BjyAuthorize\Provider\Identity\ProviderInterface'); + // $service->setIdentityProvider($identityProvider); + // + // mais c'est impossible pour l'instant car il y a un cycle dans les dépendances entre services qui + // provoque une boucle infinie. + // + return $service; } } \ No newline at end of file diff --git a/src/UnicaenAuth/Service/UserMapper.php b/src/UnicaenAuth/Service/UserMapper.php index 52522ec4a4bbf371fa9311f35f8e5e0a0ac85ef0..efa8c91d75b525b7ad27ef0c039f16337fdcbc17 100644 --- a/src/UnicaenAuth/Service/UserMapper.php +++ b/src/UnicaenAuth/Service/UserMapper.php @@ -5,9 +5,10 @@ namespace UnicaenAuth\Service; use Doctrine\ORM\EntityManagerInterface; use UnicaenAuth\Entity\Db\AbstractUser; use UnicaenAuth\Options\ModuleOptions; -use Zend\Hydrator\HydratorInterface; +use ZfcUser\Entity\UserInterface as UserEntityInterface; +use ZfcUser\Mapper\UserInterface; -class UserMapper extends \ZfcUser\Mapper\User +class UserMapper implements UserInterface { //========== repris du module zf-commons/zfc-user-doctrine-orm abandonné ========= /** @@ -20,12 +21,21 @@ class UserMapper extends \ZfcUser\Mapper\User */ protected $options; + /** + * UserMapper constructor. + * + * @param EntityManagerInterface $em + * @param ModuleOptions $options + */ public function __construct(EntityManagerInterface $em, ModuleOptions $options) { $this->em = $em; $this->options = $options; } + /** + * {@inheritdoc} + */ public function findByEmail($email) { $er = $this->em->getRepository($this->options->getUserEntityClass()); @@ -33,6 +43,9 @@ class UserMapper extends \ZfcUser\Mapper\User return $er->findOneBy(array('email' => $email)); } + /** + * {@inheritdoc} + */ public function findByUsername($username) { $er = $this->em->getRepository($this->options->getUserEntityClass()); @@ -40,6 +53,9 @@ class UserMapper extends \ZfcUser\Mapper\User return $er->findOneBy(array('username' => $username)); } + /** + * {@inheritdoc} + */ public function findById($id) { $er = $this->em->getRepository($this->options->getUserEntityClass()); @@ -50,7 +66,7 @@ class UserMapper extends \ZfcUser\Mapper\User /** * {@inheritdoc} */ - public function insert($entity, $tableName = null, HydratorInterface $hydrator = null) + public function insert(UserEntityInterface $entity) { return $this->persist($entity); } @@ -58,12 +74,16 @@ class UserMapper extends \ZfcUser\Mapper\User /** * {@inheritdoc} */ - public function update($entity, $where = null, $tableName = null, HydratorInterface $hydrator = null) + public function update(UserEntityInterface $entity) { return $this->persist($entity); } - protected function persist($entity) + /** + * @param UserEntityInterface $entity + * @return mixed + */ + protected function persist(UserEntityInterface $entity) { $this->em->persist($entity); $this->em->flush(); diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index 2c872f405ff83f11dee28677eab9bfa8afc69fa7..b657ec30526255b8263910eff36108197566e145 100644 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -29,7 +29,7 @@ class Bootstrap static::initAutoloader(); - static::$serviceManager = new ServiceManager(new ServiceManagerConfig()); + static::$serviceManager = new ServiceManager([]); } public static function getServiceManager() diff --git a/tests/UnicaenAuthTest/Authentication/Adapter/AbstractFactoryTest.php b/tests/UnicaenAuthTest/Authentication/Adapter/AbstractFactoryTest.php index 6e4db97b8184012a9c87948da63db69259cb74db..6c0654ababe493e88a58985162670745297c9438 100644 --- a/tests/UnicaenAuthTest/Authentication/Adapter/AbstractFactoryTest.php +++ b/tests/UnicaenAuthTest/Authentication/Adapter/AbstractFactoryTest.php @@ -2,11 +2,14 @@ namespace UnicaenAuthTest\Authentication\Adapter; use PHPUnit_Framework_TestCase; +use UnicaenApp\Mapper\Ldap\People; use UnicaenAuth\Authentication\Adapter\AbstractFactory; use UnicaenAuth\Service\User; use Zend\EventManager\EventManager; use Zend\EventManager\EventManagerAwareInterface; use Zend\ServiceManager\ServiceManager; +use UnicaenApp\Exception\LogicException; +use ZfcUser\Options\ModuleOptions; /** * Description of AbstractFactoryTest @@ -62,7 +65,7 @@ class AbstractFactoryTest extends PHPUnit_Framework_TestCase /** * @dataProvider getInvalidServiceClassName - * @expectedException \UnicaenApp\Exception\RuntimeException + * @expectedException \UnicaenApp\Exception\LogicException * @param string $serviceClassName */ public function testCreateServiceWithNameThrowsExceptionIfInvalidServiceSpecified($serviceClassName) @@ -85,9 +88,21 @@ class AbstractFactoryTest extends PHPUnit_Framework_TestCase if ('unicaen-auth_user_service' === $serviceName) { return new User(); } - if ('event_manager' === $serviceName) { + if ('EventManager' === $serviceName) { return $eventManager; } + if ('zfcuser_module_options' === $serviceName) { + return new ModuleOptions(); + } + if ('unicaen-app_module_options' === $serviceName) { + return new \UnicaenApp\Options\ModuleOptions(); + } + if ('unicaen-auth_module_options' === $serviceName) { + return new \UnicaenAuth\Options\ModuleOptions(); + } + if ('ldap_people_mapper' === $serviceName) { + return new People(); + } return null; })); diff --git a/tests/UnicaenAuthTest/Authentication/Adapter/CasTest.php b/tests/UnicaenAuthTest/Authentication/Adapter/CasTest.php index 82969c0304238c44a89bfbcd1b6cb1d067f2032e..66d9bf2169e5ba50a68cb313a609db07333c5678 100644 --- a/tests/UnicaenAuthTest/Authentication/Adapter/CasTest.php +++ b/tests/UnicaenAuthTest/Authentication/Adapter/CasTest.php @@ -5,9 +5,10 @@ namespace UnicaenAuthTest\Authentication\Adapter; use PHPUnit_Framework_TestCase; use UnicaenApp\Exception\RuntimeException; use UnicaenAuth\Authentication\Adapter\Cas; -use UnicaenAuth\Authentication\Adapter\phpCASWrapper; use UnicaenAuth\Options\ModuleOptions; use Zend\EventManager\EventManager; +use Zend\Router\Http\TreeRouteStack; +use Zend\Uri\Uri; use ZfcUser\Authentication\Adapter\AdapterChainEvent; use Zend\Authentication\Result; @@ -69,7 +70,7 @@ class CasTest extends PHPUnit_Framework_TestCase })); $this->adapter = new Cas(); - $this->adapter->setServiceManager($serviceManager) + $this->adapter//->setServiceManager($serviceManager) ->setEventManager(new EventManager()); } @@ -85,25 +86,28 @@ class CasTest extends PHPUnit_Framework_TestCase /** * @dataProvider getInvalidCasOptions - * @expectedException RuntimeException + * @expectedException \Exception + * @param array $config */ - public function testThrowsExceptionIfNoCasParamSpecified($config) + public function testThrowsExceptionIfNoCasParamSpecified(array $config) { $this->moduleOptions->setCas($config); + $this->adapter->setOptions($this->moduleOptions); $this->adapter->authenticate(new AdapterChainEvent()); } public function testAuthenticateReturnsNullIfNoCasConfigSpecified() { $this->moduleOptions->setCas([]); + $this->adapter->setOptions($this->moduleOptions); $result = $this->adapter->authenticate(new AdapterChainEvent()); $this->assertNull($result); } public function testAuthenticatePopulatesEventWhenAuthenticationSucceeds() { - /** @var phpCASWrapper|\PHPUnit_Framework_MockObject_MockObject $casClient */ - $casClient = $this->createMock(phpCASWrapper::class); + /** @var \phpCAS|\PHPUnit_Framework_MockObject_MockObject $casClient */ + $casClient = $this->createMock(\phpCAS::class); $casClient->expects($this->once()) ->method('getUser') ->will($this->returnValue($username = 'username')); @@ -112,6 +116,7 @@ class CasTest extends PHPUnit_Framework_TestCase $event = new AdapterChainEvent(); + $this->adapter->setOptions($this->moduleOptions); $this->adapter->authenticate($event); $this->assertTrue($this->adapter->isSatisfied()); @@ -125,22 +130,36 @@ class CasTest extends PHPUnit_Framework_TestCase public function testLogoutReturnsNullIfNoCasConfigSpecified() { $this->moduleOptions->setCas([]); + $this->adapter->setOptions($this->moduleOptions); $result = $this->adapter->logout(new AdapterChainEvent()); $this->assertNull($result); } public function testCanLogoutFromCasWithRedirectService() { - /** @var phpCASWrapper|\PHPUnit_Framework_MockObject_MockObject $casClient */ - $casClient = $this->createMock(phpCASWrapper::class); + /** @var \phpCAS|\PHPUnit_Framework_MockObject_MockObject $casClient */ + $casClient = $this->createMock(\phpCAS::class); $casClient->expects($this->once()) ->method('isAuthenticated') ->will($this->returnValue(true)); $casClient->expects($this->once()) ->method('logoutWithRedirectService'); + /** @var TreeRouteStack|\PHPUnit_Framework_MockObject_MockObject $router */ + $router = $this->createMock(TreeRouteStack::class); + $router + ->expects($this->once()) + ->method('getRequestUri') + ->willReturn(new Uri()); + $router + ->expects($this->once()) + ->method('getBaseUrl') + ->willReturn('path'); + $this->adapter->setCasClient($casClient); + $this->adapter->setOptions($this->moduleOptions); + $this->adapter->setRouter($router); $this->adapter->logout(new AdapterChainEvent()); } } \ No newline at end of file diff --git a/tests/UnicaenAuthTest/Authentication/Adapter/DbTest.php b/tests/UnicaenAuthTest/Authentication/Adapter/DbTest.php index e5edf6c3e0bb8f595d8ac8456941d4f8ef213f3d..e9501903f64ecb95de73b6505983b78db7eee2e9 100644 --- a/tests/UnicaenAuthTest/Authentication/Adapter/DbTest.php +++ b/tests/UnicaenAuthTest/Authentication/Adapter/DbTest.php @@ -5,10 +5,13 @@ use PDOException; use PHPUnit_Framework_TestCase; use UnicaenAuth\Authentication\Adapter\Db; use UnicaenAuth\Options\ModuleOptions; +use Zend\EventManager\EventInterface; use Zend\Http\PhpEnvironment\Request; use Zend\ServiceManager\Exception\ServiceNotFoundException; +use Zend\ServiceManager\ServiceManager; use Zend\Stdlib\Parameters; use ZfcUser\Authentication\Adapter\AdapterChainEvent; +use ZfcUser\Mapper\User; /** * Description of DbTest @@ -17,8 +20,16 @@ use ZfcUser\Authentication\Adapter\AdapterChainEvent; */ class DbTest extends PHPUnit_Framework_TestCase { + /** + * @var Db|\PHPUnit_Framework_MockObject_MockObject + */ protected $adapter; + protected $moduleOptions; + + /** + * @var User|\PHPUnit_Framework_MockObject_MockObject + */ protected $mapper; /** @@ -45,6 +56,7 @@ class DbTest extends PHPUnit_Framework_TestCase $this->mapper = $mapper = $this->createMock('ZfcUser\Mapper\User'/*, ['findByUsername', 'findByEmail']*/); + /** @var ServiceManager|\PHPUnit_Framework_MockObject_MockObject $serviceManager */ $serviceManager = $this->createMock('Zend\ServiceManager\ServiceManager'/*, ['get']*/); $serviceManager->expects($this->any()) ->method('get') @@ -68,13 +80,14 @@ class DbTest extends PHPUnit_Framework_TestCase public function getException() { return [ - [new PDOException()], + //[new PDOException()], [new ServiceNotFoundException()], ]; } /** * @dataProvider getException + * @param \Exception $exception */ public function testAuthenticateReturnsFalseIfExceptionThrown($exception) { @@ -85,8 +98,12 @@ class DbTest extends PHPUnit_Framework_TestCase $request = new Request(); $request->setPost(new Parameters(['identity' => 'bob', 'credential' => "xxxxx"])); - $event = new AdapterChainEvent(); - $event->setRequest($request); + /** @var EventInterface|\PHPUnit_Framework_MockObject_MockObject $event */ + $event = $this->createMock(EventInterface::class); + $event + ->expects($this->exactly(2)) + ->method('getTarget') + ->willReturn((new AdapterChainEvent())->setRequest($request)); $result = $this->adapter->authenticate($event); $this->assertFalse($result); @@ -97,8 +114,12 @@ class DbTest extends PHPUnit_Framework_TestCase $request = new Request(); $request->setPost(new Parameters(['identity' => 'bob', 'credential' => "xxxxx"])); - $event = new AdapterChainEvent(); - $event->setRequest($request); + /** @var EventInterface|\PHPUnit_Framework_MockObject_MockObject $event */ + $event = $this->createMock(EventInterface::class); + $event + ->expects($this->exactly(2)) + ->method('getTarget') + ->willReturn((new AdapterChainEvent())->setRequest($request)); $result = $this->adapter->authenticate($event); $this->assertFalse($result); diff --git a/tests/UnicaenAuthTest/Authentication/Adapter/LdapTest.php b/tests/UnicaenAuthTest/Authentication/Adapter/LdapTest.php index bf14c6bdf0a98b4642e8953b4ea1afc12ecef9a3..3bbf47bc3d3c4b452b1afffdeaf0604c28b08d4f 100644 --- a/tests/UnicaenAuthTest/Authentication/Adapter/LdapTest.php +++ b/tests/UnicaenAuthTest/Authentication/Adapter/LdapTest.php @@ -3,8 +3,11 @@ namespace UnicaenAuthTest\Authentication\Adapter; use PHPUnit_Framework_TestCase; +use UnicaenApp\Mapper\Ldap\People; use UnicaenAuth\Authentication\Adapter\Ldap; use Zend\Authentication\Result; +use Zend\Authentication\Storage\StorageInterface; +use Zend\EventManager\EventInterface; use Zend\EventManager\EventManager; use Zend\Http\Request; use Zend\ServiceManager\ServiceManager; @@ -19,7 +22,7 @@ use ZfcUser\Authentication\Adapter\AdapterChainEvent; class LdapTest extends PHPUnit_Framework_TestCase { /** - * @var Ldap + * @var Ldap|\PHPUnit_Framework_MockObject_MockObject */ protected $adapter; @@ -82,12 +85,14 @@ class LdapTest extends PHPUnit_Framework_TestCase })); $this->adapter = new Ldap(); - $this->adapter->setServiceManager($serviceManager) + $this->adapter//->setServiceManager($serviceManager) ->setEventManager(new EventManager()); } public function testCanProvideDefaultLdapAuthAdapter() { + $this->adapter->setAppModuleOptions($this->appModuleOptions); + $adapter = $this->adapter->getLdapAuthAdapter(); $this->assertInstanceOf('Zend\Authentication\Adapter\Ldap', $adapter); @@ -99,10 +104,35 @@ class LdapTest extends PHPUnit_Framework_TestCase public function testAuthenticatingReturnsNullIfAlreadyStatisfied() { - $event = new AdapterChainEvent(); - $this->adapter->setSatisfied(); + /** @var AdapterChainEvent|\PHPUnit_Framework_MockObject_MockObject $adapterChainEvent */ + $adapterChainEvent = $this->createMock(AdapterChainEvent::class); + $adapterChainEvent + ->expects($this->once()) + ->method('setIdentity') + ->with('IDENTITY') + ->willReturnSelf(); + $adapterChainEvent + ->expects($this->once()) + ->method('setCode') + ->with(Result::SUCCESS) + ->willReturnSelf(); + + /** @var EventInterface|\PHPUnit_Framework_MockObject_MockObject $event */ + $event = $this->createMock(EventInterface::class); + $event + ->expects($this->once()) + ->method('getTarget') + ->willReturn($adapterChainEvent); + + /** @var StorageInterface|\PHPUnit_Framework_MockObject_MockObject $storage */ + $storage = $this->createMock(StorageInterface::class); + $storage + ->expects($this->exactly(2)) + ->method('read') + ->willReturn(['is_satisfied' => true, 'identity' => 'IDENTITY']); + + $this->adapter->setStorage($storage); $this->assertNull($this->adapter->authenticate($event)); - $this->assertEquals($event->getCode(), Result::SUCCESS); } public function testUsurpationWithAllowedUsernameAndSuccessfulAuthentication() @@ -228,7 +258,7 @@ class LdapTest extends PHPUnit_Framework_TestCase $this->assertFalse($event->propagationIsStopped()); } - protected function _authenticateWithUsurpation($authenticationResultCode, AdapterChainEvent &$event) + protected function _authenticateWithUsurpation($authenticationResultCode, AdapterChainEvent &$adapterChainEvent) { $usernameUsurpateur = 'usurpateur'; $usernameUsurpe = 'usurpe'; @@ -246,10 +276,39 @@ class LdapTest extends PHPUnit_Framework_TestCase ->will($this->returnValue(new Result($authenticationResultCode, $usernameUsurpateur))); $this->adapter->setLdapAuthAdapter($this->zendAuthLdapAdapter); + $ldapPeopleMapper = $this->createMock(People::class); + $ldapPeopleMapper + ->expects($this->once()) + ->method('findOneByUsername') + ->willReturn('not empty'); + + $this->adapter->setLdapPeopleMapper($ldapPeopleMapper); + $request = new Request(); $request->setPost(new Parameters(['identity' => $username, 'credential' => "xxxxx"])); - $event->setRequest($request); + $adapterChainEvent->setRequest($request); + +// /** @var AdapterChainEvent|\PHPUnit_Framework_MockObject_MockObject $adapterChainEvent */ +// $adapterChainEvent = $this->createMock(AdapterChainEvent::class); +// $adapterChainEvent +// ->expects($this->once()) +// ->method('setIdentity') +// ->with('IDENTITY') +// ->willReturnSelf(); +// $adapterChainEvent +// ->expects($this->once()) +// ->method('setCode') +// ->with(Result::SUCCESS) +// ->willReturnSelf(); + + /** @var EventInterface|\PHPUnit_Framework_MockObject_MockObject $event */ + $event = $this->createMock(EventInterface::class); + $event + ->expects($this->once()) + ->method('getTarget') + ->willReturn($adapterChainEvent); + $this->adapter->setOptions($this->authModuleOptions); $this->adapter->authenticate($event); } } \ No newline at end of file