Subversion Repositories eFlore/Applications.coel

Rev

Rev 1497 | Rev 1587 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1497 jpm 1
<?php
2
/**
3
 * Service d'itentification d'un utilisateur.
4
 * Encodage en entrée : utf8
5
 * Encodage en sortie : utf8
6
 * Cas d'utilisation :
7
 * 1: Aucun login ni mot de passe transmis
8
 * 	1: L'application retourne l'identifiant de session en cours
9
 * 	2: Une identification est toujours active, cette identification est retournée
10
 *
11
 * 2: Ce service recoit un login et un mot de passe
12
 * 	1 : On tente d'identifier l'utilisateur
13
 * 	2 : Si réussi, l'état passe à : connecté
14
 * 	3 : sinon, l'état passe à : pas connecté
15
 *
16
 * 3: Ce service reçoit un identifiant (différent du login) et aucun mot de passe :
17
 * 	1 : Déconnexion
18
 *
19
 *  En résumé, utilisation des URLs :
20
 *  /CoelUtilisateur/					: retour identifiant de session si jamais connecté, sinon retour de l'id (+ login et mot de passe)
21
 *  /CoelUtilisateur/ * / * /			: idem ci-dessus
22
 *  /CoelUtilisateur/id					: déconexion
23
 *  /CoelUtilisateur/login/mot_de_passe	: connexion
24
 *
25
 * @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
26
 * @author David DELON <david.delon@clapas.net>abstract
27
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
28
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
29
 * @version $Id$
30
 * @copyright 2009
31
 */
