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

Refactorisations.

parent 30760bf8
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
<?php

use UnicaenAuth\Authentication\Adapter\ShibSimulatorAdapter;
use UnicaenAuth\Authentication\Storage\ShibSimulatorStorage;
use UnicaenAuth\Controller\AuthControllerFactory;
use UnicaenAuth\Service\ShibService;
use UnicaenAuth\Service\ShibServiceFactory;
@@ -374,6 +376,7 @@ return [
            'UnicaenAuth\Authentication\Storage\Db'   => 'UnicaenAuth\Authentication\Storage\Db',
            'UnicaenAuth\Authentication\Storage\Ldap' => 'UnicaenAuth\Authentication\Storage\Ldap',
            'UnicaenAuth\Authentication\Storage\Shib' => 'UnicaenAuth\Authentication\Storage\Shib',
            'UnicaenAuth\Authentication\Storage\ShibSimulatorStorage' => ShibSimulatorStorage::class,
            'UnicaenAuth\View\RedirectionStrategy'    => 'UnicaenAuth\View\RedirectionStrategy',
            'UnicaenAuth\Service\User'                => 'UnicaenAuth\Service\User',
            'UnicaenAuth\Service\CategoriePrivilege'  => 'UnicaenAuth\Service\CategoriePrivilegeService',
+0 −33
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@
namespace UnicaenAuth\Authentication\Storage;

use UnicaenAuth\Entity\Shibboleth\ShibUser;
use UnicaenAuth\Options\ModuleOptions;
use UnicaenAuth\Service\ShibService;
use Zend\Authentication\Storage\Session;
use Zend\Authentication\Storage\StorageInterface;
@@ -25,11 +24,6 @@ class Shib implements ChainableStorage, ServiceLocatorAwareInterface
     */
    protected $storage;

    /**
     * @var ModuleOptions
     */
    protected $options;

    /**
     * @var ShibUser
     */
@@ -63,10 +57,6 @@ class Shib implements ChainableStorage, ServiceLocatorAwareInterface
     */
    private function getAuthenticatedUser()
    {
        if (! $this->isShibbolethEnabled()) {
            return null;
        }

        if (null !== $this->resolvedIdentity) {
            return $this->resolvedIdentity;
        }
@@ -79,29 +69,6 @@ class Shib implements ChainableStorage, ServiceLocatorAwareInterface
        return $this->resolvedIdentity;
    }

    /**
     * @return bool
     */
    private function isShibbolethEnabled()
    {
        $options = $this->getModuleOptions();
        $shibboleth = $options->getShibboleth();

        return isset($shibboleth['enable']) && (bool) $shibboleth['enable'];
    }

    /**
     * @return ModuleOptions
     */
    private function getModuleOptions()
    {
        if (null === $this->options) {
            $this->options = $this->getServiceLocator()->get('unicaen-auth_module_options');
        }

        return $this->options;
    }

    /**
     * Writes $contents to storage
     *
+70 −0
Original line number Diff line number Diff line
<?php

namespace UnicaenAuth\Authentication\Storage;

use UnicaenAuth\Service\ShibService;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;

/**
 * Storage permettant de simuler un utilisateur authentifié via Shibboleth.
 *
 * @author Unicaen
 */
class ShibSimulatorStorage implements ChainableStorage, ServiceLocatorAwareInterface
{
    use ServiceLocatorAwareTrait;

    /**
     * @var ShibService
     */
    protected $shibService;

    /**
     * @var array
     */
    protected $shibbolethOptions;

    /**
     * {@inheritdoc}
     */
    public function read(ChainEvent $e)
    {
        if (! $this->getShibService()->isShibbolethEnabled()) {
            return;
        }
        if (! $this->getShibService()->isSimulationActive()) {
            return;
        }

        $this->getShibService()->handleSimulation();
    }

    /**
     * {@inheritdoc}
     */
    public function write(ChainEvent $e)
    {
        // nop
    }

    /**
     * {@inheritdoc}
     */
    public function clear(ChainEvent $e)
    {
        // nop
    }

    /**
     * @return ShibService
     */
    private function getShibService()
    {
        if ($this->shibService === null) {
            $this->shibService = $this->serviceLocator->get(ShibService::class);
        }

        return $this->shibService;
    }
}
 No newline at end of file
+60 −34
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@
namespace UnicaenAuth\Controller;

use UnicaenApp\Exception\RuntimeException;
use UnicaenAuth\Service\ShibService;
use UnicaenAuth\Service\Traits\ShibServiceAwareTrait;
use UnicaenAuth\Service\Traits\UserServiceAwareTrait;
use Zend\Authentication\AuthenticationService;
@@ -24,15 +23,17 @@ class AuthController extends AbstractActionController
    use UserServiceAwareTrait;

    /**
     * Cette action n'est exécutée qu'une fois l'authentification Shibboleth réalisée avec succès.
     * Cette action peut être appelée lorsque l'authentification Shibboleth est activée
     * (unicaen-auth.shibboleth.enable === true).
     *
     * Lorsque l'authentification Shibboleth est activée (unicaen-auth.shibboleth.enable === true),
     * et que la config Apache est correcte, une requête à l'adresse correspondant à cette action
     * (suite au clic sur le bouton "Authentification Shibboleth, typiquement)
     * est détournée pour réaliser l'authentification.
     * Ce n'est qu'une fois l'authentification réalisée avec succès que cette action entre en jeu.
     * > Si la config Apache de Shibboleth est correcte, une requête à l'adresse correspondant à cette action
     * (suite au clic sur le bouton "Authentification Shibboleth", typiquement)
     * est détournée par Apache pour réaliser l'authentification Shibboleth.
     * Ce n'est qu'une fois l'authentification réalisée avec succès que cette action est appelée.
     *
     * @see ShibService::apacheConfigSnippet()
     * > Si la config Apache de Shibboleth est incorrecte ou absente (localhost par exemple), et que la simulation
     * Shibboleth est activée dans la config (unicaen-auth.shibboleth.simulate), cette action est appelée et
     * la simulation est enclenchée.
     *
     * @return Response|array
     */
@@ -41,6 +42,38 @@ class AuthController extends AbstractActionController
        $operation = $this->params()->fromRoute('operation');

        if ($operation === 'deconnexion') {
            return $this->shibbolethLogout();
        }

        $redirectUrl = $this->params()->fromQuery('redirect', '/');

        // enclenchement de la simulation shibboleth éventuellement activée dans la config
        if ($simulate = $this->shibService->getShibbolethSimulate()) {
            $this->setStoredAuthenticatedUsername($simulate['eppn']); // tout simplement!

            return $this->redirect()->toUrl($redirectUrl);
        }

        $shibUser = $this->shibService->getAuthenticatedUser();
        if ($shibUser === null) {
            return []; // une page d'aide s'affichera si les données issues de Shibboleth attendues sont absentes
        }

        // arrivé ici, l'authentification shibboleth a été faite en bonne et due forme et a réussie.

        $this->setStoredAuthenticatedUsername($shibUser->getUsername());
        $this->userService->userAuthenticated($shibUser);

        return $this->redirect()->toUrl($redirectUrl);
    }

    /**
     * Déconnexion Shibboleth.
     *
     * @return array|Response
     */
    private function shibbolethLogout()
    {
        // déconnexion applicative quoiqu'il arrive
        $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters();
        $this->zfcUserAuthentication()->getAuthAdapter()->logoutAdapters();
@@ -61,24 +94,17 @@ class AuthController extends AbstractActionController
        }
    }

        $shibUser = $this->shibService->getAuthenticatedUser();

        if ($shibUser === null) {
            return []; // une page d'aide s'affichera
        }

    /**
     * @param string $username
     */
    private function setStoredAuthenticatedUsername($username)
    {
        /** @var AuthenticationService $authService */
        $authService = $this->getServiceLocator()->get('zfcuser_auth_service');
        try {
            $authService->getStorage()->write($shibUser->getUsername());
            $authService->getStorage()->write($username);
        } catch (ExceptionInterface $e) {
            throw new RuntimeException("Impossible d'écrire dans le storage");
        }

        $this->userService->userAuthenticated($shibUser);

        $redirectUrl = $this->params()->fromQuery('redirect', '/');

        return $this->redirect()->toUrl($redirectUrl);
    }
}
 No newline at end of file
