Easy_solution/src/EventSubscriber/LoginSubscriber.php

116 lines
4.3 KiB
PHP

<?php
namespace App\EventSubscriber;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use League\Bundle\OAuth2ServerBundle\Model\AccessToken;
use League\Bundle\OAuth2ServerBundle\Model\Client;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
class LoginSubscriber implements EventSubscriberInterface
{
private EntityManagerInterface $entityManager;
public function __construct(
EntityManagerInterface $entityManager,
private string $clientIdentifier,
private string $easycheckUrl,
private LoggerInterface $logger
)
{
$this->entityManager = $entityManager;
}
public static function getSubscribedEvents()
{
return [
LoginSuccessEvent::class => 'onLoginSuccess',
];
}
public function onLoginSuccess(LoginSuccessEvent $event): void
{
$passportUser = $event->getUser();
// 1. Check if we have a user at all
if (!$passportUser) {
return;
}
// 2. IMPORTANT: Check if this is a real User entity from your DB.
// If it's a Machine/Client login, it will be an instance of
// League\Bundle\OAuth2ServerBundle\Security\User\ClientCredentialsUser
if (!$passportUser instanceof \App\Entity\User) {
// It's a machine (M2M), so we don't track "last connection" or create manual tokens
return;
}
// Now we know it's a real human user
$user = $this->entityManager->getRepository(User::class)->findOneBy([
'email' => $passportUser->getUserIdentifier()
]);
if ($user) {
$user->setLastConnection(new \DateTime('now', new \DateTimeZone('Europe/Paris')));
$easySolution = $this->entityManager->getRepository(Client::class)->findOneBy(['identifier' => $this->clientIdentifier]);
if ($easySolution) {
$accessToken = new AccessToken(
identifier: bin2hex(random_bytes(40)),
expiry: new \DateTimeImmutable('+1 hour', new \DateTimeZone('Europe/Paris')),
client: $easySolution,
userIdentifier: $user->getUserIdentifier(),
scopes: ['email', 'profile', 'openid', 'apps:easySolutions']
);
$this->entityManager->persist($user);
$this->entityManager->persist($accessToken);
$this->entityManager->flush();
}
}
// Vérifier si un paramètre redirect_app est présent dans l'URL
$request = $event->getRequest();
$redirectApp = $request->query->get('redirect_app');
if ($redirectApp) {
$this->logger->info('User logged in with redirect_app parameter', [
'user' => $user?->getUserIdentifier(),
'redirect_app' => $redirectApp
]);
// Mapper le nom de l'application vers son URL de connexion SSO
$appUrls = [
'easycheck' => $this->easycheckUrl . '/sso/login',
// Ajouter d'autres applications ici au fur et à mesure
];
if (isset($appUrls[$redirectApp])) {
$redirectUrl = $appUrls[$redirectApp];
$this->logger->info('Redirecting to application after login', [
'user' => $user?->getUserIdentifier(),
'app' => $redirectApp,
'url' => $redirectUrl
]);
$event->setResponse(new RedirectResponse($redirectUrl));
} else {
$this->logger->warning('Unknown redirect_app parameter, using default target path', [
'redirect_app' => $redirectApp,
'user' => $user?->getUserIdentifier()
]);
}
} else {
// Pas de paramètre redirect_app : laisser Symfony gérer la redirection par défaut
$this->logger->info('Normal login - using default target path', [
'user' => $user?->getUserIdentifier()
]);
}
}
}