feat(etl): Add ETL authentication and navigation

Add Keycloak authentication for ETL users.
Configure ETL routes and login/logout functionality.
Integrate ETL with Keycloak SSO.
Update vite.config.js to include etl.js.
Create EtlController with home, login, and logout routes.
Implement EtlAuthenticator for email/password login.
Configure security.yaml for ETL firewall and providers.
Add etl.js and etl.scss for ETL frontend.
Add Keycloak client configuration for ETL.
Update PrestaireController to use absolute URL for login.
This commit is contained in:
Serreau Jovann
2026-02-06 11:43:31 +01:00
parent 919bf7038a
commit 42e33a5908
15 changed files with 538 additions and 37 deletions

View File

@@ -3,63 +3,108 @@
namespace App\Controller;
use App\Entity\Account;
use App\Entity\AccountResetPasswordRequest;
use App\Entity\Contrats;
use App\Entity\ContratsPayments;
use App\Entity\Customer;
use App\Entity\CustomerAddress;
use App\Form\RequestPasswordConfirmType;
use App\Form\RequestPasswordRequestType;
use App\Logger\AppLogger;
use App\Entity\Prestaire;
use App\Form\PrestairePasswordType;
use App\Repository\ContratsRepository;
use App\Repository\CustomerAddressRepository;
use App\Repository\CustomerRepository;
use App\Service\Mailer\Mailer;
use App\Service\Pdf\ContratPdfService;
use App\Service\Pdf\PlPdf;
use App\Service\ResetPassword\Event\ResetPasswordConfirmEvent;
use App\Service\ResetPassword\Event\ResetPasswordEvent;
use App\Service\Signature\Client;
use Doctrine\ORM\EntityManagerInterface;
use Google\Service\Directory\UserAddress;
use Symfony\Bundle\SecurityBundle\Security;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
class EtlController extends AbstractController
{
#[Route('/etl', name: 'etl_home')]
public function eltHome(AuthenticationUtils $authenticationUtils): Response
public function eltHome(ContratsRepository $contratsRepository): Response
{
if(!$this->getUser())
$user = $this->getUser();
if (!$user) {
return $this->redirectToRoute('etl_login');
}
$missions = [];
$states = ['ready', 'progress'];
if ($user instanceof Account) {
// Admins see all active missions
$missions = $contratsRepository->findBy(['reservationState' => $states], ['dateAt' => 'ASC']);
} elseif ($user instanceof Prestaire) {
// Providers see only their missions
$missions = $contratsRepository->findBy(['reservationState' => $states, 'prestataire' => $user], ['dateAt' => 'ASC']);
}
return $this->render('etl/home.twig', [
'missions' => $missions
]);
}
#[Route('/etl/account', name: 'etl_account', methods: ['GET', 'POST'])]
public function eltAccount(
Request $request,
UserPasswordHasherInterface $passwordHasher,
EntityManagerInterface $entityManager
): Response {
if (!$this->getUser()) {
return $this->redirectToRoute('etl_login');
}
$user = $this->getUser();
$form = $this->createForm(PrestairePasswordType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$hashedPassword = $passwordHasher->hashPassword(
$user,
$form->get('password')->getData()
);
$user->setPassword($hashedPassword);
$entityManager->flush();
$this->addFlash('success', 'Votre mot de passe a été modifié avec succès.');
return $this->redirectToRoute('etl_account');
}
return $this->render('etl/account.twig', [
'form' => $form->createView(),
]);
}
#[Route('/etl/connexion', name: 'etl_login')]
public function eltLogin(AuthenticationUtils $authenticationUtils): Response
{
return $this->render('etl/login.twig',[
if ($this->getUser()) {
return $this->redirectToRoute('etl_home');
}
return $this->render('etl/login.twig', [
'last_username' => $authenticationUtils->getLastUsername(),
'error' => $authenticationUtils->getLastAuthenticationError()
]);
}
#[Route('/etl/logout', name: 'etl_logout')]
#[Route('/etl/logout', name: 'elt_logout')]
public function eltLogout(): Response
{
return $this->redirectToRoute('etl_home');
// This method can be blank - it will be intercepted by the logout key on your firewall
return $this->redirectToRoute('etl_login');
}
#[Route('/etl/connect/keycloak', name: 'connect_keycloak_etl_start')]
public function connectKeycloakEtlStart(ClientRegistry $clientRegistry): RedirectResponse
{
return $clientRegistry
->getClient('keycloak_etl')
->redirect(['openid', 'profile', 'email']);
}
#[Route('/etl/oauth/sso', name: 'connect_keycloak_etl_check')]
public function connectKeycloakEtlCheck(): Response
{
return new Response('Auth check', 200); // Intercepted by authenticator
}
}