login fonctionnel, redirection selon le rôle et début de tableau de bord pour le rôle admin

This commit is contained in:
sermandm 2025-04-13 19:22:46 +02:00
parent cb7f8bb772
commit a79caf705d
16 changed files with 196 additions and 62 deletions

View File

@ -3,7 +3,6 @@
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="App\" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="App\Tests\" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/cache" />

View File

@ -1,3 +1,7 @@
body {
background: url("../image/fond.png") center center / cover no-repeat !important;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}

View File

@ -1,51 +1,50 @@
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\Utilisateur
property: email
firewalls:
main:
lazy: true
provider: app_user_provider
form_login:
login_path: _login
check_path: _login
enable_csrf: true
csrf_token_id: authenticate
logout:
path: _logout
target: _login
# 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\Utilisateur
property: email
firewalls:
main:
lazy: true
provider: app_user_provider
form_login:
login_path: _login
check_path: _login
success_handler: App\Security\CustomAuthenticationSuccessHandler
enable_csrf: true
csrf_token_id: authenticate
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
# 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:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/profile, roles: ROLE_USER }
# 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: ^/secretaire, roles: ROLE_SECRETAIRE }
- { path: ^/chauffagiste, roles: ROLE_CHAUFFAGISTE }
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
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

@ -15,4 +15,17 @@ class CalendrierController extends AbstractController
'controller_name' => 'CalendrierController',
]);
}
#[Route('/calendrier/secretaire', name: 'calendrier_index_secretaire')]
public function indexSecretaire(): Response
{
return $this->render('calendrier/indexSecretaire.html.twig');
}
#[Route('/calendrier/chauffagiste', name: 'calendrier_index_chauffagiste')]
public function indexChauffagiste(): Response
{
return $this->render('calendrier/indexChauffagiste.html.twig');
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class DashboardController extends AbstractController
{
#[Route('/admin/dashboard', name: 'admin_dashboard')]
public function admin(): Response
{
return $this->render('dashboard/admin.html.twig');
}
#[Route('/secretaire/dashboard', name: 'secretaire_dashboard')]
public function secretaire(): Response
{
return $this->render('dashboard/secretaire.html.twig');
}
#[Route('/chauffagiste/dashboard', name: 'chauffagiste_dashboard')]
public function chauffagiste(): Response
{
return $this->render('dashboard/chauffagiste.html.twig');
}
}

View File

@ -17,7 +17,7 @@ final class FaultController extends AbstractController
#[Route(name: 'app_fault_index', methods: ['GET'])]
public function index(FaultRepository $faultRepository): Response
{
return $this->render('fault/index.html.twig', [
return $this->render('fault/admin.html.twig', [
'faults' => $faultRepository->findAll(),
]);
}

View File

@ -17,7 +17,7 @@ final class InterventionController extends AbstractController
#[Route(name: 'app_intervention_index', methods: ['GET'])]
public function index(InterventionRepository $interventionRepository): Response
{
return $this->render('intervention/index.html.twig', [
return $this->render('intervention/admin.html.twig', [
'interventions' => $interventionRepository->findAll(),
]);
}

View File

@ -17,7 +17,7 @@ final class SkillController extends AbstractController
#[Route(name: 'app_skill_index', methods: ['GET'])]
public function index(SkillRepository $skillRepository): Response
{
return $this->render('skill/index.html.twig', [
return $this->render('skill/admin.html.twig', [
'skills' => $skillRepository->findAll(),
]);
}

View File

@ -17,7 +17,7 @@ final class StockController extends AbstractController
#[Route(name: 'app_stock_index', methods: ['GET'])]
public function index(StockRepository $stockRepository): Response
{
return $this->render('stock/index.html.twig', [
return $this->render('stock/admin.html.twig', [
'stocks' => $stockRepository->findAll(),
]);
}

View File

@ -17,7 +17,7 @@ final class UserController extends AbstractController
#[Route(name: 'app_user_index', methods: ['GET'])]
public function index(UserRepository $userRepository): Response
{
return $this->render('user/index.html.twig', [
return $this->render('user/admin.html.twig', [
'users' => $userRepository->findAll(),
]);
}

View File

@ -17,7 +17,7 @@ final class VehicleController extends AbstractController
#[Route(name: 'app_vehicle_index', methods: ['GET'])]
public function index(VehicleRepository $vehicleRepository): Response
{
return $this->render('vehicle/index.html.twig', [
return $this->render('vehicle/admin.html.twig', [
'vehicles' => $vehicleRepository->findAll(),
]);
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
{
private RouterInterface $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token): RedirectResponse
{
$user = $token->getUser();
$roles = $user->getRoles();
return match (true) {
in_array('ROLE_ADMIN', $roles) => new RedirectResponse($this->router->generate('admin_dashboard')),
in_array('ROLE_SECRETAIRE', $roles) => new RedirectResponse($this->router->generate('secretaire_dashboard')),
in_array('ROLE_CHAUFFAGISTE', $roles) => new RedirectResponse($this->router->generate('chauffagiste_dashboard')),
default => new RedirectResponse($this->router->generate('_login')),
};
}
}

View File

@ -2,16 +2,53 @@
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
{% block stylesheets %}
{% endblock %}
{% block javascripts %}
{% block importmap %}{{ importmap('app') }}{% endblock %}
{% endblock %}
<title>{% block title %}Mon App Symfony{% endblock %}</title>
{% block stylesheets %}{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
{% if app.user %}
<div class="user-info">
Connecté en tant que {{ app.user.email }} |
Rôles :
{% for role in app.user.roles %}
{{ role }}{% if not loop.last %}, {% endif %}
{% endfor %}
</div>
<nav>
<ul>
{% if is_granted('ROLE_ADMIN') %}
<li><a href="{{ path('admin_dashboard') }}">Dashboard Admin</a></li>
<li><a href="{{ path('app_user_new') }}">Créer un utilisateur</a></li>
<li><a href="{{ path('app_calendrier') }}">Tous les plannings</a></li>
<li><a href="{{ path('app_stock_index') }}">Gérer les stocks</a></li>
<li><a href="{{ path('app_vehicle_index') }}">Gérer les véhicules</a></li>
{% endif %}
{% if is_granted('ROLE_SECRETAIRE') %}
<li><a href="{{ path('secretaire_dashboard') }}">Dashboard Secrétaire</a></li>
<li><a href="{{ path('user_new') }}">Créer un chauffagiste</a></li>
<li><a href="{{ path('calendrier_index_secretaire') }}">Plannings chauffagistes</a></li>
<li><a href="{{ path('stock_index') }}">Gérer les stocks</a></li>
<li><a href="{{ path('vehicle_index') }}">Gérer les véhicules</a></li>
{% endif %}
{% if is_granted('ROLE_CHAUFFAGISTE') %}
<li><a href="{{ path('chauffagiste_dashboard') }}">Dashboard Chauffagiste</a></li>
<li><a href="{{ path('calendrier_index_chauffagiste') }}">Mon planning</a></li>
<li><a href="{{ path('intervention_index') }}">Mes interventions</a></li>
<li><a href="{{ path('stock_index') }}">Pièces détachées</a></li>
{% endif %}
<li><a href="{{ path('_logout') }}">Déconnexion</a></li>
</ul>
</nav>
{% endif %}
<div class="content">
{% block body %}{% endblock %}
</div>
{% block javascripts %}{% endblock %}
</body>
</html>
</html>

View File

@ -0,0 +1,7 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Bienvenue Admin</h1>
<p>Tu as tous les droits ici !</p>
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Bienvenue chauffagiste</h1>
<p>Vas travailler</p>
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Bienvenue Secretaire</h1>
<p>Fais ce que tu veux</p>
{% endblock %}