Paillasse/portail/app/Http/Controllers/Auth/ConnexionController.php

133 lines
4.3 KiB
PHP
Raw Permalink Normal View History

<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\Eleve;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Validation\ValidationException;
class ConnexionController extends Controller
{
public function connexionProf(Request $request): RedirectResponse
{
$donnees = $request->validate([
'email' => ['required', 'email'],
'password' => ['required', 'string'],
]);
$this->appliquerLimiteTentatives($request, 'prof:'.$donnees['email']);
if (! Auth::guard('web')->attempt($donnees)) {
RateLimiter::hit($this->cleLimite($request, 'prof:'.$donnees['email']));
throw ValidationException::withMessages([
'email' => 'Identifiants incorrects.',
]);
}
RateLimiter::clear($this->cleLimite($request, 'prof:'.$donnees['email']));
$request->session()->regenerate();
/** @var User $prof */
$prof = Auth::guard('web')->user();
$avaitDejaUneSession = $prof->jeton_session_actif !== null;
$request->session()->put('jeton_session_web', $prof->demarreNouvelleSession());
return redirect()->route('mes-classes.index')
->with('session_precedente_fermee', $avaitDejaUneSession);
}
public function connexionEleve(Request $request): RedirectResponse
{
$donnees = $request->validate([
'identifiant' => ['required', 'string'],
'code' => ['required', 'string'],
]);
$this->appliquerLimiteTentatives($request, 'eleve:'.$donnees['identifiant']);
$succes = Auth::guard('eleve')->attempt([
'identifiant' => $donnees['identifiant'],
'password' => $donnees['code'],
]);
if (! $succes) {
RateLimiter::hit($this->cleLimite($request, 'eleve:'.$donnees['identifiant']));
throw ValidationException::withMessages([
'identifiant' => 'Identifiant ou code secret incorrect.',
]);
}
RateLimiter::clear($this->cleLimite($request, 'eleve:'.$donnees['identifiant']));
$request->session()->regenerate();
/** @var Eleve $eleve */
$eleve = Auth::guard('eleve')->user();
$eleve->forceFill(['derniere_connexion_a' => now()])->save();
$request->session()->put('jeton_session_eleve', $eleve->demarreNouvelleSession());
return redirect()->route('eleve');
}
/**
* Connexion directe par QR (à usage unique, voir App\Services\GenerateurCompteEleve).
*/
public function connexionParQr(Request $request, string $jeton): RedirectResponse
{
$eleve = Eleve::where('jeton_qr', $jeton)->first();
if ($eleve === null) {
abort(404);
}
$eleve->forceFill(['jeton_qr' => null, 'derniere_connexion_a' => now()])->save();
Auth::guard('eleve')->login($eleve);
$request->session()->regenerate();
$request->session()->put('jeton_session_eleve', $eleve->demarreNouvelleSession());
return redirect()->route('eleve');
}
public function deconnexion(Request $request): RedirectResponse
{
if (Auth::guard('web')->check()) {
Auth::guard('web')->user()->terminerSession();
Auth::guard('web')->logout();
}
if (Auth::guard('eleve')->check()) {
Auth::guard('eleve')->user()->terminerSession();
Auth::guard('eleve')->logout();
}
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect()->route('accueil');
}
private function cleLimite(Request $request, string $identifiant): string
{
return 'connexion:'.$identifiant.'|'.$request->ip();
}
private function appliquerLimiteTentatives(Request $request, string $identifiant): void
{
$cle = $this->cleLimite($request, $identifiant);
if (RateLimiter::tooManyAttempts($cle, 5)) {
$secondes = RateLimiter::availableIn($cle);
throw ValidationException::withMessages([
'identifiant' => "Trop de tentatives. Réessaie dans {$secondes} secondes.",
]);
}
}
}