Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
51.46% covered (warning)
51.46%
53 / 103
60.71% covered (warning)
60.71%
34 / 56
CRAP
0.00% covered (danger)
0.00%
0 / 1
User
51.46% covered (warning)
51.46%
53 / 103
60.71% covered (warning)
60.71%
34 / 56
932.05
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 getId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __toString
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
3.58
 hasAccessTo
30.00% covered (danger)
30.00%
6 / 20
0.00% covered (danger)
0.00%
0 / 1
129.13
 getFirstName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setFirstName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLastName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setLastName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFullName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEmail
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setEmail
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUsername
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPassword
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setPassword
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPlainPassword
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setPlainPassword
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 eraseCredentials
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getForgetPasswordToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setForgetPasswordToken
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSalt
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRoles
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRoles
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isEnabled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setEnabled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCollectivity
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCollectivity
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLastLogin
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setLastLogin
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getServices
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setServices
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCollectivitesReferees
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCollectivitesReferees
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getApiAuthorized
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setApiAuthorized
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isInUserServices
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 getFavoriteDocuments
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setFavoriteDocuments
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 addFavoriteDocument
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 removeFavoriteDocument
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 isDocumentView
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setDocumentView
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getMoreInfos
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setMoreInfos
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEmailNotificationPreference
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setEmailNotificationPreference
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getNotifications
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setNotifications
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSsoKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setSsoKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isNotGeneratesNotifications
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setNotGeneratesNotifications
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 hasModuleTools
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasModuleConformiteTraitement
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasModuleConformiteOrganisation
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasServices
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasModule
57.14% covered (warning)
57.14%
4 / 7
0.00% covered (danger)
0.00%
0 / 1
8.83
1<?php
2
3/**
4 * This file is part of the MADIS - RGPD Management application.
5 *
6 * @copyright Copyright (c) 2018-2019 Soluris - Solutions Numériques Territoriales Innovantes
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22declare(strict_types=1);
23
24namespace App\Domain\User\Model;
25
26use App\Application\Interfaces\CollectivityRelated;
27use App\Application\Traits\Model\HistoryTrait;
28use App\Application\Traits\Model\SoftDeletableTrait;
29use App\Domain\Documentation\Model\Document;
30use App\Domain\Reporting\Model\LoggableSubject;
31use App\Domain\User\Dictionary\UserRoleDictionary;
32use Doctrine\Common\Collections\ArrayCollection;
33use Doctrine\Common\Collections\Collection;
34use Ramsey\Uuid\Uuid;
35use Ramsey\Uuid\UuidInterface;
36use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
37use Symfony\Component\Security\Core\User\UserInterface;
38
39class User implements LoggableSubject, UserInterface, CollectivityRelated, PasswordAuthenticatedUserInterface
40{
41    use SoftDeletableTrait;
42    use HistoryTrait;
43
44    /**
45     * @var UuidInterface
46     */
47    private $id;
48
49    /**
50     * @var string|null
51     */
52    private $firstName;
53
54    /**
55     * @var string|null
56     */
57    private $lastName;
58
59    /**
60     * @var string|null
61     */
62    private $email;
63
64    /**
65     * @var string|null
66     */
67    private $password;
68
69    /**
70     * @var string|null
71     */
72    private $plainPassword;
73
74    /**
75     * @var string|null
76     */
77    private $forgetPasswordToken;
78
79    /**
80     * @var array
81     */
82    private $roles;
83
84    /**
85     * @var bool
86     */
87    private $enabled;
88
89    /**
90     * @var Collectivity
91     */
92    private $collectivity;
93
94    /**
95     * @var Collection|Service[]
96     */
97    private $services;
98
99    /**
100     * @var iterable
101     */
102    private $collectivitesReferees;
103
104    /**
105     * @var \DateTimeImmutable|null
106     */
107    private $lastLogin;
108
109    /**
110     * @var bool
111     */
112    private $apiAuthorized;
113
114    /**
115     * @var Collection|null
116     */
117    private $favoriteDocuments;
118
119    /**
120     * @var bool
121     */
122    private $documentView;
123
124    /**
125     * @var array|null
126     */
127    private $moreInfos;
128
129    private ?EmailNotificationPreference $emailNotificationPreference;
130
131    /**
132     * @var Collection|array|null
133     */
134    private $notifications;
135
136    /**
137     * @var string|null
138     */
139    private $ssoKey;
140
141    private ?bool $notGeneratesNotifications;
142
143    /**
144     * User constructor.
145     *
146     * @throws \Exception
147     */
148    public function __construct()
149    {
150        $this->id                          = Uuid::uuid4();
151        $this->roles                       = [];
152        $this->enabled                     = true;
153        $this->collectivitesReferees       = [];
154        $this->moreInfos                   = [];
155        $this->emailNotificationPreference = new EmailNotificationPreference();
156        $this->notGeneratesNotifications   = false;
157    }
158
159    public function getId(): UuidInterface
160    {
161        return $this->id;
162    }
163
164    public function __toString(): string
165    {
166        if (\is_null($this->getFullName())) {
167            return '';
168        }
169
170        if (\mb_strlen($this->getFullName()) > 150) {
171            return \mb_substr($this->getFullName(), 0, 150) . '...';
172        }
173
174        return $this->getFullName();
175    }
176
177    /**
178     * Checks if this user has access to the object or not.
179     */
180    public function hasAccessTo($object, $checkService = true): bool
181    {
182        $collectivity = null;
183        if ($object instanceof CollectivityRelated) {
184            $collectivity = $object->getCollectivity();
185        } elseif ($object instanceof Collectivity) {
186            $collectivity = $object;
187        } elseif (method_exists(get_class($object), 'getCollectivity')) {
188            $collectivity = $object->getCollectivity();
189        }
190
191        // No collectivity, can be viewed by anyone
192        if (!$collectivity) {
193            return true;
194        }
195
196        // Admins can view everything
197        if (\in_array(UserRoleDictionary::ROLE_ADMIN, $this->getRoles())) {
198            return true;
199        }
200        // Referents can view their collectivities
201        if (\in_array(UserRoleDictionary::ROLE_REFERENT, $this->getRoles()) && (in_array($collectivity, \iterable_to_array($this->getCollectivitesReferees())) || $this->getCollectivity() === $collectivity)) {
202            // Check service if necessary
203            if ($checkService && $collectivity->getIsServicesEnabled() && !$object->isInUserServices($this)) {
204                return false;
205            }
206
207            return true;
208        }
209        // users can view their collectivity
210        if ((\in_array(UserRoleDictionary::ROLE_PREVIEW, $this->getRoles()) || \in_array(UserRoleDictionary::ROLE_USER, $this->getRoles())) && $this->getCollectivity() === $collectivity) {
211            // Check service if necessary
212            if ($checkService && $collectivity->getIsServicesEnabled() && !$object->isInUserServices($this)) {
213                return false;
214            }
215
216            return true;
217        }
218
219        return false;
220    }
221
222    public function getFirstName(): ?string
223    {
224        return $this->firstName;
225    }
226
227    public function setFirstName(?string $firstName): void
228    {
229        $this->firstName = $firstName;
230    }
231
232    public function getLastName(): ?string
233    {
234        return $this->lastName;
235    }
236
237    public function setLastName(?string $lastName): void
238    {
239        $this->lastName = $lastName;
240    }
241
242    public function getFullName(): string
243    {
244        return "{$this->firstName} {$this->lastName}";
245    }
246
247    public function getEmail(): ?string
248    {
249        return $this->email;
250    }
251
252    public function setEmail(?string $email): void
253    {
254        $this->email = $email;
255    }
256
257    public function getUsername(): ?string
258    {
259        return $this->email;
260    }
261
262    public function getPassword(): ?string
263    {
264        return $this->password;
265    }
266
267    public function setPassword(?string $password): void
268    {
269        $this->password = $password;
270    }
271
272    public function getPlainPassword(): ?string
273    {
274        return $this->plainPassword;
275    }
276
277    public function setPlainPassword(?string $plainPassword): void
278    {
279        $this->plainPassword = $plainPassword;
280    }
281
282    public function eraseCredentials(): void
283    {
284        $this->plainPassword = null;
285    }
286
287    public function getForgetPasswordToken(): ?string
288    {
289        return $this->forgetPasswordToken;
290    }
291
292    public function setForgetPasswordToken(?string $forgetPasswordToken): void
293    {
294        $this->forgetPasswordToken = $forgetPasswordToken;
295    }
296
297    public function getSalt()
298    {
299        return null;
300    }
301
302    public function getRoles(): array
303    {
304        return $this->roles;
305    }
306
307    public function setRoles(array $roles): void
308    {
309        $this->roles = $roles;
310    }
311
312    public function isEnabled(): bool
313    {
314        return $this->enabled;
315    }
316
317    public function setEnabled(bool $enabled): void
318    {
319        $this->enabled = $enabled;
320    }
321
322    public function getCollectivity(): ?Collectivity
323    {
324        return $this->collectivity;
325    }
326
327    public function setCollectivity(Collectivity $collectivity): void
328    {
329        $this->collectivity = $collectivity;
330    }
331
332    public function getLastLogin(): ?\DateTimeImmutable
333    {
334        return $this->lastLogin;
335    }
336
337    public function setLastLogin(?\DateTimeImmutable $lastLogin): void
338    {
339        $this->lastLogin = $lastLogin;
340    }
341
342    public function getServices(): ?Collection
343    {
344        return $this->services;
345    }
346
347    public function setServices($services): void
348    {
349        $this->services = $services;
350    }
351
352    public function getCollectivitesReferees(): iterable
353    {
354        return $this->collectivitesReferees;
355    }
356
357    public function setCollectivitesReferees(iterable $collectivitesReferees): void
358    {
359        $this->collectivitesReferees = $collectivitesReferees;
360    }
361
362    public function getApiAuthorized(): ?bool
363    {
364        return $this->apiAuthorized;
365    }
366
367    public function setApiAuthorized(?bool $apiAuthorized): void
368    {
369        $this->apiAuthorized = $apiAuthorized;
370    }
371
372    public function isInUserServices(User $user): bool
373    {
374        if (false == $user->getCollectivity()->getIsServicesEnabled()) {
375            return true;
376        }
377
378        $result = false;
379
380        if ($user->getServices() === $this->getServices()) {
381            $result = true;
382        }
383
384        return $result;
385    }
386
387    public function getFavoriteDocuments(): ?Collection
388    {
389        return $this->favoriteDocuments;
390    }
391
392    public function setFavoriteDocuments(?Collection $favoriteDocuments): User
393    {
394        $this->favoriteDocuments = $favoriteDocuments;
395
396        return $this;
397    }
398
399    public function addFavoriteDocument(Document $doc): User
400    {
401        if (null === $this->favoriteDocuments) {
402            $this->favoriteDocuments = new ArrayCollection();
403        }
404        if (!$this->favoriteDocuments->contains($doc)) {
405            $this->favoriteDocuments->add($doc);
406        }
407
408        return $this;
409    }
410
411    public function removeFavoriteDocument(Document $doc): User
412    {
413        if (null !== $this->favoriteDocuments && !$this->favoriteDocuments->contains($doc)) {
414            $this->favoriteDocuments->removeElement($doc);
415        }
416
417        return $this;
418    }
419
420    public function isDocumentView(): ?bool
421    {
422        return $this->documentView;
423    }
424
425    public function setDocumentView(bool $documentView): void
426    {
427        $this->documentView = $documentView;
428    }
429
430    public function getMoreInfos(): ?array
431    {
432        return $this->moreInfos;
433    }
434
435    public function setMoreInfos(array $moreInfos): void
436    {
437        $this->moreInfos = $moreInfos;
438    }
439
440    public function getEmailNotificationPreference(): ?EmailNotificationPreference
441    {
442        return $this->emailNotificationPreference;
443    }
444
445    public function setEmailNotificationPreference(?EmailNotificationPreference $emailNotificationPreference): void
446    {
447        $this->emailNotificationPreference = $emailNotificationPreference;
448    }
449
450    public function getNotifications(): ?Collection
451    {
452        return $this->notifications;
453    }
454
455    public function setNotifications(?Collection $notifications): void
456    {
457        $this->notifications = $notifications;
458    }
459
460    public function getSsoKey(): ?string
461    {
462        return $this->ssoKey;
463    }
464
465    public function setSsoKey(?string $ssoKey): void
466    {
467        $this->ssoKey = $ssoKey;
468    }
469
470    public function isNotGeneratesNotifications(): ?bool
471    {
472        return $this->notGeneratesNotifications;
473    }
474
475    public function setNotGeneratesNotifications(?bool $notGeneratesNotifications): void
476    {
477        $this->notGeneratesNotifications = $notGeneratesNotifications;
478    }
479
480    public function hasModuleTools(): bool
481    {
482        return $this->hasModule('isHasModuleTools');
483    }
484
485    public function hasModuleConformiteTraitement(): bool
486    {
487        return $this->hasModule('isHasModuleConformiteTraitement');
488    }
489
490    public function hasModuleConformiteOrganisation(): bool
491    {
492        return $this->hasModule('isHasModuleConformiteOrganisation');
493    }
494
495    public function hasServices(): bool
496    {
497        return $this->hasModule('getIsServicesEnabled');
498    }
499
500    private function hasModule($func)
501    {
502        if (in_array(UserRoleDictionary::ROLE_REFERENT, $this->getRoles())) {
503            foreach ($this->getCollectivitesReferees() as $collectivity) {
504                /** @var Collectivity $collectivity */
505                if ($collectivity->{$func}()) {
506                    return true;
507                }
508            }
509        }
510        if (in_array(UserRoleDictionary::ROLE_ADMIN, $this->getRoles())) {
511            return true;
512        }
513
514        return $this->getCollectivity() && $this->getCollectivity()->{$func}();
515    }
516}