Commit 425a430b authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Work in progress

parent 0d70b318
Loading
Loading
Loading
Loading
Loading
+3 −0
Changes for module/Application/src/Application/Authentication/Adapter/AbstractFactory.php: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -42,6 +42,9 @@ class AbstractFactory implements AbstractFactoryInterface
            case __NAMESPACE__ . '\Shib':
                $adapter = new Shib();
                break;
            case __NAMESPACE__ . '\Ldap':
                $adapter = new Ldap();
                break;
            default:
                throw new Exception\RuntimeException("Service demandé inattendu : '$requestedName'!");
                break;
+41 −65
Changes for module/Application/src/Application/Authentication/Adapter/Shib.php: 41 added lines, 65 removed lines.
Original line number Diff line number Diff line
@@ -2,30 +2,20 @@

namespace Application\Authentication\Adapter;

use phpCAS;
use UnicaenApp\Exception;
use UnicaenApp\Exception\RuntimeException;
use UnicaenAuth\Options\ModuleOptions;
use Zend\Authentication\Exception\ExceptionInterface;
use Zend\Authentication\Exception\UnexpectedValueException;
use Zend\Authentication\Result as AuthenticationResult;
use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\Http\Headers;
use Zend\Http\Request;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\Http\Response;
use ZfcUser\Authentication\Adapter\AbstractAdapter;
use ZfcUser\Authentication\Adapter\AdapterChainEvent as AuthEvent;
use ZfcUser\Authentication\Adapter\ChainableAdapter;

/**
 * CAS authentication adpater
 * Shibboleth authentication adpater
 *
 * @author Bertrand GAUTHIER <bertrand.gauthier@unicaen.fr>
 * @author Unicaen
 */
class Shib extends AbstractAdapter implements ServiceManagerAwareInterface, EventManagerAwareInterface
class Shib implements ServiceManagerAwareInterface, EventManagerAwareInterface
{
    /**
     * @var ServiceManager
@@ -48,71 +38,57 @@ class Shib extends AbstractAdapter implements ServiceManagerAwareInterface, Even
    protected $shibOptions;

    /**
     * @var phpCAS
     * @var ShibUser
     */
    protected $casClient;
    protected $authenticatedUser;