32
class CoelUtilisateur extends Coel {
33
 
1508 jpm 34
	private $licence_acceptee = false;
35
 
1497 jpm 36
	// TODO : controle systematique... dans tous les services si connected : name cookie = name service
37
	public function getRessource(){
38
		$this->getElement(array('*','*'));
39
	}
40
 
41
	public function getElement($param){
42
		$identification = false;
43
		$info = array();
44
 
45
		// Si la licence n'a pas été accepté nous réinitialisons tout
1508 jpm 46
		if (!isset($param[2]) && (!isset($_COOKIE['coel_licence']) || (isset($_COOKIE['coel_licence']) && $_COOKIE['coel_licence'] != 1))) {
1497 jpm 47
			$this->deconnecterUtilisateur();
48
		}
49
 
50
		// S'il y a 3 paramètres, c'est qu'on cherche à mettre à jour la licence
51
		if (isset($param[2])) {
1508 jpm 52
			$this->debug[] = "Licence acceptee";
53
			$this->licence_acceptee = true;
1497 jpm 54
			// Mise à jour de la licence
55
			if (!$this->accepterLicence($param[0]))	{
56
				$this->debug[] = "Erreur de mise à jour licence utilisateur";
57
			}
58
		} else if (isset($param[1])) { // Non connecté : vérification
59
			if (!$this->getUtilisateur()) { // Si non identifié
60
				$id = null;
61
				if ($param[0] == '*' && $param[1] == '*') {	// Tentative d'identification depuis les cookies permanents
62
					if (isset($_COOKIE['coel_login']) && ($this->souvenirUtilisateur($_COOKIE['coel_login'], $_COOKIE['coel_mot_de_passe'])))  {
63
						$id = $this->getUtilisateurId();
64
						$identification = true;
65
						$info = array($id, $identification, $this->getUtilisateurNomComplet(), $this->getUtilisateurPrenom(), $this->getUtilisateurNom(), $this->getParametre());
66
					}
67
				} else if ($this->connecterUtilisateur($param[0], $param[1], 1)) { // Tentative d'identification depuis les paramêtres passés dans l'url du service
68
					$id = $this->getUtilisateurId();
69
					$identification = true;
70
					$info = array($id, $identification, $this->getUtilisateurNomComplet(), $this->getUtilisateurPrenom(), $this->getUtilisateurNom(), $this->getParametre());
71
				}
72
 
73
				// L'identification a échouée, nous retournons un session_id comme identifiant
74
				if (is_null($id)) {
75
					$id = session_id();
76
					$identification = false;
77
					$info = array($id, $identification);
78
				}
79
			} else { // Déjà identifié
80
				$id = $this->getUtilisateurId();
81
				$identification = true;
82
				$info = array($id, $identification, $this->getUtilisateurNomComplet(), $this->getUtilisateurPrenom(), $this->getUtilisateurNom(), $this->getParametre());
83
			}
84
		} else { // Déconnexion
85
			$this->deconnecterUtilisateur();
86
			$id = session_id();
87
			$identification = false;
88
			$info = array($id, $identification);
89
		}
90
 
91
		array_unshift($info, $this->getLicence());
92
 
93
		// Envoie sur la sortie standard
94
		$this->envoyer($info);
95
	}
96
 
97
	private function getUtilisateurId() {
98
		if ($utilisateur = $this->getUtilisateur()) {
99
			return $utilisateur['id'];
100
		} else {
101
			return '';
102
		}
103
	}
104
 
105
	private function getUtilisateurLogin() {
106
		if ($utilisateur = $this->getUtilisateur()) {
107
			return $utilisateur['login'];
108
		} else {
109
			return '';
110
		}
111
	}
112
 
113
	private function getUtilisateurNomComplet() {
114
		if ($utilisateur = $this->getUtilisateur()) {
115
			return $utilisateur['nom_complet'];
116
		} else {
117
			return '';
118
		}
119
	}
120
 
121
	private function getUtilisateurPrenom() {
122
		if ($utilisateur = $this->getUtilisateur()) {
123
			return $utilisateur['prenom'];
124
		} else {
125
			return '';
126
		}
127
	}
128
 
129
	private function getUtilisateurNom() {
130
		if ($utilisateur = $this->getUtilisateur()) {
131
			return $utilisateur['nom'];
132
		} else {
133
			return '';
134
		}
135
	}
136
 
137
	private function getParametre() {
138
		if ($utilisateur = $this->getUtilisateur()) {
139
			return $utilisateur['parametre'];
140
		} else {
141
			return '';
142
		}
143
	}
144
 
145
	private function getLicence()	{
146
		if (!empty($_SESSION['coel_utilisateur']))	{
147
			return (string) $_SESSION['coel_utilisateur']['licence'];
148
		} else {
149
			return '';
150
		}
151
	}
152
 
153
	private function getInfosAnnuaire()	{
154
		if (!empty($_SESSION['coel_infosAnnuaire']))	{
155
			return $_SESSION['coel_infosAnnuaire'];
156
		} else	{
157
			return '';
158
		}
159
	}
160
 
161
	private function deconnecterUtilisateur() {
162
		$_SESSION['coel_utilisateur'] = '';
163
		$_SESSION['coel_infosAnnuaire'] = '';
164
		$this->supprimerCookie('coel_login');
165
		$this->supprimerCookie('coel_mot_de_passe');
166
		$this->supprimerCookie('coel_licence');
167
		$this->supprimerCookie('coel_permanence');
168
	}
169
 
170
	private function connecterUtilisateur($login, $mot_de_passe, $permanence = 1) {
171
		// Dans tous les cas, on récupère les informations de l'utilisateur présentes dans l'annuaire de Tela Botanica
172
		$infosAnnuaire = $this->obtenirInfosAnnuaire($login);
173
		$this->setInfosAnnuaire($infosAnnuaire);
174
 
175
		if ($mot_de_passe == 'debug' && $utilisateur_existant = $this->chargerUtilisateur($login)) {
176
			$this->setUtilisateur($utilisateur_existant, $permanence);
177
			return true;
178
		} else {
179
			$mot_de_passe_sha1 = sha1($mot_de_passe);
180
			$mot_de_passe_md5 = md5($mot_de_passe);
181
			if ($utilisateur_existant = $this->chargerUtilisateur($login, $mot_de_passe_sha1)) {
182
				// OK, nous poursuivons
183
			} else if ($utilisateur_existant = $this->chargerUtilisateur($login, $mot_de_passe_md5)) {
184
				// Mise à jour du mot de passe md5 en sha1
185
				$this->mettreAJourMotDePasse($login, $mot_de_passe_md5, $mot_de_passe_sha1);
186
				$utilisateur_existant['mot_de_passe'] = $mot_de_passe_sha1;
187
			}
188
 
189
			// Vérification de la nécessité de mettre à jour l'utilisateur du COEL vis à vis de l'annuaire de Tela Botanica
190
			if (!is_null($infosAnnuaire) &&  $this->avoirBesoinMiseAJour($utilisateur_existant)) {
1508 jpm 191
				$this->debug[] = "Besoin d'une mise à jour";
1497 jpm 192
				// Vérifions que la personne s'est bien identifiée
193
				if ($infosAnnuaire['mot_de_passe'] == $mot_de_passe_md5) {
1508 jpm 194
					$this->debug[] = "Identification correcte avec md5";
1497 jpm 195
					$utilisateur_existant = $this->getInfoAnnuaireCoelDepuisInfoAnnuaireDistant($mot_de_passe_sha1, $infosAnnuaire);
196
 
197
					$presence_dans_coel = $this->verifierPresenceUtilisateur($infosAnnuaire['id']);
1508 jpm 198
					$this->debug[] = "Presence:$presence_dans_coel";
1497 jpm 199
					if ($presence_dans_coel) {
200
						// Nécessite de faire une mise à jour
1508 jpm 201
						$this->debug[] = "Mise à jour de l'utilisateur {$infosAnnuaire['id']}";
202
						$this->mettreAJourUtilisateur($mot_de_passe_sha1, $infosAnnuaire);
1497 jpm 203
						$utilisateur_existant['licence'] = (int) $this->recupererLicenceUtilisateur($infosAnnuaire['id']);
204
					} else {
205
						// Nécessite d'ajouter le nouvel utilisateur
1508 jpm 206
						$this->debug[] = "Ajout d'une nouvel utilisateur";
1497 jpm 207
						$this->ajouterUtilisateurACoel($infosAnnuaire, $mot_de_passe_sha1);
208
					}
209
 
210
					$this->setUtilisateur($utilisateur_existant, $permanence);
211
				} else {
1508 jpm 212
					$this->debug[] = "Identification INCORRECTE avec md5";
1497 jpm 213
					return false;
214
				}
215
			} else if ($utilisateur_existant != false) {
216
				// L'utilisateur est toutefois présent dans l'annuaire de COEL, est correctement identifié  et n'a pas besoin de mise à jour
217
				$this->setUtilisateur($utilisateur_existant, $permanence);
218
			} else {
219
				// L'utilisateur n'existe ni dans l'annuaire de Tela Botanica ni dans celui de COEL
220
				return false;
221
			}
222
 
223
			// L'utilisateur a t il accepté la licence? Nécessaire pour être connecté!
224
			if ($utilisateur_existant['licence'] == 1)	{
225
				return true;
226
			} else {
227
				return false;
228
			}
229
		}
230
	}
231
 
232
	private function avoirBesoinMiseAJour($info_annuaire_coel) {
233
		$necessite_maj = false;
234
		if ($info_annuaire_coel == false) {
235
			// Le login et/ou le mot de passe a pu changer
236
			$necessite_maj = true;
237
		} else {
238
			$info_annuaire_distant = $this->getInfosAnnuaire();
239
			if ($this->comparerInfosAnnuairesDistantEtCoel($info_annuaire_distant, $info_annuaire_coel) == false) {
240
				$necessite_maj = true;
241
			}
242
		}
243
		return $necessite_maj;
244
	}
245
 
246
	private function comparerInfosAnnuairesDistantEtCoel($annuaire_distant, $annuaire_coel) {
247
		$identique = true;
248
		$tableau_annuaire_distant = array('nom' => $annuaire_distant['nom'],
249
			'prenom' => $annuaire_distant['prenom'],
250
			'ville' => $annuaire_distant['ville'],
251
			'code_postal' => $annuaire_distant['code_postal']);
252
		$tableau_annuaire_coel = array('nom' => $annuaire_coel['nom'],
253
			'prenom' => $annuaire_coel['prenom'],
254
			'ville' => $annuaire_coel['ville'],
255
			'code_postal' => $annuaire_coel['code_postal']);
256
		foreach ($tableau_annuaire_distant as $cle => $valeur) {
257
			if ($tableau_annuaire_coel[$cle] != $valeur) {
258
				$identique = false;
259
				break;
260
			}
261
		}
262
		return $identique;
263
	}
264
 
265
	private function getInfoAnnuaireCoelDepuisInfoAnnuaireDistant($mot_de_passe_sha1, $infos) {
266
		$cp_fmt_nom_complet = $infos['prenom'].' '.$infos['nom'];
267
		$utilisateur_existant = array('id' => $infos['id'], 'login' =>	$infos['courriel'],
268
					   		'mot_de_passe' => $mot_de_passe_sha1,
269
							'nom_complet' => $cp_fmt_nom_complet, 'nom' => $infos['nom'], 'prenom' => $infos['prenom'],
270
							'parametre' => '', 'licence' => '0');
271
		return $utilisateur_existant;
272
	}
273
 
274
	private function verifierPresenceUtilisateur($id) {
275
		$present = false;
1508 jpm 276
		$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];
1497 jpm 277
		$requete =	'SELECT COUNT(cp_id_personne) AS nbre '.
278
					'FROM coel_personne '.
1508 jpm 279
					"WHERE cp_ce_annuaire = {$this->bdd->quote($id)} ".
280
					"	AND cp_ce_annuaire = cp_id_personne ".
281
					"	AND cp_ce_projet = '$cp_ce_projet' ";
1497 jpm 282
		try {
283
			$nbre = $this->bdd->query($requete)->fetchColumn();
1508 jpm 284
			if (0 == $nbre) {
285
				$this->debug[] = "Utilisateur NON présent dans l'annuaire de COEL.";
286
			} else if (1 == $nbre) {
287
				$this->debug[] = "Utilisateur présent dans l'annuaire de COEL.";
1497 jpm 288
				$present = true;
1508 jpm 289
			} else if (false === $nbre) {
290
				$this->debug[] = "Erreur dans la requête de vérification de présence dans l'annuaire de COEL.";
1497 jpm 291
			}
292
		} catch (PDOException $e) {
293
			$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage());
294
		}
