2022-04-07 11:49:17 +02:00
< ? php
namespace App\Controller ;
2022-05-03 08:54:45 +02:00
use PDO ;
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\HttpFoundation\Response ;
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 ;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils ;
2022-04-07 11:49:17 +02:00
class MainController extends AbstractController
{
2022-05-03 08:54:45 +02:00
/**
* @ var Session
*/
private $session ;
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 08:54:45 +02:00
public function __construct ( PdoServices $pdoServices , HttpClientInterface $client , SessionInterface $session )
{
$this -> pdoServices = $pdoServices ;
$this -> session = $session ;
$this -> client = $client ;
}
/**
* @ 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 )
{
$user = new User ();
$loginForm = $this -> createForm ( UserType :: class , $user );
$loginForm -> handleRequest ( $request );
if ( $loginForm -> isSubmitted () && $loginForm -> isValid ()){
$email = $loginForm -> get ( 'email' ) -> getData ();
$dbh = $this -> pdoServices -> connection ();
try {
//requête préparée
$query = $dbh -> prepare ( $this -> getParameter ( " queryHashPassword " ) . " ' " . $email . " '; " );
$query -> execute ();
$hashPassword = $query -> fetch ( PDO :: FETCH_ASSOC );
if ( ! $hashPassword ){
// 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' , [
'form' => $loginForm -> createView (),
" error " => " mail non trouvé " ,
]);
}
$hashPassword = array_values ( $hashPassword )[ 0 ];
$password = $loginForm -> get ( 'password' ) -> getData ();
if ( $this -> pdoServices -> verifyPassword ( $password , $hashPassword )){
$this -> session -> set ( 'datas' , $this -> pdoServices -> fetchDatas ( $email ));
$response = $this -> client -> request ( 'PUT' , $this -> getParameter ( 'url_login_challenge_accept' ) . $this -> session -> get ( 'challenge' ), [
'json' => [
'subject' => $email ,
],
]);
// On initie l'acceptation du login challenge émis par hydra et on récupère l'url de redirection
// dd($response->toArray());
$redirect_to = $response -> toArray ()[ 'redirect_to' ];
return $this -> redirect ( $redirect_to , 301 );
} else {
return $this -> render ( 'login.html.twig' , [
'form' => $loginForm -> createView (),
" error " => " Le mot de passe est incorrect "
]);
}
} catch ( \Exception $e ){
dd ( $e );
}
// $rememberMe = $loginForm->get('rememberMe')->getData();
}
return $this -> render ( 'login.html.twig' , [
'form' => $loginForm -> createView (),
" error_mail " => false ,
" error_password " => false
]);
}
/**
* @ 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-04-07 11:49:17 +02:00
}