User.php 6.22 KB
Newer Older
1
<?php
2

3
4
namespace UnicaenAuth\Service;

5
use UnicaenAuth\Event\UserAuthenticatedEvent;
6
use PDOException;
7
8
use UnicaenApp\Entity\Ldap\People;
use UnicaenApp\Exception\RuntimeException;
9
use UnicaenApp\Mapper\Ldap\People as LdapPeopleMapper;
10
use UnicaenAuth\Entity\Shibboleth\ShibUser;
11
use UnicaenAuth\Options\ModuleOptions;
12
13
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;
14
15
16
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
use ZfcUser\Entity\UserInterface;
17
use ZfcUser\Options\AuthenticationOptionsInterface;
18
use ZfcUser\Options\ModuleOptions as ZfcUserModuleOptions;
19
20

/**
21
 * Service d'enregistrement dans la table des utilisateurs de l'application
22
 * de l'utilisateur authentifié avec succès.
23
 *
24
 * @see \UnicaenAuth\Authentication\Adapter\AbstractFactory
25
 * @author Unicaen
26
 */
27
class User implements ServiceLocatorAwareInterface, EventManagerAwareInterface
28
{
29
    use ServiceLocatorAwareTrait;
30

31
    const EVENT_USER_AUTHENTICATED_PRE_PERSIST = 'userAuthenticated.prePersist';
32

33
34
35
36
37
    /**
     * @var EventManagerInterface
     */
    protected $eventManager;

38
    /**
39
     * @var ModuleOptions
40
41
42
43
     */
    protected $options;

    /**
44
     * @var AuthenticationOptionsInterface
45
46
     */
    protected $zfcUserOptions;
47

48
    /**
49
     * @var LdapPeopleMapper
50
     */
51
    protected $ldapPeopleMapper;
52

53
54
    /**
     * Save authenticated user in database from LDAP data.
55
     *
56
     * @param UserInterface|People $userData
57
58
     * @return bool
     */
59
    public function userAuthenticated($userData)
60
61
62
63
    {
        if (!$this->getOptions()->getSaveLdapUserInDatabase()) {
            return false;
        }
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

        switch (true) {
            case $userData instanceof People:
                $username = $userData->getSupannAliasLogin();
                $email = $userData->getMail();
                $password = 'ldap';
                $state = in_array('deactivated', ldap_explode_dn($userData->getDn(), 1)) ? 0 : 1;

                break;
            case $userData instanceof ShibUser:
                $username = $userData->getUsername();
                $email = $userData->getEmail();
                $password = 'shib';
                $state = 1;
                break;
            default:
                throw new RuntimeException("A implémenter!!");
                break;
        }

        if (!$username) {
85
86
            return false;
        }
87

88
        if (is_int($username)) {
89
            // c'est un id : cela signifie que l'utilisateur existe déjà dans la bdd (et pas dans le LDAP), rien à faire
90
91
            return true;
        }
92

93
        if (!is_string($username)) {
94
            throw new RuntimeException("Identité rencontrée inattendue.");
95
        }
96

97
        // update/insert de l'utilisateur dans la table de l'appli
98
        $mapper = $this->getServiceLocator()->get('zfcuser_user_mapper'); /* @var $mapper \ZfcUserDoctrineORM\Mapper\User */
99
        try {
100
            /** @var UserInterface $entity */
101
            $entity = $mapper->findByUsername($username);
102
103
104
105
106
107
108
109
110
            if (!$entity) {
                $entityClass = $this->getZfcUserOptions()->getUserEntityClass();
                $entity = new $entityClass;
                $entity->setUsername($username);
                $method = 'insert';
            }
            else {
                $method = 'update';
            }
111
112
113
114
115
116
117
            $entity->setEmail($email);
            $entity->setDisplayName($userData->getDisplayName());
            $entity->setPassword($password);
            $entity->setState($state);

            // pre-persist
            $this->triggerUserAuthenticatedEvent($entity, $userData);
118

119
            // persist
120
121
            $mapper->$method($entity);
        }
122
        catch (PDOException $pdoe) {
123
            throw new RuntimeException("Impossible d'enregistrer l'utilisateur authentifié dans la base de données.", null, $pdoe);
124
        }
125

126
127
        return true;
    }
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
    /**
     * Déclenche l'événement donnant aux applications clientes l'opportunité de modifier l'entité
     * utilisateur avant qu'elle ne soit persistée.
     *
     * @param mixed $entity
     * @param People|ShibUser $userData
     */
    private function triggerUserAuthenticatedEvent($entity, $userData)
    {
        $event = new UserAuthenticatedEvent(UserAuthenticatedEvent::PRE_PERSIST);
        $event->setTarget($this);
        $event->setDbUser($entity);
        if ($userData instanceof People) {
            $event->setLdapUser($userData);
        } elseif ($userData instanceof ShibUser) {
            $event->setShibUser($userData);
        }

        $this->getEventManager()->trigger($event);
    }
149

150
151
152
153
154
155
156
157
158
159
160
    /**
     * Retrieve the event manager
     *
     * Lazy-loads an EventManager instance if none registered.
     *
     * @return EventManagerInterface
     */
    public function getEventManager()
    {
        return $this->eventManager;
    }
161

162
163
164
165
    /**
     * Inject an EventManager instance
     *
     * @param  EventManagerInterface $eventManager
166
     * @return self
167
168
169
     */
    public function setEventManager(EventManagerInterface $eventManager)
    {
170
        $eventManager->setIdentifiers([
171
172
            __CLASS__,
            get_called_class(),
173
        ]);
174
175
176
        $this->eventManager = $eventManager;
        return $this;
    }
177
178

    /**
179
     * @param ModuleOptions $options
180
     * @return self
181
     */
182
    public function setOptions(ModuleOptions $options)
183
184
    {
        $this->options = $options;
185
        return $this;
186
187
188
    }

    /**
189
     * @return ModuleOptions
190
191
192
     */
    public function getOptions()
    {
193
        if (!$this->options instanceof ModuleOptions) {
194
            $this->setOptions($this->getServiceLocator()->get('unicaen-auth_module_options'));
195
196
197
198
199
        }
        return $this->options;
    }

    /**
200
     * @param ZfcUserModuleOptions $options
201
     * @return self
202
     */
203
    public function setZfcUserOptions(ZfcUserModuleOptions $options)
204
205
    {
        $this->zfcUserOptions = $options;
206
        return $this;
207
208
209
    }

    /**
210
     * @return ZfcUserModuleOptions
211
212
213
     */
    public function getZfcUserOptions()
    {
214
        if (!$this->zfcUserOptions instanceof ZfcUserModuleOptions) {
Laurent Lécluse's avatar
Laurent Lécluse committed
215
            $this->setZfcUserOptions($this->getServiceLocator()->get('zfcuser_module_options'));
216
217
218
        }
        return $this->zfcUserOptions;
    }
219
}