Select Git revision
LdapAdapterFactory.php
-
Bertrand Gauthier authoredBertrand Gauthier authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
UserContext.php 7.62 KiB
<?php
namespace UnicaenAuth\Service;
use UnicaenApp\Exception\RuntimeException;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
use Zend\Session\Container as SessionContainer;
use Zend\Permissions\Acl\Role\RoleInterface;
use ZfcUser\Entity\UserInterface;
use UnicaenAuth\Entity\Ldap\People;
use UnicaenAuth\Acl\NamedRole;
/**
* Service centralisant des méthodes utiles concernant l'utilisateur authentifié.
*
* @author Laurent LÉCLUSE <laurent.lecluse at unicaen.fr>
*/
class UserContext implements ServiceLocatorAwareInterface
{
use ServiceLocatorAwareTrait;
/**
* @var mixed
*/
protected $identity;
/**
* @var array
*/
protected $identityRoles;
/**
* @var SessionContainer
*/
protected $sessionContainer;
/**
* Retourne l'utilisateur BDD courant
*
* @return UserInterface
*/
public function getDbUser()
{
if (($identity = $this->getIdentity())) {
if (isset($identity['db']) && $identity['db'] instanceof UserInterface) {
return $identity['db'];
}
}
return null;
}
/**
* Retourne l'utilisateur LDAP courant
*
* @return People
*/
public function getLdapUser()
{
if (($identity = $this->getIdentity())) {
if (isset($identity['ldap']) && $identity['ldap'] instanceof People) {
return $identity['ldap'];
}
}
return null;
}
/**
* Retourne les données d'identité correspondant à l'utilisateur courant.
*
* @return mixed
*/
public function getIdentity()
{
if (null === $this->identity) {
$authenticationService = $this->getServiceLocator()->get('Zend\Authentication\AuthenticationService');
if ($authenticationService->hasIdentity()) {
$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()
{
if (null === $this->identityRoles) {
$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é,
* 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 ($this->getNextSelectedIdentityRole()) {
$this->getSessionContainer()->selectedIdentityRole = $this->getNextSelectedIdentityRole();
}
if (null === $this->getSessionContainer()->selectedIdentityRole && $this->getIdentity()) {
$roles = $this->getSelectableIdentityRoles();
$this->setSelectedIdentityRole(reset($roles));
}
$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 RuntimeException("Rôle spécifié invalide.");
}
if ($role instanceof RoleInterface) {
$role = $role->getRoleId();
}
$this->getSessionContainer()->selectedIdentityRole = $role;
}
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 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;
}
if ($role === $r) {
return $r;
}
}
return $role;
}
/**
* Teste si le rôle spécifié fait partie des rôles disponibles.
*
* @param RoleInterface|string $role
* @return boolean
*/
protected function isRoleValid($role)
{
if ($role instanceof RoleInterface) {
$role = $role->getRoleId();
}
foreach ($this->getIdentityRoles() as $r) {
if ($r instanceof RoleInterface) {
$r = $r->getRoleId();
}
if ($role === $r) {
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
* sélectionné par l'utilsateur.
*
* @return SessionContainer
*/
protected function getSessionContainer()
{
if (null === $this->sessionContainer) {
$this->sessionContainer = new SessionContainer(get_class());
}
return $this->sessionContainer;
}
}