Subversion Repositories eFlore/Applications.coel

Rev

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