- Ajout de la vue et du fonctionement de l'inscription.

- Ajout de la vue connexion.
This commit is contained in:
2025-01-29 10:24:13 +01:00
parent f2dd1047a1
commit 6f78a8a4a3
12 changed files with 1268 additions and 174 deletions

View File

@ -13,9 +13,11 @@
"symfony/console": "7.0.*", "symfony/console": "7.0.*",
"symfony/dotenv": "7.0.*", "symfony/dotenv": "7.0.*",
"symfony/flex": "^2", "symfony/flex": "^2",
"symfony/form": "7.0.*",
"symfony/framework-bundle": "7.0.*", "symfony/framework-bundle": "7.0.*",
"symfony/http-client": "7.0.*", "symfony/http-client": "7.0.*",
"symfony/runtime": "7.0.*", "symfony/runtime": "7.0.*",
"symfony/security-bundle": "7.0.*",
"symfony/twig-bundle": "7.0.*", "symfony/twig-bundle": "7.0.*",
"symfony/webpack-encore-bundle": "^2.2", "symfony/webpack-encore-bundle": "^2.2",
"symfony/yaml": "7.0.*", "symfony/yaml": "7.0.*",

1122
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -9,4 +9,5 @@ return [
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
]; ];

View File

@ -0,0 +1,48 @@
security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
# 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: app_user_provider
# 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
# Ajout de la gestion de la déconnexion
logout:
path: /logout # Route pour déconnecter l'utilisateur
target: /login # Redirection vers la page de login après déconnexion
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
when@test:
security:
password_hashers:
# By default, password hashers are resource intensive and take time. This is
# important to generate secure password hashes. In tests however, secure hashes
# are not important, waste resources and increase test times. The following
# reduces the work factor to the lowest possible values.
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
algorithm: auto
cost: 4 # Lowest possible value for bcrypt
time_cost: 3 # Lowest possible value for argon
memory_cost: 10 # Lowest possible value for argon

View File

@ -0,0 +1,3 @@
_security_logout:
resource: security.route_loader.logout
type: service

View File

