Dead code.
[platal.git] / modules / platal.php
CommitLineData
e59506eb 1<?php
2/***************************************************************************
179afa7f 3 * Copyright (C) 2003-2008 Polytechnique.org *
e59506eb 4 * http://opensource.polytechnique.org/ *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
21
5de0b7e1 22function bugize($list)
23{
24 $list = split(',', $list);
25 $ans = array();
26
27 foreach ($list as $bug) {
28 $clean = str_replace('#', '', $bug);
29 $ans[] = "<a href='http://trackers.polytechnique.org/task/$clean'>$bug</a>";
30 }
31
32 return join(',', $ans);
33}
34
35
e59506eb 36class PlatalModule extends PLModule
37{
38 function handlers()
39 {
40 return array(
c9178c75 41 'index' => $this->make_hook('index', AUTH_PUBLIC),
ddb64990 42 'cacert.pem' => $this->make_hook('cacert', AUTH_PUBLIC),
5de0b7e1 43 'changelog' => $this->make_hook('changelog', AUTH_PUBLIC),
44
4da0b8d7 45 // Preferences thingies
bee33d93 46 'prefs' => $this->make_hook('prefs', AUTH_COOKIE),
47 'prefs/rss' => $this->make_hook('prefs_rss', AUTH_COOKIE),
bce2f8eb 48 'prefs/webredirect'
bee33d93 49 => $this->make_hook('webredir', AUTH_MDP),
50 'prefs/skin' => $this->make_hook('skin', AUTH_COOKIE),
4da0b8d7 51
52 // password related thingies
1a5da857 53 'password' => $this->make_hook('password', AUTH_MDP),
54 'tmpPWD' => $this->make_hook('tmpPWD', AUTH_PUBLIC),
55 'password/smtp' => $this->make_hook('smtppass', AUTH_MDP),
8858cfc1 56 'recovery' => $this->make_hook('recovery', AUTH_PUBLIC),
5de0b7e1 57 'exit' => $this->make_hook('exit', AUTH_PUBLIC),
ddb64990 58 'review' => $this->make_hook('review', AUTH_PUBLIC),
58abb43b 59 'deconnexion.php' => $this->make_hook('exit', AUTH_PUBLIC),
e59506eb 60 );
61 }
62
c9178c75 63 function handler_index(&$page)
64 {
ab66bf7f 65 // Include X-XRDS-Location response-header for Yadis discovery
78507d96 66 global $globals;
ab66bf7f
AA
67 header('X-XRDS-Location: ' . $globals->baseurl . '/openid/idp_xrds');
68
69 // Redirect to the suitable page
cab08090 70 if (S::logged()) {
8b00e0e0 71 pl_redirect('events');
ddb64990 72 } else if (!@$GLOBALS['IS_XNET_SITE']) {
78d4079a 73 $this->handler_review($page);
c9178c75 74 }
c9178c75 75 }
76
5de0b7e1 77 function handler_cacert(&$page)
78 {
ca877168 79 $data = file_get_contents("/etc/ssl/xorgCA/cacert.pem","r");
80 header("Pragma:");
dc41059a 81 header("Set-Cookie:");
82 header("Cache-Control:");
83 header("Expires:");
84 header("Content-Type: application/x-x509-ca-cert");
ca877168 85 header("Content-Length: ".strlen($data));
5de0b7e1 86 echo $data;
87 exit;
88 }
89
78d4079a 90 function handler_changelog(&$page, $core = null)
5de0b7e1 91 {
8b1f8e12 92 $page->changeTpl('platal/changeLog.tpl');
5de0b7e1 93
78d4079a
FB
94 function formatChangeLog($file) {
95 $clog = pl_entities(file_get_contents($file));
96 $clog = preg_replace('/===+\s*/', '</pre><hr /><pre>', $clog);
97 // url catch only (not all wiki syntax)
98 $clog = preg_replace(array(
99 '/((?:https?|ftp):\/\/(?:\.*,*[\w@~%$£µ&i#\-+=_\/\?;])*)/ui',
100 '/(\s|^)www\.((?:\.*,*[\w@~%$£µ&i#\-+=_\/\?;])*)/iu',
101 '/(?:mailto:)?([a-z0-9.\-+_]+@([\-.+_]?[a-z0-9])+)/i'),
102 array(
103 '<a href="\\0">\\0</a>',
104 '\\1<a href="http://www.\\2">www.\\2</a>',
105 '<a href="mailto:\\0">\\0</a>'),
106 $clog);
107 $clog = preg_replace('!(#[0-9]+(,[0-9]+)*)!e', 'bugize("\1")', $clog);
108 $clog = preg_replace('!vim:.*$!', '', $clog);
109 return preg_replace("!(<hr />(\\s|\n)*)?<pre>(\s|\n)*</pre>((\\s|\n)*<hr />)?!m", "", "<pre>$clog</pre>");
110 }
111 if ($core != 'core') {
112 $page->assign('core', false);
113 $page->assign('ChangeLog', formatChangeLog(dirname(__FILE__).'/../ChangeLog'));
114 } else {
115 $page->assign('core', true);
116 $page->assign('ChangeLog', formatChangeLog(dirname(__FILE__).'/../core/ChangeLog'));
117 }
5de0b7e1 118 }
119
7927d719 120 function __set_rss_state($state)
121 {
7927d719 122 if ($state) {
31e01c97
FB
123 S::set('token', rand_url_id(16));
124 XDB::execute('UPDATE accounts
125 SET token = {?}
126 WHERE uid = {?}', S::s('token'), S::i('uid'));
7927d719 127 } else {
31e01c97
FB
128 S::kill('token');
129 XDB::execute('UPDATE accounts
130 SET token = NULL
131 WHERE uid = {?}', S::i('uid'));
7927d719 132 }
133 }
134
e59506eb 135 function handler_prefs(&$page)
136 {
8b1f8e12 137 $page->changeTpl('platal/preferences.tpl');
46f272fe 138 $page->setTitle('Mes préférences');
e59506eb 139
31e01c97
FB
140 if (Post::has('email_format')) {
141 $fmt = Post::s('email_format');
142 XDB::execute("UPDATE accounts
143 SET email_format = {?}
144 WHERE uid = {?}",
145 $fmt, S::v('uid'));
146 S::set('email_format', $fmt);
e59506eb 147 }
148
bee33d93 149 if (Post::has('rss')) {
5e2307dc 150 $this->__set_rss_state(Post::b('rss'));
e59506eb 151 }
e67b4436
VZ
152
153 # FIXME: this code is not multi-domain compatible. We should decide how
154 # carva will extend to users not in the main domain.
155 $res = XDB::query("SELECT alias
156 FROM aliases
157 WHERE id = {?} AND FIND_IN_SET('bestalias', flags)",
158 S::user()->id());
159 $page->assign('bestalias', $res->fetchOneCell());
e59506eb 160 }
9bae6004 161
bce2f8eb 162 function handler_webredir(&$page)
163 {
8b1f8e12 164 $page->changeTpl('platal/webredirect.tpl');
bce2f8eb 165
46f272fe 166 $page->setTitle('Redirection de page WEB');
bce2f8eb 167
cab08090 168 $log =& S::v('log');
5e2307dc 169 $url = Env::v('url');
bce2f8eb 170
5e2307dc 171 if (Env::v('submit') == 'Valider' and Env::has('url')) {
31e01c97
FB
172 XDB::execute('UPDATE auth_user_quick
173 SET redirecturl = {?} WHERE user_id = {?}',
174 $url, S::i('uid'));
732e5855 175 S::logger()->log('carva_add', 'http://'.Env::v('url'));
a7d35093 176 $page->trigSuccess("Redirection activée vers <a href='http://$url'>$url</a>");
5e2307dc 177 } elseif (Env::v('submit') == "Supprimer") {
31e01c97
FB
178 XDB::execute("UPDATE auth_user_quick
179 SET redirecturl = ''
180 WHERE user_id = {?}",
181 S::i('uid'));
732e5855 182 S::logger()->log("carva_del", $url);
bce2f8eb 183 Post::kill('url');
a7d35093 184 $page->trigSuccess('Redirection supprimée');
bce2f8eb 185 }
186
31e01c97
FB
187 $res = XDB::query('SELECT redirecturl
188 FROM auth_user_quick
189 WHERE user_id = {?}',
190 S::i('uid'));
bce2f8eb 191 $page->assign('carva', $res->fetchOneCell());
e67b4436
VZ
192
193 # FIXME: this code is not multi-domain compatible. We should decide how
194 # carva will extend to users not in the main domain.
195 $res = XDB::query("SELECT alias
196 FROM aliases
197 WHERE id = {?} AND FIND_IN_SET('bestalias', flags)",
198 S::user()->id());
199 $page->assign('bestalias', $res->fetchOneCell());
bce2f8eb 200 }
201
4da0b8d7 202 function handler_prefs_rss(&$page)
7927d719 203 {
8b1f8e12 204 $page->changeTpl('platal/filrss.tpl');
7927d719 205
5e2307dc 206 $page->assign('goback', Env::v('referer', 'login'));
7927d719 207
5e2307dc 208 if (Env::v('act_rss') == 'Activer') {
7927d719 209 $this->__set_rss_state(true);
a7d35093 210 $page->trigSuccess("Ton Fil RSS est activé.");
7927d719 211 }
7927d719 212 }
213
7c77c3ee 214 function handler_password(&$page)
215 {
84270653
VZ
216 global $globals;
217
40d428d8 218 if (Post::has('response2')) {
40d428d8 219 S::assert_xsrf_token();
7c77c3ee 220
31e01c97
FB
221 S::set('password', $password = Post::v('response2'));
222 XDB::execute('UPDATE accounts
223 SET password = {?}
224 WHERE uid={?}', $password,
225 S::i('uid'));
7c77c3ee 226
84270653
VZ
227 // If GoogleApps is enabled, and the user did choose to use synchronized passwords,
228 // updates the Google Apps password as well.
229 if ($globals->mailstorage->googleapps_domain) {
230 require_once 'googleapps.inc.php';
d56cb887 231 $account = new GoogleAppsAccount(S::user());
f5c4bf30 232 if ($account->active() && $account->sync_password) {
84270653
VZ
233 $account->set_password($password);
234 }
235 }
236
604dfd58
FB
237 S::logger()->log('passwd');
238 Platal::session()->setAccessCookie(true);
7c77c3ee 239
8b1f8e12 240 $page->changeTpl('platal/motdepasse.success.tpl');
7c77c3ee 241 $page->run();
242 }
243
8b1f8e12 244 $page->changeTpl('platal/motdepasse.tpl');
c99ef281 245 $page->addJsLink('motdepasse.js');
46f272fe 246 $page->setTitle('Mon mot de passe');
7c77c3ee 247 }
248
1a5da857 249 function handler_smtppass(&$page)
250 {
8b1f8e12 251 $page->changeTpl('platal/acces_smtp.tpl');
46f272fe 252 $page->setTitle('Acces SMTP/NNTP');
eaf30d86 253
8f201b69
FB
254 $wp = new PlWikiPage('Xorg.SMTPSécurisé');
255 $wp->buildCache();
256 $wp = new PlWikiPage('Xorg.NNTPSécurisé');
257 $wp->buildCache();
1a5da857 258
31e01c97 259 $uid = S::i('uid');
5e2307dc 260 $pass = Env::v('smtppass1');
1a5da857 261
eaf30d86 262 if (Env::v('op') == "Valider" && strlen($pass) >= 6
31e01c97
FB
263 && Env::v('smtppass1') == Env::v('smtppass2')) {
264 // FIXME: Put smtppass somewhere
265 XDB::execute('UPDATE auth_user_md5
266 SET smtppass = {?}
267 WHERE user_id = {?}', $pass, $uid);
a7d35093 268 $page->trigSuccess('Mot de passe enregistré');
732e5855 269 S::logger()->log("passwd_ssl");
5e2307dc 270 } elseif (Env::v('op') == "Supprimer") {
31e01c97
FB
271 // FIXME: Put smtppass somewhere
272 XDB::execute('UPDATE auth_user_md5
273 SET smtppass = ""
274 WHERE user_id = {?}', $uid);
a7d35093 275 $page->trigSuccess('Compte SMTP et NNTP supprimé');
732e5855 276 S::logger()->log("passwd_del");
1a5da857 277 }
278
eaf30d86 279 $res = XDB::query("SELECT IF(smtppass != '', 'actif', '')
1a5da857 280 FROM auth_user_md5
281 WHERE user_id = {?}", $uid);
282 $page->assign('actif', $res->fetchOneCell());
1a5da857 283 }
284
8858cfc1 285 function handler_recovery(&$page)
286 {
287 global $globals;
288
8b1f8e12 289 $page->changeTpl('platal/recovery.tpl');
8858cfc1 290
291 if (!Env::has('login') || !Env::has('birth')) {
fd8f77de 292 return;
8858cfc1 293 }
294
5e2307dc 295 if (!ereg('[0-3][0-9][0-1][0-9][1][9]([0-9]{2})', Env::v('birth'))) {
a7d35093 296 $page->trigError('Date de naissance incorrecte ou incohérente');
c9110c6c 297 return;
8858cfc1 298 }
c9110c6c 299
300 $birth = sprintf('%s-%s-%s',
5e2307dc 301 substr(Env::v('birth'), 4, 4),
302 substr(Env::v('birth'), 2, 2),
303 substr(Env::v('birth'), 0, 2));
8858cfc1 304
5e2307dc 305 $mailorg = strtok(Env::v('login'), '@');
8858cfc1 306
31e01c97 307 // XXX: recovery requires usage of profile data.
08cce2ff 308 $res = XDB::query(
8858cfc1 309 "SELECT user_id, naissance
310 FROM auth_user_md5 AS u
3a5c1551 311 INNER JOIN aliases AS a ON (u.user_id=a.id AND type != 'homonyme')
8858cfc1 312 WHERE a.alias={?} AND u.perms IN ('admin','user') AND u.deces=0", $mailorg);
313 list($uid, $naissance) = $res->fetchOneRow();
314
315 if ($naissance == $birth) {
8c28edc9 316 $res = XDB::query("SELECT COUNT(*)
317 FROM emails
318 WHERE uid = {?} AND flags != 'panne' AND flags != 'filter'", $uid);
319 $count = intval($res->fetchOneCell());
320 if ($count == 0) {
321 $page->assign('no_addr', true);
322 return;
323 }
324
8858cfc1 325 $page->assign('ok', true);
326
eaf30d86
PH
327 $url = rand_url_id();
328 XDB::execute('INSERT INTO perte_pass (certificat,uid,created)
a4d5829b 329 VALUES ({?},{?},NOW())', $url, $uid);
330 $res = XDB::query('SELECT email
331 FROM emails
332 WHERE uid = {?} AND email = {?}',
333 $uid, Post::v('email'));
334 if ($res->numRows()) {
335 $mails = $res->fetchOneCell();
336 } else {
337 $res = XDB::query('SELECT email
338 FROM emails
339 WHERE uid = {?} AND NOT FIND_IN_SET("filter", flags)', $uid);
340 $mails = implode(', ', $res->fetchColumn());
341 }
1e33266a 342 $mymail = new PlMailer();
1d55fe45 343 $mymail->setFrom('"Gestion des mots de passe" <support+password@' . $globals->mail->domain . '>');
8858cfc1 344 $mymail->addTo($mails);
345 $mymail->setSubject('Ton certificat d\'authentification');
346 $mymail->setTxtBody("Visite la page suivante qui expire dans six heures :
347{$globals->baseurl}/tmpPWD/$url
348
e887e90d 349Si en cliquant dessus tu n'y arrives pas, copie intégralement l'adresse dans la barre de ton navigateur. Si tu n'as pas utilisé ce lien dans six heures, tu peux tout simplement recommencer cette procédure.
8858cfc1 350
eaf30d86 351--
8858cfc1 352Polytechnique.org
a7de4ef7 353\"Le portail des élèves & anciens élèves de l'Ecole polytechnique\"
8858cfc1 354
faefdbb7 355Email envoyé à ".Env::v('login') . (Post::has('email') ? "
a4d5829b 356Adresse de secours : " . Post::v('email') : ""));
8858cfc1 357 $mymail->send();
358
359 // on cree un objet logger et on log l'evenement
cf40e1ae 360 S::logger(uid)->log('recovery', $mails);
8858cfc1 361 } else {
a7d35093 362 $page->trigError('Les informations que tu as rentrées ne permettent pas de récupérer ton mot de passe.<br />'.
3a5c1551 363 'Si tu as un homonyme, utilise prenom.nom.promo comme login');
8858cfc1 364 }
8858cfc1 365 }
366
6c49d0af 367 function handler_tmpPWD(&$page, $certif = null)
368 {
84270653 369 global $globals;
31e01c97
FB
370 // XXX: recovery requires data from the profile
371 XDB::execute('DELETE FROM perte_pass
372 WHERE DATE_SUB(NOW(), INTERVAL 380 MINUTE) > created');
6c49d0af 373
31e01c97
FB
374 $res = XDB::query('SELECT uid
375 FROM perte_pass WHERE certificat={?}', $certif);
6c49d0af 376 $ligne = $res->fetchOneAssoc();
377 if (!$ligne) {
8b1f8e12 378 $page->changeTpl('platal/index.tpl');
6c49d0af 379 $page->kill("Cette adresse n'existe pas ou n'existe plus sur le serveur.");
380 }
381
382 $uid = $ligne["uid"];
383 if (Post::has('response2')) {
5e2307dc 384 $password = Post::v('response2');
31e01c97
FB
385 XDB::query('UPDATE accounts
386 SET password={?}
387 WHERE uid = {?} AND state = \'active\'',
388 $password, $uid);
389 XDB::query('DELETE FROM perte_pass
390 WHERE certificat={?}', $certif);
84270653
VZ
391
392 // If GoogleApps is enabled, and the user did choose to use synchronized passwords,
393 // updates the Google Apps password as well.
394 if ($globals->mailstorage->googleapps_domain) {
395 require_once 'googleapps.inc.php';
d56cb887 396 $account = new GoogleAppsAccount(User::getSilent($uid));
f5c4bf30 397 if ($account->active() && $account->sync_password) {
84270653
VZ
398 $account->set_password($password);
399 }
400 }
401
cf40e1ae 402 S::logger($uid)->log("passwd", "");
8b1f8e12 403 $page->changeTpl('platal/tmpPWD.success.tpl');
6c49d0af 404 } else {
8b1f8e12 405 $page->changeTpl('platal/motdepasse.tpl');
c99ef281 406 $page->addJsLink('motdepasse.js');
6c49d0af 407 }
6c49d0af 408 }
409
9bae6004 410 function handler_skin(&$page)
411 {
412 global $globals;
413
8b1f8e12 414 $page->changeTpl('platal/skins.tpl');
46f272fe 415 $page->setTitle('Skins');
9bae6004 416
a7de4ef7 417 if (Env::has('newskin')) { // formulaire soumis, traitons les données envoyées
31e01c97
FB
418 XDB::execute('UPDATE accounts
419 SET skin = {?}
420 WHERE uid = {?}',
421 Env::i('newskin'), S::i('uid'));
92e6a287 422 S::kill('skin');
47fa97fe 423 Platal::session()->setSkin();
9bae6004 424 }
425
31e01c97
FB
426 $res = XDB::query('SELECT id
427 FROM skins
428 WHERE skin_tpl = {?}', S::v('skin'));
92e6a287 429 $page->assign('skin_id', $res->fetchOneCell());
430
31e01c97
FB
431 $sql = 'SELECT s.*, auteur, COUNT(*) AS nb
432 FROM skins AS s
433 LEFT JOIN accounts AS a ON (a.skin = s.id)
434 WHERE skin_tpl != \'\' AND ext != \'\'
435 GROUP BY id ORDER BY s.date DESC';
a3afa47c 436 $page->assign('skins', XDB::iterator($sql));
9bae6004 437 }
4da0b8d7 438
5de0b7e1 439 function handler_exit(&$page, $level = null)
440 {
0c02607e
FB
441 if (S::suid()) {
442 S::logger()->log('suid_stop', S::user()->login() . " by " . S::suid('hruid'));
47fa97fe 443 Platal::session()->stopSUID();
ae277b9f 444 pl_redirect('admin/user/' . S::user()->login());
5de0b7e1 445 }
446
447 if ($level == 'forget' || $level == 'forgetall') {
604dfd58 448 Platal::session()->killAccessCookie();
5de0b7e1 449 }
450
451 if ($level == 'forgetuid' || $level == 'forgetall') {
604dfd58 452 Platal::session()->killLoginFormCookies();
5de0b7e1 453 }
454
604dfd58 455 S::logger()->log('deconnexion', @$_SERVER['HTTP_REFERER']);
47fa97fe 456 Platal::session()->destroy();
5de0b7e1 457
458 if (Get::has('redirect')) {
5e2307dc 459 http_redirect(rawurldecode(Get::v('redirect')));
5de0b7e1 460 } else {
8b1f8e12 461 $page->changeTpl('platal/exit.tpl');
5de0b7e1 462 }
5de0b7e1 463 }
ddb64990
FB
464
465 function handler_review(&$page, $action = null, $mode = null)
466 {
78507d96
AA
467 // Include X-XRDS-Location response-header for Yadis discovery
468 global $globals;
469 header('X-XRDS-Location: ' . $globals->baseurl . '/openid/idp_xrds');
470
460d8f55 471 $this->load('review.inc.php');
ddb64990
FB
472 $dom = 'Review';
473 if (@$GLOBALS['IS_XNET_SITE']) {
474 $dom .= 'Xnet';
475 }
8f201b69
FB
476 $wp = new PlWikiPage($dom . '.Admin');
477 $conf = explode('%0a', $wp->getField('text'));
6d20fb1d 478 $wiz = new PlWizard('Tour d\'horizon', PlPage::getCoreTpl('plwizard.tpl'), true);
ddb64990
FB
479 foreach ($conf as $line) {
480 $list = preg_split('/\s*[*|]\s*/', $line, -1, PREG_SPLIT_NO_EMPTY);
481 $wiz->addPage('ReviewPage', $list[0], $list[1]);
482 }
483 $wiz->apply($page, 'review', $action, $mode);
484 }
e59506eb 485}
486
a7de4ef7 487// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
e59506eb 488?>