From 35f8127dca6e3c61d4e7c0ba487b4925f246729b Mon Sep 17 00:00:00 2001 From: Bertrand Gauthier <bertrand.gauthier@unicaen.fr> Date: Wed, 23 May 2018 13:46:14 +0200 Subject: [PATCH] Action usurperIdentite manquante! --- .../Controller/UtilisateurController.php | 135 +++++++++++++++++- 1 file changed, 133 insertions(+), 2 deletions(-) diff --git a/src/UnicaenAuth/Controller/UtilisateurController.php b/src/UnicaenAuth/Controller/UtilisateurController.php index fbb9fc5..18bccc4 100644 --- a/src/UnicaenAuth/Controller/UtilisateurController.php +++ b/src/UnicaenAuth/Controller/UtilisateurController.php @@ -2,14 +2,30 @@ namespace UnicaenAuth\Controller; +use UnicaenApp\Exception\RuntimeException; +use UnicaenApp\Mapper\Ldap\People as LdapPeopleMapper; +use UnicaenAuth\Entity\Db\AbstractUser; +use UnicaenAuth\Entity\Ldap\People; +use UnicaenAuth\Entity\Shibboleth\ShibUser; +use UnicaenAuth\Options\ModuleOptions; +use UnicaenAuth\Service\ShibService; +use UnicaenAuth\Service\UserContext; +use Zend\Authentication\AuthenticationService; use Zend\Http\Request; +use Zend\Http\Response; use Zend\Mvc\Controller\AbstractActionController; +use ZfcUser\Mapper\User as UserMapper; /** * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr> */ class UtilisateurController extends AbstractActionController { + /** + * @var LdapPeopleMapper + */ + protected $ldapPeopleMapper; + /** * 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. @@ -43,12 +59,127 @@ class UtilisateurController extends AbstractActionController return false; } - + /** - * @return \UnicaenAuth\Service\UserContext + * Usurpe l'identité d'un autre utilisateur. + * + * @return Response + */ + public function usurperIdentiteAction() + { + $request = $this->getRequest(); + if (! $request instanceof Request) { + exit(1); + } + + $newIdentity = $request->getQuery('identity', $request->getPost('identity')); + if (! $newIdentity) { + return $this->redirect()->toRoute('home'); + } + + /** @var AuthenticationService $authenticationService */ + $authenticationService = $this->getServiceLocator()->get(AuthenticationService::class); + + $currentIdentity = $authenticationService->getIdentity(); + if (! $currentIdentity || ! is_array($currentIdentity)) { + return $this->redirect()->toRoute('home'); + } + + if (isset($currentIdentity['ldap'])) { + // si l'identifiant demandé contient un @, on estime qu'il s'agit d'un eppn shibboleth : on autorise pas le mélange des genres! + // todo: faire mieux + if (strpos($newIdentity, '@') !== false) { + throw new RuntimeException("Usurpation Shibboleth interdite depuis une authentification LDAP"); + } + /** @var People $currentIdentity */ + $currentIdentity = $currentIdentity['ldap']; + + // vérif existence de l'individu dans l'annuaire LDAP + $ldapPeople = $this->getLdapPeopleMapper()->findOneByUsername($newIdentity); + if (!$ldapPeople) { + throw new RuntimeException("Identifiant LDAP inconnu"); + } + } elseif (isset($currentIdentity['shib'])) { + // si l'identifiant demandé ne contient pas @, on estime qu'il s'agit d'un identifiant LDAP : on autorise pas le mélange des genres! + // todo: faire mieux + if (strpos($newIdentity, '@') === false) { + throw new RuntimeException("Usurpation LDAP interdite depuis une authentification Shibboleth"); + } + /** @var ShibUser $currentIdentity */ + $currentIdentity = $currentIdentity['shib']; + } + else { + return $this->redirect()->toRoute('home'); + } + + // seuls les logins spécifiés dans la config sont habilités à usurper des identités + /** @var ModuleOptions $options */ + $options = $this->getServiceLocator()->get('unicaen-auth_module_options'); + if (! in_array($currentIdentity->getUsername(), $options->getUsurpationAllowedUsernames())) { + throw new RuntimeException("Usurpation non explicitement autorisée"); + } + + // cuisine spéciale pour Shibboleth + if ($currentIdentity instanceof ShibUser) { + $fromShibUser = $currentIdentity; + $toShibUser = $this->createShibUserFromUtilisateurUsername($newIdentity); + /** @var ShibService $shibService */ + $shibService = $this->getServiceLocator()->get(ShibService::class); + $shibService->activateUsurpation($fromShibUser, $toShibUser); + } + + $authenticationService->getStorage()->write($newIdentity); + + return $this->redirect()->toRoute('home'); + } + + /** + * Recherche l'utilisateur dont le login est spécifié puis instancie un ShibUser à partir + * des attributs de cet utilisateur. + * + * @param string $username Ex tartempion@unicaen.fr + * @return ShibUser + */ + protected function createShibUserFromUtilisateurUsername($username) + { + /** @var AbstractUser $utilisateur */ + $utilisateur = $this->getUserMapper()->findByUsername($username); + if ($utilisateur === null) { + throw new RuntimeException("L'utilisateur '$username' n'existe pas dans la table des utilisateurs"); + } + + $shibUser = new ShibUser(); + $shibUser->setEppn($utilisateur->getUsername()); + $shibUser->setId(uniqid()); // peut pas mieux faire pour l'instant + $shibUser->setDisplayName($utilisateur->getDisplayName()); + $shibUser->setEmail($utilisateur->getEmail()); + $shibUser->setNom('?'); // peut pas mieux faire pour l'instant + $shibUser->setPrenom('?'); // peut pas mieux faire pour l'instant + + return $shibUser; + } + + /** + * @return UserMapper + */ + public function getUserMapper() + { + return $this->getServiceLocator()->get('zfcuser_user_mapper'); + } + + /** + * @return UserContext */ protected function getAuthUserContextService() { return $this->getServiceLocator()->get('AuthUserContext'); } + + /** + * @return LdapPeopleMapper + */ + public function getLdapPeopleMapper() + { + return $this->serviceLocator->get('ldap_people_mapper'); + } } \ No newline at end of file -- GitLab