UtilisateurController.php 7.52 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\ShibServiceAwareTrait;
13
use UnicaenAuth\Service\Traits\UserContextServiceAwareTrait;
14
15
use UnicaenAuth\Service\UserContext;
use Zend\Authentication\AuthenticationService;
16
use Zend\Http\Request;
17
use Zend\Http\Response;
18
use Zend\Mvc\Controller\AbstractActionController;
19
use ZfcUser\Mapper\User as UserMapper;
20
21
22
23

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

29
30
31
32
33
    /**
     * @var LdapPeopleMapper
     */
    protected $ldapPeopleMapper;

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    /**
     * @param LdapPeopleMapper $ldapPeopleMapper
     */
    public function setLdapPeopleMapper(LdapPeopleMapper $ldapPeopleMapper)
    {
        $this->ldapPeopleMapper = $ldapPeopleMapper;
    }

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

    /**
     * @var AuthenticationService
     */
50
    protected $authenticationService;
51
52
53
54

    /**
     * @var ModuleOptions
     */
55
    protected $options;
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

    /**
     * @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 UserContext $userContextService
83
     * @deprecated Utiliser UserContextServiceAwareTrait::setServiceUserContext() à la place, svp.
84
85
86
     */
    public function setUserContextService(UserContext $userContextService)
    {
87
        $this->serviceUserContext = $userContextService;
88
89
    }

90
91
92
    /**
     * 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.
93
94
95
     *
     * @param bool $addFlashMessage
     * @return bool|string
96
     */
97
    public function selectionnerProfilAction($addFlashMessage = true)
98
    {
99
100
101
102
103
104
        $request = $this->getRequest();
        if (! $request instanceof Request) {
            exit(1);
        }
        if (! $request->isXmlHttpRequest()) {
            return $this->redirect()->toRoute('home');
105
        }
106
        
107
        $role = $request->getPost('role');
108
109
        
        if ($role) {
110
            $this->serviceUserContext->setSelectedIdentityRole($role);
111
        }
112

113
        if ($addFlashMessage) {
114
            $selectedRole = $this->serviceUserContext->getSelectedIdentityRoleToString();
115
            $message = sprintf("Vous endossez à présent le profil utilisateur <strong>%s</strong>.", $selectedRole);
116
            $this->flashMessenger()->setNamespace('UnicaenAuth/success')->addMessage($message);
117
        }
118
119

        return false;
120
    }
121

122
    /**
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
     * 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');
        }

139
        $currentIdentity = $this->authenticationService->getIdentity();
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
170
171
        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
172
        if (! in_array($currentIdentity->getUsername(), $this->options->getUsurpationAllowedUsernames())) {
173
174
175
176
177
178
179
            throw new RuntimeException("Usurpation non explicitement autorisée");
        }

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

183
        $this->authenticationService->getStorage()->write($newIdentity);
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

        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()
    {
219
        return $this->userMapper;
220
221
222
223
    }

    /**
     * @return UserContext
224
     * @deprecated Utiliser $this->serviceUserContext directement, svp.
225
226
227
     */
    protected function getAuthUserContextService()
    {
228
        return $this->serviceUserContext;
229
    }
230
231
232
233
234
235

    /**
     * @return LdapPeopleMapper
     */
    public function getLdapPeopleMapper()
    {
236
        return $this->ldapPeopleMapper;
237
    }
238
}