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