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

namespace UnicaenAuth\Service;

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

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

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

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

34

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

    /**
     * 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'];
            }
        }
48

49
50
51
        return null;
    }

52
53


54
55
56
57
58
59
60
61
62
63
64
65
    /**
     * 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'];
            }
        }
66

67
68
69
        return null;
    }

70
71


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

86
87
        return $this->identity;
    }
88

89
90


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

107
108
        return $this->identityRoles;
    }
109

110
111


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

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

127
128


129
    /**
130
     * Si un utilisateur est authentifié, retourne le rôle utilisateur sélectionné,
131
     * ou alors le premier sélectionnable si aucun n'a été sélectionné.
132
133
134
135
     *
     * 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.
     *
136
137
138
139
     * @return mixed
     */
    public function getSelectedIdentityRole()
    {
140

141
142
143
144
145
146
147
        if ($this->getNextSelectedIdentityRole()) {
            $this->getSessionContainer()->selectedIdentityRole = $this->getNextSelectedIdentityRole();
        }

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

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

152
153
154
155
156
157
158
159
160
        if ($roleId) {

            $roles = $this->getServiceAuthorize()->getRoles(); // Récupération de tous les rôles du provider
            if (isset($roles[$roleId])) {
                $role = $roles[$roleId];
            }else{
                $role = null;
            }

161
162
163
            if ($this->isRoleValid($role)) {
                return $role;
            }
164
        }
165

166
        return null;
167
    }
168

169
170


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

        return $this;
    }

198
199


200
201
202
203
204
    /**
     * Retourne l'éventuel rôle spécifié en session devant être le prochain rôle sélectionné.
     *
     * @return string|null
     */
205
    public function getNextSelectedIdentityRole()
206
207
208
209
    {
        return $this->getSessionContainer()->nextSelectedIdentityRole;
    }

210
211


212
213
214
215
216
217
    /**
     * 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
218
     *
219
220
221
222
223
224
225
226
227
228
229
     * @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');
230
        } else {
231
232
233
            unset($this->getSessionContainer()->nextSelectedIdentityRole);
        }

234
235
        return $this;
    }
236

237
238


239
    /**
240
     * Teste si le rôle spécifié fait partie des rôles disponibles.
241
242
     *
     * @param RoleInterface|string $role
243
     *
244
     * @return boolean
245
     */
246
    protected function isRoleValid($role)
247
    {
Bertrand Gauthier's avatar
Bertrand Gauthier committed
248
249
250
        if ($role instanceof RoleInterface) {
            $role = $role->getRoleId();
        }
251

252
        foreach ($this->getIdentityRoles() as $r) {
253
            if ($r instanceof RoleInterface) {
254
255
256
257
258
259
                $r = $r->getRoleId();
            }
            if ($role === $r) {
                return true;
            }
        }
260

261
262
        return false;
    }
263

264
265


266
    /**
267
     *
268
269
270
271
     * @return \UnicaenAuth\Provider\Identity\Chain
     */
    private function getIdentityProvider()
    {
272
273
        return $this->getServiceAuthorize()->getIdentityProvider();
        /* @var $identityProvider \UnicaenAuth\Provider\Identity\Chain */
274
    }
275

276
}