Subversion Repositories eFlore/Applications.del

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2212 arthur 1
<?php
2
// declare(encoding='UTF-8');
3
/**
4
 * Classe de controle d'accès HTTP AUTH aux services de DEL, à n'utiliser
5
 * que dans ce cas (HTTP AUTH), et pas dans le cas de l'identification générale sur le SSO
6
 *
7
 * Cette classe propose des méthodes permettant :
8
 *  - l'authentification HTTP pour bloquer ou autoriser l'accès
9
 *  - de déterminer le statut d'admin des utilisateurs
10
 *
11
 * @category  DEL
12
 * @package   Services
13
 * @package   Bibliotheque
14
 * @version   0.1
15
 * @author    Mathias CHOUET <mathias@tela-botanica.org>
16
 * @author    Jean-Pascal MILCENT <jpm@tela-botanica.org>
17
 * @author    Aurelien PERONNET <aurelien@tela-botanica.org>
18
 * @license   GPL v3 <http://www.gnu.org/licenses/gpl.txt>
19
 * @license   CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
20
 * @copyright 1999-2014 Tela Botanica <accueil@tela-botanica.org>
21
 */
22
class ControleAcces {
23
 
24
	protected $conteneur;
25
	protected $bdd;
26
 
27
	public function __construct($conteneur) {
28
		throw new Exception("obsolète - ne plus utiliser"); // go pyoubelz
29
		$this->conteneur = $conteneur;
30
		$this->bdd = $this->conteneur->getBdd();
31
	}
32
 
33
	/**
34
	 * Vérifie que l'IP du client est dans la liste "ip_autorisees" de la config
35
	 * @throws Exception
36
	 * @return boolean
37
	 */
38
	public function controlerIpAutorisees() {
39
		$ipsAutorisees = $this->conteneur->getParametreTableau('ip_autorisees');
40
 
41
		$remoteIp = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP);
42
		$serverIp = filter_input(INPUT_SERVER, 'SERVER_ADDR', FILTER_VALIDATE_IP);
43
		if (in_array($remoteIp, $ipsAutorisees) == false) {
44
			if ($remoteIp != $serverIp) {// ATTENTION : maintenir ce test à l'intérieur du précédent
45
				$message = "Accès interdit. \n".
46
					"Vous n'êtes pas autorisé à accéder à ce service depuis '$remoteIp' !\n";
47
				$code = RestServeur::HTTP_CODE_ACCES_NON_AUTORISE;
48
				throw new Exception($message, $code);
49
			}
50
		}
51
		return true;
52
	}
53
 
54
	/**
55
	 * Exige qu'un administrateur s'autenthentifie à l'aide de HTTP AUTH
56
	 */
57
	public function demanderAuthentificationAdmin() {
58
		if (!$this->etreAdminAutoriseParHttp()) {
59
			$this->authentifierAdmin();
60
		}
61
	}
62
	/**
63
	 * Exige qu'un utilisateur s'autenthentifie à l'aide de HTTP AUTH
64
	 */
65
	public function demanderAuthentificationUtilisateur() {
66
		if (!$this->etreUtilisateurAutoriseParHttp()) {
67
			$this->authentifierUtilisateur();
68
		}
69
	}
70
 
71
 
72
	/**
73
	 * Lit les entêtes HTTP AUTH et vérifie si l'utilisateur
74
	 * existe (courriel / mot de passe); si $doitEtreAdmin est true,
75
	 * vérifiera également que l'utilisateur est administrateur de Del
76
	 *
77
	 * @return boolean true si l'utilisateur est identifié, false sinon
78
	 */
79
	protected function etreUtilisateurAutoriseParHttp($doitEtreAdmin=false) {
80
		$identifiant = $this->getAuthIdentifiant();
81
		$mdp = $this->getAuthMotDePasse();
82
		$existe = $this->obtenirUtilisateur($identifiant, $mdp);
83
 
84
		$autorisation = (isset($existe) && $existe) ? true :false; // c'est quoi ces tests de clodos ??
85
 
86
		if ($doitEtreAdmin === true) {
87
			$autorisation = ($autorisation && $this->etreAdmin($identifiant));
88
		}
89
		return $autorisation;
90
	}	/**
91
	 * Lit les entêtes HTTP AUTH et vérifie que l'utilisateur est identifié
92
	 * et est administrateur de Del
93
	 *
94
	 * @return boolean true si l'utilisateur est identifié et admin de Del, false sinon
95
	 */
96
	protected function etreAdminAutoriseParHttp() {
97
		return $this->etreUtilisateurAutoriseParHttp(true);
98
	}
99
 
100
	/**
101
	 * Lit l'identifiant utilisateur dans les entêtes HTTP AUTH
102
	 * @return String l'identifiant utilisateur ou null
103
	 */
104
	protected function getAuthIdentifiant() {
105
		$id = (isset($_SERVER['PHP_AUTH_USER'])) ? $_SERVER['PHP_AUTH_USER'] : null;
106
		return $id;
107
	}
108
 
109
	/**
110
	 * Lit le mot de passe dans les entêtes HTTP AUTH
111
	 * @return String le mot de passe ou null
112
	 */
113
	protected function getAuthMotDePasse() {
114
		$mdp = (isset($_SERVER['PHP_AUTH_PW'])) ? $_SERVER['PHP_AUTH_PW'] : null;
115
		return $mdp;
116
	}
117
 
118
 
119
 
