Systeme de Login OK, nouvelle migration clean + migrations pour Utilisateurs/Mail:string -> Mail:json

Ajout d'un controlleur et form User pour ajouter un Utilisateurs dans la table avec le password Hash et le role au formet Array
Ajout de l'Authenticator pour verifier le Login
Nouveau Form pour le login, permet le login correctement
Changement des Vu pour Login, permet de POST le password et le mail correctement
Ajout d'un IndexController pour les tests
Changement du Utilisateurs.php (Table) pour mettre le Login correctement en place (Ajout du systele de login symfony, Mot_de_Passe -> Password, Mail -> UserIdentifier)
This commit is contained in:
Joshua 2024-10-25 19:15:26 +02:00
parent 8213037f96
commit fef9b0d56e
26 changed files with 1996 additions and 76 deletions

View File

@ -7,6 +7,7 @@
"php": ">=8.2", "php": ">=8.2",
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*", "ext-iconv": "*",
"amphp/http-client": "4.2.1",
"doctrine/dbal": "^3", "doctrine/dbal": "^3",
"doctrine/doctrine-bundle": "^2.13", "doctrine/doctrine-bundle": "^2.13",
"doctrine/doctrine-migrations-bundle": "^3.3", "doctrine/doctrine-migrations-bundle": "^3.3",

1324
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +1,46 @@
security: security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers: password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers: providers:
users_in_memory: { memory: null } app_user_provider:
entity:
class: App\Entity\Utilisateurs
property: Mail
firewalls: firewalls:
dev: dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/ pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false security: false
main: main:
lazy: true lazy: true
provider: users_in_memory provider: app_user_provider
form_login:
login_path: app_login
check_path: app_login
custom_authenticator: App\Security\LoginAuthenticator
entry_point: App\Security\LoginAuthenticator
logout:
path: logout
target: login
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control: access_control:
# - { path: ^/admin, roles: ROLE_ADMIN } # - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
# - { path: ^/profile, roles: ROLE_USER } - { path: ^/logout, roles: IS_AUTHENTICATED_ANONYMOUSLY }
# - { path: ^/, roles: ROLE_USER }
when@test: #when@test:
security: # security:
password_hashers: # password_hashers:
# By default, password hashers are resource intensive and take time. This is # # By default, password hashers are resource intensive and take time. This is
# important to generate secure password hashes. In tests however, secure hashes # # important to generate secure password hashes. In tests however, secure hashes
# are not important, waste resources and increase test times. The following # # are not important, waste resources and increase test times. The following
# reduces the work factor to the lowest possible values. # # reduces the work factor to the lowest possible values.
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: # Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
algorithm: auto # algorithm: auto
cost: 4 # Lowest possible value for bcrypt # cost: 4 # Lowest possible value for bcrypt
time_cost: 3 # Lowest possible value for argon # time_cost: 3 # Lowest possible value for argon
memory_cost: 10 # Lowest possible value for argon # memory_cost: 10 # Lowest possible value for argon

View File

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace DoctrineMigrations; namespace DoctrineMigrations\Latest;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\AbstractMigration;

