<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
use Scheb\TwoFactorBundle\Model\TrustedDeviceInterface;
/**
* @UniqueEntity(fields={"email"})
* @ORM\Entity
* @ORM\Table(name="users")
* @ApiResource(
* iri="http://schema.org/Thing",
* collectionOperations={
* "get"={
* "access_control"="is_granted('ROLE_ADMIN') or is_granted('ROLE_SUPER_ADMIN')",
* "method"="GET",
* "normalization_context"={
* "groups"={
* "output"
* }
* },
* "denormalization_context"={
* "groups"={
* "input"
* }
* }
* },
* "post"={
* "method"="POST",
* "normalization_context"={
* "groups"={
* "output"
* }
* },
* "denormalization_context"={
* "groups"={
* "input"
* }
* }
* }
* },
* itemOperations={
* "get"={
* "access_control"="is_granted('IS_OWNER', object) or is_granted('ROLE_ADMIN') or is_granted('ROLE_SUPER_ADMIN')",
* "method"="GET",
* "normalization_context"={
* "groups"={
* "output"
* }
* },
* "denormalization_context"={
* "groups"={
* "input"
* }
* }
* },
* "put"={
* "access_control"="is_granted('IS_OWNER', object) or is_granted('ROLE_ADMIN') or is_granted('ROLE_SUPER_ADMIN')",
* "method"="PUT",
* "normalization_context"={
* "groups"={
* "output"
* }
* },
* "denormalization_context"={
* "groups"={
* "input"
* }
* }
* }
* },
* attributes={
* "filters"={
* "user.numeric_filter",
* "user.search_filter",
* "user.search_name_filter",
* "user.order_filter",
* "user.date_filter",
* "user.null_filter",
* "user.locked_filter"
* },
* "normalization_context"={
* "groups"={""}
* },
* "denormalization_context"={
* "groups"={""}
* },
* "pagination_items_per_page"=10,
* "pagination_client_items_per_page"=true
* }
* )
*
* The most generic type of item.
*
* @see http://schema.org/Thing Documentation on Schema.org
*/
class User implements UserInterface, PasswordAuthenticatedUserInterface, TwoFactorInterface, TrustedDeviceInterface
{
const ROLE_SUPER_ADMIN = 'ROLE_SUPER_ADMIN';
const ROLE_ADMIN = 'ROLE_ADMIN';
const ROLE_USER = 'ROLE_USER';
const EMAIL_2FA_CODE_VALID_TIME = '-10 minutes';
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
* @Groups({"output"})
*
* @var int|null
*/
protected $id;
/**
* @ORM\Column(type="string")
* @Groups({"output", "input"})
*
* @var string|null
*/
public $email;
/**
* @ORM\Column(type="boolean")
* @Groups({"input", "output"})
*
* @var bool|null
*/
public $enabled;
/**
* @ORM\Column(type="string", nullable=true)
* @var string|null
*/
public $salt;
/**
* @ORM\Column(type="string")
* @var string|null
*/
public $password;
/**
* @Groups({"input"})
*
* @var string|null
*/
public $plainPassword;
/**
* @ORM\Column(type="datetime", nullable=true)
* @Groups({"output"})
*
* @var \DateTimeInterface|null
*
*/
public $lastLogin;
/**
* @ORM\Column(type="string", nullable=true)
*
* @var string|null
*/
public $confirmationToken;
/**
* @ORM\Column(type="datetime", nullable=true)
*
* @var string|null
*/
public $passwordRequestedAt;
/**
* @ORM\Column(type="json")
* @Groups({"input", "output"})
*
* @var array|null
*/
public $roles;
/**
* @ORM\Column(type="datetime", nullable=true)
* @Groups({"output"})
*
* @var \DateTimeInterface|null
*
*/
public $createdAt;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User")
*
* @var User|null
*/
public $createdBy;
/**
* @ORM\Column(type="datetime", nullable=true)
* @Groups({"output"})
*
* @var \DateTimeInterface|null
*
*/
public $updatedAt;
/**
* @ORM\Column(type="datetime", nullable=true)
* @Groups({"output"})
*
* @var \DateTimeInterface|null
*
*/
public $statusUpdatedAt;
/**
* @ORM\Column(type="boolean", nullable=true)
* @Groups({"input", "output"})
*
* @var bool|null
*/
public $locked;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User")
*
* @var User|null
*/
public $updatedBy;
/**
* @ORM\Column(type="string", length=180, nullable=false)
* @Groups({"output", "input"})
*
* @var string|null
*/
public $firstName;
/**
* @ORM\Column(type="string", length=180, nullable=true)
* @Groups({"output", "input"})
*
* @var string|null
*/
public $middleName;
/**
* @ORM\Column(type="string", length=180, nullable=false)
* @Groups({"output", "input"})
*
* @var string|null
*/
public $lastName;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\PhoneNumber")
* @Groups({"output", "input"})
*
* @var PhoneNumber|null
*/
public $homePhoneNumber;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\PhoneNumber")
* @Groups({"output", "input"})
*
* @var PhoneNumber|null
*/
public $workPhoneNumber;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\PhoneNumber")
* @Groups({"output", "input"})
*
* @var PhoneNumber|null
*/
public $mobilePhoneNumber;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
* @Groups({"security_output", "output", "input"})
*
* @var Lookup|null
*/
public $securityQuestion1;
/**
* @ORM\Column(type="string", length=180, nullable=false)
* @Groups({"security_input", "input"})
*
* @var string|null
*/
public $securityAnswer1;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
* @Groups({"security_output", "output", "input"})
*
* @var Lookup|null
*/
public $securityQuestion2;
/**
* @ORM\Column(type="string", length=180, nullable=false)
* @Groups({"security_input", "input"})
*
* @var string|null
*/
public $securityAnswer2;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
* @Groups({"output", "input"})
*
* @var Lookup|null
*/
public $primaryLanguage;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
* @Groups({"output", "input"})
*
* @var Lookup|null
*/
public $suffix;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
* @Groups({"output", "input"})
*
* @var Lookup|null
*/
public $referrerType;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
* @Groups({"output", "input"})
*
* @var Lookup|null
*/
public $prefix;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Lookup")
* @Groups({"output", "input"})
*
* @var Lookup|null
*/
public $reference;
/**
* @ORM\Column(type="integer", nullable=true)
*
* @var int|null
*/
public $attemptsLeft;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Child", mappedBy="createdBy")
* @ORM\JoinColumn(referencedColumnName="id")
*
* @var Collection<Child>
*
* @Assert\NotNull
*/
public $children;
/**
* @ORM\OneToMany(targetEntity=UserGroup::class, mappedBy="user", orphanRemoval=true)
*/
private $userGroups;
public function __construct()
{
$this->children = new ArrayCollection();
$this->userGroups = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function addChild(Child $child): self
{
$this->children[] = $child;
return $this;
}
public function removeChild(Child $child): self
{
$this->children->removeElement($child);
return $this;
}
public function getChildren(): Collection
{
return $this->children;
}
public function setPasswordRequestedAt(?string $passwordRequestedAt): self
{
$this->passwordRequestedAt = $passwordRequestedAt;
return $this;
}
public function setAttemptsLeft(?int $attemptsLeft): self
{
$this->attemptsLeft = $attemptsLeft;
return $this;
}
public function getAttemptsLeft(): ?int
{
return $this->attemptsLeft;
}
/**
* The public representation of the user (e.g. a username, an email address, etc.)
*
* @see UserInterface
*/
public function getUserIdentifier(): string
{
return (string) $this->email;
}
/**
* @deprecated since Symfony 5.3
*/
public function getUsername(): string
{
return (string) $this->email;
}
/**
* @see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
/**
* @see PasswordAuthenticatedUserInterface
*/
public function getPassword(): string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getEmail(): string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function setHomePhoneNumber(?PhoneNumber $homePhoneNumber): self
{
$this->homePhoneNumber = $homePhoneNumber;
return $this;
}
public function getHomePhoneNumber(): ?PhoneNumber
{
return $this->homePhoneNumber;
}
public function setWorkPhoneNumber(?PhoneNumber $workPhoneNumber): self
{
$this->workPhoneNumber = $workPhoneNumber;
return $this;
}
public function getWorkPhoneNumber(): ?PhoneNumber
{
return $this->workPhoneNumber;
}
public function setMobilePhoneNumber(?PhoneNumber $mobilePhoneNumber): self
{
$this->mobilePhoneNumber = $mobilePhoneNumber;
return $this;
}
public function getMobilePhoneNumber(): ?PhoneNumber
{
return $this->mobilePhoneNumber;
}
public function getEnabled(): bool
{
return $this->enabled;
}
public function setEnabled(bool $enabled): self
{
$this->enabled = $enabled;
return $this;
}
public function getConfirmationToken(): ?string
{
return $this->confirmationToken;
}
public function setConfirmationToken(?string $confirmationToken): self
{
$this->confirmationToken = $confirmationToken;
return $this;
}
/**
* Returning a salt is only needed, if you are not using a modern
* hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
*
* @see UserInterface
*/
public function getSalt(): ?string
{
return null;
}
/**
* @see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
/**
* @return Collection|UserGroup[]
*/
public function getUserGroups(): Collection
{
return $this->userGroups;
}
public function addUserGroup(UserGroup $userGroup): self
{
if (!$this->userGroups->contains($userGroup)) {
$this->userGroups[] = $userGroup;
$userGroup->setUser($this);
}
return $this;
}
public function removeUserGroup(UserGroup $userGroup): self
{
if ($this->userGroups->removeElement($userGroup)) {
// set the owning side to null (unless already changed)
if ($userGroup->getUser() === $this) {
$userGroup->setUser(null);
}
}
return $this;
}
/**
* @ORM\Column(type="string", length=180, nullable=true)
* @Groups({"output", "input"})
*
* @var string|null
*/
public $incipientEmail;
public function getIncipientEmail(): ?string
{
return $this->incipientEmail;
}
public function setIncipientEmail(?string $incipientEmail): self
{
$this->incipientEmail = $incipientEmail;
return $this;
}
/**
* @ORM\Column(type="boolean")
*
* @var bool
*/
public $emailAuthEnabled = false;
/**
* @ORM\Column(type="string", length=6, nullable=true)
*
* @var string|null
*/
public $emailAuthCode;
/**
* @ORM\Column(type="datetime", nullable=true)
*
* @var \DateTimeInterface|null
*/
public $emailAuthCodeCreatedAt;
public function isEmailAuthEnabled(): bool
{
return $this->emailAuthEnabled;
}
public function getEmailAuthRecipient(): string
{
return $this->email;
}
public function setEmailAuthCode(?string $authCode): void
{
$this->emailAuthCode = $authCode;
$this->emailAuthCodeCreatedAt = $authCode ? new \DateTime() : null;
}
public function getEmailAuthCode(): string
{
if ($this->emailAuthCode === null) {
return '';
}
if ($this->emailAuthCodeCreatedAt && $this->emailAuthCodeCreatedAt < new \DateTime(self::EMAIL_2FA_CODE_VALID_TIME)) {
return '';
}
return $this->emailAuthCode;
}
public function setEmailAuthEnabled(bool $emailAuthEnabled): self
{
$this->emailAuthEnabled = $emailAuthEnabled;
return $this;
}
public function getEmailAuthEnabled(): bool
{
return $this->emailAuthEnabled;
}
public function isEmailAuthCodeExpired(): bool
{
if ($this->emailAuthCodeCreatedAt === null) {
return true;
}
return $this->emailAuthCodeCreatedAt < new \DateTime(self::EMAIL_2FA_CODE_VALID_TIME);
}
/**
* @ORM\Column(type="string", length=6, nullable=true)
* @var string|null
*/
public $passwordResetCode;
/**
* @ORM\Column(type="datetime", nullable=true)
* @var \DateTimeInterface|null
*/
public $passwordResetCodeCreatedAt;
/**
* @ORM\Column(type="integer")
* @var int
*/
public $trustedTokenVersion = 0;
public function getTrustedTokenVersion(): int
{
return $this->trustedTokenVersion;
}
}