src/Entity/User.php line 109

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Entity;
  4. use ApiPlatform\Core\Annotation\ApiResource;
  5. use Doctrine\Common\Collections\Collection;
  6. use Doctrine\ORM\Mapping as ORM;
  7. use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
  8. use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
  9. use Symfony\Component\Security\Core\User\UserInterface;
  10. use Symfony\Component\Serializer\Annotation\Groups;
  11. use Symfony\Component\Validator\Constraints as Assert;
  12. use Doctrine\Common\Collections\ArrayCollection;
  13. use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
  14. use Scheb\TwoFactorBundle\Model\TrustedDeviceInterface;
  15. /**
  16. * @UniqueEntity(fields={"email"})
  17. * @ORM\Entity
  18. * @ORM\Table(name="users")
  19. * @ApiResource(
  20. * iri="http://schema.org/Thing",
  21. * collectionOperations={
  22. * "get"={
  23. * "access_control"="is_granted('ROLE_ADMIN') or is_granted('ROLE_SUPER_ADMIN')",
  24. * "method"="GET",
  25. * "normalization_context"={
  26. * "groups"={
  27. * "output"
  28. * }
  29. * },
  30. * "denormalization_context"={
  31. * "groups"={
  32. * "input"
  33. * }
  34. * }
  35. * },
  36. * "post"={
  37. * "method"="POST",
  38. * "normalization_context"={
  39. * "groups"={
  40. * "output"
  41. * }
  42. * },
  43. * "denormalization_context"={
  44. * "groups"={
  45. * "input"
  46. * }
  47. * }
  48. * }
  49. * },
  50. * itemOperations={
  51. * "get"={
  52. * "access_control"="is_granted('IS_OWNER', object) or is_granted('ROLE_ADMIN') or is_granted('ROLE_SUPER_ADMIN')",
  53. * "method"="GET",
  54. * "normalization_context"={
  55. * "groups"={
  56. * "output"
  57. * }
  58. * },
  59. * "denormalization_context"={
  60. * "groups"={
  61. * "input"
  62. * }
  63. * }
  64. * },
  65. * "put"={
  66. * "access_control"="is_granted('IS_OWNER', object) or is_granted('ROLE_ADMIN') or is_granted('ROLE_SUPER_ADMIN')",
  67. * "method"="PUT",
  68. * "normalization_context"={
  69. * "groups"={
  70. * "output"
  71. * }
  72. * },
  73. * "denormalization_context"={
  74. * "groups"={
  75. * "input"
  76. * }
  77. * }
  78. * }
  79. * },
  80. * attributes={
  81. * "filters"={
  82. * "user.numeric_filter",
  83. * "user.search_filter",
  84. * "user.search_name_filter",
  85. * "user.order_filter",
  86. * "user.date_filter",
  87. * "user.null_filter",
  88. * "user.locked_filter"
  89. * },
  90. * "normalization_context"={
  91. * "groups"={""}
  92. * },
  93. * "denormalization_context"={
  94. * "groups"={""}
  95. * },
  96. * "pagination_items_per_page"=10,
  97. * "pagination_client_items_per_page"=true
  98. * }
  99. * )
  100. *
  101. * The most generic type of item.
  102. *
  103. * @see http://schema.org/Thing Documentation on Schema.org
  104. */
  105. class User implements UserInterface, PasswordAuthenticatedUserInterface, TwoFactorInterface, TrustedDeviceInterface
  106. {
  107. const ROLE_SUPER_ADMIN = 'ROLE_SUPER_ADMIN';
  108. const ROLE_ADMIN = 'ROLE_ADMIN';
  109. const ROLE_USER = 'ROLE_USER';
  110. const EMAIL_2FA_CODE_VALID_TIME = '-10 minutes';
  111. /**
  112. * @ORM\Id
  113. * @ORM\GeneratedValue(strategy="AUTO")
  114. * @ORM\Column(type="integer")
  115. * @Groups({"output"})
  116. *
  117. * @var int|null
  118. */
  119. protected $id;
  120. /**
  121. * @ORM\Column(type="string")
  122. * @Groups({"output", "input"})
  123. *
  124. * @var string|null
  125. */
  126. public $email;
  127. /**
  128. * @ORM\Column(type="boolean")
  129. * @Groups({"input", "output"})
  130. *
  131. * @var bool|null
  132. */
  133. public $enabled;
  134. /**
  135. * @ORM\Column(type="string", nullable=true)
  136. * @var string|null
  137. */
  138. public $salt;
  139. /**
  140. * @ORM\Column(type="string")
  141. * @var string|null
  142. */
  143. public $password;
  144. /**
  145. * @Groups({"input"})
  146. *
  147. * @var string|null
  148. */
  149. public $plainPassword;
  150. /**
  151. * @ORM\Column(type="datetime", nullable=true)
  152. * @Groups({"output"})
  153. *
  154. * @var \DateTimeInterface|null
  155. *
  156. */
  157. public $lastLogin;
  158. /**
  159. * @ORM\Column(type="string", nullable=true)
  160. *
  161. * @var string|null
  162. */
  163. public $confirmationToken;
  164. /**
  165. * @ORM\Column(type="datetime", nullable=true)
  166. *
  167. * @var string|null
  168. */
  169. public $passwordRequestedAt;
  170. /**
  171. * @ORM\Column(type="json")
  172. * @Groups({"input", "output"})
  173. *
  174. * @var array|null
  175. */
  176. public $roles;
  177. /**
  178. * @ORM\Column(type="datetime", nullable=true)
  179. * @Groups({"output"})
  180. *
  181. * @var \DateTimeInterface|null
  182. *
  183. */
  184. public $createdAt;
  185. /**
  186. * @ORM\ManyToOne(targetEntity="App\Entity\User")
  187. *
  188. * @var User|null
  189. */
  190. public $createdBy;
  191. /**
  192. * @ORM\Column(type="datetime", nullable=true)
  193. * @Groups({"output"})
  194. *
  195. * @var \DateTimeInterface|null
  196. *
  197. */
  198. public $updatedAt;
  199. /**
  200. * @ORM\Column(type="datetime", nullable=true)
  201. * @Groups({"output"})
  202. *
  203. * @var \DateTimeInterface|null
  204. *
  205. */
  206. public $statusUpdatedAt;
  207. /**
  208. * @ORM\Column(type="boolean", nullable=true)
  209. * @Groups({"input", "output"})
  210. *
  211. * @var bool|null
  212. */
  213. public $locked;
  214. /**
  215. * @ORM\ManyToOne(targetEntity="App\Entity\User")
  216. *
  217. * @var User|null
  218. */
  219. public $updatedBy;
  220. /**
  221. * @ORM\Column(type="string", length=180, nullable=false)
  222. * @Groups({"output", "input"})
  223. *
  224. * @var string|null
  225. */
  226. public $firstName;
  227. /**
  228. * @ORM\Column(type="string", length=180, nullable=true)
  229. * @Groups({"output", "input"})
  230. *
  231. * @var string|null
  232. */
  233. public $middleName;
  234. /**
  235. * @ORM\Column(type="string", length=180, nullable=false)
  236. * @Groups({"output", "input"})
  237. *
  238. * @var string|null
  239. */
  240. public $lastName;
  241. /**
  242. * @ORM\ManyToOne(targetEntity="App\Entity\PhoneNumber")
  243. * @Groups({"output", "input"})
  244. *
  245. * @var PhoneNumber|null
  246. */
  247. public $homePhoneNumber;
  248. /**
  249. * @ORM\ManyToOne(targetEntity="App\Entity\PhoneNumber")
  250. * @Groups({"output", "input"})
  251. *
  252. * @var PhoneNumber|null
  253. */
  254. public $workPhoneNumber;
  255. /**
  256. * @ORM\ManyToOne(targetEntity="App\Entity\PhoneNumber")
  257. * @Groups({"output", "input"})
  258. *
  259. * @var PhoneNumber|null
  260. */
  261. public $mobilePhoneNumber;
  262. /**
  263. * @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
  264. * @Groups({"security_output", "output", "input"})
  265. *
  266. * @var Lookup|null
  267. */
  268. public $securityQuestion1;
  269. /**
  270. * @ORM\Column(type="string", length=180, nullable=false)
  271. * @Groups({"security_input", "input"})
  272. *
  273. * @var string|null
  274. */
  275. public $securityAnswer1;
  276. /**
  277. * @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
  278. * @Groups({"security_output", "output", "input"})
  279. *
  280. * @var Lookup|null
  281. */
  282. public $securityQuestion2;
  283. /**
  284. * @ORM\Column(type="string", length=180, nullable=false)
  285. * @Groups({"security_input", "input"})
  286. *
  287. * @var string|null
  288. */
  289. public $securityAnswer2;
  290. /**
  291. * @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
  292. * @Groups({"output", "input"})
  293. *
  294. * @var Lookup|null
  295. */
  296. public $primaryLanguage;
  297. /**
  298. * @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
  299. * @Groups({"output", "input"})
  300. *
  301. * @var Lookup|null
  302. */
  303. public $suffix;
  304. /**
  305. * @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
  306. * @Groups({"output", "input"})
  307. *
  308. * @var Lookup|null
  309. */
  310. public $referrerType;
  311. /**
  312. * @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
  313. * @Groups({"output", "input"})
  314. *
  315. * @var Lookup|null
  316. */
  317. public $prefix;
  318. /**
  319. * @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
  320. * @Groups({"output", "input"})
  321. *
  322. * @var Lookup|null
  323. */
  324. public $reference;
  325. /**
  326. * @ORM\Column(type="integer", nullable=true)
  327. *
  328. * @var int|null
  329. */
  330. public $attemptsLeft;
  331. /**
  332. * @ORM\OneToMany(targetEntity="App\Entity\Child", mappedBy="createdBy")
  333. * @ORM\JoinColumn(referencedColumnName="id")
  334. *
  335. * @var Collection<Child>
  336. *
  337. * @Assert\NotNull
  338. */
  339. public $children;
  340. /**
  341. * @ORM\OneToMany(targetEntity=UserGroup::class, mappedBy="user", orphanRemoval=true)
  342. */
  343. private $userGroups;
  344. public function __construct()
  345. {
  346. $this->children = new ArrayCollection();
  347. $this->userGroups = new ArrayCollection();
  348. }
  349. public function getId(): ?int
  350. {
  351. return $this->id;
  352. }
  353. public function addChild(Child $child): self
  354. {
  355. $this->children[] = $child;
  356. return $this;
  357. }
  358. public function removeChild(Child $child): self
  359. {
  360. $this->children->removeElement($child);
  361. return $this;
  362. }
  363. public function getChildren(): Collection
  364. {
  365. return $this->children;
  366. }
  367. public function setPasswordRequestedAt(?string $passwordRequestedAt): self
  368. {
  369. $this->passwordRequestedAt = $passwordRequestedAt;
  370. return $this;
  371. }
  372. public function setAttemptsLeft(?int $attemptsLeft): self
  373. {
  374. $this->attemptsLeft = $attemptsLeft;
  375. return $this;
  376. }
  377. public function getAttemptsLeft(): ?int
  378. {
  379. return $this->attemptsLeft;
  380. }
  381. /**
  382. * The public representation of the user (e.g. a username, an email address, etc.)
  383. *
  384. * @see UserInterface
  385. */
  386. public function getUserIdentifier(): string
  387. {
  388. return (string) $this->email;
  389. }
  390. /**
  391. * @deprecated since Symfony 5.3
  392. */
  393. public function getUsername(): string
  394. {
  395. return (string) $this->email;
  396. }
  397. /**
  398. * @see UserInterface
  399. */
  400. public function getRoles(): array
  401. {
  402. $roles = $this->roles;
  403. // guarantee every user at least has ROLE_USER
  404. $roles[] = 'ROLE_USER';
  405. return array_unique($roles);
  406. }
  407. public function setRoles(array $roles): self
  408. {
  409. $this->roles = $roles;
  410. return $this;
  411. }
  412. /**
  413. * @see PasswordAuthenticatedUserInterface
  414. */
  415. public function getPassword(): string
  416. {
  417. return $this->password;
  418. }
  419. public function setPassword(string $password): self
  420. {
  421. $this->password = $password;
  422. return $this;
  423. }
  424. public function getEmail(): string
  425. {
  426. return $this->email;
  427. }
  428. public function setEmail(string $email): self
  429. {
  430. $this->email = $email;
  431. return $this;
  432. }
  433. public function setHomePhoneNumber(?PhoneNumber $homePhoneNumber): self
  434. {
  435. $this->homePhoneNumber = $homePhoneNumber;
  436. return $this;
  437. }
  438. public function getHomePhoneNumber(): ?PhoneNumber
  439. {
  440. return $this->homePhoneNumber;
  441. }
  442. public function setWorkPhoneNumber(?PhoneNumber $workPhoneNumber): self
  443. {
  444. $this->workPhoneNumber = $workPhoneNumber;
  445. return $this;
  446. }
  447. public function getWorkPhoneNumber(): ?PhoneNumber
  448. {
  449. return $this->workPhoneNumber;
  450. }
  451. public function setMobilePhoneNumber(?PhoneNumber $mobilePhoneNumber): self
  452. {
  453. $this->mobilePhoneNumber = $mobilePhoneNumber;
  454. return $this;
  455. }
  456. public function getMobilePhoneNumber(): ?PhoneNumber
  457. {
  458. return $this->mobilePhoneNumber;
  459. }
  460. public function getEnabled(): bool
  461. {
  462. return $this->enabled;
  463. }
  464. public function setEnabled(bool $enabled): self
  465. {
  466. $this->enabled = $enabled;
  467. return $this;
  468. }
  469. public function getConfirmationToken(): ?string
  470. {
  471. return $this->confirmationToken;
  472. }
  473. public function setConfirmationToken(?string $confirmationToken): self
  474. {
  475. $this->confirmationToken = $confirmationToken;
  476. return $this;
  477. }
  478. /**
  479. * Returning a salt is only needed, if you are not using a modern
  480. * hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
  481. *
  482. * @see UserInterface
  483. */
  484. public function getSalt(): ?string
  485. {
  486. return null;
  487. }
  488. /**
  489. * @see UserInterface
  490. */
  491. public function eraseCredentials()
  492. {
  493. // If you store any temporary, sensitive data on the user, clear it here
  494. // $this->plainPassword = null;
  495. }
  496. /**
  497. * @return Collection|UserGroup[]
  498. */
  499. public function getUserGroups(): Collection
  500. {
  501. return $this->userGroups;
  502. }
  503. public function addUserGroup(UserGroup $userGroup): self
  504. {
  505. if (!$this->userGroups->contains($userGroup)) {
  506. $this->userGroups[] = $userGroup;
  507. $userGroup->setUser($this);
  508. }
  509. return $this;
  510. }
  511. public function removeUserGroup(UserGroup $userGroup): self
  512. {
  513. if ($this->userGroups->removeElement($userGroup)) {
  514. // set the owning side to null (unless already changed)
  515. if ($userGroup->getUser() === $this) {
  516. $userGroup->setUser(null);
  517. }
  518. }
  519. return $this;
  520. }
  521. /**
  522. * @ORM\Column(type="string", length=180, nullable=true)
  523. * @Groups({"output", "input"})
  524. *
  525. * @var string|null
  526. */
  527. public $incipientEmail;
  528. public function getIncipientEmail(): ?string
  529. {
  530. return $this->incipientEmail;
  531. }
  532. public function setIncipientEmail(?string $incipientEmail): self
  533. {
  534. $this->incipientEmail = $incipientEmail;
  535. return $this;
  536. }
  537. /**
  538. * @ORM\Column(type="boolean")
  539. *
  540. * @var bool
  541. */
  542. public $emailAuthEnabled = false;
  543. /**
  544. * @ORM\Column(type="string", length=6, nullable=true)
  545. *
  546. * @var string|null
  547. */
  548. public $emailAuthCode;
  549. /**
  550. * @ORM\Column(type="datetime", nullable=true)
  551. *
  552. * @var \DateTimeInterface|null
  553. */
  554. public $emailAuthCodeCreatedAt;
  555. public function isEmailAuthEnabled(): bool
  556. {
  557. return $this->emailAuthEnabled;
  558. }
  559. public function getEmailAuthRecipient(): string
  560. {
  561. return $this->email;
  562. }
  563. public function setEmailAuthCode(?string $authCode): void
  564. {
  565. $this->emailAuthCode = $authCode;
  566. $this->emailAuthCodeCreatedAt = $authCode ? new \DateTime() : null;
  567. }
  568. public function getEmailAuthCode(): string
  569. {
  570. if ($this->emailAuthCode === null) {
  571. return '';
  572. }
  573. if ($this->emailAuthCodeCreatedAt && $this->emailAuthCodeCreatedAt < new \DateTime(self::EMAIL_2FA_CODE_VALID_TIME)) {
  574. return '';
  575. }
  576. return $this->emailAuthCode;
  577. }
  578. public function setEmailAuthEnabled(bool $emailAuthEnabled): self
  579. {
  580. $this->emailAuthEnabled = $emailAuthEnabled;
  581. return $this;
  582. }
  583. public function getEmailAuthEnabled(): bool
  584. {
  585. return $this->emailAuthEnabled;
  586. }
  587. public function isEmailAuthCodeExpired(): bool
  588. {
  589. if ($this->emailAuthCodeCreatedAt === null) {
  590. return true;
  591. }
  592. return $this->emailAuthCodeCreatedAt < new \DateTime(self::EMAIL_2FA_CODE_VALID_TIME);
  593. }
  594. /**
  595. * @ORM\Column(type="string", length=6, nullable=true)
  596. * @var string|null
  597. */
  598. public $passwordResetCode;
  599. /**
  600. * @ORM\Column(type="datetime", nullable=true)
  601. * @var \DateTimeInterface|null
  602. */
  603. public $passwordResetCodeCreatedAt;
  604. /**
  605. * @ORM\Column(type="integer")
  606. * @var int
  607. */
  608. public $trustedTokenVersion = 0;
  609. public function getTrustedTokenVersion(): int
  610. {
  611. return $this->trustedTokenVersion;
  612. }
  613. }