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

namespace UnicaenAuth\Controller;

5
6
7
8
9
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;
10
use UnicaenAuth\Formatter\RoleFormatter;
11
use UnicaenAuth\Options\ModuleOptions;
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\UserInterface;
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
    /**
     * @param LdapPeopleMapper $ldapPeopleMapper
     */
    public function setLdapPeopleMapper(LdapPeopleMapper $ldapPeopleMapper)
    {
        $this->ldapPeopleMapper = $ldapPeopleMapper;
    }

    /**
43
     * @var UserInterface
44
45
46
47
48
49
     */
    private $userMapper;

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

    /**
     * @var ModuleOptions
     */
55
    protected $options;
56
57

    /**
58
     * @param UserInterface $userMapper
59
     */
60
    public function setUserMapper(UserInterface $userMapper)
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    {
        $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;
    }

81
82
83
    /**
     * 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.
84
85
86
     *
     * @param bool $addFlashMessage
     * @return bool|string
87
     */
88
    public function selectionnerProfilAction($addFlashMessage = true)
89
    {
90
91
92
93
94
95
        $request = $this->getRequest();
        if (! $request instanceof Request) {
            exit(1);
        }
        if (! $request->isXmlHttpRequest()) {
            return $this->redirect()->toRoute('home');
96
        }
97
        
98
        $role = $request->getPost('role');
99
100
        
        if ($role) {
101
            $this->serviceUserContext->setSelectedIdentityRole($role);
102
        }
103

104
        if ($addFlashMessage) {
105
106
107
108
109
            $selectedRole = $this->serviceUserContext->getSelectedIdentityRole();
            $message = sprintf(
                "Vous endossez à présent le rôle utilisateur '<strong>%s</strong>'.",
                (new RoleFormatter())->format($selectedRole)
            );
110
            $this->flashMessenger()->setNamespace('UnicaenAuth/success')->addMessage($message);
111
        }
112
113

        return false;
114
    }
115

116
    /**
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
     * 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');
        }

133
        $currentIdentity = $this->authenticationService->getIdentity();
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
        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
166
        if (! in_array($currentIdentity->getUsername(), $this->options->getUsurpationAllowedUsernames())) {
167
168
169
170
171
172
173
            throw new RuntimeException("Usurpation non explicitement autorisée");
        }

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

177
        $this->authenticationService->getStorage()->write($newIdentity);
178
179
180
181
182
183
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

        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;
    }

    /**
209
     * @return UserInterface
210
211
212
     */
    public function getUserMapper()
    {
213
        return $this->userMapper;
214
215
216
217
    }

    /**
     * @return UserContext
218
     * @deprecated Utiliser $this->serviceUserContext directement, svp.
219
220
221
     */
    protected function getAuthUserContextService()
    {
222
        return $this->serviceUserContext;
223
    }
224
225
226
227
228
229

    /**
     * @return LdapPeopleMapper
     */
    public function getLdapPeopleMapper()
    {
230
        return $this->ldapPeopleMapper;
231
    }
232
}