295
 
296
		return $present;
297
	}
298
 
299
	private function recupererLicenceUtilisateur($id) {
1508 jpm 300
		$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];
1497 jpm 301
		$requete =	'SELECT cp_mark_licence '.
302
					'FROM coel_personne '.
1508 jpm 303
					"WHERE cp_ce_annuaire = {$this->bdd->quote($id)} ".
304
					"	AND cp_ce_annuaire = cp_id_personne ".
305
					"	AND cp_ce_projet = '$cp_ce_projet' ";
1497 jpm 306
		try {
307
			$licence = $this->bdd->query($requete)->fetchColumn();
308
			if ($licence === false) {
309
				$this->debug[] = "La licence n'a pas pu être récupérée.";
310
				return 0;
311
			} else {
312
				return $licence;
313
			}
314
		} catch (PDOException $e) {
315
			$this->messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage());
316
		}
317
	}
318
 
319
	private function mettreAJourMotDePasse($login, $mot_de_passe_md5, $mot_de_passe_sha1) {
320
		try {
1508 jpm 321
		   	$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];
322
			$requete = 	'UPDATE coel_personne '.
1497 jpm 323
		   				"SET cp_mot_de_passe = '$mot_de_passe_sha1' ".
324
		   				"WHERE cp_login = '$login' ".
1508 jpm 325
		   				"	AND cp_ce_projet = '$cp_ce_projet' ".
326
		   				"	AND cp_mot_de_passe = '$mot_de_passe_md5' ";
1497 jpm 327
			// Ajout des données
328
			$resultat = $this->bdd->exec($requete);
329
			if ($resultat === false) {
330
				$this->messages[] = "Le mot de passe de l'utilisateur n'a pas été mis à jour car la requête a échouée.";
331
			}
332
		} catch (PDOException $e) {
333
			$messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete);
