Commit 35f8127d authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Action usurperIdentite manquante!

parent eefbdbc4
Loading
Loading
Loading
Loading
+133 −2
Original line number Diff line number Diff line
@@ -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.
@@ -45,10 +61,125 @@ class UtilisateurController extends AbstractActionController
    }

    /**
     * @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