+21 −24
Original line number Diff line number Diff line
@@ -58,26 +58,12 @@ EOS;
        }

        if ($this->authenticatedUser === null) {
            if (! $this->getShibbolethSimulate() && ! isset($_SERVER['REMOTE_USER'])) {
                try {
                    Assertion::keyIsset($_SERVER, 'REMOTE_USER');
                } catch (AssertionFailedException $e) {
                    throw new RuntimeException("La clé suivante est introuvable ou sans valeur dans \$_SERVER : 'REMOTE_USER'.");
                }
            }

            // gestion de l'usurpation éventuelle
            if ($this->isUsurpationActive()) {
            $this->handleUsurpation();
            }

            if (empty($_SERVER['REMOTE_USER'])) {
                if ($this->isSimulationActive()) {
                    $this->handleSimulation();
                } else {
                return null;
            }
            }

            $this->authenticatedUser = $this->createShibUserFromServerArrayData();
        }
@@ -114,7 +100,7 @@ EOS;
     *
     * @return bool
     */
    private function isSimulationActive()
    public function isSimulationActive()
    {
        $options = $this->options->getShibboleth();

@@ -126,10 +112,17 @@ EOS;
    }

    /**
     * @return $this
     * @return ShibUser|null
     */
    private function handleSimulation()
    public function handleSimulation()
    {
        if (! $this->isSimulationActive()) {
            return null;
        }

        // si nécessaire
        $this->handleUsurpation();

        $simulate = $this->getShibbolethSimulate();

        try {
@@ -154,9 +147,9 @@ EOS;
        $shibUser->setNom('Shibboleth');
        $shibUser->setPrenom('Simulation');

        ShibService::simulateAuthenticatedUser($shibUser);
        $this->simulateAuthenticatedUser($shibUser);

        return $this;
        return $shibUser;
    }

    /**
@@ -205,8 +198,12 @@ EOS;
    /**
     * @return $this
     */
    private function handleUsurpation()
    public function handleUsurpation()
    {
        if (! $this->isUsurpationActive()) {
            return $this;
        }

        $session = $this->getSessionContainer();

        /** @var ShibUser|null $toShibUser */
@@ -215,7 +212,7 @@ EOS;
            throw new RuntimeException("Anomalie: 'toShibUser' introuvable");
        }

        static::simulateAuthenticatedUser($toShibUser, 'supannEmpId');
        $this->simulateAuthenticatedUser($toShibUser, 'supannEmpId');

        return $this;
    }
@@ -236,7 +233,7 @@ EOS;
     * @param string $keyForId Clé du tableau $_SERVER dans laquelle mettre l'id de l'utilsateur spécifié.
     *                         Ex: 'supannEmpId', 'supannEtuId'.
     */
    public static function simulateAuthenticatedUser(ShibUser $shibUser, $keyForId = 'supannEmpId')
    public function simulateAuthenticatedUser(ShibUser $shibUser, $keyForId = 'supannEmpId')
    {
        $_SERVER['REMOTE_USER'] = $shibUser->getEppn();
        $_SERVER[$keyForId] = $shibUser->getId();
Loading