Rev 1587 | Rev 1852 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/*** Service d'itentification d'un utilisateur.* Encodage en entrée : utf8* Encodage en sortie : utf8* Cas d'utilisation :* 1: Aucun login ni mot de passe transmis* 1: L'application retourne l'identifiant de session en cours* 2: Une identification est toujours active, cette identification est retournée** 2: Ce service recoit un login et un mot de passe* 1 : On tente d'identifier l'utilisateur* 2 : Si réussi, l'état passe à : connecté* 3 : sinon, l'état passe à : pas connecté** 3: Ce service reçoit un identifiant (différent du login) et aucun mot de passe :* 1 : Déconnexion** En résumé, utilisation des URLs :* /CoelUtilisateur/ : retour identifiant de session si jamais connecté, sinon retour de l'id (+ login et mot de passe)* /CoelUtilisateur/ * / * / : idem ci-dessus* /CoelUtilisateur/id : déconexion* /CoelUtilisateur/login/mot_de_passe : connexion** @author Jean-Pascal MILCENT <jpm@tela-botanica.org>* @author David DELON <david.delon@clapas.net>abstract* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>* @version $Id$* @copyright 2009*/class CoelUtilisateur extends Coel {private $licence_acceptee = false;// TODO : controle systematique... dans tous les services si connected : name cookie = name servicepublic function getRessource(){$this->getElement(array('*','*'));}public function getElement($param){$identification = false;$info = array();// Si la licence n'a pas été accepté nous réinitialisons toutif (!isset($param[2]) && (!isset($_COOKIE['coel_licence']) || (isset($_COOKIE['coel_licence']) && $_COOKIE['coel_licence'] != 1))) {$this->deconnecterUtilisateur();}// S'il y a 3 paramètres, c'est qu'on cherche à mettre à jour la licenceif (isset($param[2])) {$this->debug[] = "Licence acceptee";$this->licence_acceptee = true;// Mise à jour de la licenceif (!$this->accepterLicence($param[0])) {$this->debug[] = "Erreur de mise à jour licence utilisateur";}} else if (isset($param[1])) { // Non connecté : vérificationif (!$this->getUtilisateur()) { // Si non identifié$id = null;if ($param[0] == '*' && $param[1] == '*') { // Tentative d'identification depuis les cookies permanentsif (isset($_COOKIE['coel_login']) && ($this->souvenirUtilisateur($_COOKIE['coel_login'], $_COOKIE['coel_mot_de_passe']))) {$id = $this->getUtilisateurId();$identification = true;$info = array($id, $identification, $this->getUtilisateurNomComplet(), $this->getUtilisateurPrenom(), $this->getUtilisateurNom(), $this->getParametre());}} else if ($this->connecterUtilisateur($param[0], $param[1], 1)) { // Tentative d'identification depuis les paramêtres passés dans l'url du service$id = $this->getUtilisateurId();$identification = true;$info = array($id, $identification, $this->getUtilisateurNomComplet(), $this->getUtilisateurPrenom(), $this->getUtilisateurNom(), $this->getParametre());}// L'identification a échouée, nous retournons un session_id comme identifiantif (is_null($id)) {$id = session_id();$identification = false;$info = array($id, $identification);}} else { // Déjà identifié$id = $this->getUtilisateurId();$identification = true;$info = array($id, $identification, $this->getUtilisateurNomComplet(), $this->getUtilisateurPrenom(), $this->getUtilisateurNom(), $this->getParametre());}} else { // Déconnexion$this->deconnecterUtilisateur();$id = session_id();$identification = false;$info = array($id, $identification);}array_unshift($info, $this->getLicence());// Envoie sur la sortie standard$this->envoyer($info);}private function getUtilisateurId() {if ($utilisateur = $this->getUtilisateur()) {return $utilisateur['id'];} else {return '';}}private function getUtilisateurLogin() {if ($utilisateur = $this->getUtilisateur()) {return $utilisateur['login'];} else {return '';}}private function getUtilisateurNomComplet() {if ($utilisateur = $this->getUtilisateur()) {return $utilisateur['nom_complet'];} else {return '';}}private function getUtilisateurPrenom() {if ($utilisateur = $this->getUtilisateur()) {return $utilisateur['prenom'];} else {return '';}}private function getUtilisateurNom() {if ($utilisateur = $this->getUtilisateur()) {return $utilisateur['nom'];} else {return '';}}private function getParametre() {if ($utilisateur = $this->getUtilisateur()) {return $utilisateur['parametre'];} else {return '';}}private function getLicence() {if (!empty($_SESSION['coel_utilisateur'])) {return (string) $_SESSION['coel_utilisateur']['licence'];} else {return '';}}private function getInfosAnnuaire() {if (!empty($_SESSION['coel_infosAnnuaire'])) {return $_SESSION['coel_infosAnnuaire'];} else {return '';}}private function deconnecterUtilisateur() {$_SESSION['coel_utilisateur'] = '';$_SESSION['coel_infosAnnuaire'] = '';$this->supprimerCookie('coel_login');$this->supprimerCookie('coel_mot_de_passe');$this->supprimerCookie('coel_licence');$this->supprimerCookie('coel_permanence');}private function connecterUtilisateur($login, $mot_de_passe, $permanence = 1) {// Dans tous les cas, on récupère les informations de l'utilisateur présentes dans l'annuaire de Tela Botanica$infosAnnuaire = $this->obtenirInfosAnnuaire($login);$this->setInfosAnnuaire($infosAnnuaire);if ($mot_de_passe == 'debug' && $utilisateur_existant = $this->chargerUtilisateur($login)) {$this->setUtilisateur($utilisateur_existant, $permanence);return true;} else {$mot_de_passe_sha1 = sha1($mot_de_passe);$mot_de_passe_md5 = md5($mot_de_passe);if ($utilisateur_existant = $this->chargerUtilisateur($login, $mot_de_passe_sha1)) {// OK, nous poursuivons} else if ($utilisateur_existant = $this->chargerUtilisateur($login, $mot_de_passe_md5)) {// Mise à jour du mot de passe md5 en sha1$this->mettreAJourMotDePasse($login, $mot_de_passe_md5, $mot_de_passe_sha1);$utilisateur_existant['mot_de_passe'] = $mot_de_passe_sha1;}// Vérification de la nécessité de mettre à jour l'utilisateur du COEL vis à vis de l'annuaire de Tela Botanicaif (!is_null($infosAnnuaire) && $this->avoirBesoinMiseAJour($utilisateur_existant)) {$this->debug[] = "Besoin d'une mise à jour";// Vérifions que la personne s'est bien identifiéeif ($infosAnnuaire['mot_de_passe'] == $mot_de_passe_md5) {$this->debug[] = "Identification correcte avec md5";$utilisateur_existant = $this->getInfoAnnuaireCoelDepuisInfoAnnuaireDistant($mot_de_passe_sha1, $infosAnnuaire);$presence_dans_coel = $this->verifierPresenceUtilisateur($infosAnnuaire['id']);$this->debug[] = "Presence:$presence_dans_coel";if ($presence_dans_coel) {// Nécessite de faire une mise à jour$this->debug[] = "Mise à jour de l'utilisateur {$infosAnnuaire['id']}";$this->mettreAJourUtilisateur($login, $mot_de_passe_sha1, $infosAnnuaire);$utilisateur_existant['licence'] = (int) $this->recupererLicenceUtilisateur($infosAnnuaire['id']);} else {// Nécessite d'ajouter le nouvel utilisateur$this->debug[] = "Ajout d'une nouvel utilisateur";$this->ajouterUtilisateurACoel($infosAnnuaire, $mot_de_passe_sha1);}$this->setUtilisateur($utilisateur_existant, $permanence);} else {$this->debug[] = "Identification INCORRECTE avec md5";return false;}} else if ($utilisateur_existant != false) {// L'utilisateur est toutefois présent dans l'annuaire de COEL, est correctement identifié et n'a pas besoin de mise à jour$this->setUtilisateur($utilisateur_existant, $permanence);} else {// L'utilisateur n'existe ni dans l'annuaire de Tela Botanica ni dans celui de COELreturn false;}// L'utilisateur a t il accepté la licence? Nécessaire pour être connecté!if ($utilisateur_existant['licence'] == 1) {return true;} else {return false;}}}private function avoirBesoinMiseAJour($info_annuaire_coel) {$necessite_maj = false;if ($info_annuaire_coel == false) {// Le login et/ou le mot de passe a pu changer$necessite_maj = true;} else {$info_annuaire_distant = $this->getInfosAnnuaire();if ($this->comparerInfosAnnuairesDistantEtCoel($info_annuaire_distant, $info_annuaire_coel) == false) {$necessite_maj = true;}}return $necessite_maj;}private function comparerInfosAnnuairesDistantEtCoel($annuaire_distant, $annuaire_coel) {$identique = true;$tableau_annuaire_distant = array('nom' => $annuaire_distant['nom'],'prenom' => $annuaire_distant['prenom'],'ville' => $annuaire_distant['ville'],'code_postal' => $annuaire_distant['code_postal']);$tableau_annuaire_coel = array('nom' => $annuaire_coel['nom'],'prenom' => $annuaire_coel['prenom'],'ville' => $annuaire_coel['ville'],'code_postal' => $annuaire_coel['code_postal']);foreach ($tableau_annuaire_distant as $cle => $valeur) {if ($tableau_annuaire_coel[$cle] != $valeur) {$identique = false;break;}}return $identique;}private function getInfoAnnuaireCoelDepuisInfoAnnuaireDistant($mot_de_passe_sha1, $infos) {$cp_fmt_nom_complet = $infos['prenom'].' '.$infos['nom'];$utilisateur_existant = array('id' => $infos['id'], 'login' => $infos['courriel'],'mot_de_passe' => $mot_de_passe_sha1,'nom_complet' => $cp_fmt_nom_complet, 'nom' => $infos['nom'], 'prenom' => $infos['prenom'],'parametre' => '', 'licence' => '0');return $utilisateur_existant;}private function verifierPresenceUtilisateur($id) {$present = false;$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];$requete = 'SELECT COUNT(cp_id_personne) AS nbre '.'FROM coel_personne '."WHERE cp_ce_annuaire = {$this->bdd->quote($id)} "." AND cp_ce_annuaire = cp_id_personne ";try {$nbre = $this->bdd->query($requete)->fetchColumn();if (0 == $nbre) {$this->debug[] = "Utilisateur NON présent dans l'annuaire de COEL.";} else if (1 == $nbre) {$this->debug[] = "Utilisateur présent dans l'annuaire de COEL.";$present = true;} else if (false === $nbre) {$this->debug[] = "Erreur dans la requête de vérification de présence dans l'annuaire de COEL.";}} catch (PDOException $e) {$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage());}return $present;}private function recupererLicenceUtilisateur($id) {$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];$requete = 'SELECT cp_mark_licence '.'FROM coel_personne '."WHERE cp_ce_annuaire = {$this->bdd->quote($id)} "." AND cp_ce_annuaire = cp_id_personne ";try {$licence = $this->bdd->query($requete)->fetchColumn();if ($licence === false) {$this->debug[] = "La licence n'a pas pu être récupérée.";return 0;} else {return $licence;}} catch (PDOException $e) {$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage());}}private function mettreAJourMotDePasse($login, $mot_de_passe_md5, $mot_de_passe_sha1) {try {$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];$requete = 'UPDATE coel_personne '."SET cp_mot_de_passe = '$mot_de_passe_sha1' "."WHERE cp_login = '$login' "." AND cp_mot_de_passe = '$mot_de_passe_md5' ";// Ajout des données$resultat = $this->bdd->exec($requete);if ($resultat === false) {$this->messages[] = "Le mot de passe de l'utilisateur n'a pas été mis à jour car la requête a échouée.";}} catch (PDOException $e) {$messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete);}}private function mettreAJourUtilisateur($login, $mot_de_passe_sha1, $infos) {try {$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];$cp_fmt_nom_complet = $infos['prenom'].' '.$infos['nom'];$requete = 'UPDATE coel_personne '."SET cp_id_personne = '{$infos['id']}', "." cp_fmt_nom_complet = '$cp_fmt_nom_complet', cp_prenom = '{$infos['prenom']}', cp_nom = '{$infos['nom']}', "." cp_code_postal = '{$infos['code_postal']}', cp_ville = '{$infos['ville']}', cp_truk_courriel = '{$infos['courriel']}', "." cp_login = '{$infos['courriel']}', cp_mot_de_passe = '$mot_de_passe_sha1', cp_ce_annuaire = '{$infos['id']}' "."WHERE cp_login = '$login' "." AND cp_mot_de_passe = '{$infos['mot_de_passe']}' ";// Ajout des données$resultat = $this->bdd->exec($requete);if ($resultat === false) {$this->messages[] = "L'utilisateur n'a pas été mis à jour car la requête a échouée.";}} catch (PDOException $e) {$messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete);}}private function ajouterUtilisateurACoel($infos, $mot_de_passe_sha1) {try {// Construction de la requête d'ajout// Notes : pour rester compatibles avec l'annuaire de Tela, les utilisateurs sont ajoutés directement avec l'id// de l'annuaire Tela. Dans CoelPersonne, les personnes qui ne sont pas utilisateur sont ajoutés avec un id supérieur à 100 000$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];$cp_fmt_nom_complet = $infos['prenom'].' '.$infos['nom'];$cp_mark_licence = '0';$requete = 'INSERT INTO coel_personne '.' (cp_id_personne, cp_ce_projet, cp_fmt_nom_complet, cp_prenom, cp_nom, cp_code_postal, '.' cp_ville, cp_truk_courriel, cp_login, cp_mot_de_passe, cp_ce_annuaire, cp_mark_licence) '."VALUES ('{$infos['id']}', '$cp_ce_projet', '$cp_fmt_nom_complet', '{$infos['prenom']}', '{$infos['nom']}', "."'{$infos['code_postal']}', '{$infos['ville']}', '{$infos['courriel']}', '{$infos['courriel']}', '".$mot_de_passe_sha1."', "."'{$infos['id']}', $cp_mark_licence) ";//$this->debug[] = $requete;// Ajout des données$resultat = $this->bdd->exec($requete);if ($resultat === false) {$this->debug[] = "Utilisateur NON ajouté dans coel_personne car la requête a échouée.";} else {$this->debug[] = "Utilisateur ajouté à coel_personne.";}} catch (PDOException $e) {$messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete);}}private function souvenirUtilisateur($login, $mot_de_passe_sha1) {if ($login == '' && $mot_de_passe_sha1 == '') {return false;} else if ($utilisateur_existant = $this->chargerUtilisateur($login, $mot_de_passe_sha1)) {if ($utilisateur_existant['mot_de_passe'] == $mot_de_passe_sha1) {$this->setUtilisateur($utilisateur_existant, $_COOKIE['coel_permanence']);return true;} else {return false;}}}private function obtenirInfosAnnuaire($login) {$url_annuaire = $this->config['coel']['urlAnnuaire'];$login_annuaire = $this->config['coel']['loginAnnuaire'];$mdp_annuaire = $this->config['coel']['mdpAnnuaire'];$login_b64 = base64_encode($login_annuaire.':'.$mdp_annuaire);$url_annuaire .= '/'.$login_b64.'/'.$login;$resultat_annuaire = file_get_contents($url_annuaire);$tableau_annuaire = null;if ($xml_utilisateur = simplexml_load_string($resultat_annuaire)) {// La fonction a retourné un objetforeach ($xml_utilisateur->children() as $key => $val) {if ((string) $val != '') {$tableau_annuaire[$key] = (String) $val;}}}return $tableau_annuaire;}private function setInfosAnnuaire($infosAnnuaire) {$_SESSION['coel_infosAnnuaire'] = $infosAnnuaire;}private function accepterLicence($login) {$sortie = false;try {$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];$requete = 'UPDATE coel_personne '.'SET cp_mark_licence = 1 '."WHERE cp_login = {$this->bdd->quote($login)} ";$resultat = $this->bdd->exec($requete);if ($resultat === false) {$this->debug[] = "La table Personne n'a pas été mise à jour car la requête a échouée.";} else {$this->debug[] = "Création du cookie licence.";$_SESSION['coel_utilisateur']['licence'] = '1';$this->setCookiePersistant('coel_licence', '1');$sortie = true;}} catch (PDOException $e) {$messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete);}return $sortie;}}?>