* @author David DELON abstract * @license GPL v3 * @license CECILL v2 * @version $Id$ * @copyright 2009 */ class CoelUtilisateur extends Coel { private $licence_acceptee = false; // TODO : controle systematique... dans tous les services si connected : name cookie = name service public function getRessource(){ $this->getElement(array('*','*')); } public function getElement($param){ $identification = false; $info = array(); // Si la licence n'a pas été accepté nous réinitialisons tout if (!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 licence if (isset($param[2])) { $this->debug[] = "Licence acceptee"; $this->licence_acceptee = true; // Mise à jour de la licence if (!$this->accepterLicence($param[0])) { $this->debug[] = "Erreur de mise à jour licence utilisateur"; } } else if (isset($param[1])) { // Non connecté : vérification if (!$this->getUtilisateur()) { // Si non identifié $id = null; if ($param[0] == '*' && $param[1] == '*') { // Tentative d'identification depuis les cookies permanents if (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 identifiant if (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 Botanica if (!is_null($infosAnnuaire) && $this->avoirBesoinMiseAJour($utilisateur_existant)) { $this->debug[] = "Besoin d'une mise à jour"; // Vérifions que la personne s'est bien identifiée if ($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 COEL return 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; $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) { $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 { $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_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_fmt_nom_complet = $infos['prenom'].' '.$infos['nom']; $cp_mark_licence = '0'; $requete = 'INSERT INTO coel_personne '. ' (cp_id_personne, 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_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 objet foreach ($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 { $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; } } ?>