/trunk/doc/bdd/.~lock.annuaire_vocabulaire.ods# |
---|
File deleted |
\ No newline at end of file |
/trunk/jrest/bibliotheque/JRestService.php |
---|
526,5 → 526,41 |
$contenu = preg_replace("/;*\s*\?>/", "; ?>", $contenu); |
return $contenu; |
} |
/** |
* Crée un nom Wiki (de la forme "JeanTalus") à partir des données de l'utilisateur; |
* gère l'utilisation du pseudo mais pas la collision de noms Wiki @TODO s'en occuper |
* |
* @param array $infos des infos de profil utilisateur - on admet qu'elles contiennent "intitule" |
* @return string un nom wiki correspondant à l' "intitulé" de l'utilisateur (prénom-nom ou pseudo) |
* ou la valeur par défaut de $defaut si celui-ci est fourni et si le nom Wiki n'a pu être construit |
*/ |
public function formaterNomWiki($intitule, $defaut="ProblemeNomWiki") { |
$nw = $this->convertirEnCamelCase($intitule); |
// on sait jamais |
if ($nw == "") { |
$nw = $defaut; |
} |
return $nw; |
} |
protected function convertirEnCamelCase($str) { |
// Suppression des accents |
$str = $this->supprimerAccents($str); |
// Suppression des caractères non alphanumériques |
$str = preg_replace('/[^\da-z]/i', '', ucwords(strtolower($str))); |
return $str; |
} |
protected function supprimerAccents($str, $charset='utf-8') { |
$str = htmlentities($str, ENT_NOQUOTES, $charset); |
$str = preg_replace('#&([A-za-z])(?:acute|cedil|caron|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str); |
$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); // pour les ligatures e.g. 'œ' |
$str = preg_replace('#&[^;]+;#', '', $str); // supprime les autres caractères |
return $str; |
} |
} |
?> |
/trunk/jrest/services/Utilisateur.php |
---|
84,42 → 84,6 |
} |
/** |
* Crée un nom Wiki (de la forme "JeanTalus") à partir des données de l'utilisateur; |
* gère l'utilisation du pseudo mais pas la collision de noms Wiki @TODO s'en occuper |
* |
* @param array $infos des infos de profil utilisateur - on admet qu'elles contiennent "intitule" |
* @return string un nom wiki correspondant à l' "intitulé" de l'utilisateur (prénom-nom ou pseudo) |
* ou la valeur par défaut de $defaut si celui-ci est fourni et si le nom Wiki n'a pu être construit |
*/ |
public function formaterNomWiki($infos, $defaut="ProblemeNomWiki") { |
$nw = $this->convertirEnCamelCase($infos['intitule']); |
// on sait jamais |
if ($nw == "") { |
$nw = $defaut; |
} |
return $nw; |
} |
protected function convertirEnCamelCase($str) { |
// Suppression des accents |
$str = $this->supprimerAccents($str); |
// Suppression des caractères non alphanumériques |
$str = preg_replace('/[^\da-z]/i', '', ucwords(strtolower($str))); |
return $str; |
} |
protected function supprimerAccents($str, $charset='utf-8') { |
$str = htmlentities($str, ENT_NOQUOTES, $charset); |
$str = preg_replace('#&([A-za-z])(?:acute|cedil|caron|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str); |
$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str); // pour les ligatures e.g. 'œ' |
$str = preg_replace('#&[^;]+;#', '', $str); // supprime les autres caractères |
return $str; |
} |
/** |
* Permet d'obtenir des infos pour un ou plusieurs ids utilisateurs indiqué(s) dans la ressource. |
* RESSOURCE : /infos-par-ids/#id[,#id]* |
* PARAMÈTRES : forceArrayOfArrays - si true, retourne un tableau associatif même s'il n'y a qu'un |
155,6 → 119,18 |
return $infos; |
} |
// proxy pour AnnuaireModele::obtenirIdParMail() car le présent service |
// est utilisé comme une lib => c'est MAL ! @TODO séparer lib et service !! |
public function getIdParCourriel($courriel) { |
return $this->getAnnuaire()->obtenirIdParMail($this->idAnnuaire, $courriel); |
} |
// proxy pour AnnuaireModele::inscrireUtilisateurCommeUnGrosPorc() car le présent service |
// est utilisé comme une lib => c'est MAL ! @TODO séparer lib et service !! |
public function inscrireUtilisateurCommeUnGrosPorc($donnees) { |
return $this->getAnnuaire()->inscrireUtilisateurCommeUnGrosPorc($donnees); |
} |
/** |
* Méthode rétrocompatible : appelle getInfosParIds et s'il n'y a qu'un résultat, |
* ne retourne pas un tableau associatif mais un tableau simple |
198,7 → 174,7 |
$utilisateur['pseudo'] = $this->obtenirPseudo($id); |
$utilisateur['pseudoUtilise'] = $this->obtenirPseudoUtilise($id); |
$utilisateur['intitule'] = $this->formaterIntitule($utilisateur); |
$utilisateur['nomWiki'] = $this->formaterNomWiki($utilisateur); |
$utilisateur['nomWiki'] = $this->formaterNomWiki($utilisateur['intitule']); |
$courriel = strtolower($courriel); |
$infos_utilisateurs[$courriel] = $utilisateur; |
} |
435,7 → 411,7 |
$this->messages[] = "Ce type de méthode '$methode_demande' n'est pas disponible pour la requete PUT."; |
} |
} else { |
$this->messages[] = "Ce service n'est pas implémanté."; |
$this->messages[] = "Ce service n'est pas implémenté."; |
} |
if (!is_null($infos)) { |
/trunk/jrest/services/auth/AuthPartnerPlantnet.php |
---|
13,38 → 13,51 |
$curl = curl_init(); |
curl_setopt($curl, CURLOPT_URL, $url); |
curl_setopt($curl, CURLOPT_POST, true); |
curl_setopt($curl, CURLOPT_POSTFIELDS, array()); // nécessaire dans les versions modernes de libcurl sinon on se prend un 400 ! |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); |
$res = curl_exec($curl); |
curl_close($curl); |
//var_dump($res); |
$res = json_decode($res, true); |
//var_dump($res); |
if (!empty($res['JWT'])) { |
$jeton = $this->lib->decoderJetonManuellement($res['JWT']); |
$this->jetonPartenaire = $res['JWT']; |
$jetonDecode = $this->auth->decoderJetonManuellement($this->jetonPartenaire); |
// stockage pour traitement dans les autres méthodes |
$this->data = $jeton; |
$this->data = $jetonDecode['details']; |
//var_dump($jeton); |
if (!empty($jeton['details']['email'])) { |
//var_dump($jeton['details']['email']); |
if ( !empty($this->data['email'])) { |
//var_dump($this->data['email']); |
return true; |
} |
} |
return false; |
} |
public function getIdentiteParCourriel() { |
protected function getNomPartenaire() { |
return "plantnet"; |
} |
echo "get identité par courriel<br/>"; |
protected function getCourriel() { |
return $this->data['email']; |
} |
public function formaterNomWiki() { |
protected function getId() { |
// la clef primaire est le "username" dans Pl@ntNet, apparemment |
return $this->data['username']; |
} |
echo "formater nom wiki<br/>"; |
protected function getValeursProfilPartenaire() { |
return array( |
'nom' => $this->data['lastname'], |
'prenom' => $this->data['firstname'], |
'email' => $this->data['email'], |
'pseudo' => $this->data['username'] |
); |
} |
public function getDateDerniereModifProfil() { |
echo "get date dernière modif profil<br/>"; |
/*public function getTimestampMajPartenaire() { |
return 420000000000; |
}*/ |
} |
} |
/trunk/jrest/services/auth/AuthPartner.php |
---|
3,17 → 3,117 |
abstract class AuthPartner { |
/** Injection de dépendance du service Auth, pour utiliser les méthodes comme decoderJetonManuellement() */ |
protected $lib; |
protected $auth; |
/** Données retournées par le service d'authentification du partenaire */ |
/** Injection de dépendance de la lib Utilisateur depuis le service Auth */ |
protected $utilisateur; |
/** Jeton brut retourné par le service d'authentification du partenaire */ |
protected $jetonPartenaire; |
/** Données décodées depuis le jeton du partenaire */ |
protected $data; |
/** Identifiant de l'utilisateur dans l'annuaire local, ou false s'il n'existe pas */ |
protected $idLocal; |
public function __construct($authLib) { |
$this->lib = $authLib; |
$this->auth = $authLib; |
$this->utilisateur = $authLib->getUtilisateur(); |
$this->idLocal = false; |
} |
/** Retourne true si l'utilisateur est authentifié par le partenaire */ |
public abstract function verifierAcces($login, $password); |
public abstract function getIdentiteParCourriel(); |
public abstract function formaterNomWiki(); |
public abstract function getDateDerniereModifProfil(); |
/** |
* Vérifie si l'annuaire contient déjà une entrée associée au |
* courriel de l'utilisateur et l'ajoute ou la met à jour au besoin |
*/ |
public function synchroniser() { |
$courriel = $this->getCourriel(); |
// l'utilisateur existe-t-il déjà ? |
$this->idLocal = $this->utilisateur->getIdParCourriel($courriel); |
if ($this->idLocal !== false) { |
if (! $this->profilEstAJour()) { |
$this->mettreAJourProfil(); |
} |
} else { |
$this->inscrireUtilisateur(); |
} |
} |
/** |
* Retourne true si le profil local est à jour par rapport à la date |
* de dernière modification fournie par le partenaire; si une telle |
* date n'existe pas, retourne $retourSiPasDeDate (true par défaut - on |
* ne met pas à jour) |
*/ |
protected function profilEstAJour($retourSiPasDeDate=true) { |
$tsMajPartenaire = $this->getTimestampMajPartenaire(); |
//echo "Timestamp partenaire : "; var_dump($tsMajPartenaire); echo "<br/>"; |
if ($tsMajPartenaire != null) { |
$dateMajLocale = $this->utilisateur->getDateDerniereModifProfil($this->idLocal); |
$tsMajLocale = strtotime($dateMajLocale); // attention à ne pas changer le format de date ! |
//echo "Timestamp local : "; var_dump($tsMajLocale); echo "<br/>"; |
return ($tsMajLocale >= $tsMajPartenaire); |
} |
// Si le partenaire ne fournit pas de date, on retourne la valeur par défaut |
return $retourSiPasDeDate; |
} |
/** |
* Retourne le nom du partenaire en cours |
*/ |
protected abstract function getNomPartenaire(); |
/** |
* Retourne le courriel de l'utilisateur fourni par le partenaire |
*/ |
protected abstract function getCourriel(); |
/** |
* Retourne l'identifiant de l'utilisateur fourni par le partenaire |
*/ |
protected abstract function getId(); |
/** |
* Retourne le timestamp de dernière mise à jour du profil fournie par le |
* partenaire; par défaut retourne null, ce qui laisse au mécanisme de |
* synchronisation le soin de décider si on met à jour le profil ou non |
*/ |
protected function getTimestampMajPartenaire() { |
return null; |
} |
/** |
* Retourne le jeton fourni par le partenaire |
*/ |
public function getJetonPartenaire() { |
return $this->jetonPartenaire; |
} |
/** |
* Retourne un tableau de valeurs correpondant au profil de l'utilisateur, |
* fourni par le partenaire, et contenant au minimum : |
* - nom |
* - prenom |
* - pseudo |
* Pour les autres champs possibles, voir AnnuaireModele::inscrireUtilisateurCommeUnGrosPorc() |
*/ |
protected abstract function getValeursProfilPartenaire(); |
protected function inscrireUtilisateur() { |
$valeursProfil = $this->getValeursProfilPartenaire(); |
$valeursProfil['partenaire'] = $this->getNomPartenaire(); |
$valeursProfil['id_partenaire'] = $this->getId(); |
// gruik gruik |
$this->utilisateur->inscrireUtilisateurCommeUnGrosPorc($valeursProfil); |
} |
protected function mettreAJourProfil() { |
throw new Exception("La mise à jour du profil n'est pas encore prise en charge"); |
$valeursProfil = $this->getValeursProfilPartenaire(); |
} |
} |
/trunk/jrest/services/Auth.php |
---|
28,6 → 28,9 |
/** Nom du cookie */ |
protected $nomCookie = "this_is_not_a_good_cookie_name"; |
/** Bibliothèque de gestion des utilisateurs */ |
protected $utilisateur; |
public function __construct($config, $demarrer_session = true) { |
parent::__construct($config, $demarrer_session); |
$this->clef = file_get_contents("clef-auth.ini"); |
38,9 → 41,20 |
$this->dureeJeton = $this->config['auth']['duree_jeton']; |
$this->dureeCookie = $this->config['auth']['duree_cookie']; |
$this->nomCookie = $this->config['auth']['nom_cookie']; |
// gestion des utilisateurs @WARNING on utilise un service comme une lib, c'est |
// mal !! @TODO séparer service et lib (ou réécrire tout ce foutoir) |
$this->utilisateur = new Utilisateur($config); |
} |
/** |
* Retourne la bobliothèque de gestion des utilisateurs (pour utilisation |
* par les classes partenaires) |
*/ |
public function getUtilisateur() { |
return $this->utilisateur; |
} |
/** |
* Notice d'utilisation succincte |
* @TODO essayer de choisir entre anglais et français |
*/ |
192,19 → 206,26 |
$this->erreur("parameters <login> and <password> required"); |
} |
$acces = false; |
$objAuth = null; |
// connexion à un partenaire ? |
$infosPartenaire = array(); |
if ($partenaire != '') { |
$classeAuth = "AuthPartner" . ucfirst(strtolower($partenaire)); |
try { |
$fichierClasse = "auth/$classeAuth.php"; |
/*if (! file_exists($fichierClasse)) { |
$this->erreur('unknown partner "' . $partenaire . '"'); |
}*/ |
$fichierClasse = getcwd() . "/services/auth/$classeAuth.php"; // @TODO vérifier si getcwd() est fiable dans ce cas |
if (! file_exists($fichierClasse)) { |
$this->erreur("unknown partner '$partenaire'"); |
} |
require $fichierClasse; |
$objAuth = new $classeAuth($this); |
$authPartenaire = new $classeAuth($this); |
// authentification par le partenaire |
$acces = $objAuth->verifierAcces($login, $password); |
$acces = $authPartenaire->verifierAcces($login, $password); |
if ($acces === true) { |
// copie des infos dans l'annuaire si besoin |
$authPartenaire->synchroniser(); |
} |
// détails à ajouter au jeton local |
$infosPartenaire['partenaire'] = $partenaire; |
$infosPartenaire['jetonPartenaire'] = $authPartenaire->getJetonPartenaire(); |
} catch(Exception $e) { |
$this->erreur($e->getMessage(), 500); |
} |
211,8 → 232,6 |
} else { |
// authentification locale |
$acces = $this->verifierAcces($login, $password); |
// faux polylmorphisme pour éviter des "if" partout |
$objAuth = new Utilisateur($this->config); |
} |
if ($acces === false) { |
$this->detruireCookie(); |
222,7 → 241,8 |
$this->erreur("authentication failed", 401); |
} |
// infos utilisateur |
$infos = $objAuth->getIdentiteParCourriel($login); |
$infos = $this->utilisateur->getIdentiteParCourriel($login); |
//var_dump($infos); exit; |
// getIdentiteParCourriel retourne toujours le courriel comme clef de tableau en lowercase |
$login = strtolower($login); |
if (count($infos) == 0 || empty($infos[$login])) { |
231,13 → 251,14 |
// si la redirection n'a pas eu lieu |
$this->erreur("could not get user info"); |
} |
// nom Wiki |
$infos[$login]['nomWiki'] = $objAuth->formaterNomWiki($infos[$login], "UnknownWikiName"); |
$infos = $infos[$login]; |
// date de dernière modification du profil |
$dateDerniereModif = $objAuth->getDateDerniereModifProfil($infos[$login]['id'], true); |
$infos[$login]['dateDerniereModif'] = $dateDerniereModif; |
$dateDerniereModif = $this->utilisateur->getDateDerniereModifProfil($infos['id'], true); |
$infos['dateDerniereModif'] = $dateDerniereModif; |
// infos partenaire |
$infos = array_merge($infos, $infosPartenaire); |
// création du jeton |
$jwt = $this->creerJeton($login, $infos[$login]); |
$jwt = $this->creerJeton($login, $infos); |
// création du cookie |
$this->creerCookie($jwt); |
// redirection si demandée - se charge de sortir du script en cas de succès |
248,7 → 269,7 |
"token" => $jwt, |
"duration" => intval($this->dureeJeton), |
"token_id" => $this->nomCookie, |
"last_modif" => $infos[$login]['dateDerniereModif'] |
"last_modif" => $infos['dateDerniereModif'] |
)); |
} |
/trunk/modeles/AnnuaireModele.php |
---|
1277,4 → 1277,63 |
} |
return false; |
} |
/** |
* Puisqu'il n'y a pas la moindre méthode métier un peu propre pour inscrire un utilisateur, on |
* va devoir tout faire à la main comme un verrat grassouilet. |
* @WARNING c'est TRES TRES MAL de faire ça, ça casse la généricité, le multi-annuaire et tous les |
* trucs mégachiants qui... euh... servent à rien en pratique :-/ mais bon c'est mal |
*/ |
public function inscrireUtilisateurCommeUnGrosPorc($donnees) { |
//echo "GRUIIIIK !!! "; |
$donneesDefaut = array('nom' => '', 'prenom' => '', 'fonction' => '', 'titre' => '', |
'password' => '', 'email' => '', 'url' => '', 'addr1' => '', 'addr2' => '', 'code_postal' => '', |
'ville' => '', 'etat' => '', 'pays' => '', 'departement' => '' |
); |
$donnees = array_merge($donneesDefaut, $donnees); |
// 1) table principale de l'annuaire |
$req = "INSERT INTO annuaire_tela VALUES(DEFAULT, '" |
. $donnees['nom'] . "', '" |
. $donnees['prenom'] . "', '" |
. $donnees['fonction'] . "', '" |
. $donnees['titre'] . "', '" |
. $donnees['password'] . "', '" |
. $donnees['email'] . "', '" |
. $donnees['url'] . "', '" |
. $donnees['addr1'] . "', '" |
. $donnees['addr2'] . "', '" |
. $donnees['code_postal'] . "', '" |
. $donnees['ville'] . "', '" |
. $donnees['etat'] . "', '" |
. $donnees['pays'] . "', '" |
. $donnees['departement'] . "', '', NULL, '', '', 0, 1, CURRENT_TIMESTAMP, NULL, 0, 0);"; |
//echo $req; $res = true; |
$res = $this->requete($req); |
if ($res) { |
// 2) récupération de l'ID à la wanagain |
$id = $this->obtenirIdParMail(1, $donnees['email']); |
//echo "ID: "; var_dump($id); |
if ($id) { |
// 3) métadonnées : pseudo et infos partenaire |
// @WARNING les ids des colonnes peuvent différer d'une base à l'autre, méga cracra ! |
$req2 = "INSERT INTO annu_meta_valeurs VALUES" |
. "(DEFAULT, 136, $id, 1)," // pseudo utilisé |
. "(DEFAULT, 99, $id, '" . $donnees['pseudo'] . "')," // pseudo |
. "(DEFAULT, 144, $id, '" . $donnees['partenaire'] . "')," // partenaire |
. "(DEFAULT, 145, $id, '" . $donnees['id_partenaire'] . "')" // id_partenaire |
; |
//echo $req2; |
$res2 = $this->requete($req2); |
// 4) date de dernière modification |
$req3 = "INSERT INTO annu_triples VALUES (DEFAULT, 1, $id, 'modification', CURRENT_TIMESTAMP)"; |
$res3 = $this->requete($req3); |
// pas grave si la ddm a raté |
return ($res2 != false); |
} |
} |
return false; |
} |
} |