View File

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace DoctrineMigrations; namespace DoctrineMigrations\Latest;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\AbstractMigration;
@ -19,7 +19,7 @@ final class Version20241017131858 extends AbstractMigration
public function up(Schema $schema): void public function up(Schema $schema): void
{ {
// this up() migration is auto-generated, please modify it to your needs // this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SEQUENCE statut_tables_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); $this->addSql('CREATE SEQUENCE statut_tables_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE statut_tables (id INT NOT NULL, tabl_id INT DEFAULT NULL, libellé VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); $this->addSql('CREATE TABLE statut_tables (id INT NOT NULL, tabl_id INT DEFAULT NULL, libellé VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_33C8A3754DE1870D ON statut_tables (tabl_id)'); $this->addSql('CREATE INDEX IDX_33C8A3754DE1870D ON statut_tables (tabl_id)');

View File

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace DoctrineMigrations; namespace DoctrineMigrations\Latest;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\AbstractMigration;

View File

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace DoctrineMigrations; namespace DoctrineMigrations\Latest;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\AbstractMigration;

View File

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace DoctrineMigrations; namespace DoctrineMigrations\Latest;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\AbstractMigration;

View File

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace DoctrineMigrations; namespace DoctrineMigrations\Latest;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\AbstractMigration;

View File

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace DoctrineMigrations; namespace DoctrineMigrations\Latest;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\AbstractMigration;

View File

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace DoctrineMigrations; namespace DoctrineMigrations\Latest;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\AbstractMigration;

View File

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace DoctrineMigrations; namespace DoctrineMigrations\Latest;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\AbstractMigration;

View File

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace DoctrineMigrations; namespace DoctrineMigrations\Latest;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\AbstractMigration;

View File

@ -0,0 +1,140 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20241020235112 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SEQUENCE clients_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE commandes_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE details_commande_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE plats_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE reductions_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE reservations_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE statut_commandes_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE statut_tables_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE tables_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE utilisateurs_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE clients (id INT NOT NULL, prenom VARCHAR(255) NOT NULL, nom VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, telephone VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE TABLE clients_tables (clients_id INT NOT NULL, tables_id INT NOT NULL, PRIMARY KEY(clients_id, tables_id))');
$this->addSql('CREATE INDEX IDX_8190D6C6AB014612 ON clients_tables (clients_id)');
$this->addSql('CREATE INDEX IDX_8190D6C685405FD2 ON clients_tables (tables_id)');
$this->addSql('CREATE TABLE commandes (id INT NOT NULL, statut_commande_id INT DEFAULT NULL, date_heure TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, statut BOOLEAN NOT NULL, total DOUBLE PRECISION NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_35D4282CFB435DFD ON commandes (statut_commande_id)');
$this->addSql('CREATE TABLE commandes_clients (commandes_id INT NOT NULL, clients_id INT NOT NULL, PRIMARY KEY(commandes_id, clients_id))');
$this->addSql('CREATE INDEX IDX_C665A6248BF5C2E6 ON commandes_clients (commandes_id)');
$this->addSql('CREATE INDEX IDX_C665A624AB014612 ON commandes_clients (clients_id)');
$this->addSql('CREATE TABLE details_commande (id INT NOT NULL, commande_id INT DEFAULT NULL, quantite INT NOT NULL, prix_unitaire DOUBLE PRECISION NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_4BCD5F682EA2E54 ON details_commande (commande_id)');
$this->addSql('CREATE TABLE plats (id INT NOT NULL, reduction_id INT DEFAULT NULL, nom VARCHAR(255) NOT NULL, description VARCHAR(255) NOT NULL, prix DOUBLE PRECISION NOT NULL, categorie VARCHAR(255) NOT NULL, statut BOOLEAN NOT NULL, nb_de_commande INT NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_854A620AC03CB092 ON plats (reduction_id)');
$this->addSql('CREATE TABLE plats_commandes (plats_id INT NOT NULL, commandes_id INT NOT NULL, PRIMARY KEY(plats_id, commandes_id))');
$this->addSql('CREATE INDEX IDX_7F8CABAAAA14E1C8 ON plats_commandes (plats_id)');
$this->addSql('CREATE INDEX IDX_7F8CABAA8BF5C2E6 ON plats_commandes (commandes_id)');
$this->addSql('CREATE TABLE reductions (id INT NOT NULL, description VARCHAR(255) NOT NULL, prix DOUBLE PRECISION NOT NULL, pourcentage INT NOT NULL, montant_fixe VARCHAR(255) NOT NULL, date_debut TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, date_fin TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE TABLE reservations (id INT NOT NULL, tabl_id INT DEFAULT NULL, date_heure TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, nb_de_prsn INT NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_4DA2394DE1870D ON reservations (tabl_id)');
$this->addSql('CREATE TABLE statut_commandes (id INT NOT NULL, libelle VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE TABLE statut_tables (id INT NOT NULL, tabl_id INT DEFAULT NULL, libellé VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_33C8A3754DE1870D ON statut_tables (tabl_id)');
$this->addSql('CREATE TABLE tables (id INT NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE TABLE utilisateurs (id INT NOT NULL, nom VARCHAR(255) NOT NULL, prenom VARCHAR(255) NOT NULL, mail VARCHAR(255) NOT NULL, mot_de_passe VARCHAR(255) NOT NULL, role VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE TABLE utilisateurs_reservations (utilisateurs_id INT NOT NULL, reservations_id INT NOT NULL, PRIMARY KEY(utilisateurs_id, reservations_id))');
$this->addSql('CREATE INDEX IDX_995A78E71E969C5 ON utilisateurs_reservations (utilisateurs_id)');
$this->addSql('CREATE INDEX IDX_995A78E7D9A7F869 ON utilisateurs_reservations (reservations_id)');
$this->addSql('CREATE TABLE utilisateurs_tables (utilisateurs_id INT NOT NULL, tables_id INT NOT NULL, PRIMARY KEY(utilisateurs_id, tables_id))');
$this->addSql('CREATE INDEX IDX_A9A665291E969C5 ON utilisateurs_tables (utilisateurs_id)');
$this->addSql('CREATE INDEX IDX_A9A6652985405FD2 ON utilisateurs_tables (tables_id)');
$this->addSql('CREATE TABLE messenger_messages (id BIGSERIAL NOT NULL, body TEXT NOT NULL, headers TEXT NOT NULL, queue_name VARCHAR(190) NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, available_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, delivered_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_75EA56E0FB7336F0 ON messenger_messages (queue_name)');
$this->addSql('CREATE INDEX IDX_75EA56E0E3BD61CE ON messenger_messages (available_at)');
$this->addSql('CREATE INDEX IDX_75EA56E016BA31DB ON messenger_messages (delivered_at)');
$this->addSql('COMMENT ON COLUMN messenger_messages.created_at IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('COMMENT ON COLUMN messenger_messages.available_at IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('COMMENT ON COLUMN messenger_messages.delivered_at IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('CREATE OR REPLACE FUNCTION notify_messenger_messages() RETURNS TRIGGER AS $$
BEGIN
PERFORM pg_notify(\'messenger_messages\', NEW.queue_name::text);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;');
$this->addSql('DROP TRIGGER IF EXISTS notify_trigger ON messenger_messages;');
$this->addSql('CREATE TRIGGER notify_trigger AFTER INSERT OR UPDATE ON messenger_messages FOR EACH ROW EXECUTE PROCEDURE notify_messenger_messages();');
$this->addSql('ALTER TABLE clients_tables ADD CONSTRAINT FK_8190D6C6AB014612 FOREIGN KEY (clients_id) REFERENCES clients (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE clients_tables ADD CONSTRAINT FK_8190D6C685405FD2 FOREIGN KEY (tables_id) REFERENCES tables (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE commandes ADD CONSTRAINT FK_35D4282CFB435DFD FOREIGN KEY (statut_commande_id) REFERENCES statut_commandes (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE commandes_clients ADD CONSTRAINT FK_C665A6248BF5C2E6 FOREIGN KEY (commandes_id) REFERENCES commandes (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE commandes_clients ADD CONSTRAINT FK_C665A624AB014612 FOREIGN KEY (clients_id) REFERENCES clients (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE details_commande ADD CONSTRAINT FK_4BCD5F682EA2E54 FOREIGN KEY (commande_id) REFERENCES commandes (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE plats ADD CONSTRAINT FK_854A620AC03CB092 FOREIGN KEY (reduction_id) REFERENCES reductions (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE plats_commandes ADD CONSTRAINT FK_7F8CABAAAA14E1C8 FOREIGN KEY (plats_id) REFERENCES plats (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE plats_commandes ADD CONSTRAINT FK_7F8CABAA8BF5C2E6 FOREIGN KEY (commandes_id) REFERENCES commandes (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE reservations ADD CONSTRAINT FK_4DA2394DE1870D FOREIGN KEY (tabl_id) REFERENCES tables (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE statut_tables ADD CONSTRAINT FK_33C8A3754DE1870D FOREIGN KEY (tabl_id) REFERENCES tables (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE utilisateurs_reservations ADD CONSTRAINT FK_995A78E71E969C5 FOREIGN KEY (utilisateurs_id) REFERENCES utilisateurs (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE utilisateurs_reservations ADD CONSTRAINT FK_995A78E7D9A7F869 FOREIGN KEY (reservations_id) REFERENCES reservations (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE utilisateurs_tables ADD CONSTRAINT FK_A9A665291E969C5 FOREIGN KEY (utilisateurs_id) REFERENCES utilisateurs (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE utilisateurs_tables ADD CONSTRAINT FK_A9A6652985405FD2 FOREIGN KEY (tables_id) REFERENCES tables (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP SEQUENCE clients_id_seq CASCADE');
$this->addSql('DROP SEQUENCE commandes_id_seq CASCADE');
$this->addSql('DROP SEQUENCE details_commande_id_seq CASCADE');
$this->addSql('DROP SEQUENCE plats_id_seq CASCADE');
$this->addSql('DROP SEQUENCE reductions_id_seq CASCADE');
$this->addSql('DROP SEQUENCE reservations_id_seq CASCADE');
$this->addSql('DROP SEQUENCE statut_commandes_id_seq CASCADE');
$this->addSql('DROP SEQUENCE statut_tables_id_seq CASCADE');
$this->addSql('DROP SEQUENCE tables_id_seq CASCADE');
$this->addSql('DROP SEQUENCE utilisateurs_id_seq CASCADE');
$this->addSql('ALTER TABLE clients_tables DROP CONSTRAINT FK_8190D6C6AB014612');
$this->addSql('ALTER TABLE clients_tables DROP CONSTRAINT FK_8190D6C685405FD2');
$this->addSql('ALTER TABLE commandes DROP CONSTRAINT FK_35D4282CFB435DFD');
$this->addSql('ALTER TABLE commandes_clients DROP CONSTRAINT FK_C665A6248BF5C2E6');
$this->addSql('ALTER TABLE commandes_clients DROP CONSTRAINT FK_C665A624AB014612');
$this->addSql('ALTER TABLE details_commande DROP CONSTRAINT FK_4BCD5F682EA2E54');
$this->addSql('ALTER TABLE plats DROP CONSTRAINT FK_854A620AC03CB092');
$this->addSql('ALTER TABLE plats_commandes DROP CONSTRAINT FK_7F8CABAAAA14E1C8');
$this->addSql('ALTER TABLE plats_commandes DROP CONSTRAINT FK_7F8CABAA8BF5C2E6');
$this->addSql('ALTER TABLE reservations DROP CONSTRAINT FK_4DA2394DE1870D');
$this->addSql('ALTER TABLE statut_tables DROP CONSTRAINT FK_33C8A3754DE1870D');
$this->addSql('ALTER TABLE utilisateurs_reservations DROP CONSTRAINT FK_995A78E71E969C5');
$this->addSql('ALTER TABLE utilisateurs_reservations DROP CONSTRAINT FK_995A78E7D9A7F869');
$this->addSql('ALTER TABLE utilisateurs_tables DROP CONSTRAINT FK_A9A665291E969C5');
$this->addSql('ALTER TABLE utilisateurs_tables DROP CONSTRAINT FK_A9A6652985405FD2');
$this->addSql('DROP TABLE clients');
$this->addSql('DROP TABLE clients_tables');
$this->addSql('DROP TABLE commandes');
$this->addSql('DROP TABLE commandes_clients');
$this->addSql('DROP TABLE details_commande');
$this->addSql('DROP TABLE plats');
$this->addSql('DROP TABLE plats_commandes');
$this->addSql('DROP TABLE reductions');
$this->addSql('DROP TABLE reservations');
$this->addSql('DROP TABLE statut_commandes');
$this->addSql('DROP TABLE statut_tables');
$this->addSql('DROP TABLE tables');
$this->addSql('DROP TABLE utilisateurs');
$this->addSql('DROP TABLE utilisateurs_reservations');
$this->addSql('DROP TABLE utilisateurs_tables');
$this->addSql('DROP TABLE messenger_messages');
}
}

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20241024193330 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE utilisateurs ALTER role TYPE JSON USING role::json');
$this->addSql('COMMENT ON COLUMN utilisateurs.role IS NULL');
}
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('ALTER TABLE utilisateurs ALTER role TYPE TEXT');
$this->addSql('COMMENT ON COLUMN utilisateurs.role IS \'(DC2Type:array)\'');
}
}

