Dossier personnel de l'élève monté comme lecteur réseau : rclone sert le dossier local, l'authentification est déléguée au portail via auth_request Nginx (mêmes identifiants que la connexion), sans nouveau système de comptes. Nettoyé par la purge RGPD comme les autres données d'élève. Corrige au passage un vrai bug d'isolation trouvé en testant avec deux comptes jetables : rewrite injectait la variable posée par auth_request_set, mais rewrite s'exécute dans une phase Nginx antérieure à cette variable, donc toujours vide - un élève pouvait lire le fichier d'un autre en devinant son nom. Corrigé par une location à regex nommée + proxy_pass. Détails : ADR 0008. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
58 lines
1.7 KiB
PHP
58 lines
1.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Eleve;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Response;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\RateLimiter;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
/**
|
|
* Sous-requête interne de Nginx (auth_request, bloc C, WebDAV des élèves) :
|
|
* mêmes identifiants que la connexion, jamais de session, jamais appelable
|
|
* directement depuis l'extérieur (location « internal » de Nginx, voir
|
|
* ansible/roles/portail/templates/nginx-portail.conf.j2). Répond 200 avec
|
|
* l'id de l'élève en en-tête (le sous-dossier auquel Nginx le limite), ou
|
|
* 401 sinon.
|
|
*/
|
|
class WebdavAuthController extends Controller
|
|
{
|
|
public function verifier(Request $request): Response
|
|
{
|
|
$identifiant = $request->getUser();
|
|
$code = $request->getPassword();
|
|
|
|
if ($identifiant === null || $code === null) {
|
|
return $this->refuser();
|
|
}
|
|
|
|
$cle = 'webdav:'.$identifiant.'|'.$request->ip();
|
|
|
|
if (RateLimiter::tooManyAttempts($cle, 5)) {
|
|
return $this->refuser();
|
|
}
|
|
|
|
$succes = Auth::guard('eleve')->once(['identifiant' => $identifiant, 'password' => $code]);
|
|
|
|
if (! $succes) {
|
|
RateLimiter::hit($cle, 300);
|
|
|
|
return $this->refuser();
|
|
}
|
|
|
|
RateLimiter::clear($cle);
|
|
|
|
/** @var Eleve $eleve */
|
|
$eleve = Auth::guard('eleve')->user();
|
|
Storage::disk('webdav')->makeDirectory((string) $eleve->id);
|
|
|
|
return response('', 200)->withHeaders(['X-Eleve-Dossier' => (string) $eleve->id]);
|
|
}
|
|
|
|
private function refuser(): Response
|
|
{
|
|
return response('', 401);
|
|
}
|
|
}
|