diff --git a/src/UnicaenAuth/Service/UserContext.php b/src/UnicaenAuth/Service/UserContext.php index 3f8897e12f635317452b443ab6f4de467d9471f7..df9d395f9be8bca632b151a68d1262377df8fa15 100644 --- a/src/UnicaenAuth/Service/UserContext.php +++ b/src/UnicaenAuth/Service/UserContext.php @@ -2,6 +2,7 @@ namespace UnicaenAuth\Service; +use UnicaenApp\Exception\RuntimeException; use Zend\ServiceManager\ServiceLocatorAwareInterface; use Zend\ServiceManager\ServiceLocatorAwareTrait; use Zend\Session\Container as SessionContainer; @@ -23,12 +24,12 @@ class UserContext implements ServiceLocatorAwareInterface * @var mixed */ protected $identity; - + /** - * @var array + * @var array */ protected $identityRoles; - + /** * @var SessionContainer */ @@ -46,7 +47,7 @@ class UserContext implements ServiceLocatorAwareInterface return $identity['db']; } } - + return null; } @@ -62,7 +63,7 @@ class UserContext implements ServiceLocatorAwareInterface return $identity['ldap']; } } - + return null; } @@ -79,13 +80,13 @@ class UserContext implements ServiceLocatorAwareInterface $this->identity = $authenticationService->getIdentity(); } } - + return $this->identity; } - + /** * Retourne tous les rôles de l'utilisateur courant, pas seulement le rôle courant sélectionné. - * + * * @return array */ public function getIdentityRoles() @@ -94,58 +95,67 @@ class UserContext implements ServiceLocatorAwareInterface $identityProvider = $this->getIdentityProvider(); $this->identityRoles = $identityProvider->getAllIdentityRoles(); } - + return $this->identityRoles; } - + /** * Retourne parmi tous les rôles de l'utilisateur courant ceux qui peuvent être sélectionnés. - * + * * @return array */ public function getSelectableIdentityRoles() { $filter = function($r) { return !($r instanceof NamedRole && !$r->getSelectable()); }; $roles = array_filter($this->getIdentityRoles(), $filter); - + return $roles; } - + /** - * Si un utilisateur est authentifié, retourne le rôle utilisateur sélectionné, + * Si un utilisateur est authentifié, retourne le rôle utilisateur sélectionné, * ou alors le premier sélectionnable si aucun n'a été sélectionné. - * + * + * NB: Si un rôle est spécifié en session comme devant être le prochain rôle sélectionné, + * c'est lui qui est pris en compte. + * * @return mixed */ public function getSelectedIdentityRole() { - if (null === $this->getSessionContainer()->selectedIdentityRole) { - if ($this->getIdentity()) { - $roles = $this->getSelectableIdentityRoles(); - $this->setSelectedIdentityRole(reset($roles)); - } + if ($this->getNextSelectedIdentityRole()) { + $this->getSessionContainer()->selectedIdentityRole = $this->getNextSelectedIdentityRole(); + } + + if (null === $this->getSessionContainer()->selectedIdentityRole && $this->getIdentity()) { + $roles = $this->getSelectableIdentityRoles(); + $this->setSelectedIdentityRole(reset($roles)); } - - $role = $this->normalizedIdentityRole($this->getSessionContainer()->selectedIdentityRole); + + $roleId = $this->getSessionContainer()->selectedIdentityRole; + + $role = $this->normalizedIdentityRole($roleId); if ($this->isRoleValid($role)) { return $role; } - + return null; } - + /** * Mémorise en session le rôle spécifié comme étant le rôle courant de l'utilisateur. + * * NB: seul l'id du rôle est mémorisé en session. - * + * * @param RoleInterface|string $role * @return \UnicaenAuth\Service\UserContext + * @throws RuntimeException */ public function setSelectedIdentityRole($role) { if ($role) { if (!$this->isRoleValid($role)) { - throw new \Common\Exception\RuntimeException("Rôle spécifié invalide."); + throw new RuntimeException("Rôle spécifié invalide."); } if ($role instanceof RoleInterface) { $role = $role->getRoleId(); @@ -155,22 +165,58 @@ class UserContext implements ServiceLocatorAwareInterface else { unset($this->getSessionContainer()->selectedIdentityRole); } - + + return $this; + } + + /** + * Retourne l'éventuel rôle spécifié en session devant être le prochain rôle sélectionné. + * + * @return string|null + */ + private function getNextSelectedIdentityRole() + { + return $this->getSessionContainer()->nextSelectedIdentityRole; + } + + /** + * Mémorise en session le rôle devant être le prochain rôle sélectionné. + * + * NB: seul l'id du rôle est mémorisé en session ; la durée de vie du stockage est de 1 requête seulement. + * + * @param RoleInterface|string $role + * @return \UnicaenAuth\Service\UserContext + */ + public function setNextSelectedIdentityRole($role) + { + if ($role instanceof RoleInterface) { + $role = $role->getRoleId(); + } + + if ($role) { + $this->getSessionContainer()->nextSelectedIdentityRole = $role; + $this->getSessionContainer()->setExpirationHops(1, 'nextSelectedIdentityRole'); + + } + else { + unset($this->getSessionContainer()->nextSelectedIdentityRole); + } + return $this; } - + /** * Recherche le role spécifié parmi les rôles connus au format objets. - * - * @param mixed $role - * @return mixed Role trouvé au format objet dans la mesure du possible + * + * @param RoleInterface|string $role + * @return RoleInterface Role trouvé au format objet dans la mesure du possible */ protected function normalizedIdentityRole($role) { if (!$role || is_object($role)) { return $role; } - + foreach ($this->getIdentityRoles() as $r) { if ($r instanceof RoleInterface && $role === $r->getRoleId()) { return $r; @@ -179,14 +225,14 @@ class UserContext implements ServiceLocatorAwareInterface return $r; } } - + return $role; } - + /** * Teste si le rôle spécifié fait partie des rôles disponibles. - * - * @param mixed $role + * + * @param RoleInterface|string $role * @return boolean */ protected function isRoleValid($role) @@ -194,7 +240,7 @@ class UserContext implements ServiceLocatorAwareInterface if ($role instanceof RoleInterface) { $role = $role->getRoleId(); } - + foreach ($this->getIdentityRoles() as $r) { if ($r instanceof RoleInterface) { $r = $r->getRoleId(); @@ -203,25 +249,25 @@ class UserContext implements ServiceLocatorAwareInterface return true; } } - + return false; } - + /** - * + * * @return \UnicaenAuth\Provider\Identity\Chain */ private function getIdentityProvider() { $authorize = $this->getServiceLocator()->get('BjyAuthorize\Service\Authorize'); - + return $authorize->getIdentityProvider(); /* @var $identityProvider \UnicaenAuth\Provider\Identity\Chain */ } - + /** - * Retourne le stockage en session utilisé pour mémoriser le profil + * Retourne le stockage en session utilisé pour mémoriser le profil * sélectionné par l'utilsateur. - * + * * @return SessionContainer */ protected function getSessionContainer() @@ -229,7 +275,7 @@ class UserContext implements ServiceLocatorAwareInterface if (null === $this->sessionContainer) { $this->sessionContainer = new SessionContainer(get_class()); } - + return $this->sessionContainer; } } \ No newline at end of file