Set-up login process

master
Julien Rosset 5 years ago
parent 8a29274e74
commit 3fe0dda209

@ -5,6 +5,7 @@
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="App\" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="App\" />
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="App\Tests\" /> <sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="App\Tests\" />
<excludeFolder url="file://$MODULE_DIR$/var" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" /> <excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/annotations" /> <excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/annotations" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/cache" /> <excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/cache" />

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WebResourcesPaths">
<contentEntries>
<entry url="file://$PROJECT_DIR$">
<entryData>
<resourceRoots>
<path value="file://$PROJECT_DIR$/public" />
</resourceRoots>
</entryData>
</entry>
</contentEntries>
</component>
</project>

@ -20,9 +20,11 @@ security:
secure: true secure: true
guard: guard:
authenticators: authenticators:
- App\Security\LoginFormAuthentificatorAuthenticator - App\Security\LoginFormAuthenticator
logout: logout:
path: app_security_logout path: app_security_logout
target: app_external_index target: app_site_index
access_control: access_control:
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
role_hierarchy:
ROLE_ADMIN: ROLE_USER

@ -1,4 +0,0 @@
framework:
test: true
session:
storage_id: session.storage.mock_file

@ -1,12 +0,0 @@
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
channels: ["!event"]
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug

@ -1,2 +0,0 @@
twig:
strict_variables: true

@ -1,3 +0,0 @@
framework:
validation:
not_compromised_password: false

@ -1,6 +0,0 @@
web_profiler:
toolbar: false
intercept_redirects: false
framework:
profiler: { collect: false }

@ -1,6 +1,6 @@
framework: framework:
default_locale: fr default_locale: en
translator: translator:
default_path: '%kernel.project_dir%/translations' default_path: '%kernel.project_dir%/translations'
fallbacks: fallbacks:
- fr - en

@ -1,7 +1,7 @@
# Redirige l'URL racine vers celle de la langue par défaut # Redirige l'URL racine vers celle de la langue par défaut
index: index:
path: / path: /
controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction
defaults: defaults:
route: 'app_external_index' route: 'app_external_index'
_locale: '%kernel.default_locale%' _locale: '%kernel.default_locale%'

@ -2,14 +2,17 @@
namespace App\Controller; namespace App\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
class ExternalController extends AbstractController { class SiteController extends AbstractController {
/** /**
* @Route("/") * @Route("/")
*
* @IsGranted("ROLE_USER")
*/ */
public function index () { public function index () {
return $this->render('external/index.html.twig'); return $this->render('site/index.html.twig');
} }
} }