334
		}
335
	}
336
 
337
	private function mettreAJourUtilisateur($mot_de_passe_sha1, $infos) {
338
		try {
339
		   	$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];
340
		   	$cp_fmt_nom_complet = $infos['prenom'].' '.$infos['nom'];
341
			$requete = 	'UPDATE coel_personne '.
1508 jpm 342
		   				"SET cp_id_personne = '{$infos['id']}', ".
1497 jpm 343
						"	cp_fmt_nom_complet = '$cp_fmt_nom_complet', cp_prenom = '{$infos['prenom']}', cp_nom = '{$infos['nom']}', ".
344
						"	cp_code_postal = '{$infos['code_postal']}', cp_ville = '{$infos['ville']}', cp_truk_courriel = '{$infos['courriel']}', ".
345
						"	cp_login = '{$infos['courriel']}', cp_mot_de_passe = '$mot_de_passe_sha1', cp_ce_annuaire = '{$infos['id']}' ".
346
		   				"WHERE cp_login = '$login' ".
1508 jpm 347
		   				"	AND cp_ce_projet = '$cp_ce_projet' ".
348
		   				"	AND cp_mot_de_passe = '$mot_de_passe_md5' ";
349
 
1497 jpm 350
			// Ajout des données
351
			$resultat = $this->bdd->exec($requete);
352
			if ($resultat === false) {
353
				$this->messages[] = "L'utilisateur n'a pas été mis à jour car la requête a échouée.";
354
			}
355
		} catch (PDOException $e) {
356
			$messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete);
357
		}
358
	}
359
 
