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

namespace UnicaenAuth\Controller;

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

/**
 * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
 */
23
class UtilisateurController extends AbstractActionController
24
{
25
26
    use UserContextServiceAwareTrait;

27
28
29
30
31
    /**
     * @var LdapPeopleMapper
     */
    protected $ldapPeopleMapper;

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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
    /**
     * @param LdapPeopleMapper $ldapPeopleMapper
     */
    public function setLdapPeopleMapper(LdapPeopleMapper $ldapPeopleMapper)
    {
        $this->ldapPeopleMapper = $ldapPeopleMapper;
    }

    /**
     * @var UserMapper
     */
    private $userMapper;

    /**
     * @var AuthenticationService
     */
    private $authenticationService;

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

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

    /**
     * @param UserMapper $userMapper
     */
    public function setUserMapper(UserMapper $userMapper)
    {
        $this->userMapper = $userMapper;
    }

    /**
     * @param AuthenticationService $authenticationService
     */
    public function setAuthenticationService(AuthenticationService $authenticationService)
    {
        $this->authenticationService = $authenticationService;
    }

    /**
     * @param ModuleOptions $options
     */
    public function setOptions(ModuleOptions $options)
    {
        $this->options = $options;
    }

    /**
     * @param ShibService $shibService
     */
    public function setShibService(ShibService $shibService)
    {
        $this->shibService = $shibService;
    }

    /**
     * @param UserContext $userContextService
94
     * @deprecated Utiliser UserContextServiceAwareTrait::setServiceUserContext() à la place, svp.
95
96
97
     */
    public function setUserContextService(UserContext $userContextService)
    {
98
        $this->serviceUserContext = $userContextService;
99
100
    }

101
102
103
    /**
     * 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.
104
105
106
     *
     * @param bool $addFlashMessage
     * @return bool|string
107
     */
108
    public function selectionnerProfilAction($addFlashMessage = true)
109
    {
110
111
112
113
114
115
        $request = $this->getRequest();
        if (! $request instanceof Request) {
            exit(1);
        }
        if (! $request->isXmlHttpRequest()) {
            return $this->redirect()->toRoute('home');
116
        }
117
        
118
        $role = $request->getPost('role');
119
120
        
        if ($role) {
121
            $this->serviceUserContext->setSelectedIdentityRole($role);
122
        }
123

124
        if ($addFlashMessage) {
125
            $selectedRole = $this->serviceUserContext->getSelectedIdentityRoleToString();
126
            $message = sprintf("Vous endossez à présent le profil utilisateur <strong>%s</strong>.", $selectedRole);
127
            $this->flashMessenger()->setNamespace('UnicaenAuth/success')->addMessage($message);
128
        }
129
130

        return false;
131
    }
132

133
    /**
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
     * 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');
        }

150
        $currentIdentity = $this->authenticationService->getIdentity();
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
        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
183
        if (! in_array($currentIdentity->getUsername(), $this->options->getUsurpationAllowedUsernames())) {
184
185
186
187
188
189
190
            throw new RuntimeException("Usurpation non explicitement autorisée");
        }

        // cuisine spéciale pour Shibboleth
        if ($currentIdentity instanceof ShibUser) {
            $fromShibUser = $currentIdentity;
            $toShibUser = $this->createShibUserFromUtilisateurUsername($newIdentity);
191
            $this->shibService->activateUsurpation($fromShibUser, $toShibUser);
192
193
        }

194
        $this->authenticationService->getStorage()->write($newIdentity);
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

        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()
    {
230
        return $this->userMapper;
231
232
233
234
    }

    /**
     * @return UserContext
235
     * @deprecated Utiliser $this->serviceUserContext directement, svp.
236
237
238
     */
    protected function getAuthUserContextService()
    {
239
        return $this->serviceUserContext;
240
    }
241
242
243
244
245
246

    /**
     * @return LdapPeopleMapper
     */
    public function getLdapPeopleMapper()
    {
247
        return $this->ldapPeopleMapper;
248
    }
249
}