2022-04-07 11:49:17 +02:00
< ? php
namespace App\Controller ;
2022-05-03 08:54:45 +02:00
use App\Entity\User ;
use App\Form\UserType ;
use App\Services\PdoServices ;
2022-04-07 11:49:17 +02:00
use Symfony\Component\HttpFoundation\Request ;
2022-05-03 08:54:45 +02:00
use Symfony\Component\Routing\Annotation\Route ;
use Symfony\Contracts\HttpClient\HttpClientInterface ;
use Symfony\Component\HttpFoundation\Session\SessionInterface ;
2022-04-07 11:49:17 +02:00
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController ;
2022-05-03 08:54:45 +02:00
use Symfony\Component\HttpFoundation\Exception\BadRequestException ;
2022-05-03 15:09:42 +02:00
use Symfony\Component\Routing\Generator\UrlGeneratorInterface ;
2022-04-07 11:49:17 +02:00
class MainController extends AbstractController
{
2022-05-03 15:09:42 +02:00
/**
2022-05-03 08:54:45 +02:00
* @ var Session
*/
private $session ;
2022-05-03 15:09:42 +02:00
/**
* @ var UrlGeneratorInterface
*/
private $router ;
2022-04-07 11:49:17 +02:00
2022-05-03 08:54:45 +02:00
/**
* @ var HttpClientInterface
*/
public $client ;
private $pdoServices ;
2022-04-07 14:35:36 +02:00
2022-05-03 15:09:42 +02:00
public function __construct ( PdoServices $pdoServices , HttpClientInterface $client , SessionInterface $session , UrlGeneratorInterface $router )
2022-05-03 08:54:45 +02:00
{
$this -> pdoServices = $pdoServices ;
$this -> session = $session ;
$this -> client = $client ;
2022-05-03 15:09:42 +02:00
$this -> router = $router ;
2022-05-03 08:54:45 +02:00
}
/**
* @ Route ( " /oauth/login " , name = " app_login " )
*/
public function loginOidc ( Request $request )
{
$challenge = $request -> query -> get ( 'login_challenge' );
// S'il n'y a pas de challenge, on déclenche une bad request
if ( ! $challenge ){
throw new BadRequestException ( 'pas de challenge' );
}
//On vérifie que la requête d'identification provient bien de hydra
$response = $this -> client -> request ( 'GET' , $this -> getParameter ( 'url_login_challenge' ) . $challenge , [
'headers' => [
'Content-Type: application/json' ,
],
]);
if ( 200 !== $response -> getStatusCode ()) {
$this -> session -> clear ();
throw new BadRequestException ( 'pa 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' , $challenge );
return $this -> redirectToRoute ( 'oauth_login' );
}
/**
* @ Route ( " /oauth/connect " , name = " oauth_login " )
*/
public function oauth ( Request $request )
{
2022-05-03 15:09:42 +02:00
if ( $request -> headers -> get ( 'referer' ) !== $this -> router -> generate ( 'oauth_login' , [], 0 ) && ! in_array ( $request -> headers -> get ( 'referer' ), $this -> getParameter ( 'urlIssuer' ))){
throw new BadRequestException ( 'Vous devez passer par le issuer pour vous connecter' );
}
2022-05-03 08:54:45 +02:00
$user = new User ();
$loginForm = $this -> createForm ( UserType :: class , $user );
$loginForm -> handleRequest ( $request );
if ( $loginForm -> isSubmitted () && $loginForm -> isValid ()){
$email = $loginForm -> get ( 'email' ) -> getData ();
try {
2022-05-03 15:09:42 +02:00
// requête préparée
$datas = $this -> pdoServices -> fetchDatas ( $email );
2022-05-03 08:54:45 +02:00
2022-05-03 15:09:42 +02:00
if ( ! $datas ){
2022-05-03 08:54:45 +02:00
// Si le hash du password n'est pas trouvé, c'est que l'email n'existe pas, on retourne la page de login avec une erreur
return $this -> render ( 'login.html.twig' , [
2022-05-03 15:09:42 +02:00
" form " => $loginForm -> createView (),
" error_mail " => " mail non trouvé " ,
2022-05-03 08:54:45 +02:00
]);
}
2022-05-03 15:09:42 +02:00
$hashPassword = $datas [ $this -> getParameter ( 'passwordColumnName' )];
2022-05-03 08:54:45 +02:00
$password = $loginForm -> get ( 'password' ) -> getData ();
if ( $this -> pdoServices -> verifyPassword ( $password , $hashPassword )){
2022-05-04 16:53:32 +02:00
// On défait la mot de passe qui ne servira plus
2022-05-03 15:09:42 +02:00
unset ( $datas [ $this -> getParameter ( 'passwordColumnName' )]);
$this -> session -> set ( 'datas' , $datas );
2022-05-03 08:54:45 +02:00
$response = $this -> client -> request ( 'PUT' , $this -> getParameter ( 'url_login_challenge_accept' ) . $this -> session -> get ( 'challenge' ), [
'json' => [
'subject' => $email ,
2022-05-04 16:53:32 +02:00
'acr' => 'string'
2022-05-03 08:54:45 +02:00
],
]);
// On initie l'acceptation du login challenge émis par hydra et on récupère l'url de redirection
$redirect_to = $response -> toArray ()[ 'redirect_to' ];
return $this -> redirect ( $redirect_to , 301 );
} else {
return $this -> render ( 'login.html.twig' , [
'form' => $loginForm -> createView (),
2022-05-03 15:09:42 +02:00
" error_password " => " Le mot de passe est incorrect "
2022-05-03 08:54:45 +02:00
]);
}
} catch ( \Exception $e ){
dd ( $e );
}
}
return $this -> render ( 'login.html.twig' , [
'form' => $loginForm -> createView (),
]);
}
/**
* @ Route ( " /oauth/consent " , name = " consent " )
*/
public function consent ( Request $request )
{
$challenge = $request -> query -> get ( 'consent_challenge' );
if ( ! $challenge ) {
throw new BadRequestException ( " Le challenge n'est pas disponible " );
}
// Vérification du consent_challenge avec hydra
$response = $this -> client -> request ( 'GET' , $this -> getParameter ( 'url_consent_challenge' ) . $challenge , [
'headers' => [
'Content-Type: application/json' ,
],
]);
if ( 200 !== $response -> getStatusCode ()){
$this -> session -> clear ();
throw new BadRequestException ( " Le challenge n'est pas authorisé " );
}
$response = $this -> client -> request ( 'PUT' , $this -> getParameter ( 'url_consent_challenge_accept' ) . $challenge , [
'headers' => [
'Content-Type: application/json' ,
],
'json' => [
'grant_scope' => [ 'openid' , 'offline_access' ],
'session' => [
'id_token' => [
'user' => $this -> session -> get ( 'datas' ),
],
],
],
]);
$redirect_to = $response -> toArray ()[ 'redirect_to' ];
return $this -> redirect ( $redirect_to , 301 );
}
2022-05-03 15:09:42 +02:00
/**
* @ Route ( " /oauth/logout " , name = " app_logout " )
*/
public function logout ()
{
$this -> session -> clear ();
return $this -> redirect ( $this -> getParameter ( 'urlLogoutSuccess' ));
}
2022-04-07 11:49:17 +02:00
}