Some checks reported warnings
Cadoles/hydra-sql/pipeline/pr-develop This commit is unstable
86 lines
3.4 KiB
PHP
86 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Hydra;
|
|
|
|
use App\Entity\User;
|
|
use App\Hydra\Exception\InvalidChallengeException;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
|
|
|
class HydraService extends AbstractController
|
|
{
|
|
private SessionInterface $session;
|
|
private Client $client;
|
|
private TokenStorageInterface $tokenStorage;
|
|
private string $baseUrl;
|
|
|
|
public function __construct(Client $client, SessionInterface $session, TokenStorageInterface $tokenStorage, string $baseUrl)
|
|
{
|
|
$this->session = $session;
|
|
$this->client = $client;
|
|
$this->tokenStorage = $tokenStorage;
|
|
$this->baseUrl = $baseUrl;
|
|
}
|
|
|
|
public function handleLoginRequest(Request $request): RedirectResponse
|
|
{
|
|
$challenge = $request->query->get('login_challenge');
|
|
// S'il n'y a pas de challenge, on déclenche une bad request
|
|
if (empty($challenge)) {
|
|
throw new InvalidChallengeException();
|
|
}
|
|
// Fetch Hydra login request info
|
|
$res = $this->client->fetchLoginRequestInfo($challenge);
|
|
$loginRequestInfo = $res->toArray();
|
|
if (200 !== $res->getStatusCode()) {
|
|
$this->session->clear();
|
|
throw new BadRequestException();
|
|
}
|
|
// si le challenge est validé par hydra, on le stocke en session pour l'utiliser par la suite et on redirige vers une route interne protégée qui va déclencher l'identification FranceConnect
|
|
$this->session->set('challenge', $loginRequestInfo['challenge']);
|
|
|
|
return new RedirectResponse($this->baseUrl.'/connect/login-accept');
|
|
}
|
|
|
|
public function handleConsentRequest(Request $request): RedirectResponse
|
|
{
|
|
$challenge = $request->query->get('consent_challenge');
|
|
if (!$challenge) {
|
|
throw new BadRequestException("Le challenge n'est pas disponible");
|
|
}
|
|
|
|
$consentRequestInfo = $this->client->fetchConsentRequestInfo($challenge)->toArray();
|
|
$user = $this->getUser();
|
|
if (!$user instanceof User) {
|
|
throw new AccessDeniedException('Utilisateur non autorisé.');
|
|
}
|
|
$consentAcceptResponse = $this->client->acceptConsentRequest($consentRequestInfo['challenge'], [
|
|
'grant_scope' => $consentRequestInfo['requested_scope'],
|
|
'session' => [
|
|
'id_token' => $user->getAttributes(),
|
|
],
|
|
])->toArray();
|
|
|
|
return new RedirectResponse($consentAcceptResponse['redirect_to']);
|
|
}
|
|
|
|
public function handleLogoutRequest(Request $request): RedirectResponse
|
|
{
|
|
$logoutChallenge = $request->get('logout_challenge');
|
|
if (empty($logoutChallenge)) {
|
|
throw new InvalidChallengeException();
|
|
}
|
|
$logoutRequestInfo = $this->client->fetchLogoutRequestInfo($logoutChallenge)->toArray();
|
|
$logoutAcceptRes = $this->client->acceptLogoutRequest($logoutRequestInfo['challenge'])->toArray();
|
|
$this->session->clear();
|
|
$this->tokenStorage->setToken(null);
|
|
|
|
return new RedirectResponse($logoutAcceptRes['redirect_to']);
|
|
}
|
|
}
|