mirror of
https://github.com/RaspbianFrance/raspisms.git
synced 2025-06-07 15:16:27 +02:00
Fix des csrf
This commit is contained in:
parent
000ee8f2f2
commit
c80431e981
32 changed files with 666 additions and 282 deletions
210
mvc/Router.php
210
mvc/Router.php
|
@ -68,6 +68,16 @@
|
|||
$this->params = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cette méthode retourne la page 404 par défaut
|
||||
*/
|
||||
public function return404 ()
|
||||
{
|
||||
http_response_code(404);
|
||||
include(PWD . 'mvc/404.php');
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne une route avec seulement l'url parsée comme il faut
|
||||
* @param string $route : La route à analyser
|
||||
|
@ -77,12 +87,12 @@
|
|||
{
|
||||
$directory_to_remove = strstr(preg_replace('#http(s)?://#', '', HTTP_PWD), '/'); //On retire la partie protocole, et l'adresse du serveur de la partie de la route à ignorer
|
||||
$route = mb_strcut($route, mb_strlen($directory_to_remove)); //On retire la partie à ignorer de la route
|
||||
|
||||
$route = preg_split('#[/?]#', $route); //On explose la route
|
||||
$route = explode('?', $route)[0]; //on ne garde que ce qui précède les arguments
|
||||
$route = preg_split('#[/]#', $route); //On explose la route
|
||||
|
||||
foreach($route as $key => $val) //On garde seulement les repertoires non vides
|
||||
{
|
||||
if(empty($val))
|
||||
if(empty($val) && $val !== 0 && $val !== '0')
|
||||
{
|
||||
unset($route[$key]);
|
||||
}
|
||||
|
@ -100,17 +110,21 @@
|
|||
public function parseController($route)
|
||||
{
|
||||
$route = $this->parseRoute($route); //On récupère la route parsé
|
||||
//On lie le bon controlleur
|
||||
if (empty($route[0]) || !file_exists(PWD_CONTROLLER . $route[0] . '.php') || mb_strpos($route[0], 'internal') !== false) //Si on a pas de premier parametre, ou qu'il ne correspond à aucun controlleur
|
||||
|
||||
//Si pas de controlleur, on prend celui par défaut
|
||||
if (empty($route[0]))
|
||||
{
|
||||
$controllerName = DEFAULT_CONTROLLER; //On défini le nom du controlleur par défaut
|
||||
return DEFAULT_CONTROLLER;
|
||||
}
|
||||
else //Sinon, si tout est bon
|
||||
|
||||
//Sinon, si le controlleur n'existe pas ou est internal, on retourne une 404
|
||||
if (!file_exists(PWD_CONTROLLER . $route[0] . '.php') || mb_strpos($route[0], 'internal') !== false)
|
||||
{
|
||||
$controllerName = $route[0]; //On défini le nom du controlleur
|
||||
return $this->return404();
|
||||
}
|
||||
|
||||
return $controllerName;
|
||||
|
||||
//On retourne le controlleur adapté
|
||||
return $route[0];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,20 +134,71 @@
|
|||
*/
|
||||
public function parseMethod($route)
|
||||
{
|
||||
//On instancie le controlleur
|
||||
$controllerName = $this->parseController($route);
|
||||
require_once(PWD_CONTROLLER . $controllerName . '.php'); //On inclus le controlleur
|
||||
$controller = new $controllerName();
|
||||
$route = $this->parseRoute($route); //On récupère la route parsé
|
||||
//On lie la bonne méthode
|
||||
if (empty($route[1]) || !method_exists($controller, $route[1])) //Si on a pas de second parametre, ou qu'il ne correspond à aucune méthode du controlleur
|
||||
$prefixMethod = '';
|
||||
|
||||
//On recupère les paramètres dans l'url pour les utiliser un peu plus tard
|
||||
$params = $this->parseParams($route);
|
||||
|
||||
|
||||
//On vérifie si le controlleur est un controlleur API, si c'est le cas on le refais avec cette fois la bonne methode
|
||||
if ($controller instanceof ApiController)
|
||||
{
|
||||
$method = DEFAULT_METHOD; //On prend la méthode par défaut
|
||||
}
|
||||
else //Sinon, si tout est bon
|
||||
{
|
||||
$method = $route[1]; //On défini la méthode appelée
|
||||
//On va choisir le type à employer
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
switch (mb_convert_case($method, MB_CASE_LOWER))
|
||||
{
|
||||
case 'delete' :
|
||||
$prefixMethod = 'delete';
|
||||
break;
|
||||
case 'patch' :
|
||||
$prefixMethod = 'patch';
|
||||
break;
|
||||
case 'post' :
|
||||
$prefixMethod = 'post';
|
||||
break;
|
||||
case 'put' :
|
||||
$prefixMethod = 'put';
|
||||
break;
|
||||
default :
|
||||
$prefixMethod = 'get';
|
||||
}
|
||||
}
|
||||
|
||||
$route = $this->parseRoute($route); //On récupère la route parsé
|
||||
|
||||
//On regarde quelle route il nous faut et on evite les routes qui commencent par '_', qui sont maintenant considérées comme privées
|
||||
if (empty($route[1]))
|
||||
{
|
||||
$method = DEFAULT_METHOD;
|
||||
}
|
||||
else
|
||||
{
|
||||
$method = $route[1];
|
||||
}
|
||||
|
||||
if ($prefixMethod)
|
||||
{
|
||||
$method = $prefixMethod . mb_convert_case($method, MB_CASE_TITLE);
|
||||
}
|
||||
|
||||
//Si la méthode à appeler n'existe pas ou si la route commencent par '_', signe qu'elle est un outils non accessibles
|
||||
if (!method_exists($controller, $method) || mb_substr($method, 0, 1) == '_')
|
||||
{
|
||||
return $this->return404();
|
||||
}
|
||||
|
||||
//On instancie la classe reflection de PHP sur la méthode que l'on veux analyser pour l'objet controller
|
||||
$methodAnalyser = new ReflectionMethod($controller, $method);
|
||||
|
||||
//Si la méthode à appeler demande plus de paramètres que fournis on retourne une 404
|
||||
if ($methodAnalyser->getNumberOfRequiredParameters() > count($params))
|
||||
{
|
||||
return $this->return404();
|
||||
}
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
|
@ -146,48 +211,83 @@
|
|||
{
|
||||
$route = $this->parseRoute($route); //On récupère la route parsé
|
||||
$params = array();
|
||||
$already_use_params = array();
|
||||
//On transforme les paramètres $_GET passés par l'url au format clef_value. Ex : prenom_pierre-lin = $_GET['prenom'] => 'pierre-lin'
|
||||
|
||||
//On transforme les paramètres $_GET passés par l'url au format clef-value. Ex : prenom-pierre-lin = $_GET['prenom'] => 'pierre-lin'
|
||||
if (count($route) > 2) //Si on a plus de deux paramètres qui ont été passé
|
||||
{
|
||||
unset($route[0], $route[1]); //On supprime le controlleur, et la route, des paramètres, il ne reste que les parametres a passer en GET
|
||||
foreach($route as $param) //On passe sur chaque paramètre a transformer en GET
|
||||
foreach ($route as $param)
|
||||
{
|
||||
$param = explode('_', $param, 2); //On récupère le paramètre, via la délimiteur '_', en s'arretant au premier
|
||||
|
||||
//Si on a déjà utilisé cette variable GET
|
||||
if (in_array($param[0], $already_use_params))
|
||||
{
|
||||
if (isset($params[$param[0]]))
|
||||
{
|
||||
$tmp_value = $params[$param[0]];
|
||||
$params[$param[0]] = array($tmp_value);
|
||||
unset($tmp_value);
|
||||
}
|
||||
|
||||
$params[$param[0]][] = (isset($param[1])) ? rawurldecode($param[1]) : NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$params[$param[0]] = (isset($param[1])) ? rawurldecode($param[1]) : NULL; //On définit la propriétée GET correspondante
|
||||
$already_use_params[] = $param[0];
|
||||
}
|
||||
$params[] = rawurldecode($param);
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cette fonction permet de vérifier si le cache est activé pour une route, et si oui quel fichier utiliser
|
||||
* @param string $route : Route à analyser
|
||||
* @return mixed : Si pas de cache, faux. Sinon un tableau avec deux clefs, "state" => statut du nom de fichier retourné (true, le fichier doit être utilisé, false, le fichier doit être créé), "file" => Le nom du fcihier de cache
|
||||
*/
|
||||
public function verifyCache($route)
|
||||
{
|
||||
//On récupère le nom du controller et de la méthode
|
||||
$controllerName = $this->parseController($route);
|
||||
$methodName = $this->parseMethod($route);
|
||||
$params = $this->parseParams($route);
|
||||
|
||||
$controller = new $controllerName();
|
||||
|
||||
//Si on ne doit pas activer le cache ou si on na pas de cache pour ce fichier
|
||||
if (!ACTIVATING_CACHE || !property_exists($controller, 'cache_' . $methodName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Si on a du cache, on va déterminer le nom approprié
|
||||
//Format de nom = <hash:nom_router.nom_methode><hash_datas>
|
||||
$hashName = md5($controllerName . $methodName);
|
||||
$hashDatas = md5(json_encode($_GET) . json_encode($_POST) . json_encode($params));
|
||||
$fileName = $hashName . $hashDatas;
|
||||
|
||||
//Si il n'existe pas de fichier de cache pour ce fichier
|
||||
if (!file_exists(PWD_CACHE . $fileName))
|
||||
{
|
||||
return array('state' => false, 'file' => $fileName);
|
||||
}
|
||||
|
||||
//Sinon, si le fichier de cache existe
|
||||
$fileLastChange = filemtime(PWD_CACHE . $fileName);
|
||||
|
||||
//On calcul la date de mise à jour valide la plus ancienne possible
|
||||
$now = new DateTime();
|
||||
$propertyName = 'cache_' . $methodName;
|
||||
$propertyValue = $controller->$propertyName;
|
||||
$now->sub(new DateInterval('PT' . $propertyValue . 'M'));
|
||||
$maxDate = $now->format('U');
|
||||
|
||||
//Si le fichier de cache est trop vieux
|
||||
if ($fileLastChange < $maxDate)
|
||||
{
|
||||
return array('state' => false, 'file' => $fileName);
|
||||
}
|
||||
|
||||
//Sinon, on retourne le fichier de cache en disant de l'utiliser
|
||||
return array('state' => true, 'file' => $fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cette fonction permet de charger la page adaptée a partir d'une url
|
||||
* Elle gère également le cache
|
||||
* @param string $route : Route à analyser pour charger une page
|
||||
* @return void
|
||||
*/
|
||||
public function loadRoute($route)
|
||||
{
|
||||
$_GET = array_merge($_GET, $this->parseParams($route)); //On fusionne les paramètres GET et ceux passés dans la route du controller
|
||||
$params = $this->parseParams($route); //On récupère les paramètres à passer à la fonction
|
||||
$controllerName = $this->parseController($route); //On récupère le nom du controleur à appeler
|
||||
$controller = new $controllerName(); //On créer le controleur
|
||||
|
||||
$beforeMethodName = DEFAULT_BEFORE; //On défini le nom de la fonction before
|
||||
if (method_exists($controller, $beforeMethodName)) //Si une fonction before existe pour ce controller, on l'appel
|
||||
{
|
||||
|
@ -195,7 +295,27 @@
|
|||
}
|
||||
|
||||
$methodName = $this->parseMethod($route); //On récupère le nom de la méthode
|
||||
$controller->$methodName(); //On appel la méthode
|
||||
}
|
||||
$verifyCache = $this->verifyCache($route);
|
||||
|
||||
//Si on ne doit pas utiliser de cache
|
||||
if ($verifyCache === false)
|
||||
{
|
||||
call_user_func_array(array($controller, $methodName), $params); //On appel la methode, en lui passant les arguments necessaires
|
||||
return null;
|
||||
}
|
||||
|
||||
//Si on doit utiliser un cache avec un nouveau fichier
|
||||
if ($verifyCache['state'] == false)
|
||||
{
|
||||
//On créer le fichier avec le contenu adapté
|
||||
ob_start();
|
||||
call_user_func_array(array($controller, $methodName), $params); //On appel la methode, en lui passant les arguments necessaires
|
||||
$content = ob_get_contents();
|
||||
file_put_contents(PWD_CACHE . $verifyCache['file'], $content);
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
//On utilise le fichier de cache
|
||||
readfile(PWD_CACHE . $verifyCache['file']);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue