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;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use UnicaenAuth\Entity\Db\Role;
/**
* User entity abstract mother class.
......@@ -71,6 +72,13 @@ abstract class AbstractUser implements UserInterface, ProviderInterface
*/
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.
*/
......@@ -259,6 +267,25 @@ abstract class AbstractUser implements UserInterface, ProviderInterface
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.
*
......
......@@ -2,11 +2,14 @@
namespace UnicaenAuth\Event\Listener;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\ListenerAggregateInterface;
use UnicaenApp\Service\EntityManagerAwareInterface;
use UnicaenApp\Service\EntityManagerAwareTrait;
use UnicaenAuth\Entity\Db\AbstractUser;
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
......@@ -14,16 +17,19 @@ use UnicaenAuth\Event\UserAuthenticatedEvent;
*
* Événements disponibles :
* - 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>
* @see UserAuthenticatedEvent
*/
abstract class AuthenticatedUserSavedAbstractListener implements ListenerAggregateInterface, EntityManagerAwareInterface
{
use ListenerAggregateTrait;
use EntityManagerAwareTrait;
use UserContextServiceAwareTrait;
/**
* @var \Zend\Stdlib\CallbackHandler[]
* @var callable[]
*/
protected $listeners = [];
......@@ -31,20 +37,33 @@ abstract class AuthenticatedUserSavedAbstractListener implements ListenerAggrega
* Méthode appelée juste avant que l'entité utilisateur soit persistée.
*
* @param UserAuthenticatedEvent $e
* @return void
*/
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.
*
* @param UserAuthenticatedEvent $e
* @return void
*/
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
[$this, 'onUserAuthenticatedPostPersist'],
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 @@
namespace UnicaenAuth\Service;
use BjyAuthorize\Acl\Role;
use Doctrine\ORM\ORMException;
use UnicaenApp\Exception\RuntimeException;
use UnicaenApp\Traits\SessionContainerTrait;
use UnicaenAuth\Acl\NamedRole;
......@@ -10,6 +10,8 @@ use UnicaenAuth\Authentication\SessionIdentity;
use UnicaenAuth\Authentication\Storage\Auth;
use UnicaenAuth\Authentication\Storage\Usurpation;
use UnicaenAuth\Entity\Db\AbstractUser;
use UnicaenAuth\Entity\Db\AbstractRole;
use UnicaenAuth\Entity\Db\Role;
use UnicaenAuth\Entity\Ldap\People;
use UnicaenAuth\Entity\Shibboleth\ShibUser;
use UnicaenAuth\Event\UserRoleSelectedEvent;
......@@ -19,8 +21,6 @@ use UnicaenAuth\Provider\Identity\Chain;
use Zend\Authentication\AuthenticationService;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerAwareTrait;
use Zend\Http\Request;
use Zend\Http\Response;
use Zend\Permissions\Acl\Role\RoleInterface;
use ZfcUser\Entity\UserInterface;
......@@ -335,11 +335,35 @@ class UserContext extends AbstractService implements EventManagerAwareInterface
unset($this->getSessionContainer()->selectedIdentityRole);
}
$role = $this->getSelectableIdentityRoles()[$role];
if ($role instanceof AbstractRole) {
$this->saveUserLastRole($role);
}
$this->triggerUserRoleSelectedEvent(UserRoleSelectedEvent::POST_SELECTION, $role);
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é.
*
......@@ -372,6 +396,11 @@ class UserContext extends AbstractService implements EventManagerAwareInterface
unset($this->getSessionContainer()->nextSelectedIdentityRole);
}
$role = $this->getSelectableIdentityRoles()[$role];
if ($role instanceof AbstractRole) {
$this->saveUserLastRole($role);
}
$this->triggerUserRoleSelectedEvent(UserRoleSelectedEvent::POST_SELECTION, $role);
return $this;
......@@ -499,5 +528,10 @@ class UserContext extends AbstractService implements EventManagerAwareInterface
$sessionIdentity = SessionIdentity::newInstance($usurpateur->getUsername(), $this->getAuthenticationType());
$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