From 4bc44971a2e8f48ff8ba6e5a9ecbbcbd6cb5f620 Mon Sep 17 00:00:00 2001 From: dece Date: Sun, 1 Oct 2023 13:27:40 +0200 Subject: [PATCH] Add user entity --- config/packages/security.yaml | 8 +- migrations/Version20231001104805.php | 35 ++++++ src/Entity/User.php | 155 +++++++++++++++++++++++++++ src/Repository/UserRepository.php | 42 ++++++++ 4 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 migrations/Version20231001104805.php create mode 100644 src/Entity/User.php create mode 100644 src/Repository/UserRepository.php diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 367af25..fbfb8ed 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -4,14 +4,18 @@ security: Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider providers: - users_in_memory: { memory: null } + # used to reload user from session & other features (e.g. switch_user) + app_user_provider: + entity: + class: App\Entity\User + property: email firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: lazy: true - provider: users_in_memory + provider: app_user_provider # activate different ways to authenticate # https://symfony.com/doc/current/security.html#the-firewall diff --git a/migrations/Version20231001104805.php b/migrations/Version20231001104805.php new file mode 100644 index 0000000..7ad70a1 --- /dev/null +++ b/migrations/Version20231001104805.php @@ -0,0 +1,35 @@ +addSql('CREATE SEQUENCE "user_id_seq" INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE "user" (id INT NOT NULL, email VARCHAR(180) NOT NULL, roles JSON NOT NULL, password VARCHAR(255) NOT NULL, username VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D649E7927C74 ON "user" (email)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('DROP SEQUENCE "user_id_seq" CASCADE'); + $this->addSql('DROP TABLE "user"'); + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php new file mode 100644 index 0000000..6df7a0e --- /dev/null +++ b/src/Entity/User.php @@ -0,0 +1,155 @@ +releases = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getEmail(): ?string + { + return $this->email; + } + + public function setEmail(string $email): static + { + $this->email = $email; + + return $this; + } + + /** + * A visual identifier that represents this user. + * + * @see UserInterface + */ + public function getUserIdentifier(): 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): static + { + $this->roles = $roles; + + return $this; + } + + /** + * @see PasswordAuthenticatedUserInterface + */ + public function getPassword(): string + { + return $this->password; + } + + public function setPassword(string $password): static + { + $this->password = $password; + + return $this; + } + + /** + * @see UserInterface + */ + public function eraseCredentials(): void + { + // If you store any temporary, sensitive data on the user, clear it here + // $this->plainPassword = null; + } + + public function getUsername(): ?string + { + return $this->username; + } + + public function setUsername(string $username): static + { + $this->username = $username; + + return $this; + } + + /** + * @return Collection + */ + public function getReleases(): Collection + { + return $this->releases; + } + + public function addRelease(Release $release): static + { + if (!$this->releases->contains($release)) { + $this->releases->add($release); + $release->setOwner($this); + } + + return $this; + } + + public function removeRelease(Release $release): static + { + if ($this->releases->removeElement($release)) { + // set the owning side to null (unless already changed) + if ($release->getOwner() === $this) { + $release->setOwner(null); + } + } + + return $this; + } +} diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php new file mode 100644 index 0000000..ff9e1b5 --- /dev/null +++ b/src/Repository/UserRepository.php @@ -0,0 +1,42 @@ + + * + * @implements PasswordUpgraderInterface + * + * @method User|null find($id, $lockMode = null, $lockVersion = null) + * @method User|null findOneBy(array $criteria, array $orderBy = null) + * @method User[] findAll() + * @method User[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + */ +class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, User::class); + } + + /** + * Used to upgrade (rehash) the user's password automatically over time. + */ + public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void + { + if (!$user instanceof User) { + throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $user::class)); + } + + $user->setPassword($newHashedPassword); + $this->getEntityManager()->persist($user); + $this->getEntityManager()->flush(); + } +}