From 90931aa603aeb8879918d2128424b84d20abfa1c Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Tue, 8 Nov 2016 09:54:59 +0100 Subject: [PATCH] Updated [manager\ManagerError] to [error\core\Error] Gestion de l'authentification + mise en place du system de hash cyclique --- build/api/core/Authentification.php | 168 ++++++++++++++++++ build/api/core/ModuleRequest.php | 136 ++++++-------- build/api/core/ModuleResponse.php | 8 +- build/api/module/release.php | 14 +- build/{manager => error}/.htaccess | 0 .../ManagerError.php => error/core/Error.php} | 4 +- config/modules.json | 11 +- public_html/index.php | 9 +- 8 files changed, 256 insertions(+), 94 deletions(-) create mode 100644 build/api/core/Authentification.php rename build/{manager => error}/.htaccess (100%) rename build/{manager/ManagerError.php => error/core/Error.php} (99%) diff --git a/build/api/core/Authentification.php b/build/api/core/Authentification.php new file mode 100644 index 0000000..f0c4bc8 --- /dev/null +++ b/build/api/core/Authentification.php @@ -0,0 +1,168 @@ +\[..|{@#))'.hash('sha256', $hash.'_)Q@#((%*_$%(@#') ); + $c++; + } + + + /* [2] Return result + =========================================================*/ + return $hash; + } + + + + + /* INITIALISATION DU SYSTEME ET MISE A JOUR CONSTANTES D'AUTHENTIFICATION + * + * + */ + public static function check(){ + /* (1) Gestion de AUTH (authentification) dans HEADER + ---------------------------------------------------------*/ + define('__AUTH__', isset($_SERVER['PHP_AUTH_DIGEST']) ? $_SERVER['PHP_AUTH_DIGEST'] : '' ); + + /* (2) Gestion de AUTH en fonction du token + ---------------------------------------------------------*/ + $define('__AUTH__', preg_match('/^[a-f0-9]{64}$/', __AUTH__, $match) ? [$match[0]] : [] ); + + /* (3) On vérifie l'authentification par BDD + ---------------------------------------------------------*/ + if( !self::deepCheck() ) + define('__AUTH__', null); + } + + + + + /* VERIFICATION DE L'AUTHENTIFICATION + * + * + */ + public static function deepCheck(){ + /* [1] Si aucune authentification + =========================================================*/ + if( self::auth() == 0 ) + return false; + + + /* [2] Vérification de l'authentification + =========================================================*/ + /* (1) Fetch cyclic-hashing-system -> check files */ + $fn = [ + 'hash' => __BUILD__.'/api/hcs/hash', + 'cycle' => __BUILD__.'/api/hcs/cycle' + ]; + + if( !is_file($fn['hash']) || !is_file($fn['hash']) ) + return false; + + /* (2) Read files -> check contents */ + $fc = [ + 'hash' => file_get_contents($fn['hash']), + 'cycle' => file_get_contents($fn['cycle']) + ]; + + if( strlen($fc['hash']) !== 64 || !is_numeric($fc['cycle']) ) + return false; + + + + + /* [3] Si pas d'erreur d'authentification, on retourne TRUE + =========================================================*/ + return true; + } + + + + + /* VERIFICATION DES ACCES EN FONCTION DE PERMISSIONS ATTENDUES + * + * @module Module concerné + * @expected Liste des permissions attendues + * + * @return status Si FALSE, pas la permission, sinon si + * + */ + public static function permission($module, $expected){ + /* [0] Mise à jour de l'authentification + =========================================================*/ + // self::check(); + + + /* [1] Gestion de l'AUTH (authentification) + =========================================================*/ + + + + /* [2] Gestion des permissions + =========================================================*/ + /* (1) Vérification de toutes les permissions requises */ + foreach($expected as $permission) + // Si il manque au minimum une permission, on retourne FALSE + if( !in_array($permission, $_SESSION['PERM']) ) + return Error::PermissionError; + + + /* [3] Vérification que le module est actif pour l'entrepot + =========================================================*/ + + /* (1) On vérifie que le module est actif dans l'entrepot */ + $allowedModule = isset($_SESSION['WAREHOUSE']['modules']) + && is_array($_SESSION['WAREHOUSE']['modules']) + && in_array($module, $_SESSION['WAREHOUSE']['modules']); + + /* (2) On vérifie si le module est un module "Default" */ + $defaultModule = preg_match('/^(\w+)Default$/', $module); + + /* (3) Si aucune autorisation et pas module "Default" */ + if( !$allowedModule && !$defaultModule ) + return Error::DisabledModule; + + + /* [4] Si on a toutes les permissions requises + =========================================================*/ + return Error::Success; + } + + + + + + /* RENVOIE LE NIVEAU D'AUTHENTIFICATION + * + * @return auth Niveau d'authentification (0 à 2) + * + */ + public static function auth(){ + return !is_array(__AUTH_) ? 0 : count(__AUTH_); + } + + } + +?> diff --git a/build/api/core/ModuleRequest.php b/build/api/core/ModuleRequest.php index 6704246..384212e 100755 --- a/build/api/core/ModuleRequest.php +++ b/build/api/core/ModuleRequest.php @@ -2,14 +2,13 @@ namespace api\core; use \database\core\DatabaseDriver; - use \manager\ManagerError; - use \api\core\Checker; + use \api\core\Authentification; class ModuleRequest{ // Constantes - public static function config_path(){ return __CONFIG__.'/modules.json'; } + public static function config_path(){ return __ROOT__.'/config/modules.json'; } public static $default_options = [ 'download' => false ]; @@ -34,15 +33,14 @@ * * @path Chemin de delegation ("module/methode") * @param Tableau associatif contenant les parametres utiles au traitement - * @token Token d'acces a l'api (OPTIONNEL) * * @return status Retourne si oui ou non tout s'est bien passe * */ - public function __construct($path=null, $params=null, $token=null){ + public function __construct($path=null, $params=null){ // Si pas parametre manquant, on quitte if( $path == null ){ - $this->error = ManagerError::MissingPath; + $this->error = Error::MissingPath; return false; } @@ -53,7 +51,7 @@ // Gestion de l'erreur de parsage if( $this->modules == null ){ - $this->error = ManagerError::ParsingFailed; + $this->error = Error::ParsingFailed; return false; } @@ -63,7 +61,7 @@ =========================================================*/ // Type de @path if( !is_string($path) ){ // Si le type est incorrect - $this->error = ManagerError::WrongPathModule; + $this->error = Error::WrongPathModule; return false; // On retourne FALSE, si erreur } @@ -80,14 +78,14 @@ /* [3] Verification des droits =========================================================*/ - if( !$this->checkPermission($token) ) // Si on a pas les droits + if( !$this->checkPermission() ) // Si on a pas les droits return false; /* [4] Verification des parametres (si @type est defini) =========================================================*/ if( !$this->checkParams($params) ){ // Verification de tous les types - $this->error = ManagerError::ParamError; + $this->error = Error::ParamError; return false; } @@ -99,13 +97,14 @@ /* [6] Construction de l'objet =========================================================*/ $this->params = $params; - $this->error = ManagerError::Success; + $this->error = Error::Success; return true; // On retourne que tout s'est bien passe } + /* EXECUTE LE TRAITEMENT ASSOCIE ET REMPLIE LA REPONSE * * @return answer Retourne une reponse de type si tout s'est bien passe @@ -119,14 +118,14 @@ /* [1] On verifie qu'aucune erreur n'a ete signalee =========================================================*/ - if( $this->error != ManagerError::Success ) // si il y a une erreur + if( $this->error != Error::Success ) // si il y a une erreur return new ModuleResponse($this->error); // on la passe a la reponse /* [2] On verifie que la methode est amorcable =========================================================*/ if( !is_callable($this->getFunctionCaller()) ){ - $this->error = ManagerError::UncallableMethod; + $this->error = Error::UncallableMethod; return new ModuleResponse($this->error); } @@ -145,20 +144,27 @@ } + + + + + + + /* EXECUTE LE TRAITEMENT ASSOCIE ET RENVOIE UN FICHIER AVEC LE HEADER ET LE BODY SPECIFIE * */ public function download(){ /* [1] On verifie qu'aucune erreur n'a ete signalee =========================================================*/ - if( $this->error != ManagerError::Success ) // si il y a une erreur + if( $this->error != Error::Success ) // si il y a une erreur return new ModuleResponse($this->error); // on la passe a la reponse /* [2] On verifie que la methode est amorcable =========================================================*/ if( !is_callable($this->getFunctionCaller()) ){ - $this->error = ManagerError::UncallableMethod; + $this->error = Error::UncallableMethod; return new ModuleResponse($this->error); } @@ -171,14 +177,14 @@ /* [4] Vérification des erreurs et paramètres =========================================================*/ /* (1) Vérification de l'erreur retournée, si pas Success, on retourne l'erreur */ - if( isset($returned['ModuleError']) && $returned['ModuleError'] != ManagerError::Success ){ + if( isset($returned['ModuleError']) && $returned['ModuleError'] != Error::Success ){ $this->error = $returned['ModuleError']; return new ModuleResponse($this->error); } /* (2) Vérification du contenu, si pas défini */ if( !isset($returned['body']) ){ - $this->error = ManagerError::ParamError; + $this->error = Error::ParamError; return new ModuleResponse($this->error); } @@ -195,10 +201,10 @@ $tmpfname = '/tmp/download_'.uniqid().'.php'; - $bodyfname = __BUILD__.'/tmp/content_'.uniqid().'.php'; + $bodyfname = __ROOT__.'/tmp/content_'.uniqid().'.php'; /* (1) On crée le fichier temporaire */ - $tmpfnameroot = __BUILD__.$tmpfname; + $tmpfnameroot = __ROOT__.$tmpfname; $tmpfile = fopen($tmpfnameroot, 'w'); fwrite($tmpfile, 'append('link', $tmpfname); return $response; @@ -256,16 +262,10 @@ */ public static function fromPost($url, $post){ - /* [0] Verification de l'authentification - =========================================================*/ - // On definit le token - $token = isset($_SERVER['PHP_AUTH_DIGEST']) ? $_SERVER['PHP_AUTH_DIGEST'] : null; - - /* [1] On verifie que le @path est renseigne =========================================================*/ /* (1) Si le path est dans @url */ - $pathInUrl = is_string($url[0]) && strlen($url[0]) > 0 && preg_match('#^([\w_-]+)/([\w_-]+)/?$#', $url[0], $urlMatches); + $pathInUrl = count($url) > 0 && is_string($url[0]) && strlen($url[0]) > 0 && preg_match('#^([\w_-]+)/([\w_-]+)/?$#', $url[0], $urlMatches); // On l'utilise pour le chemin if( $pathInUrl ) @@ -276,6 +276,7 @@ return new ModuleRequest(); + /* [2] On verifie que @data est renseigne =========================================================*/ // Si variable n'existe pas, on cree un tableau vide @@ -297,10 +298,13 @@ /* [4] On retourne une instance de =========================================================*/ // On cree notre requete avec le token - return new ModuleRequest($post['path'], $params, $token); + return new ModuleRequest($post['path'], $params); } + + + /* VERIFICATION DU FORMAT ET DE LA COHERENCE DU CHEMIN SPECIFIE * * @path String correspondant au chemin de delegation ("module/methode") @@ -312,7 +316,7 @@ /* [1] Verification format general =========================================================*/ if( !preg_match('#^([\w_-]+)/([\w_-]+)$#i', $path, $matches) ){ // Si mauvais format - $this->error = ManagerError::WrongPathModule; + $this->error = Error::WrongPathModule; return false; } @@ -324,14 +328,15 @@ /* [2] Verification de l'existence du module (conf) =========================================================*/ if( !array_key_exists($module, $this->modules) ){ // Si le module n'est pas specifie dans la conf - $this->error = ManagerError::UnknownModule; + $this->error = Error::UnknownModule; return false; // On retourne FALSE, si erreur } + /* [3] Verification de l'existence de la methode (conf) =========================================================*/ if( array_key_exists($method, $this->modules[$module]) === false ){ // Si la methode n'est pas specifie dans la conf - $this->error = ManagerError::UnknownMethod; + $this->error = Error::UnknownMethod; return false; // On retourne FALSE, si erreur } @@ -348,14 +353,16 @@ } + + + + /* RETOURNE SI ON A LA PERMISSION D'EXECUTER CETTE METHODE * - * @token Token d'acces a l'API (OPTIONNEL) - * * @return permission Retourne si on a les droits ou pas pour executer cette methode * */ - private function checkPermission($token=null){ + private function checkPermission(){ /* [1] On recupere les informations utiles =========================================================*/ // On recupere le nom de la methode @@ -364,59 +371,24 @@ // Si aucune permission n'est definie if( !isset($method['permissions']) ) return true; - /* [2] Gestion si un @token est defini + + /* [2] Vérification des permissions et de l'authentification =========================================================*/ - if( Checker::run('hash', $token) ){ + $granted = Authentification::permission($this->path['module'], $method['permissions']); + + /* (1) On retourne FAUX si aucun droit n'a ete trouve */ + if( $granted !== Error::Success ) + $this->error = Error::PermissionError; - /* (1) On verifie que le token est valide */ - // $checkToken = new Repo('token/check', [$token] ); - $token_permissions = false; - // TODO: Token management - // $token_permissions = $checkToken->answer(); - - // Si le token est invalide, on retourne une erreur -> FAUX - if( $token_permissions === false ){ - $this->error = ManagerError::TokenError; - return false; - } - - $local_permissions = $token_permissions; - - - /* [3] Gestion si aucun token, avec utilisateur connecté - =========================================================*/ - }else if( isset($_SESSION['permission']) ) - $local_permissions = $_SESSION['permission']; - - // Si ni token, ni SESSION, erreur - else{ - $this->error = ManagerError::PermissionError; - return false; - } - - /* [4] Verification des droits parmi les permissions donnees - =========================================================*/ - /* (1) On recupere la liste des permissions possibles */ - $permissions = $method['permissions']; - - /* (2) Si aucune permission n'est definie, on laisse l'acces */ - if( !$permissions == 0 ) return true; - - /* (3) On verifie qu'il y a aucune permission manquante */ - foreach($permissions as $permission) - if( !in_array($permission, $local_permissions) ){ - $this->error = ManagerError::PermissionError; - return false; - } - - - /* [5] On retourne FAUX si aucun droit n'a ete trouve + /* [3] On retourne VRAI si la permission est ok =========================================================*/ return true; } + + /* VERIFICATION DU TYPE DES PARAMETRES ENVOYES * * @params Tableau associatif contenant les parametres @@ -477,6 +449,9 @@ } + + + /* AJOUT DES OPTIONS A PARTIR DE LA CONFIGURATION * */ @@ -517,6 +492,9 @@ } + + + /* RENVOI LE CHEMIN D'AMORCAGE DE LA METHODE * * @return path Retourne le chemin d'amorcage de la requete diff --git a/build/api/core/ModuleResponse.php b/build/api/core/ModuleResponse.php index 17c570e..256a7ee 100755 --- a/build/api/core/ModuleResponse.php +++ b/build/api/core/ModuleResponse.php @@ -1,7 +1,7 @@ Erreur passee par la requete (si existe) * */ - public function __construct($error=ManagerError::Success){ + public function __construct($error=Error::Success){ $this->data = []; $this->error = $error; } @@ -138,7 +138,7 @@ public function serialize(){ // Code Http - ManagerError::setHttpCode($this->error); + Error::setHttpCode($this->error); // Type de contenu header('Content-Type: application/json; charset=utf-8'); @@ -147,7 +147,7 @@ $returnData = array_merge( [ 'ModuleError' => $this->error, - 'ErrorDescription' => ManagerError::explicit($this->error) + 'ErrorDescription' => Error::explicit($this->error) ], $this->data ); diff --git a/build/api/module/release.php b/build/api/module/release.php index ad955a3..ef46360 100755 --- a/build/api/module/release.php +++ b/build/api/module/release.php @@ -2,7 +2,7 @@ namespace api\core; - use \manager\ManagerError; + use \error\core\Error; class release{ @@ -21,28 +21,28 @@ /* (1) Fetch file */ $fc = file_get_contents(__CONFIG__.'/projects.json'); if( !$fc ) - return ['ModuleError'=>ManagerError::UnreachableResource]; + return ['ModuleError'=>Error::UnreachableResource]; /* (2) Checks json format */ $js = json_decode( $fc, true ); if( !$js ) - return ['ModuleError'=>ManagerError::ParsingFailed]; + return ['ModuleError'=>Error::ParsingFailed]; /* [2] Checks @project argument and files =========================================================*/ /* (1) Checks @project */ if( !isset($js[$project]) ) - return ['ModuleError'=>ManagerError::UnreachableResource]; + return ['ModuleError'=>Error::UnreachableResource]; /* (2) Checks @project's folder */ if( !is_dir($js[$project]['git']) ) - return ['ModuleError'=>ManagerError::UnreachableResource]; + return ['ModuleError'=>Error::UnreachableResource]; /* (3) Checks @git directory */ if( !is_dir($js[$project]['git'].'/.git') ) - return ['ModuleError'=>ManagerError::UnreachableResource]; + return ['ModuleError'=>Error::UnreachableResource]; /* [3] Launch script @@ -53,7 +53,7 @@ /* (2) If error, raise error */ if( is_null($stdout) ) - return ['ModuleError'=>ManagerError::PermissionError, 'command'=>$cmd]; + return ['ModuleError'=>Error::PermissionError, 'command'=>$cmd]; /* [4] Return success error diff --git a/build/manager/.htaccess b/build/error/.htaccess similarity index 100% rename from build/manager/.htaccess rename to build/error/.htaccess diff --git a/build/manager/ManagerError.php b/build/error/core/Error.php similarity index 99% rename from build/manager/ManagerError.php rename to build/error/core/Error.php index d6a5994..75080c3 100755 --- a/build/manager/ManagerError.php +++ b/build/error/core/Error.php @@ -1,10 +1,10 @@