    /**
     * Réalise l'authentification.
     *
     * @param AuthEvent $e
     * @return Response|null
     * @see ChainableAdapter
     * @return ShibUser|null
     */
    public function authenticate(AuthEvent $e)
    public function getAuthenticatedUser()
    {
	    if ($this->isSatisfied()) {
            try {
                $storage = $this->getStorage()->read();
            } catch (ExceptionInterface $e) {
                throw new Exception\RuntimeException("Erreur de lecture du storage");
            }
            $e
                ->setIdentity($storage['identity'])
                ->setCode(AuthenticationResult::SUCCESS)
                ->setMessages(['Authentication successful.']);
        if ($this->authenticatedUser === null) {
            if (!isset($_SERVER['REMOTE_USER'])) {
                return null;
            }
            $this->authenticatedUser = $this->createShibUser();
        }

        if (empty($_SERVER['REMOTE_USER'])) {

            /** @var Request $request */
            $request = $e->getRequest();
            $returnUrl = $request->getQuery('redirect', false);
        return $this->authenticatedUser;
    }

            $response = new Response();
            $response->setStatusCode(Response::STATUS_CODE_302);
            $response->getHeaders()->addHeaders([
                'Location' => "/secure?redirect=" . urlencode($returnUrl),
            ]);
    /**
     * @return ShibUser
     */
    private function createShibUser()
    {
        $eppn = $_SERVER['REMOTE_USER'];

            return $response;
        if (isset($_SERVER['supannEtuId'])) {
            $id = $_SERVER['supannEtuId'];
        } elseif (isset($_SERVER['supannEmpId'])) {
            $id = $_SERVER['supannEmpId'];
        } else {
            throw new RuntimeException('Un au moins des attributs suivants doivent exister dans $_SERVER : supannEtuId, supannEmpId.');
        }

        $eppn = $_SERVER['REMOTE_USER'];
        $mail = null;
        if (isset($_SERVER['mail'])) {
            $mail = $_SERVER['mail'];
        }

        $e->setIdentity($eppn);
        $this->setSatisfied(true);
        try {
            $storage = $this->getStorage()->read();
            $storage['identity'] = $e->getIdentity();
            $this->getStorage()->write($storage);
        } catch (ExceptionInterface $e) {
            throw new Exception\RuntimeException("Erreur de concernant le storage");
        $displayName = null;
        if (isset($_SERVER['displayName'])) {
            $displayName = $_SERVER['displayName'];
        }
        $e
            ->setCode(AuthenticationResult::SUCCESS)
            ->setMessages(['Authentication successful.']);

        $userData = new ShibUser();
        $userData->setId($eppn);
        $userData->setUsername($eppn);
        $userData->setDisplayName($eppn);
        $userData->setEmail($eppn);

        /* @var $userService \Application\Service\User */
        $userService = $this->getServiceManager()->get('unicaen-auth_user_service');
        $userService->userAuthenticated($e->getIdentity(), $userData);

        $shibUser = new ShibUser();
        $shibUser->setId($id);
        $shibUser->setUsername($eppn);
        $shibUser->setDisplayName($displayName);
        $shibUser->setEmail($mail);

        return $shibUser;
    }

    /**
+28 −14
Changes for module/Application/src/Application/Authentication/Adapter/ShibUser.php: 28 added lines, 14 removed lines.
Original line number Diff line number Diff line
@@ -6,20 +6,44 @@ use ZfcUser\Entity\UserInterface;

class ShibUser implements UserInterface
{
    /**
     * @var string
     */
    protected $id;

    /**
     * @var string
     */
    protected $username;

    /**
     * @var string
     */
    protected $email;

    /**
     * @var string
     */
    protected $displayName;

    /**
     * @var int
     */
    protected $state = 1;


    /**
     * @return string
     */
    public function getEppn()
    {
        return $this->getUsername();
    }

    /**
     * Get id.
     *
     * @return int
     * @return string
     */
    public function getId()
    {
@@ -29,13 +53,11 @@ class ShibUser implements UserInterface
    /**
     * Set id.
     *
     * @param int $id
     *
     * @return void
     * @param string $id
     */
    public function setId($id)
    {
        $this->id = (int) $id;
        $this->id = $id;
    }

    /**
@@ -52,8 +74,6 @@ class ShibUser implements UserInterface
     * Set username.
     *
     * @param string $username
     *
     * @return void
     */
    public function setUsername($username)
    {
@@ -74,8 +94,6 @@ class ShibUser implements UserInterface
     * Set email.
     *
     * @param string $email
     *
     * @return void
     */
    public function setEmail($email)
    {
@@ -96,8 +114,6 @@ class ShibUser implements UserInterface
     * Set displayName.
     *
     * @param string $displayName
     *
     * @return void
     */
    public function setDisplayName($displayName)
    {
@@ -138,8 +154,6 @@ class ShibUser implements UserInterface
     * Set state.
     *
     * @param int $state
     *
     * @return void
     */
    public function setState($state)
    {
@@ -152,6 +166,6 @@ class ShibUser implements UserInterface
     */
    public function __toString()
    {
        return (string) $this->getDisplayName();
        return $this->getDisplayName();
    }
}
 No newline at end of file
+108 −55
Changes for module/Application/src/Application/Authentication/Storage/AppStorage.php: 108 added lines, 55 removed lines.
Original line number Diff line number Diff line
@@ -2,12 +2,15 @@

namespace Application\Authentication\Storage;

use Application\Authentication\Adapter\ShibUser;
use Application\Entity\Db\Doctorant;
use Application\Entity\Db\EcoleDoctoraleIndividu;
use Application\Entity\Db\UniteRechercheIndividu;
use Application\Entity\Db\Utilisateur;
use Application\Service\Doctorant\DoctorantServiceAwareTrait;
use Application\Service\EcoleDoctorale\EcoleDoctoraleServiceAwareTrait;
use Application\Service\UniteRecherche\UniteRechercheServiceAwareTrait;
use Application\Service\Utilisateur\UtilisateurServiceAwareTrait;
use Doctrine\ORM\NonUniqueResultException;
use UnicaenApp\Exception\RuntimeException;
use UnicaenAuth\Authentication\Storage\ChainableStorage;
@@ -34,10 +37,12 @@ use Zend\Authentication\Exception\ExceptionInterface;
 */
class AppStorage implements ChainableStorage
{
    use UtilisateurServiceAwareTrait;
    use DoctorantServiceAwareTrait;
    use EcoleDoctoraleServiceAwareTrait;
    use UniteRechercheServiceAwareTrait;

    const KEY_DB_UTILSATEUR = 'db';
    const KEY_DOCTORANT = 'doctorant';
    const KEY_ECOLE_DOCTORALE_INDIVIDU = 'ecoleDoctoraleIndividu';
    const KEY_UNITE_RECHERCHE_INDIVIDU = 'uniteRechercheIndividu';
@@ -52,6 +57,11 @@ class AppStorage implements ChainableStorage
     */
    private $people;

    /**
     * @var ShibUser
     */
    private $shibUser;

    /**
     * @var Doctorant
     */
@@ -75,22 +85,61 @@ class AppStorage implements ChainableStorage
    public function read(ChainEvent $e)
    {
        $this->contents = $e->getContents();

        $this->people = $this->contents['ldap'];
        $this->shibUser = $this->contents['shib'];

        if (null === $this->people && null === $this->shibUser) {
            throw new RuntimeException("Aucune donnée d'authentification LDAP ni Shibboleth disponible");
        }

        /**
         * Collecte des données au cas où l'utilisateur connecté est trouvé dans la table Doctorant.
         * Recherche de l'utilisateur connecté dans la table Utilisateur.
         */
        $this->addDoctorantContents($e);
        $this->addDbUtilisateurContents($e);

        /**
         * Collecte des données au cas où l'utilisateur connecté est trouvé dans la table EcoleDoctoraleIndividu.
         * Collecte des données au cas où l'utilisateur connecté est trouvé dans la table Doctorant.
         */
        $this->addEcoleDoctoraleIndividuContents($e);
        $this->addDoctorantContents($e);

//        /**
//         * Collecte des données au cas où l'utilisateur connecté est trouvé dans la table EcoleDoctoraleIndividu.
//         */
//        $this->addEcoleDoctoraleIndividuContents($e);
//
//        /**
//         * Collecte des données au cas où l'utilisateur connecté est trouvé dans la table UniteRechercheIndividu.
//         */
//        $this->addUniteRechercheIndividuContents($e);
    }

    protected function addDbUtilisateurContents(ChainEvent $e)
    {
        try {
            $e->addContents(self::KEY_DB_UTILSATEUR, $this->fetchUtilisateur());
        } catch (ExceptionInterface $e) {
            throw new RuntimeException("Erreur imprévue rencontrée.", 0, $e);
        }

        return $this;
    }

    /**
         * Collecte des données au cas où l'utilisateur connecté est trouvé dans la table UniteRechercheIndividu.
     * @return null|Utilisateur
     */
        $this->addUniteRechercheIndividuContents($e);
    private function fetchUtilisateur()
    {
        if (null !== $this->people) {
            $username = $this->people->getSupannAliasLogin();
        } else {
            $username = $this->shibUser->getUsername();
        }

        /** @var Utilisateur $utilisateur */
        $utilisateur = $this->utilisateurService->getRepository()->findOneBy(['username' => $username]);

        return $utilisateur;
    }

    /**
@@ -119,7 +168,11 @@ class AppStorage implements ChainableStorage
         * - avec son numéro étudiant (Doctorant::sourceCode),
         * - avec son persopass (DoctorantCompl::persopass), seulement après qu'il l'a saisi sur la page d'identité de la thèse.
         */
        if (null !== $this->people) {
            $username = $this->people->getSupannAliasLogin();
        } else {
            $username = $this->shibUser->getUsername();
        }
        // todo: solution provisoire!
        $etablissement = 'UCN';
        try {
@@ -131,55 +184,55 @@ class AppStorage implements ChainableStorage
        return $this->doctorant;
    }

    private function addEcoleDoctoraleIndividuContents(ChainEvent $e)
    {
        try {
            $e->addContents(self::KEY_ECOLE_DOCTORALE_INDIVIDU, $this->fetchEcoleDoctoraleIndividu());
        } catch (ExceptionInterface $e) {
            throw new RuntimeException("Erreur imprévue rencontrée.", 0, $e);
        }

        return $this;
    }

    private function fetchEcoleDoctoraleIndividu()
    {
        if (null !== $this->ecoleDoctoraleIndividu) {
            return $this->ecoleDoctoraleIndividu;
        }

        $sourceCodeIndividu = $this->people->getSupannEmpId();

        $this->ecoleDoctoraleIndividu =
            $this->ecoleDoctoraleService->getRepository()->findMembresBySourceCodeIndividu($sourceCodeIndividu);

        return $this->ecoleDoctoraleIndividu;
    }

    private function addUniteRechercheIndividuContents(ChainEvent $e)
    {
        try {
            $e->addContents(self::KEY_UNITE_RECHERCHE_INDIVIDU, $this->fetchUniteRechercheIndividu());
        } catch (ExceptionInterface $e) {
            throw new RuntimeException("Erreur imprévue rencontrée.", 0, $e);
        }

        return $this;
    }

    private function fetchUniteRechercheIndividu()
    {
        if (null !== $this->uniteRechercheIndividu) {
            return $this->uniteRechercheIndividu;
        }

        $sourceCodeIndividu = $this->people->getSupannEmpId();

        $this->uniteRechercheIndividu =
            $this->uniteRechercheService->getRepository()->findMembresBySourceCodeIndividu($sourceCodeIndividu);

        return $this->uniteRechercheIndividu;
    }
//    private function addEcoleDoctoraleIndividuContents(ChainEvent $e)
//    {
//        try {
//            $e->addContents(self::KEY_ECOLE_DOCTORALE_INDIVIDU, $this->fetchEcoleDoctoraleIndividu());
//        } catch (ExceptionInterface $e) {
//            throw new RuntimeException("Erreur imprévue rencontrée.", 0, $e);
//        }
//
//        return $this;
//    }
//
//    private function fetchEcoleDoctoraleIndividu()
//    {
//        if (null !== $this->ecoleDoctoraleIndividu) {
//            return $this->ecoleDoctoraleIndividu;
//        }
//
//        $sourceCodeIndividu = $this->people->getSupannEmpId();
//
//        $this->ecoleDoctoraleIndividu =
//            $this->ecoleDoctoraleService->getRepository()->findMembresBySourceCodeIndividu($sourceCodeIndividu);
//
//        return $this->ecoleDoctoraleIndividu;
//    }
//
//    private function addUniteRechercheIndividuContents(ChainEvent $e)
//    {
//        try {
//            $e->addContents(self::KEY_UNITE_RECHERCHE_INDIVIDU, $this->fetchUniteRechercheIndividu());
//        } catch (ExceptionInterface $e) {
//            throw new RuntimeException("Erreur imprévue rencontrée.", 0, $e);
//        }
//
//        return $this;
//    }
//
//    private function fetchUniteRechercheIndividu()
//    {
//        if (null !== $this->uniteRechercheIndividu) {
//            return $this->uniteRechercheIndividu;
//        }
//
//        $sourceCodeIndividu = $this->people->getSupannEmpId();
//
//        $this->uniteRechercheIndividu =
//            $this->uniteRechercheService->getRepository()->findMembresBySourceCodeIndividu($sourceCodeIndividu);
//
//        return $this->uniteRechercheIndividu;
//    }

    public function write(ChainEvent $e)
    {
+5 −0
Changes for module/Application/src/Application/Authentication/Storage/AppStorageFactory.php: 5 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ namespace Application\Authentication\Storage;
use Application\Service\Doctorant\DoctorantService;
use Application\Service\EcoleDoctorale\EcoleDoctoraleService;
use Application\Service\UniteRecherche\UniteRechercheService;
use Application\Service\Utilisateur\UtilisateurService;
use Zend\ServiceManager\ServiceLocatorInterface;

class AppStorageFactory
@@ -15,6 +16,9 @@ class AppStorageFactory
     */
    public function __invoke(ServiceLocatorInterface $sl)
    {
        /** @var UtilisateurService $utilisateurService */
        $utilisateurService = $sl->get('UtilisateurService');

        /** @var DoctorantService $doctorantService */
        $doctorantService = $sl->get(DoctorantService::class);

@@ -25,6 +29,7 @@ class AppStorageFactory
        $urService = $sl->get(UniteRechercheService::class);

        $service = new AppStorage();
        $service->setUtilisateurService($utilisateurService);
        $service->setDoctorantService($doctorantService);
        $service->setEcoleDoctoraleService($edService);
        $service->setUniteRechercheService($urService);
Loading