UtilisateurController.php 6.49 KB
Newer Older
1
2
3
4
<?php

namespace UnicaenAuth\Controller;

5
6
7
8
9
10
11
12
13
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;
14
use Zend\Http\Request;
15
use Zend\Http\Response;
16
use Zend\Mvc\Controller\AbstractActionController;
17
use ZfcUser\Mapper\User as UserMapper;
18
19
20
21
22
23

/**
 * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
 */
class UtilisateurController extends AbstractActionController
{
24
25
26
27
28
    /**
     * @var LdapPeopleMapper
     */
    protected $ldapPeopleMapper;

29
30
31
    /**
     * 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.
32
33
34
     *
     * @param bool $addFlashMessage
     * @return bool|string
35
     */
36
    public function selectionnerProfilAction($addFlashMessage = true)
37
    {
38
39
40
41
42
43
        $request = $this->getRequest();
        if (! $request instanceof Request) {
            exit(1);
        }
        if (! $request->isXmlHttpRequest()) {
            return $this->redirect()->toRoute('home');
44
        }
45
        
46
        $role = $request->getPost('role');
47
48
        
        if ($role) {
49
50
            $this->getAuthUserContextService()->setSelectedIdentityRole($role);
        }
51

52
        if ($addFlashMessage) {
53
54
            $selectedRole = $this->getAuthUserContextService()->getSelectedIdentityRoleToString();
            $message = sprintf("Vous endossez à présent le profil utilisateur <strong>%s</strong>.", $selectedRole);
55
            $this->flashMessenger()->setNamespace('UnicaenAuth/success')->addMessage($message);
56
        }
57
58

        return false;
59
    }
60

61
    /**
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
     * 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
170
171
172
173
174
     */
    protected function getAuthUserContextService()
    {
        return $this->getServiceLocator()->get('AuthUserContext');
    }
175
176
177
178
179
180
181
182

    /**
     * @return LdapPeopleMapper
     */
    public function getLdapPeopleMapper()
    {
        return $this->serviceLocator->get('ldap_people_mapper');
    }
183
}