@ -10,8 +10,7 @@ use Symfony\Component\Security\Core\User\UserInterface;
/** /**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository") * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*/ */
class User implements UserInterface class User implements UserInterface {
{
/** /**
* @var int The internal ID of user * @var int The internal ID of user
* *
@ -48,14 +47,12 @@ class User implements UserInterface
* @ORM\Column(type="string", length=255) * @ORM\Column(type="string", length=255)
*/ */
private string $name; private string $name;
/** /**
* @var string|null The user first name * @var string|null The user first name
* *
* @ORM\Column(type="string", length=255, nullable=true) * @ORM\Column(type="string", length=255, nullable=true)
*/ */
private ?string $fist_name; private ?string $fist_name;
/** /**
* @var int The user gender * @var int The user gender
* 0 = no gender * 0 = no gender
@ -66,7 +63,6 @@ class User implements UserInterface
* @ORM\Column(type="smallint") * @ORM\Column(type="smallint")
*/ */
private int $gender; private int $gender;
/** /**
* @var string|null The user avatar relative path * @var string|null The user avatar relative path
* *
@ -96,35 +92,30 @@ class User implements UserInterface
* ) * )
*/ */
private ArrayCollection $friends; private ArrayCollection $friends;
/** /**
* @var ArrayCollection The user {@see ConfigNotification configured notifications} * @var ArrayCollection The user {@see ConfigNotification configured notifications}
* *
* @ORM\OneToMany(targetEntity="App\Entity\ConfigNotification", mappedBy="user", orphanRemoval=true) * @ORM\OneToMany(targetEntity="App\Entity\ConfigNotification", mappedBy="user", orphanRemoval=true)
*/ */
private ArrayCollection $configNotifications; private ArrayCollection $configNotifications;
/** /**
* @var ArrayCollection Thue user {@see UserNotification notifications} * @var ArrayCollection Thue user {@see UserNotification notifications}
* *
* @ORM\OneToMany(targetEntity="App\Entity\UserNotification", mappedBy="user", orphanRemoval=true) * @ORM\OneToMany(targetEntity="App\Entity\UserNotification", mappedBy="user", orphanRemoval=true)
*/ */
private ArrayCollection $notifications; private ArrayCollection $notifications;
/** /**
* @var ArrayCollection The user owned {@see Wish wishes} * @var ArrayCollection The user owned {@see Wish wishes}
* *
* @ORM\OneToMany(targetEntity="App\Entity\Wish", mappedBy="owner") * @ORM\OneToMany(targetEntity="App\Entity\Wish", mappedBy="owner")
*/ */
private ArrayCollection $ownedWishes; private ArrayCollection $ownedWishes;
/** /**
* @var ArrayCollection The user {@see Participant participations} * @var ArrayCollection The user {@see Participant participations}
* *
* @ORM\OneToMany(targetEntity="App\Entity\Participant", mappedBy="user", orphanRemoval=true) * @ORM\OneToMany(targetEntity="App\Entity\Participant", mappedBy="user", orphanRemoval=true)
*/ */
private ArrayCollection $participations; private ArrayCollection $participations;
/** /**
* @var ArrayCollection The user {@see Comment comments} * @var ArrayCollection The user {@see Comment comments}
* *
@ -132,13 +123,6 @@ class User implements UserInterface
*/ */
private ArrayCollection $comments; private ArrayCollection $comments;
/**
* @var bool Is the user inactive ?
*
* @ORM\Column(type="boolean")
*/
private $inactive;
public function __construct () { public function __construct () {
$this->friends = new ArrayCollection(); $this->friends = new ArrayCollection();
$this->configNotifications = new ArrayCollection(); $this->configNotifications = new ArrayCollection();
@ -148,18 +132,14 @@ class User implements UserInterface
$this->comments = new ArrayCollection(); $this->comments = new ArrayCollection();
} }
public function getId(): ?int public function getId (): ?int {
{
return $this->id; return $this->id;
} }
public function getEmail(): ?string public function getEmail (): ?string {
{
return $this->email; return $this->email;
} }
public function setEmail (string $email): self {
public function setEmail(string $email): self
{
$this->email = $email; $this->email = $email;
return $this; return $this;
@ -170,25 +150,22 @@ class User implements UserInterface
* *
* @see UserInterface * @see UserInterface
*/ */
public function getUsername(): string public function getUsername (): string {
{ return (string)$this->email;
return (string) $this->email;
} }
/** /**
* @see UserInterface * @see UserInterface
*/ */
public function getRoles(): array public function getRoles (): array {
{
$roles = $this->roles; $roles = $this->roles;
// guarantee every user at least has ROLE_USER
// Every user must have at least the ROLE_USER
$roles[] = 'ROLE_USER'; $roles[] = 'ROLE_USER';
return array_unique($roles); return array_unique($roles);
} }
public function setRoles (array $roles): self {
public function setRoles(array $roles): self
{
$this->roles = $roles; $this->roles = $roles;
return $this; return $this;
@ -197,13 +174,10 @@ class User implements UserInterface
/** /**
* @see UserInterface * @see UserInterface
*/ */
public function getPassword(): string public function getPassword (): string {
{ return (string)$this->password;
return (string) $this->password;
} }
public function setPassword (string $password): self {
public function setPassword(string $password): self
{
$this->password = $password; $this->password = $password;
return $this; return $this;
@ -212,16 +186,13 @@ class User implements UserInterface
/** /**
* @see UserInterface * @see UserInterface
*/ */
public function getSalt() public function getSalt () {
{
// not needed when using the "bcrypt" algorithm in security.yaml // not needed when using the "bcrypt" algorithm in security.yaml
} }
/** /**
* @see UserInterface * @see UserInterface
*/ */
public function eraseCredentials() public function eraseCredentials () {
{
// If you store any temporary, sensitive data on the user, clear it here // If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null; // $this->plainPassword = null;
} }
@ -229,7 +200,6 @@ class User implements UserInterface
public function getName (): ?string { public function getName (): ?string {
return $this->name; return $this->name;
} }
public function setName (string $name): self { public function setName (string $name): self {
$this->name = $name; $this->name = $name;
@ -239,7 +209,6 @@ class User implements UserInterface
public function getFistname (): ?string { public function getFistname (): ?string {
return $this->fist_name; return $this->fist_name;
} }
public function setFistname (?string $fist_name): self { public function setFistname (?string $fist_name): self {
$this->fist_name = $fist_name; $this->fist_name = $fist_name;
@ -249,7 +218,6 @@ class User implements UserInterface
public function getGender (): ?int { public function getGender (): ?int {
return $this->gender; return $this->gender;
} }
public function setGender (int $gender): self { public function setGender (int $gender): self {
$this->gender = $gender; $this->gender = $gender;
@ -259,7 +227,6 @@ class User implements UserInterface
public function getAvatar (): ?string { public function getAvatar (): ?string {
return $this->avatar; return $this->avatar;
} }
public function setAvatar (?string $avatar): self { public function setAvatar (?string $avatar): self {
$this->avatar = $avatar; $this->avatar = $avatar;
@ -269,7 +236,6 @@ class User implements UserInterface
public function getLanguage (): ?Language { public function getLanguage (): ?Language {
return $this->language; return $this->language;
} }
public function setLanguage (?Language $language): self { public function setLanguage (?Language $language): self {
$this->language = $language; $this->language = $language;
@ -282,7 +248,6 @@ class User implements UserInterface
public function getFriends (): Collection { public function getFriends (): Collection {
return $this->friends; return $this->friends;
} }
public function addFriend (self $friend): self { public function addFriend (self $friend): self {
if (!$this->friends->contains($friend)) { if (!$this->friends->contains($friend)) {
$this->friends[] = $friend; $this->friends[] = $friend;
@ -290,7 +255,6 @@ class User implements UserInterface
return $this; return $this;
} }
public function removeFriend (self $friend): self { public function removeFriend (self $friend): self {
if ($this->friends->contains($friend)) { if ($this->friends->contains($friend)) {
$this->friends->removeElement($friend); $this->friends->removeElement($friend);
@ -305,7 +269,6 @@ class User implements UserInterface
public function getConfigNotifications (): Collection { public function getConfigNotifications (): Collection {
return $this->configNotifications; return $this->configNotifications;
} }
public function addConfigNotification (ConfigNotification $configNotification): self { public function addConfigNotification (ConfigNotification $configNotification): self {
if (!$this->configNotifications->contains($configNotification)) { if (!$this->configNotifications->contains($configNotification)) {
$this->configNotifications[] = $configNotification; $this->configNotifications[] = $configNotification;
@ -314,7 +277,6 @@ class User implements UserInterface
return $this; return $this;
} }
public function removeConfigNotification (ConfigNotification $configNotification): self { public function removeConfigNotification (ConfigNotification $configNotification): self {
if ($this->configNotifications->contains($configNotification)) { if ($this->configNotifications->contains($configNotification)) {
$this->configNotifications->removeElement($configNotification); $this->configNotifications->removeElement($configNotification);
@ -333,7 +295,6 @@ class User implements UserInterface
public function getNotifications (): Collection { public function getNotifications (): Collection {
return $this->notifications; return $this->notifications;
} }
public function addNotification (UserNotification $notification): self { public function addNotification (UserNotification $notification): self {
if (!$this->notifications->contains($notification)) { if (!$this->notifications->contains($notification)) {
$this->notifications[] = $notification; $this->notifications[] = $notification;
@ -342,7 +303,6 @@ class User implements UserInterface
return $this; return $this;
} }
public function removeNotification (UserNotification $notification): self { public function removeNotification (UserNotification $notification): self {
if ($this->notifications->contains($notification)) { if ($this->notifications->contains($notification)) {
$this->notifications->removeElement($notification); $this->notifications->removeElement($notification);
@ -358,13 +318,10 @@ class User implements UserInterface
/** /**
* @return Collection|Wish[] * @return Collection|Wish[]
*/ */
public function getOwnedWishes(): Collection public function getOwnedWishes (): Collection {
{
return $this->ownedWishes; return $this->ownedWishes;
} }
public function addOwnedWish (Wish $ownedWish): self {
public function addOwnedWish(Wish $ownedWish): self
{
if (!$this->ownedWishes->contains($ownedWish)) { if (!$this->ownedWishes->contains($ownedWish)) {
$this->ownedWishes[] = $ownedWish; $this->ownedWishes[] = $ownedWish;
$ownedWish->setOwner($this); $ownedWish->setOwner($this);
@ -372,9 +329,7 @@ class User implements UserInterface
return $this; return $this;
} }
public function removeOwnedWish (Wish $ownedWish): self {
public function removeOwnedWish(Wish $ownedWish): self
{
if ($this->ownedWishes->contains($ownedWish)) { if ($this->ownedWishes->contains($ownedWish)) {
$this->ownedWishes->removeElement($ownedWish); $this->ownedWishes->removeElement($ownedWish);
// set the owning side to null (unless already changed) // set the owning side to null (unless already changed)
@ -389,13 +344,10 @@ class User implements UserInterface
/** /**
* @return Collection|Participant[] * @return Collection|Participant[]
*/ */
public function getParticipations(): Collection public function getParticipations (): Collection {
{
return $this->participations; return $this->participations;
} }
public function addParticipation (Participant $participation): self {
public function addParticipation(Participant $participation): self
{
if (!$this->participations->contains($participation)) { if (!$this->participations->contains($participation)) {
$this->participations[] = $participation; $this->participations[] = $participation;
$participation->setUser($this); $participation->setUser($this);
@ -403,9 +355,7 @@ class User implements UserInterface
return $this; return $this;
} }
public function removeParticipation (Participant $participation): self {
public function removeParticipation(Participant $participation): self
{
if ($this->participations->contains($participation)) { if ($this->participations->contains($participation)) {
$this->participations->removeElement($participation); $this->participations->removeElement($participation);
// set the owning side to null (unless already changed) // set the owning side to null (unless already changed)
@ -420,13 +370,10 @@ class User implements UserInterface
/** /**
* @return Collection|Comment[] * @return Collection|Comment[]
*/ */
public function getComments(): Collection public function getComments (): Collection {
{
return $this->comments; return $this->comments;
} }
public function addComment (Comment $comment): self {
public function addComment(Comment $comment): self
{
if (!$this->comments->contains($comment)) { if (!$this->comments->contains($comment)) {
$this->comments[] = $comment; $this->comments[] = $comment;
$comment->setUser($this); $comment->setUser($this);
@ -434,9 +381,7 @@ class User implements UserInterface
return $this; return $this;
} }
public function removeComment (Comment $comment): self {
public function removeComment(Comment $comment): self
{
if ($this->comments->contains($comment)) { if ($this->comments->contains($comment)) {
$this->comments->removeElement($comment); $this->comments->removeElement($comment);
// set the owning side to null (unless already changed) // set the owning side to null (unless already changed)
@ -447,16 +392,4 @@ class User implements UserInterface
return $this; return $this;
} }
public function getInactive(): ?bool
{
return $this->inactive;
}
public function setInactive(bool $inactive): self
{
$this->inactive = $inactive;
return $this;
}
} }

@ -20,13 +20,13 @@ use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticato
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface; use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait; use Symfony\Component\Security\Http\Util\TargetPathTrait;
class LoginFormAuthentificatorAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface { class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface {
use TargetPathTrait; use TargetPathTrait;
private $entityManager; private EntityManagerInterface $entityManager;
private $urlGenerator; private UrlGeneratorInterface $urlGenerator;
private $csrfTokenManager; private CsrfTokenManagerInterface $csrfTokenManager;
private $passwordEncoder; private UserPasswordEncoderInterface $passwordEncoder;
public function __construct ( public function __construct (
EntityManagerInterface $entityManager, EntityManagerInterface $entityManager,
@ -80,6 +80,10 @@ class LoginFormAuthentificatorAuthenticator extends AbstractFormLoginAuthenticat
/** /**
* Used to upgrade (rehash) the user's password automatically over time. * Used to upgrade (rehash) the user's password automatically over time.
*
* @param string[] $credentials Old informations
*
* @return string|null
*/ */
public function getPassword ($credentials): ?string { public function getPassword ($credentials): ?string {
return $credentials['password']; return $credentials['password'];
@ -90,7 +94,7 @@ class LoginFormAuthentificatorAuthenticator extends AbstractFormLoginAuthenticat
return new RedirectResponse($targetPath); return new RedirectResponse($targetPath);
} }
return new RedirectResponse($this->urlGenerator->generate('app_external_index')); return new RedirectResponse($this->urlGenerator->generate('app_site_index'));
} }
protected function getLoginUrl () { protected function getLoginUrl () {

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="file.ext">
<body>
<trans-unit id="Invalid credentials.">
<source>Invalid credentials.</source>
<target>Invalid email or password.</target>
</trans-unit>
</body>
</file>
</xliff>

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="file.ext">
<body>
<trans-unit id="Invalid credentials.">
<source>Invalid credentials.</source>
<target>Email ou mot de passe incorrect</target>
</trans-unit>
</body>
</file>
</xliff>
Loading…
Cancel
Save