UserContext.php 7.33 KB
Newer Older
1
2
3
4
<?php

namespace UnicaenAuth\Service;

5
use UnicaenApp\Exception\RuntimeException;
6
use UnicaenApp\Traits\SessionContainerTrait;
7
use UnicaenAuth\Provider\Identity\Chain;
8
use Zend\Session\Container as SessionContainer;
9
use Zend\Permissions\Acl\Role\RoleInterface;
10
11
use ZfcUser\Entity\UserInterface;
use UnicaenAuth\Entity\Ldap\People;
12
use UnicaenAuth\Acl\NamedRole;
13
14

/**
15
 * Service centralisant des méthodes utiles concernant l'utilisateur authentifié.
16
17
18
 *
 * @author Laurent LÉCLUSE <laurent.lecluse at unicaen.fr>
 */
19
class UserContext extends AbstractService
20
{
21
    use SessionContainerTrait;
22
23
24
25
26

    /**
     * @var mixed
     */
    protected $identity;
27

28
    /**
29
     * @var array
30
     */
31
    protected $identityRoles;
32

33

34
35
36
37
38
39
40
41
42
43
44
45
46

    /**
     * Retourne l'utilisateur BDD courant
     *
     * @return UserInterface
     */
    public function getDbUser()
    {
        if (($identity = $this->getIdentity())) {
            if (isset($identity['db']) && $identity['db'] instanceof UserInterface) {
                return $identity['db'];
            }
        }
47

48
49
50
        return null;
    }

51
52


53
54
55
56
57
58
59
60
61
62
63
64
    /**
     * Retourne l'utilisateur LDAP courant
     *
     * @return People
     */
    public function getLdapUser()
    {
        if (($identity = $this->getIdentity())) {
            if (isset($identity['ldap']) && $identity['ldap'] instanceof People) {
                return $identity['ldap'];
            }
        }
65

66
67
68
        return null;
    }

69
70


71
    /**
72
     * Retourne les données d'identité correspondant à l'utilisateur courant.
73
     *
74
     * @return mixed
75
     */
76
    public function getIdentity()
77
    {
78
79
80
81
82
83
        if (null === $this->identity) {
            $authenticationService = $this->getServiceLocator()->get('Zend\Authentication\AuthenticationService');
            if ($authenticationService->hasIdentity()) {
                $this->identity = $authenticationService->getIdentity();
            }
        }
84

85
86
        return $this->identity;
    }
87

88
89


90
    /**
91
     * Retourne tous les rôles de l'utilisateur courant, pas seulement le rôle courant sélectionné.
92
     *
93
94
95
96
97
     * @return array
     */
    public function getIdentityRoles()
    {
        if (null === $this->identityRoles) {
98
            $identityProvider    = $this->getIdentityProvider();
99
100
101
102
103
            if ($identityProvider instanceof Chain){
                $this->identityRoles = $identityProvider->getAllIdentityRoles();
            }else{
                $this->identityRoles = $identityProvider->getIdentityRoles();
            }
104
        }
105

106
107
        return $this->identityRoles;
    }
108

109
110


111
    /**
112
     * Retourne parmi tous les rôles de l'utilisateur courant ceux qui peuvent être sélectionnés.
113
     *
114
115
116
117
     * @return array
     */
    public function getSelectableIdentityRoles()
    {
118
119
120
        $filter = function ($r) {
            return !($r instanceof NamedRole && !$r->getSelectable());
        };
Bertrand Gauthier's avatar
Bertrand Gauthier committed
121
        $roles  = array_filter($this->getIdentityRoles(), $filter);
122

Bertrand Gauthier's avatar
Bertrand Gauthier committed
123
        return $roles;
124
    }
125

126
127


128
    /**
129
     * Si un utilisateur est authentifié, retourne le rôle utilisateur sélectionné,
130
     * ou alors le premier sélectionnable si aucun n'a été sélectionné.
131
132
133
134
     *
     * NB: Si un rôle est spécifié en session comme devant être le prochain rôle sélectionné,
     * c'est lui qui est pris en compte.
     *
135
136
137
138
     * @return mixed
     */
    public function getSelectedIdentityRole()
    {
139
140
141
142
143
144
145
        if ($this->getNextSelectedIdentityRole()) {
            $this->getSessionContainer()->selectedIdentityRole = $this->getNextSelectedIdentityRole();
        }

        if (null === $this->getSessionContainer()->selectedIdentityRole && $this->getIdentity()) {
            $roles = $this->getSelectableIdentityRoles();
            $this->setSelectedIdentityRole(reset($roles));
146
        }
147
148
149

        $roleId = $this->getSessionContainer()->selectedIdentityRole;

150
151
152
153
154
        if ($roleId){
            $role = $this->normalizedIdentityRole($roleId);
            if ($this->isRoleValid($role)) {
                return $role;
            }
155
        }
156

157
        return null;
158
    }
159

160
161


162
    /**
Bertrand Gauthier's avatar
Bertrand Gauthier committed
163
     * Mémorise en session le rôle spécifié comme étant le rôle courant de l'utilisateur.
164
     *
Bertrand Gauthier's avatar
Bertrand Gauthier committed
165
     * NB: seul l'id du rôle est mémorisé en session.
166
     *
Bertrand Gauthier's avatar
Bertrand Gauthier committed
167
     * @param RoleInterface|string $role
168
     *
169
     * @return \UnicaenAuth\Service\UserContext
170
     * @throws RuntimeException
171
172
173
174
175
     */
    public function setSelectedIdentityRole($role)
    {
        if ($role) {
            if (!$this->isRoleValid($role)) {
176
                throw new RuntimeException("Rôle spécifié invalide.");
177
            }
Bertrand Gauthier's avatar
Bertrand Gauthier committed
178
179
180
181
            if ($role instanceof RoleInterface) {
                $role = $role->getRoleId();
            }
            $this->getSessionContainer()->selectedIdentityRole = $role;
182
        } else {
183
184
            unset($this->getSessionContainer()->selectedIdentityRole);
        }
185
186
187
188

        return $this;
    }

189
190


191
192
193
194
195
    /**
     * Retourne l'éventuel rôle spécifié en session devant être le prochain rôle sélectionné.
     *
     * @return string|null
     */
196
    public function getNextSelectedIdentityRole()
197
198
199
200
    {
        return $this->getSessionContainer()->nextSelectedIdentityRole;
    }

201
202


203
204
205
206
207
208
    /**
     * Mémorise en session le rôle devant être le prochain rôle sélectionné.
     *
     * NB: seul l'id du rôle est mémorisé en session ; la durée de vie du stockage est de 1 requête seulement.
     *
     * @param RoleInterface|string $role
209
     *
210
211
212
213
214
215
216
217
218
219
220
     * @return \UnicaenAuth\Service\UserContext
     */
    public function setNextSelectedIdentityRole($role)
    {
        if ($role instanceof RoleInterface) {
            $role = $role->getRoleId();
        }

        if ($role) {
            $this->getSessionContainer()->nextSelectedIdentityRole = $role;
            $this->getSessionContainer()->setExpirationHops(1, 'nextSelectedIdentityRole');
221
        } else {
222
223
224
            unset($this->getSessionContainer()->nextSelectedIdentityRole);
        }

225
226
        return $this;
    }
227

228
229


230
231
    /**
     * Recherche le role spécifié parmi les rôles connus au format objets.
232
233
     *
     * @param RoleInterface|string $role
234
     *
235
     * @return RoleInterface Role trouvé au format objet dans la mesure du possible
236
237
238
     */
    protected function normalizedIdentityRole($role)
    {
Bertrand Gauthier's avatar
Bertrand Gauthier committed
239
        if (!$role || is_object($role)) {
240
241
            return $role;
        }
242

243
244
245
246
247
248
249
250
        foreach ($this->getIdentityRoles() as $r) {
            if ($r instanceof RoleInterface && $role === $r->getRoleId()) {
                return $r;
            }
            if ($role === $r) {
                return $r;
            }
        }
251

252
253
        return $role;
    }
254

255
256


257
    /**
258
     * Teste si le rôle spécifié fait partie des rôles disponibles.
259
260
     *
     * @param RoleInterface|string $role
261
     *
262
     * @return boolean
263
     */
264
    protected function isRoleValid($role)
265
    {
Bertrand Gauthier's avatar
Bertrand Gauthier committed
266
267
268
        if ($role instanceof RoleInterface) {
            $role = $role->getRoleId();
        }
269

270
        foreach ($this->getIdentityRoles() as $r) {
271
            if ($r instanceof RoleInterface) {
272
273
274
275
276
277
                $r = $r->getRoleId();
            }
            if ($role === $r) {
                return true;
            }
        }
278

279
280
        return false;
    }
281

282
283


284
    /**
285
     *
286
287
288
289
     * @return \UnicaenAuth\Provider\Identity\Chain
     */
    private function getIdentityProvider()
    {
290
291
        return $this->getServiceAuthorize()->getIdentityProvider();
        /* @var $identityProvider \UnicaenAuth\Provider\Identity\Chain */
292
    }
293

294
}