* @author Jean-Pascal MILCENT * @author Aurelien PERONNET * @license GPL v3 * @license CECILL v2 * @copyright 1999-2014 Tela Botanica */ 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; } }