Subversion Repositories eFlore/Applications.del

Rev

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

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