PlLogger should be replaced by S::logger().
[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
FB
72 } else if (!@$GLOBALS['IS_XNET_SITE']) {
73 pl_redirect('review');
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
90 function handler_changelog(&$page)
91 {
8b1f8e12 92 $page->changeTpl('platal/changeLog.tpl');
5de0b7e1 93
493b6abe 94 $clog = pl_entities(file_get_contents(dirname(__FILE__).'/../ChangeLog'));
8249b26c 95 $clog = preg_replace('/===+\s*/', '</pre><hr /><pre>', $clog);
4e95f720 96 // url catch only (not all wiki syntax)
97 $clog = preg_replace(array(
98 '/((?:https?|ftp):\/\/(?:\.*,*[\w@~%$£µ&i#\-+=_\/\?;])*)/ui',
99 '/(\s|^)www\.((?:\.*,*[\w@~%$£µ&i#\-+=_\/\?;])*)/iu',
100 '/(?:mailto:)?([a-z0-9.\-+_]+@([\-.+_]?[a-z0-9])+)/i'),
101 array(
102 '<a href="\\0">\\0</a>',
103 '\\1<a href="http://www.\\2">www.\\2</a>',
104 '<a href="mailto:\\0">\\0</a>'),
105 $clog);
5de0b7e1 106 $clog = preg_replace('!(#[0-9]+(,[0-9]+)*)!e', 'bugize("\1")', $clog);
9408f155 107 $clog = preg_replace('!vim:.*$!', '', $clog);
02722b9d 108 $clog = preg_replace("!(<hr />(\\s|\n)*)?<pre>(\s|\n)*</pre>((\\s|\n)*<hr />)?!m", "", "<pre>$clog</pre>");
5de0b7e1 109 $page->assign('ChangeLog', $clog);
110 }
111
7927d719 112 function __set_rss_state($state)
113 {
7927d719 114 if ($state) {
115 $_SESSION['core_rss_hash'] = rand_url_id(16);
08cce2ff 116 XDB::execute('UPDATE auth_user_quick
7927d719 117 SET core_rss_hash={?} WHERE user_id={?}',
cab08090 118 S::v('core_rss_hash'), S::v('uid'));
7927d719 119 } else {
08cce2ff 120 XDB::execute('UPDATE auth_user_quick
7927d719 121 SET core_rss_hash="" WHERE user_id={?}',
cab08090 122 S::v('uid'));
123 S::kill('core_rss_hash');
7927d719 124 }
125 }
126
e59506eb 127 function handler_prefs(&$page)
128 {
8b1f8e12 129 $page->changeTpl('platal/preferences.tpl');
46f272fe 130 $page->setTitle('Mes préférences');
e59506eb 131
bee33d93 132 if (Post::has('mail_fmt')) {
5e2307dc 133 $fmt = Post::v('mail_fmt');
e59506eb 134 if ($fmt != 'texte') $fmt = 'html';
08cce2ff 135 XDB::execute("UPDATE auth_user_quick
e59506eb 136 SET core_mail_fmt = '$fmt'
137 WHERE user_id = {?}",
cab08090 138 S::v('uid'));
e59506eb 139 $_SESSION['mail_fmt'] = $fmt;
e59506eb 140 }
141
bee33d93 142 if (Post::has('rss')) {
5e2307dc 143 $this->__set_rss_state(Post::b('rss'));
e59506eb 144 }
e67b4436
VZ
145
146 # FIXME: this code is not multi-domain compatible. We should decide how
147 # carva will extend to users not in the main domain.
148 $res = XDB::query("SELECT alias
149 FROM aliases
150 WHERE id = {?} AND FIND_IN_SET('bestalias', flags)",
151 S::user()->id());
152 $page->assign('bestalias', $res->fetchOneCell());
e59506eb 153 }
9bae6004 154
bce2f8eb 155 function handler_webredir(&$page)
156 {
8b1f8e12 157 $page->changeTpl('platal/webredirect.tpl');
bce2f8eb 158
46f272fe 159 $page->setTitle('Redirection de page WEB');
bce2f8eb 160
cab08090 161 $log =& S::v('log');
5e2307dc 162 $url = Env::v('url');
bce2f8eb 163
5e2307dc 164 if (Env::v('submit') == 'Valider' and Env::has('url')) {
08cce2ff 165 XDB::execute('UPDATE auth_user_quick
bce2f8eb 166 SET redirecturl = {?} WHERE user_id = {?}',
cab08090 167 $url, S::v('uid'));
732e5855 168 S::logger()->log('carva_add', 'http://'.Env::v('url'));
a7d35093 169 $page->trigSuccess("Redirection activée vers <a href='http://$url'>$url</a>");
5e2307dc 170 } elseif (Env::v('submit') == "Supprimer") {
08cce2ff 171 XDB::execute("UPDATE auth_user_quick
bce2f8eb 172 SET redirecturl = ''
173 WHERE user_id = {?}",
cab08090 174 S::v('uid'));
732e5855 175 S::logger()->log("carva_del", $url);
bce2f8eb 176 Post::kill('url');
a7d35093 177 $page->trigSuccess('Redirection supprimée');
bce2f8eb 178 }
179
08cce2ff 180 $res = XDB::query('SELECT redirecturl
bce2f8eb 181 FROM auth_user_quick
182 WHERE user_id = {?}',
cab08090 183 S::v('uid'));
bce2f8eb 184 $page->assign('carva', $res->fetchOneCell());
e67b4436
VZ
185
186 # FIXME: this code is not multi-domain compatible. We should decide how
187 # carva will extend to users not in the main domain.
188 $res = XDB::query("SELECT alias
189 FROM aliases
190 WHERE id = {?} AND FIND_IN_SET('bestalias', flags)",
191 S::user()->id());
192 $page->assign('bestalias', $res->fetchOneCell());
bce2f8eb 193 }
194
4da0b8d7 195 function handler_prefs_rss(&$page)
7927d719 196 {
8b1f8e12 197 $page->changeTpl('platal/filrss.tpl');
7927d719 198
5e2307dc 199 $page->assign('goback', Env::v('referer', 'login'));
7927d719 200
5e2307dc 201 if (Env::v('act_rss') == 'Activer') {
7927d719 202 $this->__set_rss_state(true);
a7d35093 203 $page->trigSuccess("Ton Fil RSS est activé.");
7927d719 204 }
7927d719 205 }
206
7c77c3ee 207 function handler_password(&$page)
208 {
84270653
VZ
209 global $globals;
210
40d428d8 211 if (Post::has('response2')) {
7c77c3ee 212 require_once 'secure_hash.inc.php';
40d428d8 213 S::assert_xsrf_token();
7c77c3ee 214
5e2307dc 215 $_SESSION['password'] = $password = Post::v('response2');
7c77c3ee 216
eaf30d86 217 XDB::execute('UPDATE auth_user_md5
9ffe0e77 218 SET password={?}
219 WHERE user_id={?}', $password,
220 S::v('uid'));
7c77c3ee 221
84270653
VZ
222 // If GoogleApps is enabled, and the user did choose to use synchronized passwords,
223 // updates the Google Apps password as well.
224 if ($globals->mailstorage->googleapps_domain) {
225 require_once 'googleapps.inc.php';
d56cb887 226 $account = new GoogleAppsAccount(S::user());
f5c4bf30 227 if ($account->active() && $account->sync_password) {
84270653
VZ
228 $account->set_password($password);
229 }
230 }
231
cab08090 232 $log =& S::v('log');
732e5855 233 S::logger()->log('passwd', '');
7c77c3ee 234
5e2307dc 235 if (Cookie::v('ORGaccess')) {
7c77c3ee 236 setcookie('ORGaccess', hash_encrypt($password), (time()+25920000), '/', '' ,0);
237 }
238
8b1f8e12 239 $page->changeTpl('platal/motdepasse.success.tpl');
7c77c3ee 240 $page->run();
241 }
242
8b1f8e12 243 $page->changeTpl('platal/motdepasse.tpl');
c99ef281 244 $page->addJsLink('motdepasse.js');
46f272fe 245 $page->setTitle('Mon mot de passe');
7c77c3ee 246 }
247
1a5da857 248 function handler_smtppass(&$page)
249 {
8b1f8e12 250 $page->changeTpl('platal/acces_smtp.tpl');
46f272fe 251 $page->setTitle('Acces SMTP/NNTP');
eaf30d86 252
8f201b69
FB
253 $wp = new PlWikiPage('Xorg.SMTPSécurisé');
254 $wp->buildCache();
255 $wp = new PlWikiPage('Xorg.NNTPSécurisé');
256 $wp->buildCache();
1a5da857 257
cab08090 258 $uid = S::v('uid');
5e2307dc 259 $pass = Env::v('smtppass1');
cab08090 260 $log = S::v('log');
1a5da857 261
eaf30d86
PH
262 if (Env::v('op') == "Valider" && strlen($pass) >= 6
263 && Env::v('smtppass1') == Env::v('smtppass2'))
1a5da857 264 {
08cce2ff 265 XDB::execute('UPDATE auth_user_md5 SET smtppass = {?}
1a5da857 266 WHERE user_id = {?}', $pass, $uid);
a7d35093 267 $page->trigSuccess('Mot de passe enregistré');
732e5855 268 S::logger()->log("passwd_ssl");
5e2307dc 269 } elseif (Env::v('op') == "Supprimer") {
08cce2ff 270 XDB::execute('UPDATE auth_user_md5 SET smtppass = ""
1a5da857 271 WHERE user_id = {?}', $uid);
a7d35093 272 $page->trigSuccess('Compte SMTP et NNTP supprimé');
732e5855 273 S::logger()->log("passwd_del");
1a5da857 274 }
275
eaf30d86 276 $res = XDB::query("SELECT IF(smtppass != '', 'actif', '')
1a5da857 277 FROM auth_user_md5
278 WHERE user_id = {?}", $uid);
279 $page->assign('actif', $res->fetchOneCell());
1a5da857 280 }
281
8858cfc1 282 function handler_recovery(&$page)
283 {
284 global $globals;
285
8b1f8e12 286 $page->changeTpl('platal/recovery.tpl');
8858cfc1 287
288 if (!Env::has('login') || !Env::has('birth')) {
fd8f77de 289 return;
8858cfc1 290 }
291
5e2307dc 292 if (!ereg('[0-3][0-9][0-1][0-9][1][9]([0-9]{2})', Env::v('birth'))) {
a7d35093 293 $page->trigError('Date de naissance incorrecte ou incohérente');
c9110c6c 294 return;
8858cfc1 295 }
c9110c6c 296
297 $birth = sprintf('%s-%s-%s',
5e2307dc 298 substr(Env::v('birth'), 4, 4),
299 substr(Env::v('birth'), 2, 2),
300 substr(Env::v('birth'), 0, 2));
8858cfc1 301
5e2307dc 302 $mailorg = strtok(Env::v('login'), '@');
8858cfc1 303
a7de4ef7 304 // paragraphe rajouté : si la date de naissance dans la base n'existe pas, on l'update
305 // avec celle fournie ici en espérant que c'est la bonne
8858cfc1 306
08cce2ff 307 $res = XDB::query(
8858cfc1 308 "SELECT user_id, naissance
309 FROM auth_user_md5 AS u
3a5c1551 310 INNER JOIN aliases AS a ON (u.user_id=a.id AND type != 'homonyme')
8858cfc1 311 WHERE a.alias={?} AND u.perms IN ('admin','user') AND u.deces=0", $mailorg);
312 list($uid, $naissance) = $res->fetchOneRow();
313
314 if ($naissance == $birth) {
8c28edc9 315 $res = XDB::query("SELECT COUNT(*)
316 FROM emails
317 WHERE uid = {?} AND flags != 'panne' AND flags != 'filter'", $uid);
318 $count = intval($res->fetchOneCell());
319 if ($count == 0) {
320 $page->assign('no_addr', true);
321 return;
322 }
323
8858cfc1 324 $page->assign('ok', true);
325
eaf30d86
PH
326 $url = rand_url_id();
327 XDB::execute('INSERT INTO perte_pass (certificat,uid,created)
a4d5829b 328 VALUES ({?},{?},NOW())', $url, $uid);
329 $res = XDB::query('SELECT email
330 FROM emails
331 WHERE uid = {?} AND email = {?}',
332 $uid, Post::v('email'));
333 if ($res->numRows()) {
334 $mails = $res->fetchOneCell();
335 } else {
336 $res = XDB::query('SELECT email
337 FROM emails
338 WHERE uid = {?} AND NOT FIND_IN_SET("filter", flags)', $uid);
339 $mails = implode(', ', $res->fetchColumn());
340 }
1e33266a 341 $mymail = new PlMailer();
1d55fe45 342 $mymail->setFrom('"Gestion des mots de passe" <support+password@' . $globals->mail->domain . '>');
8858cfc1 343 $mymail->addTo($mails);
344 $mymail->setSubject('Ton certificat d\'authentification');
345 $mymail->setTxtBody("Visite la page suivante qui expire dans six heures :
346{$globals->baseurl}/tmpPWD/$url
347
e887e90d 348Si 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 349
eaf30d86 350--
8858cfc1 351Polytechnique.org
a7de4ef7 352\"Le portail des élèves & anciens élèves de l'Ecole polytechnique\"
8858cfc1 353
faefdbb7 354Email envoyé à ".Env::v('login') . (Post::has('email') ? "
a4d5829b 355Adresse de secours : " . Post::v('email') : ""));
8858cfc1 356 $mymail->send();
357
358 // on cree un objet logger et on log l'evenement
ef4b26a5 359 $logger = $_SESSION['log'] = S::logger($uid);
732e5855 360 S::logger()->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;
08cce2ff 370 XDB::execute('DELETE FROM perte_pass
6c49d0af 371 WHERE DATE_SUB(NOW(), INTERVAL 380 MINUTE) > created');
372
08cce2ff 373 $res = XDB::query('SELECT uid FROM perte_pass WHERE certificat={?}', $certif);
6c49d0af 374 $ligne = $res->fetchOneAssoc();
375 if (!$ligne) {
8b1f8e12 376 $page->changeTpl('platal/index.tpl');
6c49d0af 377 $page->kill("Cette adresse n'existe pas ou n'existe plus sur le serveur.");
378 }
379
380 $uid = $ligne["uid"];
381 if (Post::has('response2')) {
5e2307dc 382 $password = Post::v('response2');
08cce2ff 383 XDB::query('UPDATE auth_user_md5 SET password={?}
6c49d0af 384 WHERE user_id={?} AND perms IN("admin","user")',
385 $password, $uid);
08cce2ff 386 XDB::query('DELETE FROM perte_pass WHERE certificat={?}', $certif);
84270653
VZ
387
388 // If GoogleApps is enabled, and the user did choose to use synchronized passwords,
389 // updates the Google Apps password as well.
390 if ($globals->mailstorage->googleapps_domain) {
391 require_once 'googleapps.inc.php';
d56cb887 392 $account = new GoogleAppsAccount(User::getSilent($uid));
f5c4bf30 393 if ($account->active() && $account->sync_password) {
84270653
VZ
394 $account->set_password($password);
395 }
396 }
397
ef4b26a5 398 $logger = S::logger($uid);
732e5855 399 S::logger()->log("passwd","");
8b1f8e12 400 $page->changeTpl('platal/tmpPWD.success.tpl');
6c49d0af 401 } else {
8b1f8e12 402 $page->changeTpl('platal/motdepasse.tpl');
c99ef281 403 $page->addJsLink('motdepasse.js');
6c49d0af 404 }
6c49d0af 405 }
406
9bae6004 407 function handler_skin(&$page)
408 {
409 global $globals;
410
8b1f8e12 411 $page->changeTpl('platal/skins.tpl');
46f272fe 412 $page->setTitle('Skins');
9bae6004 413
a7de4ef7 414 if (Env::has('newskin')) { // formulaire soumis, traitons les données envoyées
08cce2ff 415 XDB::execute('UPDATE auth_user_quick
63528107 416 SET skin={?} WHERE user_id={?}',
5e2307dc 417 Env::i('newskin'), S::v('uid'));
92e6a287 418 S::kill('skin');
47fa97fe 419 Platal::session()->setSkin();
9bae6004 420 }
421
92e6a287 422 $res = XDB::query('SELECT id FROM skins WHERE skin_tpl={?}', S::v('skin'));
423 $page->assign('skin_id', $res->fetchOneCell());
424
9bae6004 425 $sql = "SELECT s.*,auteur,count(*) AS nb
426 FROM skins AS s
427 LEFT JOIN auth_user_quick AS a ON s.id=a.skin
428 WHERE skin_tpl != '' AND ext != ''
429 GROUP BY id ORDER BY s.date DESC";
a3afa47c 430 $page->assign('skins', XDB::iterator($sql));
9bae6004 431 }
4da0b8d7 432
5de0b7e1 433 function handler_exit(&$page, $level = null)
434 {
cab08090 435 if (S::has('suid')) {
e74411f7 436 $suid = S::v('suid');
437 $log = S::v('log');
ae277b9f 438 S::logger()->log("suid_stop", S::user()->login() . " by " . $suid['hruid']);
47fa97fe 439 Platal::session()->stopSUID();
ae277b9f 440 pl_redirect('admin/user/' . S::user()->login());
5de0b7e1 441 }
442
443 if ($level == 'forget' || $level == 'forgetall') {
444 setcookie('ORGaccess', '', time() - 3600, '/', '', 0);
445 Cookie::kill('ORGaccess');
446 if (isset($_SESSION['log']))
732e5855 447 S::logger()->log("cookie_off");
5de0b7e1 448 }
449
450 if ($level == 'forgetuid' || $level == 'forgetall') {
451 setcookie('ORGuid', '', time() - 3600, '/', '', 0);
452 Cookie::kill('ORGuid');
453 setcookie('ORGdomain', '', time() - 3600, '/', '', 0);
454 Cookie::kill('ORGdomain');
455 }
456
457 if (isset($_SESSION['log'])) {
458 $ref = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
732e5855 459 S::logger()->log('deconnexion',$ref);
5de0b7e1 460 }
47fa97fe 461 Platal::session()->destroy();
5de0b7e1 462
463 if (Get::has('redirect')) {
5e2307dc 464 http_redirect(rawurldecode(Get::v('redirect')));
5de0b7e1 465 } else {
8b1f8e12 466 $page->changeTpl('platal/exit.tpl');
5de0b7e1 467 }
5de0b7e1 468 }
ddb64990
FB
469
470 function handler_review(&$page, $action = null, $mode = null)
471 {
78507d96
AA
472 // Include X-XRDS-Location response-header for Yadis discovery
473 global $globals;
474 header('X-XRDS-Location: ' . $globals->baseurl . '/openid/idp_xrds');
475
460d8f55 476 $this->load('review.inc.php');
ddb64990
FB
477 $dom = 'Review';
478 if (@$GLOBALS['IS_XNET_SITE']) {
479 $dom .= 'Xnet';
480 }
8f201b69
FB
481 $wp = new PlWikiPage($dom . '.Admin');
482 $conf = explode('%0a', $wp->getField('text'));
6d20fb1d 483 $wiz = new PlWizard('Tour d\'horizon', PlPage::getCoreTpl('plwizard.tpl'), true);
ddb64990
FB
484 foreach ($conf as $line) {
485 $list = preg_split('/\s*[*|]\s*/', $line, -1, PREG_SPLIT_NO_EMPTY);
486 $wiz->addPage('ReviewPage', $list[0], $list[1]);
487 }
488 $wiz->apply($page, 'review', $action, $mode);
489 }
e59506eb 490}
491
a7de4ef7 492// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
e59506eb 493?>