]> Raphaël G. Git Repositories - userbundle/blob - Entity/User.php
Remove mail and hash possible leak from failure_path context
[userbundle] / Entity / User.php
1 <?php declare(strict_types=1);
2
3 /*
4 * this file is part of the rapsys packbundle package.
5 *
6 * (c) raphaël gertz <symfony@rapsys.eu>
7 *
8 * for the full copyright and license information, please view the license
9 * file that was distributed with this source code.
10 */
11
12 namespace Rapsys\UserBundle\Entity;
13
14 use Doctrine\Common\Collections\Collection;
15 use Doctrine\Common\Collections\ArrayCollection;
16 use Doctrine\ORM\Event\PreUpdateEventArgs;
17 use Symfony\Component\Security\Core\User\UserInterface;
18 use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
19
20 use Rapsys\UserBundle\Entity\Civility;
21 use Rapsys\UserBundle\Entity\Group;
22
23 /**
24 * User
25 */
26 class User implements UserInterface, PasswordAuthenticatedUserInterface {
27 /**
28 * @var ?integer
29 */
30 protected ?int $id;
31
32 /**
33 * @var string
34 */
35 protected string $mail;
36
37 /**
38 * @var string
39 */
40 protected string $password;
41
42 /**
43 * @var ?string
44 */
45 protected ?string $forename;
46
47 /**
48 * @var ?string
49 */
50 protected ?string $surname;
51
52 /**
53 * @var bool
54 */
55 protected bool $active;
56
57 /**
58 * @var bool
59 */
60 protected bool $enable;
61
62 /**
63 * @var \DateTime
64 */
65 protected \DateTime $created;
66
67 /**
68 * @var \DateTime
69 */
70 protected \DateTime $updated;
71
72 /**
73 * @var Civility
74 */
75 protected ?Civility $civility;
76
77 /**
78 * @var Doctrine\Common\Collections\Collection
79 */
80 protected Collection $groups;
81
82 /**
83 * Constructor
84 *
85 * @param string $mail The user mail
86 * @param string $password The user password
87 * @param ?Civility $civility The user civility
88 * @param ?string $forename The user forename
89 * @param ?string $surname The user surname
90 * @param bool $active The user active
91 * @param bool $enable The user enable
92 */
93 public function __construct(string $mail, string $password, ?Civility $civility = null, ?string $forename = null, ?string $surname = null, bool $active = false, bool $enable = true) {
94 //Set defaults
95 $this->mail = $mail;
96 $this->password = $password;
97 $this->civility = $civility;
98 $this->forename = $forename;
99 $this->surname = $surname;
100 $this->active = $active;
101 $this->enable = $enable;
102 $this->created = new \DateTime('now');
103 $this->updated = new \DateTime('now');
104
105 //Set collections
106 $this->groups = new ArrayCollection();
107 }
108
109 /**
110 * Get id
111 *
112 * @return ?int
113 */
114 public function getId(): ?int {
115 return $this->id;
116 }
117
118 /**
119 * Set mail
120 *
121 * @param string $mail
122 * @return User
123 */
124 public function setMail(string $mail): User {
125 //Set mail
126 $this->mail = $mail;
127
128 return $this;
129 }
130
131 /**
132 * Get mail
133 *
134 * @return string
135 */
136 public function getMail(): string {
137 return $this->mail;
138 }
139
140 /**
141 * Set forename
142 *
143 * @param ?string $forename
144 *
145 * @return User
146 */
147 public function setForename(?string $forename): User {
148 $this->forename = $forename;
149
150 return $this;
151 }
152
153 /**
154 * Get forename
155 *
156 * @return ?string
157 */
158 public function getForename(): ?string {
159 return $this->forename;
160 }
161
162 /**
163 * Set surname
164 *
165 * @param ?string $surname
166 *
167 * @return User
168 */
169 public function setSurname(?string $surname): User {
170 $this->surname = $surname;
171
172 return $this;
173 }
174
175 /**
176 * Get surname
177 *
178 * @return ?string
179 */
180 public function getSurname(): ?string {
181 return $this->surname;
182 }
183
184 /**
185 * Set password
186 *
187 * @param string $password
188 *
189 * @return User
190 */
191 public function setPassword(string $password): User {
192 //Set password
193 $this->password = $password;
194
195 return $this;
196 }
197
198 /**
199 * Get password
200 *
201 * {@inheritdoc}
202 *
203 * @return string
204 */
205 public function getPassword(): string {
206 return $this->password;
207 }
208
209 /**
210 * Set active
211 *
212 * @param bool $active
213 *
214 * @return User
215 */
216 public function setActive(bool $active): User {
217 $this->active = $active;
218
219 return $this;
220 }
221
222 /**
223 * Get active
224 *
225 * @return bool
226 */
227 public function getActive(): bool {
228 return $this->active;
229 }
230
231 /**
232 * Set enable
233 *
234 * @param bool $enable
235 *
236 * @return User
237 */
238 public function setEnable(bool $enable): User {
239 $this->enable = $enable;
240
241 return $this;
242 }
243
244 /**
245 * Get enable
246 *
247 * @return bool
248 */
249 public function getEnable(): bool {
250 return $this->enable;
251 }
252
253 /**
254 * Set created
255 *
256 * @param \DateTime $created
257 *
258 * @return User
259 */
260 public function setCreated(\DateTime $created): User {
261 $this->created = $created;
262
263 return $this;
264 }
265
266 /**
267 * Get created
268 *
269 * @return \DateTime
270 */
271 public function getCreated(): \DateTime {
272 return $this->created;
273 }
274
275 /**
276 * Set updated
277 *
278 * @param \DateTime $updated
279 *
280 * @return User
281 */
282 public function setUpdated(\DateTime $updated): User {
283 $this->updated = $updated;
284
285 return $this;
286 }
287
288 /**
289 * Get updated
290 *
291 * @return \DateTime
292 */
293 public function getUpdated(): \DateTime {
294 return $this->updated;
295 }
296
297 /**
298 * Set civility
299 */
300 public function setCivility(?Civility $civility = null): User {
301 $this->civility = $civility;
302
303 return $this;
304 }
305
306 /**
307 * Get civility
308 */
309 public function getCivility(): ?Civility {
310 return $this->civility;
311 }
312
313 /**
314 * Add group
315 *
316 * @param Group $group
317 *
318 * @return User
319 */
320 public function addGroup(Group $group): User {
321 $this->groups[] = $group;
322
323 return $this;
324 }
325
326 /**
327 * Remove group
328 *
329 * @param Group $group
330 *
331 * @return Doctrine\Common\Collections\Collection
332 */
333 public function removeGroup(Group $group): Collection {
334 return $this->groups->removeElement($group);
335 }
336
337 /**
338 * Get groups
339 *
340 * @return Doctrine\Common\Collections\Collection
341 */
342 public function getGroups(): Collection {
343 return $this->groups;
344 }
345
346 /**
347 * {@inheritdoc}
348 */
349 public function getRoles(): array {
350 //Get the unique roles list by id
351 return array_unique(array_reduce(
352 //Cast groups as array
353 $this->groups->toArray(),
354 //Reduce to an array of id => group tuples
355 function ($array, $group) {
356 $array[$group->getId()] = $group->getRole();
357 return $array;
358 },
359 //Init with empty array
360 //XXX: on registration, add each group present in rapsys_user.default.group array to user
361 //XXX: see vendor/rapsys/userbundle/Controller/DefaultController.php +450
362 []
363 ));
364 }
365
366 /**
367 * {@inheritdoc}
368 */
369 public function getRole(): ?string {
370 //Retrieve roles
371 $roles = $this->getRoles();
372
373 //With roles array empty
374 if ($roles === []) {
375 //Return null
376 return null;
377 }
378
379 //Return the role with max id
380 //XXX: should be rewriten if it change in your configuration
381 return $roles[array_reduce(
382 array_keys($roles),
383 function($cur, $id) {
384 if ($cur === null || $id > $cur) {
385 return $id;
386 }
387 return $cur;
388 },
389 null
390 )];
391 }
392
393 /**
394 * {@inheritdoc}
395 */
396 public function getSalt(): ?string {
397 //No salt required with bcrypt
398 return null;
399 }
400
401 /**
402 * {@inheritdoc}
403 */
404 public function getUsername(): string {
405 return $this->mail;
406 }
407
408 /**
409 * {@inheritdoc}
410 */
411 public function getUserIdentifier(): string {
412 return $this->mail;
413 }
414
415 /**
416 * {@inheritdoc}
417 */
418 public function eraseCredentials(): void {}
419
420 /**
421 * {@inheritdoc}
422 */
423 public function __serialize(): array {
424 return [
425 $this->id,
426 $this->mail,
427 $this->forename,
428 $this->surname,
429 $this->password,
430 $this->active,
431 $this->enable,
432 $this->created,
433 $this->updated
434 ];
435 }
436
437 /**
438 * {@inheritdoc}
439 */
440 public function __unserialize(array $data): void {
441 list(
442 $this->id,
443 $this->mail,
444 $this->forename,
445 $this->surname,
446 $this->password,
447 $this->active,
448 $this->enable,
449 $this->created,
450 $this->updated
451 ) = $data;
452 }
453
454 /**
455 * Check if account is activated
456 *
457 * @see vendor/rapsys/userbundle/Checker/UserChecker.php
458 */
459 public function isActivated(): bool {
460 return $this->active;
461 }
462
463 /**
464 * Check if account is enabled
465 *
466 * @see vendor/symfony/security-core/User/InMemoryUserChecker.php
467 */
468 public function isEnabled(): bool {
469 return $this->enable;
470 }
471
472 /**
473 * {@inheritdoc}
474 */
475 public function preUpdate(PreUpdateEventArgs $eventArgs) {
476 //Check that we have an user instance
477 if (($user = $eventArgs->getEntity()) instanceof User) {
478 //Set updated value
479 $user->setUpdated(new \DateTime('now'));
480 }
481 }
482
483 /**
484 * Returns a recipient name of the user
485 *
486 * @return string
487 */
488 public function getRecipientName(): string {
489 //Without forename and surname
490 if (empty($this->forename) && empty($this->surname)) {
491 //Return recipient name from mail
492 return ucwords(trim(preg_replace('/[^a-zA-Z]+/', ' ', current(explode('@', $this->mail)))));
493 }
494
495 //Return recipient name from forename and surname
496 return implode(' ', [$this->forename, $this->surname]);
497 }
498
499 /**
500 * Returns a string representation of the user
501 *
502 * @return string
503 */
504 public function __toString(): string {
505 return $this->civility.' '.$this->forename.' '.$this->surname;
506 }
507 }