@ -0,0 +1,40 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class LoginController extends AbstractController
{
#[Route('/login', name: 'app_login')]
public function login(AuthenticationUtils $authenticationUtils): Response
{
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
if ($error) {
$this->addFlash('error', 'Les identifiants sont incorrects.');
}
if ($this->getUser()) {
$this->addFlash('success', 'Connexion réussie !');
return $this->redirectToRoute('home');
}
return $this->render('login/index.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
]);
}
#[Route('/logout', name: 'app_logout')]
public function logout(): Response
{
return $this->redirectToRoute('app_login');
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\RegistrationType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Doctrine\ORM\EntityManagerInterface;
class RegistrationController extends AbstractController
{
private $entityManager;
public function __construct(EntityManagerInterface $entityManager) // Injection du service EntityManagerInterface
{
$this->entityManager = $entityManager;
}
#[Route('/registration', name: 'app_registration')]
public function register (Request $request): Response
{
$user = new User();
$form = $this->createForm(RegistrationType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// Utilisation de l'EntityManager injecté
$this->entityManager->persist($user);
$this->entityManager->flush();
$this->addFlash('success', 'Votre compte a été créé avec succès !');
return $this->redirectToRoute('home');
}
return $this->render('registration/index.html.twig', [
'form' => $form->createView(),
]);
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class, [
'label' => 'Email',
'attr' => ['class' => 'form-control']
])
->add('password', PasswordType::class, [
'label' => 'Mot de passe',
'attr' => ['class' => 'form-control']
])
->add('pseudo', TextType::class, [
'label' => 'Pseudo',
'attr' => ['class' => 'form-control']
])
->add('firstname', TextType::class, [
'label' => 'Prénom',
'attr' => ['class' => 'form-control']
])
->add('lastname', TextType::class, [
'label' => 'Nom',
'attr' => ['class' => 'form-control']
])
->add('submit', SubmitType::class, [
'label' => 'S\'inscrire',
'attr' => ['class' => 'btn btn-primary']
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}

View File

@ -109,6 +109,19 @@
"config/routes.yaml" "config/routes.yaml"
] ]
}, },
"symfony/security-bundle": {
"version": "7.0",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.4",
"ref": "2ae08430db28c8eb4476605894296c82a642028f"
},
"files": [
"config/packages/security.yaml",
"config/routes/security.yaml"
]
},
"symfony/twig-bundle": { "symfony/twig-bundle": {
"version": "7.0", "version": "7.0",
"recipe": { "recipe": {

View File

@ -24,15 +24,15 @@
<li <li
class="mb-4 lg:mb-0 lg:pe-2" data-twe-nav-item-ref> class="mb-4 lg:mb-0 lg:pe-2" data-twe-nav-item-ref>
<!-- Dashboard link --> <!-- Dashboard link -->
<a class="text-neutral-500 transition duration-200 hover:text-neutral-700 hover:ease-in-out focus:text-neutral-700 disabled:text-black/30 motion-reduce:transition-none dark:text-neutral-200 dark:hover:text-neutral-300 dark:focus:text-neutral-300 lg:px-2 [&.active]:text-black/90 dark:[&.active]:text-zinc-400" href="#" data-twe-nav-link-ref>Accueil</a> <a class="text-neutral-500 transition duration-200 hover:text-neutral-700 hover:ease-in-out focus:text-neutral-700 disabled:text-black/30 motion-reduce:transition-none dark:text-neutral-200 dark:hover:text-neutral-300 dark:focus:text-neutral-300 lg:px-2 [&.active]:text-black/90 dark:[&.active]:text-zinc-400" href="/" data-twe-nav-link-ref>Accueil</a>
</li> </li>
<!-- Team link --> <!-- Team link -->
<li class="mb-4 lg:mb-0 lg:pe-2" data-twe-nav-item-ref> <li class="mb-4 lg:mb-0 lg:pe-2" data-twe-nav-item-ref>
<a class="text-neutral-500 transition duration-200 hover:text-neutral-700 hover:ease-in-out focus:text-neutral-700 disabled:text-black/30 motion-reduce:transition-none dark:text-neutral-200 dark:hover:text-neutral-300 dark:focus:text-neutral-300 lg:px-2 [&.active]:text-black/90 dark:[&.active]:text-neutral-400" href="#" data-twe-nav-link-ref>Découvrir</a> <a class="text-neutral-500 transition duration-200 hover:text-neutral-700 hover:ease-in-out focus:text-neutral-700 disabled:text-black/30 motion-reduce:transition-none dark:text-neutral-200 dark:hover:text-neutral-300 dark:focus:text-neutral-300 lg:px-2 [&.active]:text-black/90 dark:[&.active]:text-neutral-400" href="/registration" data-twe-nav-link-ref>Inscription</a>
</li> </li>
<!-- Projects link --> <!-- Projects link -->
<li class="mb-4 lg:mb-0 lg:pe-2" data-twe-nav-item-ref> <li class="mb-4 lg:mb-0 lg:pe-2" data-twe-nav-item-ref>
<a class="text-neutral-500 transition duration-200 hover:text-neutral-700 hover:ease-in-out focus:text-neutral-700 disabled:text-black/30 motion-reduce:transition-none dark:text-neutral-200 dark:hover:text-neutral-300 dark:focus:text-neutral-300 lg:px-2 [&.active]:text-black/90 dark:[&.active]:text-neutral-400" href="#" data-twe-nav-link-ref>Mes favoris</a> <a class="text-neutral-500 transition duration-200 hover:text-neutral-700 hover:ease-in-out focus:text-neutral-700 disabled:text-black/30 motion-reduce:transition-none dark:text-neutral-200 dark:hover:text-neutral-300 dark:focus:text-neutral-300 lg:px-2 [&.active]:text-black/90 dark:[&.active]:text-neutral-400" href="/login" data-twe-nav-link-ref>Connexion</a>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -0,0 +1,50 @@
{# templates/login/login.html.twig #}
{% extends 'base.html.twig' %}
{% block title %}Connexion{% endblock %}
{% block body %}
<div class="min-h-screen flex items-center justify-center bg-gray-100">
<div class="max-w-lg w-full p-6 bg-white rounded-lg shadow-md">
<h2 class="text-2xl font-semibold text-center text-gray-700 mb-6">Connexion</h2>
<form action="{{ path('app_login') }}" method="post">
<div class="mb-4">
<label for="username" class="block text-sm font-medium text-gray-700">Email</label>
<div class="mt-1">
<input type="text" id="username" name="_username" value="{{ last_username }}" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required autofocus>
</div>
</div>
<div class="mb-4">
<label for="password" class="block text-sm font-medium text-gray-700">Mot de passe</label>
<div class="mt-1">
<input type="password" id="password" name="_password" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
</div>
</div>
{% if error %}
<div class="text-red-500 text-sm mt-2">
{{ error.messageKey|trans(error.messageData, 'security') }}
</div>
{% endif %}
<div class="mt-6 text-center">
<button type="submit" class="w-full px-4 py-2 bg-indigo-600 text-white font-semibold rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500">
Se connecter
</button>
{% for type, messages in app.flashes %}
<div class="mb-4">
{% for message in messages %}
<div class="text-sm {% if type == 'success' %}text-green-600{% else %}text-red-600{% endif %}">
{{ message }}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</form>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,63 @@
{# templates/registration/register.html.twig #}
{% extends 'base.html.twig' %}
{% block title %}Inscription{% endblock %}
{% block body %}
<div class="min-h-screen flex items-center justify-center bg-gray-100">
<div class="max-w-lg w-full p-6 bg-white rounded-lg shadow-md">
<h2 class="text-2xl font-semibold text-center text-gray-700 mb-6">Créer un compte</h2>
{{ form_start(form) }}
<div class="mb-4">
{{ form_label(form.email, 'Email', {'label_attr': {'class': 'block text-sm font-medium text-gray-700'}}) }}
<div class="mt-1">
{{ form_widget(form.email, {'attr': {'class': 'w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm'}}) }}
</div>
{{ form_errors(form.email) }}
</div>
<div class="mb-4">
{{ form_label(form.password, 'Mot de passe', {'label_attr': {'class': 'block text-sm font-medium text-gray-700'}}) }}
<div class="mt-1">
{{ form_widget(form.password, {'attr': {'class': 'w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm'}}) }}
</div>
{{ form_errors(form.password) }}
</div>
<div class="mb-4">
{{ form_label(form.pseudo, 'Pseudo', {'label_attr': {'class': 'block text-sm font-medium text-gray-700'}}) }}
<div class="mt-1">
{{ form_widget(form.pseudo, {'attr': {'class': 'w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm'}}) }}
</div>
{{ form_errors(form.pseudo) }}
</div>
<div class="mb-4">
{{ form_label(form.firstname, 'Prénom', {'label_attr': {'class': 'block text-sm font-medium text-gray-700'}}) }}
<div class="mt-1">
{{ form_widget(form.firstname, {'attr': {'class': 'w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm'}}) }}
</div>
{{ form_errors(form.firstname) }}
</div>
<div class="mb-4">
{{ form_label(form.lastname, 'Nom', {'label_attr': {'class': 'block text-sm font-medium text-gray-700'}}) }}
<div class="mt-1">
{{ form_widget(form.lastname, {'attr': {'class': 'w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm'}}) }}
</div>
{{ form_errors(form.lastname) }}
</div>
<div class="mt-6 text-center">
{{ form_widget(form.submit, {
'attr': {'class': 'w-full px-4 py-2 bg-indigo-600 text-white font-semibold rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500'}
}) }}
</div>
{{ form_end(form) }}
</div>
</div>
{% endblock %}