360
	private function ajouterUtilisateurACoel($infos, $mot_de_passe_sha1) {
361
		try {
362
			// Construction de la requête d'ajout
363
		   	// Notes : pour rester compatibles avec l'annuaire de Tela, les utilisateurs sont ajoutés directement avec l'id
364
		   	// de l'annuaire Tela. Dans CoelPersonne, les personnes qui ne sont pas utilisateur sont ajoutés avec un id supérieur à 100 000
365
		   	$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];
366
		   	$cp_fmt_nom_complet = $infos['prenom'].' '.$infos['nom'];
367
		   	$cp_mark_licence = '0';
368
		   	$requete = 	'INSERT INTO coel_personne '.
1508 jpm 369
		   				'	(cp_id_personne, cp_ce_projet, cp_fmt_nom_complet, cp_prenom, cp_nom, cp_code_postal, '.
370
						'	cp_ville, cp_truk_courriel, cp_login, cp_mot_de_passe, cp_ce_annuaire, cp_mark_licence) '.
371
		   				"VALUES ('{$infos['id']}', '$cp_ce_projet', '$cp_fmt_nom_complet', '{$infos['prenom']}', '{$infos['nom']}', ".
372
		   				"'{$infos['code_postal']}', '{$infos['ville']}', '{$infos['courriel']}', '{$infos['courriel']}', '".$mot_de_passe_sha1."', ".
1497 jpm 373
		   				"'{$infos['id']}', $cp_mark_licence) ";
1508 jpm 374
		   	//$this->debug[] = $requete;
1497 jpm 375
			// Ajout des données
376
			$resultat = $this->bdd->exec($requete);
377
			if ($resultat === false) {
1508 jpm 378
				$this->debug[] = "Utilisateur NON ajouté dans coel_personne car la requête a échouée.";
379
			} else {
380
				$this->debug[] = "Utilisateur ajouté à coel_personne.";
1497 jpm 381
			}
382
		} catch (PDOException $e) {
383
			$messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete);
384
		}
385
	}
386
 
387
	private function souvenirUtilisateur($login, $mot_de_passe_sha1) {
388
		if ($login == '' && $mot_de_passe_sha1 == '') {
389
			return false;
390
		} else if ($utilisateur_existant = $this->chargerUtilisateur($login, $mot_de_passe_sha1)) {
391
			if ($utilisateur_existant['mot_de_passe'] == $mot_de_passe_sha1) {
392
				$this->setUtilisateur($utilisateur_existant, $_COOKIE['coel_permanence']);
393
				return true;
394
			} else {
395
				return false;
396
			}
397
		}
398
	}
399
 
400
	private function obtenirInfosAnnuaire($login)	{
401
		$url_annuaire = $this->config['coel']['urlAnnuaire'];
402
		$login_annuaire = $this->config['coel']['loginAnnuaire'];
403
		$mdp_annuaire = $this->config['coel']['mdpAnnuaire'];
404
 
405
		$login_b64 = base64_encode($login_annuaire.':'.$mdp_annuaire);
406
		$url_annuaire .= '/'.$login_b64.'/'.$login;
407
 
408
		$resultat_annuaire = file_get_contents($url_annuaire);
409
		$tableau_annuaire = null;
410
		if ($xml_utilisateur = simplexml_load_string($resultat_annuaire))	{
411
			// La fonction a retourné un objet
412
			foreach ($xml_utilisateur->children() as $key => $val) {
413
				if ((string) $val != '') {
414
			  		$tableau_annuaire[$key] = (String) $val;
415
				}
416
			}
417
		}
418
		return $tableau_annuaire;
419
	}
420
 
421
	private function setInfosAnnuaire($infosAnnuaire)	{
422
		$_SESSION['coel_infosAnnuaire'] = $infosAnnuaire;
423
	}
424
 
1508 jpm 425
	private function accepterLicence($login)	{
1497 jpm 426
		$sortie = false;
427
		try {
1508 jpm 428
			$cp_ce_projet = $this->config['coel']['idProjetUtilisateurs'];
1497 jpm 429
			$requete = 	'UPDATE coel_personne '.
430
						'SET cp_mark_licence = 1 '.
1508 jpm 431
						"WHERE cp_login = {$this->bdd->quote($login)} ";
432
						"	AND cp_ce_projet = '$cp_ce_projet' ";
1497 jpm 433
			$resultat = $this->bdd->exec($requete);
434
			if ($resultat === false) {
1508 jpm 435
				$this->debug[] = "La table Personne n'a pas été mise à jour car la requête a échouée.";
1497 jpm 436
			} else {
1508 jpm 437
				$this->debug[] = "Création du cookie licence.";
1497 jpm 438
				$_SESSION['coel_utilisateur']['licence'] = '1';
1508 jpm 439
				$this->setCookiePersistant('coel_licence', '1');
1497 jpm 440
				$sortie = true;
441
			}
442
		} catch (PDOException $e) {
443
		 	$messages[] = sprintf($this->getTxt('sql_erreur'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete);
444
		}
445
		return $sortie;
446
	}
447
}
448
?>