View File

@ -1 +1,18 @@
<?php <?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class IndexController extends AbstractController
{
#[Route('/index', name: 'app_index')]
public function index(): Response
{
return $this->render('index/index.html.twig', [
'controller_name' => 'IndexController',
]);
}
}

View File

@ -2,22 +2,34 @@
namespace App\Controller; namespace App\Controller;
use App\Form\LoginFormType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class LoginController extends AbstractController class LoginController extends AbstractController
{ {
#[Route('/login', name: 'app_login')] #[Route('/login', name: 'app_login')]
public function index(Request $request): Response public function index(AuthenticationUtils $authenticationUtils): Response
{ {
$form = $this->createForm(LoginFormType::class); // if ($this->getUser()) {
$form->handleRequest($request); // return $this->redirectToRoute('index/index.html.twig');
// }
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('login/index.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
return $this->render('login/login.html.twig',[
'form' => $form->createView(),
]);
} }
#[Route(path: '/logout', name: 'app_logout')]
public function logout(): void
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
} }

View File

@ -0,0 +1,52 @@
<?php
namespace App\Controller;
use App\Entity\Utilisateurs;
use App\Form\AddUserFormType;
use App\Security\LoginAuthenticator;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class UserController extends AbstractController
{
#[Route('/user', name: 'app_user')]
public function index(): Response
{
return $this->render('user/index.html.twig', [
'controller_name' => 'UserController',
]);
}
#[Route('/user/add', name: 'add_user')]
public function register(Request $request, UserPasswordHasherInterface $userPasswordHasher, Security $security, EntityManagerInterface $entityManager): Response
{
$user = new Utilisateurs();
$form = $this->createForm(AddUserFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var string $plainPassword */
$plainPassword = $form->get('Password')->getData();
// encode the plain password
$user->setPassword($userPasswordHasher->hashPassword($user, $plainPassword));
$entityManager->persist($user);
$entityManager->flush();
// do anything else you need here, like send an email
return $security->login($user, LoginAuthenticator::class, 'main');
}
return $this->render('user/user.html.twig', [
'registrationForm' => $form,
]);
}
}

View File

@ -6,12 +6,14 @@ use App\Repository\UtilisateursRepository;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
#[ORM\Entity(repositoryClass: UtilisateursRepository::class)] #[ORM\Entity(repositoryClass: UtilisateursRepository::class)]
class Utilisateurs class Utilisateurs implements UserInterface, PasswordAuthenticatedUserInterface
{ {
#[ORM\Id] #[ORM\Id]
#[ORM\GeneratedValue] #[ORM\GeneratedValue(strategy: 'SEQUENCE')]
#[ORM\Column] #[ORM\Column]
private ?int $id = null; private ?int $id = null;
@ -21,14 +23,14 @@ class Utilisateurs
#[ORM\Column(length: 255)] #[ORM\Column(length: 255)]
private ?string $Prenom = null; private ?string $Prenom = null;
#[ORM\Column(length: 255)] #[ORM\Column(length: 255, unique: true)]
private ?string $Mail = null; private ?string $Mail = null;
#[ORM\Column(length: 255)] #[ORM\Column(length: 255)]
private ?string $MotDePasse = null; private ?string $MotDePasse = null;
#[ORM\Column(length: 255)] #[ORM\Column(type: 'json', length: 255)]
private ?string $Role = null; private array $Role = [];
/** /**
* @var Collection<int, Reservations> * @var Collection<int, Reservations>
@ -77,42 +79,47 @@ class Utilisateurs
return $this; return $this;
} }
public function getMail(): ?string public function getUserIdentifier(): string
{ {
return $this->Mail; return $this->Mail;
} }
public function setMail(string $Mail): static public function setUserIdentifier(string $userIdentifier): self
{ {
$this->Mail = $Mail; $this->Mail = $userIdentifier;
return $this; return $this;
} }
public function getMotDePasse(): ?string public function getPassword(): ?string
{ {
return $this->MotDePasse; return $this->MotDePasse;
} }
public function setMotDePasse(string $MotDePasse): static public function setPassword(string $MotDePasse): static
{ {
$this->MotDePasse = $MotDePasse; $this->MotDePasse = $MotDePasse;
return $this; return $this;
} }
public function getRole(): ?string public function getRoles(): array
{ {
return $this->Role; return $this->Role;
} }
public function setRole(string $Role): static public function setRoles(array $Role): self
{ {
$this->Role = $Role; $this->Role = $Role;
return $this; return $this;
} }
public function eraseCredentials(): void
{
// Méthode pour effacer les données sensibles (ex : plaintext password)
}
/** /**
* @return Collection<int, Reservations> * @return Collection<int, Reservations>
*/ */

View File

@ -0,0 +1,69 @@
<?php
namespace App\Form;
use App\Entity\Utilisateurs;
use App\Entity\Tables;
use App\Entity\Clients;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
class AddUserFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('UserIdentifier')
->add('Password', PasswordType::class, [
// instead of being set onto the object directly,
// this is read and encoded in the controller
'mapped' => false,
'attr' => ['autocomplete' => 'new-password'],
'constraints' => [
new NotBlank([
'message' => 'Please enter a password',
]),
new Length([
'min' => 6,
'minMessage' => 'Your password should be at least {{ limit }} characters',
// max length allowed by Symfony for security reasons
'max' => 4096,
]),
],
])
->add('Nom')
->add('Prenom')
->add('Roles', TextType::class)
->add('Submit', SubmitType::class);
// Convertir le champ role en tableau
$builder->get('Roles')->addModelTransformer(new CallbackTransformer(
function ($rolesAsArray) {
return implode(', ', $rolesAsArray); // Convertit l'array en string
},
function ($rolesAsString) {
return array_map('trim', explode(',', $rolesAsString)); // Convertit la string en array
}
));
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Utilisateurs::class,
]);
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\SecurityRequestAttributes;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class LoginAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
public function __construct(private UrlGeneratorInterface $urlGenerator)
{
}
public function authenticate(Request $request): Passport
{
$mail = $request->getPayload()->getString('UserIdentifier');
$request->getSession()->set(SecurityRequestAttributes::LAST_USERNAME, $mail);
return new Passport(
new UserBadge($mail),
new PasswordCredentials($request->getPayload()->getString('Password')),
[
new CsrfTokenBadge('authenticate', $request->getPayload()->getString('_csrf_token')),
new RememberMeBadge(),
]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
return new RedirectResponse($targetPath);
}
// For example:
return new RedirectResponse($this->urlGenerator->generate('app_index'));
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}

View File

@ -0,0 +1,20 @@
{% extends 'base.html.twig' %}
{% block title %}Hello IndexController!{% endblock %}
{% block body %}
<style>
.example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
.example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>
<div class="example-wrapper">
<h1>Hello {{ controller_name }}! ✅</h1>
This friendly message is coming from:
<ul>
<li>Your controller at <code>D:/Devellopement/FestinHegre/src/Controller/IndexController.php</code></li>
<li>Your template at <code>D:/Devellopement/FestinHegre/templates/index/index.html.twig</code></li>
</ul>
</div>
{% endblock %}

View File

@ -0,0 +1,143 @@
{% extends 'base.html.twig' %}
{% block stylesheets %}
<link rel="stylesheet" href="../../../assets/styles/login.css">
{% endblock %}
{% block title %}Login{% endblock %}
{% block body %}
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
{% if app.user %}
<div class="mb-3">
You are logged in as {{ app.user.userIdentifier }}, <a href="{{ path('app_logout') }}">Logout</a>
</div>
{% endif %}
<style>
html {
background-image: url("asset/image/BackgroundLogin.jpg"); background-repeat: no-repeat; background-size: cover;
height: 100%;
width: 100%;
}
body {
height: 100%;
width: 100%;
}
.Login {
width: 100%;
height: 100%;
}
.Circle {
background: #db5559;
width: 41%;
height: 80%;
margin: 0 auto;
border-style: solid;
border-radius: 50%;
border-color: white;
border-width: 5px;
}
.Form {
background: #791c1c;
height: 40%;
width: 55%;
margin: auto;
border-style: solid;
border-radius: 50px;
border-color: white;
border-width: 2px;
text-align: center;
font-family: "Qwitcher Grypen", cursive;
font-size: 40px;
font-style: italic;
color: white;
padding-bottom: 0;
}
.Logo {
display: flex;
margin: auto;
margin-top: 8%;
}
.Title1 {
margin: 0;
padding: 0;
}
.Title2 {
display: grid;
place-items: center;
height: 7vh;
color: black;
font-family: "Qwitcher Grypen", cursive;
font-size: 40px;
margin: 0;
}
.form-group{
display: grid;
place-items: center;
height: 7vh;
align-items: center;
text-align: center;
/*margin-bottom: 10px;*/
}
.form-control{
background-color: #f19595;
margin-left: 10px;
border-radius: 5px;
}
.btn{
background-color: #279b63;
border-radius: 6px;
height: 30px;
}
</style>
<div class="Login">
<div class="Circle">
<img src="asset/image/LogoHegre.png" class="Logo">
<form method="post">
{% if error %}
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="UserIdentifier">Email:</label>
<input type="text" id="UserIdentifier" name="UserIdentifier" value="{{ last_username }}" required autofocus>
<label for="Password">Password:</label>
<input type="password" id="Password" name="Password" required>
<input type="hidden" name="_csrf_token"
value="{{ csrf_token('authenticate') }}"
>
<div class="checkbox mb-3">
<label>
<input type="checkbox" name="_remember_me"> Remember me
</label>
</div>
<button class="btn btn-lg btn-primary" type="submit">
Sign in
</button>
<h1 class="Title2">Volaille en fête, Saveurs parfaites !</h1>
</form>
</div>
</div>
{% endblock %}

View File

@ -100,22 +100,24 @@
<div class="Login"> <div class="Login">
<div class="Circle"> <div class="Circle">
<img src="asset/image/LogoHegre.png" class="Logo"> <img src="asset/image/LogoHegre.png" class="Logo">
<div class="Form"> <form action="{{ path('login') }}" method="post">
{{ form_start(form) }} <div class="Form">
<h1 class="Title1">Bienvenue !</h1> {{ form_start(form) }}
<div class="form-group"> <h1 class="Title1">Bienvenue !</h1>
{{ form_label(form.email) }} <div class="form-group">
{{ form_widget(form.email, {'attr': {'class': 'form-control'}}) }} {{ form_label(form.email) }}
</div> {{ form_widget(form.email, {'attr': {'class': 'form-control'}}) }}
<div class="form-group"> </div>
{{ form_label(form.password) }} <div class="form-group">
{{ form_widget(form.password, {'attr': {'class': 'form-control'}}) }} {{ form_label(form.password) }}
</div> {{ form_widget(form.password, {'attr': {'class': 'form-control'}}) }}
<div class="form-group"> </div>
{{ form_widget(form.confirm, {'attr': {'class': 'btn btn-primary'}}) }} <div class="form-group">
</div> {{ form_widget(form.confirm, {'attr': {'class': 'btn btn-primary'}}) }}
{{ form_end(form) }} </div>
</div> {{ form_end(form) }}
</div>
</form>
<h1 class="Title2">Volaille en fête, Saveurs parfaites !</h1> <h1 class="Title2">Volaille en fête, Saveurs parfaites !</h1>
</div> </div>
</div> </div>

View File

@ -0,0 +1,20 @@
{% extends 'base.html.twig' %}
{% block title %}Hello UserController!{% endblock %}
{% block body %}
<style>
.example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
.example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>
<div class="example-wrapper">
<h1>Hello {{ controller_name }}! ✅</h1>
This friendly message is coming from:
<ul>
<li>Your controller at <code>D:/Devellopement/FestinHegre/src/Controller/UserController.php</code></li>
<li>Your template at <code>D:/Devellopement/FestinHegre/templates/user/index.html.twig</code></li>
</ul>
</div>
{% endblock %}

View File

@ -0,0 +1,21 @@
{% extends 'base.html.twig' %}
{% block stylesheets %}
{% endblock %}
{% block title %}AddUser{% endblock %}
{% block body %}
<h1>Register</h1>
{{ form_errors(registrationForm) }}
{{ form_start(registrationForm) }}
{{ form_row(registrationForm.UserIdentifier) }}
{{ form_row(registrationForm.Password, {
label: 'Password'
}) }}
{{ form_end(registrationForm) }}
{% endblock %}