Rev 1815 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php// declare(encoding='UTF-8');/*** Classe de controle d'accès HTTP AUTH aux services de DEL, à n'utiliser* que dans ce cas (HTTP AUTH), et pas dans le cas de l'identification générale sur le SSO** Cette classe propose des méthodes permettant :* - l'authentification HTTP pour bloquer ou autoriser l'accès* - de déterminer le statut d'admin des utilisateurs** @category DEL* @package Services* @package Bibliotheque* @version 0.1* @author Mathias CHOUET <mathias@tela-botanica.org>* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>* @author Aurelien PERONNET <aurelien@tela-botanica.org>* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>* @copyright 1999-2014 Tela Botanica <accueil@tela-botanica.org>*/class ControleAcces {protected $conteneur;protected $bdd;public function __construct($conteneur) {$this->conteneur = $conteneur;$this->bdd = $this->conteneur->getBdd();}/*** Vérifie que l'IP du client est dans la liste "ip_autorisees" de la config* @throws Exception* @return boolean*/public function controlerIpAutorisees() {$ipsAutorisees = $this->conteneur->getParametreTableau('ip_autorisees');$remoteIp = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP);$serverIp = filter_input(INPUT_SERVER, 'SERVER_ADDR', FILTER_VALIDATE_IP);if (in_array($remoteIp, $ipsAutorisees) == false) {if ($remoteIp != $serverIp) {// ATTENTION : maintenir ce test à l'intérieur du précédent$message = "Accès interdit. \n"."Vous n'êtes pas autorisé à accéder à ce service depuis '$remoteIp' !\n";$code = RestServeur::HTTP_CODE_ACCES_NON_AUTORISE;throw new Exception($message, $code);}}return true;}/*** Exige qu'un administrateur s'autenthentifie à l'aide de HTTP AUTH*/public function demanderAuthentificationAdmin() {if (!$this->etreAdminAutoriseParHttp()) {$this->authentifierAdmin();}}/*** Exige qu'un utilisateur s'autenthentifie à l'aide de HTTP AUTH*/public function demanderAuthentificationUtilisateur() {if (!$this->etreUtilisateurAutoriseParHttp()) {$this->authentifierUtilisateur();}}/*** Lit les entêtes HTTP AUTH et vérifie si l'utilisateur* existe (courriel / mot de passe); si $doitEtreAdmin est true,* vérifiera également que l'utilisateur est administrateur de Del** @return boolean true si l'utilisateur est identifié, false sinon*/protected function etreUtilisateurAutoriseParHttp($doitEtreAdmin=false) {$identifiant = $this->getAuthIdentifiant();$mdp = $this->getAuthMotDePasse();$existe = $this->obtenirUtilisateur($identifiant, $mdp);$autorisation = (isset($existe) && $existe) ? true :false; // c'est quoi ces tests de clodos ??if ($doitEtreAdmin === true) {$autorisation = ($autorisation && $this->etreAdmin($identifiant));}return $autorisation;}/*** Lit les entêtes HTTP AUTH et vérifie que l'utilisateur est identifié* et est administrateur de Del** @return boolean true si l'utilisateur est identifié et admin de Del, false sinon*/protected function etreAdminAutoriseParHttp() {return $this->etreUtilisateurAutoriseParHttp(true);}/*** Lit l'identifiant utilisateur dans les entêtes HTTP AUTH* @return String l'identifiant utilisateur ou null*/protected function getAuthIdentifiant() {$id = (isset($_SERVER['PHP_AUTH_USER'])) ? $_SERVER['PHP_AUTH_USER'] : null;return $id;}/*** Lit le mot de passe dans les entêtes HTTP AUTH* @return String le mot de passe ou null*/protected function getAuthMotDePasse() {$mdp = (isset($_SERVER['PHP_AUTH_PW'])) ? $_SERVER['PHP_AUTH_PW'] : null;return $mdp;}/*** Envoie un message HTTP 401 / une boîte de login HTTP AUTH avec des* messages correspondant à la demande d'authentification d'un administrateur* TODO: externaliser noms et adresses spécifiques à Tela Botanica* @return boolean*/protected function authentifierAdmin() {$message_accueil = "Veuillez vous identifier avec votre compte administrateur Tela Botanica.";$message_echec = "Accès limité aux administrateurs de DEL.\n"."Votre tentative d'identification a échoué.\n"."Actualiser la page pour essayer à nouveau si vous êtes bien inscrit comme administrateur.";return $this->authentifier($message_accueil, $message_echec, 'Admin');}/*** Envoie un message HTTP 401 / une boîte de login HTTP AUTH avec des* messages correspondant à la demande d'authentification d'un utilisateur* TODO: externaliser noms et adresses spécifiques à Tela Botanica* @return boolean*/protected function authentifierUtilisateur() {$message_accueil = "Veuillez vous identifier avec votre compte Tela Botanica.";$message_echec = "Accès limité aux utilisateurs de DEL.\n"."Inscrivez vous http://www.tela-botanica.org/page:inscription pour le devenir.\n"."Votre tentative d'identification a échoué.\n"."Actualiser la page pour essayer à nouveau si vous êtes déjà inscrit ou contacter 'accueil@tela-botanica.org'.";return $this->authentifier($message_accueil, $message_echec, 'Utilisateur');}/*** Envoie l'authentification HTTP AUTH , et accepte un mode "debug" pour* les petits malins*/protected function authentifier($message_accueil, $message_echec, $type) {$id = $this->getAuthIdentifiant();if (!isset($id)) {$this->envoyerAuth($message_accueil, $message_echec);} else {if ($type == 'Utilisateur' && $this->getAuthMotDePasse() == 'debug') {$autorisation = true;} else {$methodeAutorisation = "etre{$type}Autorise";$autorisation = $this->$methodeAutorisation();}if ($autorisation == false) {$this->envoyerAuth($message_accueil, $message_echec);}}return true;}/*** Envoie un message HTTP 401 / une boîte de login HTTP AUTH* @param string $message_accueil* @param string $message_echec*/private function envoyerAuth($message_accueil, $message_echec) {header('HTTP/1.0 401 Unauthorized');header('WWW-Authenticate: realm="'.mb_convert_encoding($message_accueil, 'ISO-8859-1', 'UTF-8').'"');header('Content-type: text/plain; charset=UTF-8');print $message_echec;exit(0);}/*** Authentifie et récupère un utilisateur directement depuis la table des* utilisateurs Del, utile pour l'authentification HTTP AUTH - ne pas* utiliser pour les services Del qui doivent être branchés au SSO*/protected function obtenirUtilisateur($login, $motDePasse) {$login = $this->bdd->proteger($login);$motDePasse = $this->bdd->proteger($motDePasse);$requete = 'SELECT id_utilisateur, nom, prenom, courriel, mot_de_passe '.'FROM del_utilisateur AS du '."WHERE courriel = $login "." AND mot_de_passe = MD5($motDePasse) ".' -- '.__FILE__.':'.__LINE__."\n";$utilisateur = $this->bdd->recuperer($requete);return $utilisateur;}/*** Vérifie dans la table des utilisateurs Del qu'un utilisateur* (identifié par son courriel) est administrateur de Del** @param string $courriel* @return boolean true si l'utilisateur est administrateur de Del, false sinon*/protected function etreAdmin($courriel) {$courriel = $this->bdd->proteger($courriel);$requete = 'SELECT dui.admin '.'FROM del_utilisateur AS du LEFT JOIN del_user_infos AS dui ON (du.id_utilisateur = dui.id_utilisateur) '."WHERE du.courriel = $courriel ".' -- '.__FILE__.':'.__LINE__."\n";$infoUtilisateur = $this->bdd->recuperer($requete);$etreAdmin = $this->verifierDroitAdmin($infoUtilisateur['admin']);return $etreAdmin;}/*** Vérifie que la valeur "admin" d'un profil utilisateur correspond à la valeur* attendue dans la config** @return true si sébon, false si sépabon*/protected function verifierDroitAdmin($droit) {$droitAdmin = $this->conteneur->getParametre('droit_superadmin');$etreAdmin = false;if (isset($droit) && $droit == $droitAdmin) {$etreAdmin = true;}return $etreAdmin;}}