120
	/**
121
	 * Envoie un message HTTP 401 / une boîte de login HTTP AUTH avec des
122
	 * messages correspondant à la demande d'authentification d'un administrateur
123
	 * TODO: externaliser noms et adresses spécifiques à Tela Botanica
124
	 * @return boolean
125
	 */
126
	protected function authentifierAdmin() {
127
		$message_accueil = "Veuillez vous identifier avec votre compte administrateur Tela Botanica.";
128
		$message_echec = "Accès limité aux administrateurs de DEL.\n".
129
			"Votre tentative d'identification a échoué.\n".
130
			"Actualiser la page pour essayer à nouveau si vous êtes bien inscrit comme administrateur.";
131
		return $this->authentifier($message_accueil, $message_echec, 'Admin');
132
	}
133
 
134
	/**
135
	 * Envoie un message HTTP 401 / une boîte de login HTTP AUTH avec des
136
	 * messages correspondant à la demande d'authentification d'un utilisateur
137
	 * TODO: externaliser noms et adresses spécifiques à Tela Botanica
138
	 * @return boolean
139
	 */
140
	protected function authentifierUtilisateur() {
141
		$message_accueil = "Veuillez vous identifier avec votre compte Tela Botanica.";
142
		$message_echec = "Accès limité aux utilisateurs de DEL.\n".
143
			"Inscrivez vous http://www.tela-botanica.org/page:inscription pour le devenir.\n".
144
			"Votre tentative d'identification a échoué.\n".
145
			"Actualiser la page pour essayer à nouveau si vous êtes déjà inscrit ou contacter 'accueil@tela-botanica.org'.";
146
		return $this->authentifier($message_accueil, $message_echec, 'Utilisateur');
147
	}	/**
148
	 * Envoie l'authentification HTTP AUTH , et accepte un mode "debug" pour
149
	 * les petits malins
150
	 */
151
	protected function authentifier($message_accueil, $message_echec, $type) {
152
		$id = $this->getAuthIdentifiant();
153
		if (!isset($id)) {
154
			$this->envoyerAuth($message_accueil, $message_echec);
155
		} else {
156
			if ($type == 'Utilisateur' && $this->getAuthMotDePasse() == 'debug') {
157
				$autorisation = true;
158
			} else {
159
				$methodeAutorisation = "etre{$type}Autorise";
160
				$autorisation = $this->$methodeAutorisation();
161
			}
162
			if ($autorisation == false) {
163
				$this->envoyerAuth($message_accueil, $message_echec);
164
			}
165
		}
166
		return true;
167
	}
168
 
169
 
170
 
171
	/**
172
	 * Envoie un message HTTP 401 / une boîte de login HTTP AUTH
173
	 * @param string $message_accueil
174
	 * @param string $message_echec
175
	 */
176
	private function envoyerAuth($message_accueil, $message_echec) {
177
		header('HTTP/1.0 401 Unauthorized');
178
		header('WWW-Authenticate:  realm="'.mb_convert_encoding($message_accueil, 'ISO-8859-1', 'UTF-8').'"');
179
		header('Content-type: text/plain; charset=UTF-8');
180
		print $message_echec;
181
		exit(0);
182
	}
183
 
184
	/**
185
	 * Authentifie et récupère un utilisateur directement depuis la table des
186
	 * utilisateurs Del, utile pour l'authentification HTTP AUTH - ne pas
187
	 * utiliser pour les services Del qui doivent être branchés au SSO
188
	 */
189
	protected function obtenirUtilisateur($login, $motDePasse) {
190
		$login = $this->bdd->proteger($login);
191
		$motDePasse = $this->bdd->proteger($motDePasse);
192
		$requete = 'SELECT id_utilisateur, nom, prenom, courriel, mot_de_passe '.
193
			'FROM del_utilisateur AS du '.
194
			"WHERE courriel = $login ".
195
			"	AND mot_de_passe = MD5($motDePasse) ".
196
			' -- '.__FILE__.':'.__LINE__."\n";
197
		$utilisateur = $this->bdd->recuperer($requete);
198
		return $utilisateur;
199
	}
200
 
201
	/**
202
	 * Vérifie dans la table des utilisateurs Del qu'un utilisateur
203
	 * (identifié par son courriel) est administrateur de Del
204
	 *
205
	 * @param string $courriel
206
	 * @return boolean true si l'utilisateur est administrateur de Del, false sinon
207
	 */
208
	protected function etreAdmin($courriel) {
209
		$courriel = $this->bdd->proteger($courriel);
210
		$requete = 'SELECT dui.admin '.
211
			'FROM del_utilisateur AS du LEFT JOIN del_user_infos AS dui ON (du.id_utilisateur = dui.id_utilisateur) '.
212
			"WHERE du.courriel = $courriel ".
213
			' -- '.__FILE__.':'.__LINE__."\n";
214
		$infoUtilisateur = $this->bdd->recuperer($requete);
215
 
216
		$etreAdmin = $this->verifierDroitAdmin($infoUtilisateur['admin']);
217
		return $etreAdmin;
218
	}
219
 
220
	/**
221
	 * Vérifie que la valeur "admin" d'un profil utilisateur correspond à la valeur
222
	 * attendue dans la config
223
	 *
224
	 * @return true si sébon, false si sépabon
225
	 */
226
	protected function verifierDroitAdmin($droit) {
227
		$droitAdmin = $this->conteneur->getParametre('droit_superadmin');
228
		$etreAdmin = false;
229
		if (isset($droit) && $droit == $droitAdmin) {
230
			$etreAdmin = true;
231
		}
232
		return $etreAdmin;
233
	}
234
 
235
}