User.php 6.28 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

        switch (true) {
            case $userData instanceof People:
67
                $username = $userData->getData($this->getOptions()->getLdapUsername());
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
                $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
            $entity->setEmail($email);
            $entity->setDisplayName($userData->getDisplayName());
            $entity->setPassword($password);
            $entity->setState($state);

            // pre-persist
117
118
            $event = new UserAuthenticatedEvent(UserAuthenticatedEvent::PRE_PERSIST);
            $this->triggerEvent($event, $entity, $userData);
119

120
            // persist
121
            $mapper->$method($entity);
122
123
124
125

            // post-persist
            $event = new UserAuthenticatedEvent(UserAuthenticatedEvent::POST_PERSIST);
            $this->triggerEvent($event, $entity, $userData);
126
        }
127
        catch (PDOException $pdoe) {
128
            throw new RuntimeException("Impossible d'enregistrer l'utilisateur authentifié dans la base de données.", null, $pdoe);
129
        }
130

131
132
        return true;
    }
133

134
    /**
135
     * @param UserInterface $entity
136
137
     * @param People|ShibUser $userData
     */
138
    private function triggerEvent(UserAuthenticatedEvent $event, $entity, $userData)
139
140
141
142
143
144
145
146
147
148
149
    {
        $event->setTarget($this);
        $event->setDbUser($entity);
        if ($userData instanceof People) {
            $event->setLdapUser($userData);
        } elseif ($userData instanceof ShibUser) {
            $event->setShibUser($userData);
        }

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

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

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

177
178
        return $this;
    }
179
180

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

188
        return $this;
189
190
191
    }

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

200
201
202
203
        return $this->options;
    }

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

211
        return $this;
212
213
214
    }

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

223
224
        return $this->zfcUserOptions;
    }
225
}