Subversion Repositories Applications.wikini

Rev

Rev 63 | Rev 66 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 63 Rev 65
1
<?php
1
<?php
2
class identificationSso {
2
class identificationSso {
3
 
3
 
4
	private $wiki = null;
4
	private $wiki = null;
5
	private $config = null;
5
	private $config = null;
6
 
6
 
7
	private $cookie_tentative_identification = "";
7
	private $cookie_tentative_identification = "";
8
	private $delai_tentative_identification = 60;
8
	private $delai_tentative_identification = 60;
-
 
9
	
-
 
10
	private $auth_header = 'Authorization';
9
 
11
 
10
	public function __construct($wiki) {
12
	public function __construct($wiki) {
11
		$this->wiki = $wiki;
13
		$this->wiki = $wiki;
12
		$this->config = $wiki->config;
14
		$this->config = $wiki->config;
-
 
15
		$this->auth_header = !empty($this->config['sso_auth_header']) ? $this->config['sso_auth_header'] : $this->auth_header;
13
		$this->cookie_tentative_identification = 'wikini_sso_tentative_identification';
16
		$this->cookie_tentative_identification = 'wikini_sso_tentative_identification';
14
	}
17
	}
15
 
18
 
16
	function getToken() {
19
	function getToken() {
17
		// Premier essai, dans le header
20
		// Premier essai, dans le header
18
		$headers = @apache_request_headers();
21
		$headers = @apache_request_headers();
19
		$token = !empty($headers['Authorization']) ? $headers['Authorization'] : null;
22
		$token = !empty($headers['Authorization']) ? $headers['Authorization'] : null;
-
 
23
		// Eventuellement, le jeton a pu être passé dans un header non standard, comme dans 
-
 
24
		// le cas où le header Authorization est supprimé par le mod cgi d'apache
-
 
25
		// Dans ce cas là on vérifie aussi dans un header alternatif si celui ci a été renseigné
-
 
26
		if($token == null && $this->auth_header != 'Authorization') {
-
 
27
			$token = !empty($headers[$this->auth_header]) ? $headers[$this->auth_header] : null;
-
 
28
		}
20
 
29
 
21
		// Sinon dans $_REQUEST ?
30
		// Sinon dans $_REQUEST ?
22
		if($token == null) {
31
		if($token == null) {
23
			$token = !empty($_REQUEST['Authorization']) ? $_REQUEST['Authorization'] : null;
32
			$token = !empty($_REQUEST['Authorization']) ? $_REQUEST['Authorization'] : null;
24
		}
33
		}
25
		
34
		
26
		// Sinon dans $_COOKIE ?
35
		// Sinon dans $_COOKIE ?
27
		if($token == null) {
36
		if($token == null) {
28
			$token = !empty($_COOKIE['tb_auth']) ? $_COOKIE['tb_auth'] : null;
37
			$token = !empty($_COOKIE['tb_auth']) ? $_COOKIE['tb_auth'] : null;
29
		}
38
		}
30
 
39
 
31
		return $token;
40
		return $token;
32
	}
41
	}
33
 
42
 
34
	function decoderToken($token) {
43
	function decoderToken($token) {
35
		$token_parts = explode('.', $token);
44
		$token_parts = explode('.', $token);
36
		return json_decode(base64_decode($token_parts[1]), true);
45
		return json_decode(base64_decode($token_parts[1]), true);
37
	}
46
	}
38
 
47
 
39
	function getPage() {
48
	function getPage() {
40
		return !empty($this->wiki->page) ? $this->wiki->page['tag'] : 'PagePrincipale';
49
		return !empty($this->wiki->page) ? $this->wiki->page['tag'] : 'PagePrincipale';
41
	}
50
	}
42
 
51
 
43
	// http://stackoverflow.com/questions/1251582/beautiful-way-to-remove-get-variables-with-php?lq=1
52
	// http://stackoverflow.com/questions/1251582/beautiful-way-to-remove-get-variables-with-php?lq=1
44
	function supprimerUrlVar($url, $var) {
53
	function supprimerUrlVar($url, $var) {
45
		 return rtrim(preg_replace('/([?&])'.$var.'=[^&]+(&|$)/','$1',$url), '&?');
54
		 return rtrim(preg_replace('/([?&])'.$var.'=[^&]+(&|$)/','$1',$url), '&?');
46
	}
55
	}
47
 
56
 
48
	function getInfosCookie() {
57
	function getInfosCookie() {
49
		$infos = null;
58
		$infos = null;
50
		if(!empty($_COOKIE[$this->cookie_tentative_identification])) {
59
		if(!empty($_COOKIE[$this->cookie_tentative_identification])) {
51
			$infos = json_decode($_COOKIE[$this->cookie_tentative_identification], true);
60
			$infos = json_decode($_COOKIE[$this->cookie_tentative_identification], true);
52
		}
61
		}
53
		return $infos;
62
		return $infos;
54
	}
63
	}
55
 
64
 
56
	function setInfosCookie($infos) {
65
	function setInfosCookie($infos) {
57
		$infos['expire'] = !empty($infos['expire']) ? $infos['expire'] : 0;
66
		$infos['expire'] = !empty($infos['expire']) ? $infos['expire'] : 0;
58
		setcookie($this->cookie_tentative_identification, json_encode($infos), $infos['expire'], $this->wiki->CookiePath);
67
		setcookie($this->cookie_tentative_identification, json_encode($infos), $infos['expire'], $this->wiki->CookiePath);
59
	}
68
	}
60
 
69
 
61
	function verifierEtInsererUtilisateurParJeton($jeton_rafraichi) {
70
	function verifierEtInsererUtilisateurParJeton($jeton_rafraichi) {
62
		if(!empty($jeton_rafraichi['session']) && $jeton_rafraichi['session'] == true) {
71
		if(!empty($jeton_rafraichi['session']) && $jeton_rafraichi['session'] == true) {
63
			$token_decode = $this->decoderToken($jeton_rafraichi['token']);
72
			$token_decode = $this->decoderToken($jeton_rafraichi['token']);
64
			
73
			
65
			$nom_wiki = $token_decode['nomWiki'];
74
			$nom_wiki = $token_decode['nomWiki'];
66
			$courriel = $token_decode['sub'];
75
			$courriel = $token_decode['sub'];
67
			
76
			
68
			$utilisateur_wiki_existe = $this->wiki->LoadAll("SELECT * FROM  ".$this->wiki->config["table_prefix"]."users ".
77
			$utilisateur_wiki_existe = $this->wiki->LoadAll("SELECT * FROM  ".$this->wiki->config["table_prefix"]."users ".
69
					"WHERE ".
78
					"WHERE ".
70
					"name = '".mysql_escape_string($nom_wiki)."' OR ".
79
					"name = '".mysql_escape_string($nom_wiki)."' OR ".
71
					"email = '".mysql_escape_string($courriel)."'");
80
					"email = '".mysql_escape_string($courriel)."'");
72
			
81
			
73
			// pas inscrit ? on l'ajout à la base de données
82
			// pas inscrit ? on l'ajout à la base de données
74
			if(empty($utilisateur_wiki_existe)) {
83
			if(empty($utilisateur_wiki_existe)) {
75
				// mot de passe généré à l'arrache, le mieux serait de trouver celui de tela encodé
84
				// mot de passe généré à l'arrache, le mieux serait de trouver celui de tela encodé
76
				// mais en gérant bien le sso on peut s'en passer car l'utilisateur ne devrait jamais avoir 
85
				// mais en gérant bien le sso on peut s'en passer car l'utilisateur ne devrait jamais avoir 
77
				// à s'identifier par le wiki
86
				// à s'identifier par le wiki
78
				$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
87
				$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
79
				$pass = substr(str_shuffle(str_repeat($pool, 16)), 0, 16);
88
				$pass = substr(str_shuffle(str_repeat($pool, 16)), 0, 16);
80
				
89
				
81
				$this->wiki->Query("insert into ".$this->wiki->config["table_prefix"]."users set ".
90
				$this->wiki->Query("insert into ".$this->wiki->config["table_prefix"]."users set ".
82
						"signuptime = now(), ".
91
						"signuptime = now(), ".
83
						"name = '".mysql_escape_string($token_decode['nomWiki'])."', ".
92
						"name = '".mysql_escape_string($token_decode['nomWiki'])."', ".
84
						"email = '".mysql_escape_string($token_decode['sub'])."', ".
93
						"email = '".mysql_escape_string($token_decode['sub'])."', ".
85
						"password = md5('".mysql_escape_string($pass)."')");
94
						"password = md5('".mysql_escape_string($pass)."')");
86
			} else {
95
			} else {
87
				// Un utilisateur peut déjà s'être inscrit sur le wiki avec un autre nom que son pseudo
96
				// Un utilisateur peut déjà s'être inscrit sur le wiki avec un autre nom que son pseudo
88
				$nom_wiki = $utilisateur_wiki_existe[0]['name'];
97
				$nom_wiki = $utilisateur_wiki_existe[0]['name'];
89
				// s'il existe un enregistrement avec ce mail et un autre avec ce nomWiki on garde celui qui correspond au bon courriel
98
				// s'il existe un enregistrement avec ce mail et un autre avec ce nomWiki on garde celui qui correspond au bon courriel
90
				foreach($utilisateur_wiki_existe as $utilisateur_wiki) {
99
				foreach($utilisateur_wiki_existe as $utilisateur_wiki) {
91
					if($utilisateur_wiki['email'] == $courriel) {
100
					if($utilisateur_wiki['email'] == $courriel) {
92
						  $nom_wiki = $utilisateur_wiki['name'];
101
						  $nom_wiki = $utilisateur_wiki['name'];
93
					}
102
					}
94
				}
103
				}
95
			}
104
			}
96
		}
105
		}
97
 
106
 
98
		return $nom_wiki;
107
		return $nom_wiki;
99
	}
108
	}
100
 
109
 
101
	function recupererIdentiteConnectee() {
110
	function recupererIdentiteConnectee() {
102
		$infos_cookie = $this->getInfosCookie();
111
		$infos_cookie = $this->getInfosCookie();
103
		if($infos_cookie == null || $infos_cookie['tentative_identification'] == false) {	
112
		if($infos_cookie == null || $infos_cookie['tentative_identification'] == false) {	
104
			// peut importe si l'annuaire répond oui ou non, on a fait une tentative d'identification
113
			// peut importe si l'annuaire répond oui ou non, on a fait une tentative d'identification
105
			// et si on a trouvé quelqu'un on ne réésaiera pas jusqu'à la fermeture du navigateur
114
			// et si on a trouvé quelqu'un on ne réésaiera pas jusqu'à la fermeture du navigateur
106
			$infos_cookie = array('tentative_identification' => true, 'expire' => 0);
115
			$infos_cookie = array('tentative_identification' => true, 'expire' => 0);
107
 			$this->setInfosCookie($infos_cookie);
116
 			$this->setInfosCookie($infos_cookie);
108
 
117
 
109
			$annuaire_url = $this->wiki->config['sso_url'].'identite';
118
			$annuaire_url = $this->wiki->config['sso_url'].'identite';
110
			// Attention si le paramètre wiki de l'url est vide, la redirection de retour pose des problèmes
119
			// Attention si le paramètre wiki de l'url est vide, la redirection de retour pose des problèmes
111
			$url = $annuaire_url.'?redirect_url='.urlencode($this->wiki->config['base_url'].$this->getPage());
120
			$url = $annuaire_url.'?redirect_url='.urlencode($this->wiki->config['base_url'].$this->getPage());
112
 
121
 
113
			header('Location: '.$url);
122
			header('Location: '.$url);
114
			exit;
123
			exit;
115
		} else {
124
		} else {
116
			$token = $this->getToken();
125
			$token = $this->getToken();
117
 
126
 
118
			if($token != null) {
127
			if($token != null) {
119
				// On demande à l'annuaire si le jeton est bien valide
128
				// On demande à l'annuaire si le jeton est bien valide
120
				$jeton_rafraichi = json_decode(file_get_contents($this->wiki->config['sso_url'].'rafraichir?token='.$token), true);
129
				$jeton_rafraichi = json_decode(file_get_contents($this->wiki->config['sso_url'].'rafraichir?token='.$token), true);
121
				$nom_wiki = $this->verifierEtInsererUtilisateurParJeton($jeton_rafraichi);
130
				$nom_wiki = $this->verifierEtInsererUtilisateurParJeton($jeton_rafraichi);
122
				$token_decode = $this->decoderToken($jeton_rafraichi['token']);
131
				$token_decode = $this->decoderToken($jeton_rafraichi['token']);
123
 
132
 
124
				// dans le pire des cas, si on se déconnecte dans une autre application, on sera déconnecté 
133
				// dans le pire des cas, si on se déconnecte dans une autre application, on sera déconnecté 
125
				// lorsque le jeton expirera
134
				// lorsque le jeton expirera
126
				$infos_cookie = array('tentative_identification' => true, 'expire' => time()+$jeton_rafraichi['duration']);
135
				$infos_cookie = array('tentative_identification' => true, 'expire' => time()+$jeton_rafraichi['duration']);
127
				$this->setInfosCookie($infos_cookie);
136
				$this->setInfosCookie($infos_cookie);
128
 
137
 
129
				$this->wiki->SetUser($this->wiki->LoadUser($nom_wiki));
138
				$this->wiki->SetUser($this->wiki->LoadUser($nom_wiki));
130
			} else {
139
			} else {
131
				// personne n'a été trouvé ? on remplace le cookie par un de durée plus courte 
140
				// personne n'a été trouvé ? on remplace le cookie par un de durée plus courte 
132
				// pour rééssayer dans delai_tentative_identification si on en a pas déjà un
141
				// pour rééssayer dans delai_tentative_identification si on en a pas déjà un
133
				if($infos_cookie['expire'] == 0) { 
142
				if($infos_cookie['expire'] == 0) { 
134
					$infos_cookie['expire'] = time()+$this->delai_tentative_identification;
143
					$infos_cookie['expire'] = time()+$this->delai_tentative_identification;
135
					$this->setInfosCookie($infos_cookie);
144
					$this->setInfosCookie($infos_cookie);
136
				}
145
				}
137
			}
146
			}
138
		}
147
		}
139
	}
148
	}
-
 
149
 
-
 
150
	function recupererIdentiteConnecteePourApi() {		
-
 
151
		$token = $this->getToken();
-
 
152
		if($token != null) {
-
 
153
			// On demande à l'annuaire si le jeton est bien valide
-
 
154
			$jeton_rafraichi = json_decode(file_get_contents($this->wiki->config['sso_url'].'rafraichir?token='.$token), true);
-
 
155
			$nom_wiki = $this->verifierEtInsererUtilisateurParJeton($jeton_rafraichi);
-
 
156
			$token_decode = $this->decoderToken($jeton_rafraichi['token']);
-
 
157
			$this->wiki->SetUser($this->wiki->LoadUser($nom_wiki));
-
 
158
		}
140
 
159
	}
141
 
160
 
142
	function connecterUtilisateur($login, $pass, $url_redirect = null) {
161
	function connecterUtilisateur($login, $pass, $url_redirect = null) {
143
		if(strpos($login, '@') === false) {
162
		if(strpos($login, '@') === false) {
144
			$utilisateur_wiki = $this->wiki->LoadSingle("SELECT email FROM  ".$this->wiki->config["table_prefix"]."users ".
163
			$utilisateur_wiki = $this->wiki->LoadSingle("SELECT email FROM  ".$this->wiki->config["table_prefix"]."users ".
145
			"WHERE name = '".mysql_escape_string($login)."'");
164
			"WHERE name = '".mysql_escape_string($login)."'");
146
 
165
 
147
			$login = !empty($utilisateur_wiki) ? $utilisateur_wiki['email'] : $login;
166
			$login = !empty($utilisateur_wiki) ? $utilisateur_wiki['email'] : $login;
148
			// TODO: si le courriel a changé dans l'annuaire, on devrait mettre à jour les informations 
167
			// TODO: si le courriel a changé dans l'annuaire, on devrait mettre à jour les informations 
149
			// si on a utilisé le nom wiki pour s'identifier mais le flow du programme rend cela complexe
168
			// si on a utilisé le nom wiki pour s'identifier mais le flow du programme rend cela complexe
150
		}
169
		}
151
 
170
 
152
		$url_redirect = ($url_redirect == null) ? $this->wiki->config['base_url'].'PagePrincipale' : $url_redirect;
171
		$url_redirect = ($url_redirect == null) ? $this->wiki->config['base_url'].'PagePrincipale' : $url_redirect;
153
 
172
 
154
		// le cookie de tentative d'identification est remis à zéro pour qu'au rechargement de la page il vérifie l'identité 
173
		// le cookie de tentative d'identification est remis à zéro pour qu'au rechargement de la page il vérifie l'identité 
155
		// connectée du nouvel utilisateur
174
		// connectée du nouvel utilisateur
156
		$infos_cookie = array('tentative_identification' => false, 'expire' => 0);
175
		$infos_cookie = array('tentative_identification' => false, 'expire' => 0);
157
		$this->setInfosCookie($infos_cookie);
176
		$this->setInfosCookie($infos_cookie);
158
		// On demande à l'annuaire si l'utilisateur est bien valide
177
		// On demande à l'annuaire si l'utilisateur est bien valide
159
		$annuaire_url = $this->wiki->config['sso_url'].'connexion?login='.$login.'&password='.$pass;
178
		$annuaire_url = $this->wiki->config['sso_url'].'connexion?login='.$login.'&password='.$pass;
160
		$url = $annuaire_url.'&redirect_url='.urlencode($url_redirect);
179
		$url = $annuaire_url.'&redirect_url='.urlencode($url_redirect);
161
 
180
 
162
		header('Location: '.$url);
181
		header('Location: '.$url);
163
		exit;
182
		exit;
164
	}
183
	}
165
 
184
 
166
	function deconnecterUtilisateur($url_redirect = null) {
185
	function deconnecterUtilisateur($url_redirect = null) {
167
		$url_redirect = ($url_redirect == null) ? $this->wiki->config['base_url'].'PagePrincipale' : $url_redirect;
186
		$url_redirect = ($url_redirect == null) ? $this->wiki->config['base_url'].'PagePrincipale' : $url_redirect;
168
		// Suppression d'un eventuel jeton contenu dans l'url
187
		// Suppression d'un eventuel jeton contenu dans l'url
169
		$url_redirect = $this->supprimerUrlVar($url_redirect, 'Authorization');
188
		$url_redirect = $this->supprimerUrlVar($url_redirect, 'Authorization');
170
		
189
		
171
		$infos_cookie = array('tentative_identification' => false, 'expire' => 0);
190
		$infos_cookie = array('tentative_identification' => false, 'expire' => 0);
172
 		$this->setInfosCookie($infos_cookie);
191
 		$this->setInfosCookie($infos_cookie);
173
		// On demande à l'annuaire si l'utilisateur est bien valide
192
		// On demande à l'annuaire si l'utilisateur est bien valide
174
		$annuaire_url = $this->wiki->config['sso_url'].'deconnexion';
193
		$annuaire_url = $this->wiki->config['sso_url'].'deconnexion';
175
		$url = $annuaire_url.'?redirect_url='.urlencode($url_redirect);
194
		$url = $annuaire_url.'?redirect_url='.urlencode($url_redirect);
176
		header('Location: '.$url);
195
		header('Location: '.$url);
177
		exit;
196
		exit;
178
	}
197
	}
179
}
198
}
180
?>
199
?>