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

[FIX] Lorsque l'usurpateur stoppait l'usurpation, il ne récupérait pas son dernier endossé

parent ba084259
Pipeline #9945 passed with stage
in 25 seconds
...@@ -6,6 +6,7 @@ use BjyAuthorize\Provider\Role\ProviderInterface; ...@@ -6,6 +6,7 @@ use BjyAuthorize\Provider\Role\ProviderInterface;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use UnicaenAuth\Entity\Db\Role;
/** /**
* User entity abstract mother class. * User entity abstract mother class.
...@@ -71,6 +72,13 @@ abstract class AbstractUser implements UserInterface, ProviderInterface ...@@ -71,6 +72,13 @@ abstract class AbstractUser implements UserInterface, ProviderInterface
*/ */
protected $roles; protected $roles;
/**
* @var AbstractRole
* @ORM\ManyToOne(targetEntity="UnicaenAuth\Entity\Db\Role")
* @ORM\JoinColumn(name="last_role_id", referencedColumnName="id")
*/
protected $lastRole;
/** /**
* Initialies the roles variable. * Initialies the roles variable.
*/ */
...@@ -259,6 +267,25 @@ abstract class AbstractUser implements UserInterface, ProviderInterface ...@@ -259,6 +267,25 @@ abstract class AbstractUser implements UserInterface, ProviderInterface
return $this; return $this;
} }
/**
* @return AbstractRole|null
*/
public function getLastRole()
{
return $this->lastRole;
}
/**
* @param AbstractRole|null $lastRole
* @return self
*/
public function setLastRole(AbstractRole $lastRole = null)
{
$this->lastRole = $lastRole;
return $this;
}
/** /**
* Retourne true si cet utilisateur est local. * Retourne true si cet utilisateur est local.
* *
......
...@@ -2,11 +2,14 @@ ...@@ -2,11 +2,14 @@
namespace UnicaenAuth\Event\Listener; namespace UnicaenAuth\Event\Listener;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\ListenerAggregateInterface;
use UnicaenApp\Service\EntityManagerAwareInterface; use UnicaenApp\Service\EntityManagerAwareInterface;
use UnicaenApp\Service\EntityManagerAwareTrait; use UnicaenApp\Service\EntityManagerAwareTrait;
use UnicaenAuth\Entity\Db\AbstractUser;
use UnicaenAuth\Event\UserAuthenticatedEvent; use UnicaenAuth\Event\UserAuthenticatedEvent;
use UnicaenAuth\Service\Traits\UserContextServiceAwareTrait;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\ListenerAggregateInterface;
use Zend\EventManager\ListenerAggregateTrait;
/** /**
* Classe abstraites pour les classes désirant scruter un événement déclenché lors de l'authentification * Classe abstraites pour les classes désirant scruter un événement déclenché lors de l'authentification
...@@ -14,16 +17,19 @@ use UnicaenAuth\Event\UserAuthenticatedEvent; ...@@ -14,16 +17,19 @@ use UnicaenAuth\Event\UserAuthenticatedEvent;
* *
* Événements disponibles : * Événements disponibles :
* - juste avant que l'entité utilisateur ne soit persistée. * - juste avant que l'entité utilisateur ne soit persistée.
* - juste après que l'entité utilisateur ait été persistée.
* *
* @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr> * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
* @see UserAuthenticatedEvent * @see UserAuthenticatedEvent
*/ */
abstract class AuthenticatedUserSavedAbstractListener implements ListenerAggregateInterface, EntityManagerAwareInterface abstract class AuthenticatedUserSavedAbstractListener implements ListenerAggregateInterface, EntityManagerAwareInterface
{ {
use ListenerAggregateTrait;
use EntityManagerAwareTrait; use EntityManagerAwareTrait;
use UserContextServiceAwareTrait;
/** /**
* @var \Zend\Stdlib\CallbackHandler[] * @var callable[]
*/ */
protected $listeners = []; protected $listeners = [];
...@@ -31,20 +37,33 @@ abstract class AuthenticatedUserSavedAbstractListener implements ListenerAggrega ...@@ -31,20 +37,33 @@ abstract class AuthenticatedUserSavedAbstractListener implements ListenerAggrega
* Méthode appelée juste avant que l'entité utilisateur soit persistée. * Méthode appelée juste avant que l'entité utilisateur soit persistée.
* *
* @param UserAuthenticatedEvent $e * @param UserAuthenticatedEvent $e
* @return void
*/ */
public function onUserAuthenticatedPrePersist(UserAuthenticatedEvent $e) public function onUserAuthenticatedPrePersist(UserAuthenticatedEvent $e)
{ {
/** @var AbstractUser $user */
$user = $e->getDbUser();
// Sélection du dernier rôle endossé.
$this->selectLastUserRole($user);
} }
/** /**
* Méthode appelée juste après que l'entité utilisateur soit persistée. * Méthode appelée juste après que l'entité utilisateur soit persistée.
* *
* @param UserAuthenticatedEvent $e * @param UserAuthenticatedEvent $e
* @return void
*/ */
public function onUserAuthenticatedPostPersist(UserAuthenticatedEvent $e) public function onUserAuthenticatedPostPersist(UserAuthenticatedEvent $e)
{ {
// nop
}
protected function selectLastUserRole(AbstractUser $user)
{
if ($role = $user->getLastRole()) {
$this->serviceUserContext->setNextSelectedIdentityRole($role);
}
} }
/** /**
...@@ -66,18 +85,4 @@ abstract class AuthenticatedUserSavedAbstractListener implements ListenerAggrega ...@@ -66,18 +85,4 @@ abstract class AuthenticatedUserSavedAbstractListener implements ListenerAggrega
[$this, 'onUserAuthenticatedPostPersist'], [$this, 'onUserAuthenticatedPostPersist'],
100); 100);
} }
/**
* Detach all previously attached listeners
*
* @param EventManagerInterface $events
*/
public function detach(EventManagerInterface $events)
{
foreach ($this->listeners as $index => $listener) {
if ($events->detach($listener)) {
unset($this->listeners[$index]);
}
}
}
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
namespace UnicaenAuth\Service; namespace UnicaenAuth\Service;
use BjyAuthorize\Acl\Role; use Doctrine\ORM\ORMException;
use UnicaenApp\Exception\RuntimeException; use UnicaenApp\Exception\RuntimeException;
use UnicaenApp\Traits\SessionContainerTrait; use UnicaenApp\Traits\SessionContainerTrait;
use UnicaenAuth\Acl\NamedRole; use UnicaenAuth\Acl\NamedRole;
...@@ -10,6 +10,8 @@ use UnicaenAuth\Authentication\SessionIdentity; ...@@ -10,6 +10,8 @@ use UnicaenAuth\Authentication\SessionIdentity;
use UnicaenAuth\Authentication\Storage\Auth; use UnicaenAuth\Authentication\Storage\Auth;
use UnicaenAuth\Authentication\Storage\Usurpation; use UnicaenAuth\Authentication\Storage\Usurpation;
use UnicaenAuth\Entity\Db\AbstractUser; use UnicaenAuth\Entity\Db\AbstractUser;
use UnicaenAuth\Entity\Db\AbstractRole;
use UnicaenAuth\Entity\Db\Role;
use UnicaenAuth\Entity\Ldap\People; use UnicaenAuth\Entity\Ldap\People;
use UnicaenAuth\Entity\Shibboleth\ShibUser; use UnicaenAuth\Entity\Shibboleth\ShibUser;
use UnicaenAuth\Event\UserRoleSelectedEvent; use UnicaenAuth\Event\UserRoleSelectedEvent;
...@@ -19,8 +21,6 @@ use UnicaenAuth\Provider\Identity\Chain; ...@@ -19,8 +21,6 @@ use UnicaenAuth\Provider\Identity\Chain;
use Zend\Authentication\AuthenticationService; use Zend\Authentication\AuthenticationService;
use Zend\EventManager\EventManagerAwareInterface; use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerAwareTrait; use Zend\EventManager\EventManagerAwareTrait;
use Zend\Http\Request;
use Zend\Http\Response;
use Zend\Permissions\Acl\Role\RoleInterface; use Zend\Permissions\Acl\Role\RoleInterface;
use ZfcUser\Entity\UserInterface; use ZfcUser\Entity\UserInterface;
...@@ -335,11 +335,35 @@ class UserContext extends AbstractService implements EventManagerAwareInterface ...@@ -335,11 +335,35 @@ class UserContext extends AbstractService implements EventManagerAwareInterface
unset($this->getSessionContainer()->selectedIdentityRole); unset($this->getSessionContainer()->selectedIdentityRole);
} }
$role = $this->getSelectableIdentityRoles()[$role];
if ($role instanceof AbstractRole) {
$this->saveUserLastRole($role);
}
$this->triggerUserRoleSelectedEvent(UserRoleSelectedEvent::POST_SELECTION, $role); $this->triggerUserRoleSelectedEvent(UserRoleSelectedEvent::POST_SELECTION, $role);
return $this; return $this;
} }
/**
* @param AbstractRole $role
*/
private function saveUserLastRole(AbstractRole $role)
{
/** @var AbstractUser $user */
$user = $this->getDbUser();
if (! $user) {
return;
}
$user->setLastRole($role);
try {
$this->getEntityManager()->flush($user);
} catch (ORMException $e) {
throw new RuntimeException("Erreur rencontrée lors de l'enregistrement en bdd", null, $e);
}
}
/** /**
* Retourne l'éventuel rôle spécifié en session devant être le prochain rôle sélectionné. * Retourne l'éventuel rôle spécifié en session devant être le prochain rôle sélectionné.
* *
...@@ -372,6 +396,11 @@ class UserContext extends AbstractService implements EventManagerAwareInterface ...@@ -372,6 +396,11 @@ class UserContext extends AbstractService implements EventManagerAwareInterface
unset($this->getSessionContainer()->nextSelectedIdentityRole); unset($this->getSessionContainer()->nextSelectedIdentityRole);
} }
$role = $this->getSelectableIdentityRoles()[$role];
if ($role instanceof AbstractRole) {
$this->saveUserLastRole($role);
}
$this->triggerUserRoleSelectedEvent(UserRoleSelectedEvent::POST_SELECTION, $role); $this->triggerUserRoleSelectedEvent(UserRoleSelectedEvent::POST_SELECTION, $role);
return $this; return $this;
...@@ -499,5 +528,10 @@ class UserContext extends AbstractService implements EventManagerAwareInterface ...@@ -499,5 +528,10 @@ class UserContext extends AbstractService implements EventManagerAwareInterface
$sessionIdentity = SessionIdentity::newInstance($usurpateur->getUsername(), $this->getAuthenticationType()); $sessionIdentity = SessionIdentity::newInstance($usurpateur->getUsername(), $this->getAuthenticationType());
$this->authenticationService->getStorage()->write($sessionIdentity); $this->authenticationService->getStorage()->write($sessionIdentity);
// Sélection du dernier rôle endossé.
if ($role = $usurpateur->getLastRole()) {
$this->setNextSelectedIdentityRole($role);
}
} }
} }
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment