2022-12-09 17:31:07 +01:00
< ? php
namespace App\Hydra ;
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 ;
class HydraService extends AbstractController
{
public SessionInterface $session ;
public Client $client ;
public TokenStorageInterface $tokenStorage ;
2023-01-06 14:02:20 +01:00
public string $baseUrl ;
2022-12-09 17:31:07 +01:00
2023-01-06 14:02:20 +01:00
public function __construct ( Client $client , SessionInterface $session , TokenStorageInterface $tokenStorage , string $baseUrl )
2022-12-09 17:31:07 +01:00
{
$this -> session = $session ;
$this -> client = $client ;
$this -> tokenStorage = $tokenStorage ;
2023-01-06 14:02:20 +01:00
$this -> baseUrl = $baseUrl ;
2022-12-09 17:31:07 +01:00
}
public function handleLoginRequest ( Request $request )
{
$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 ( 'pas de code 200' );
}
// 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' ]);
2023-01-09 15:06:49 +01:00
return new RedirectResponse ( $this -> baseUrl . '/connect/login-accept' );
2022-12-09 17:31:07 +01:00
}
public function handleConsentRequest ( Request $request )
{
$challenge = $request -> query -> get ( 'consent_challenge' );
if ( ! $challenge ) {
throw new BadRequestException ( " Le challenge n'est pas disponible " );
}
$consentRequestInfo = $this -> client -> fetchConsentRequestInfo ( $challenge ) -> toArray ();
/** @var User */
$user = $this -> getUser ();
$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 )
{
$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 ();
2022-12-13 15:46:24 +01:00
$this -> tokenStorage -> setToken ( null );
2022-12-09 17:31:07 +01:00
return new RedirectResponse ( $logoutAcceptRes [ 'redirect_to' ]);
}
}