Happy new year!
[platal.git] / modules / platal.php
1 <?php
2 /***************************************************************************
3 * Copyright (C) 2003-2008 Polytechnique.org *
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
22 function 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
36 class PlatalModule extends PLModule
37 {
38 function handlers()
39 {
40 return array(
41 'index' => $this->make_hook('index', AUTH_PUBLIC),
42 'cacert.pem' => $this->make_hook('cacert', AUTH_PUBLIC),
43 'changelog' => $this->make_hook('changelog', AUTH_PUBLIC),
44
45 // Preferences thingies
46 'prefs' => $this->make_hook('prefs', AUTH_COOKIE),
47 'prefs/rss' => $this->make_hook('prefs_rss', AUTH_COOKIE),
48 'prefs/webredirect'
49 => $this->make_hook('webredir', AUTH_MDP),
50 'prefs/skin' => $this->make_hook('skin', AUTH_COOKIE),
51
52 // password related thingies
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),
56 'recovery' => $this->make_hook('recovery', AUTH_PUBLIC),
57 'exit' => $this->make_hook('exit', AUTH_PUBLIC),
58 'review' => $this->make_hook('review', AUTH_PUBLIC),
59 'deconnexion.php' => $this->make_hook('exit', AUTH_PUBLIC),
60 );
61 }
62
63 function handler_index(&$page)
64 {
65 if (S::logged()) {
66 pl_redirect('events');
67 } else if (!@$GLOBALS['IS_XNET_SITE']) {
68 pl_redirect('review');
69 }
70 }
71
72 function handler_cacert(&$page)
73 {
74 $data = file_get_contents("/etc/ssl/xorgCA/cacert.pem","r");
75 header("Pragma:");
76 header("Set-Cookie:");
77 header("Cache-Control:");
78 header("Expires:");
79 header("Content-Type: application/x-x509-ca-cert");
80 header("Content-Length: ".strlen($data));
81 echo $data;
82 exit;
83 }
84
85 function handler_changelog(&$page)
86 {
87 $page->changeTpl('platal/changeLog.tpl');
88
89 $clog = pl_entities(file_get_contents(dirname(__FILE__).'/../ChangeLog'));
90 $clog = preg_replace('/=+\s*/', '</pre><hr /><pre>', $clog);
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);
101 $clog = preg_replace('!(#[0-9]+(,[0-9]+)*)!e', 'bugize("\1")', $clog);
102 $clog = preg_replace('!vim:.*$!', '', $clog);
103 $clog = preg_replace("!(<hr />(\\s|\n)*)?<pre>(\s|\n)*</pre>((\\s|\n)*<hr />)?!m", "", "<pre>$clog</pre>");
104 $page->assign('ChangeLog', $clog);
105 }
106
107 function __set_rss_state($state)
108 {
109 if ($state) {
110 $_SESSION['core_rss_hash'] = rand_url_id(16);
111 XDB::execute('UPDATE auth_user_quick
112 SET core_rss_hash={?} WHERE user_id={?}',
113 S::v('core_rss_hash'), S::v('uid'));
114 } else {
115 XDB::execute('UPDATE auth_user_quick
116 SET core_rss_hash="" WHERE user_id={?}',
117 S::v('uid'));
118 S::kill('core_rss_hash');
119 }
120 }
121
122 function handler_prefs(&$page)
123 {
124 $page->changeTpl('platal/preferences.tpl');
125 $page->assign('xorg_title','Polytechnique.org - Mes préférences');
126
127 if (Post::has('mail_fmt')) {
128 $fmt = Post::v('mail_fmt');
129 if ($fmt != 'texte') $fmt = 'html';
130 XDB::execute("UPDATE auth_user_quick
131 SET core_mail_fmt = '$fmt'
132 WHERE user_id = {?}",
133 S::v('uid'));
134 $_SESSION['mail_fmt'] = $fmt;
135 }
136
137 if (Post::has('rss')) {
138 $this->__set_rss_state(Post::b('rss'));
139 }
140 }
141
142 function handler_webredir(&$page)
143 {
144 $page->changeTpl('platal/webredirect.tpl');
145
146 $page->assign('xorg_title','Polytechnique.org - Redirection de page WEB');
147
148 $log =& S::v('log');
149 $url = Env::v('url');
150
151 if (Env::v('submit') == 'Valider' and Env::has('url')) {
152 XDB::execute('UPDATE auth_user_quick
153 SET redirecturl = {?} WHERE user_id = {?}',
154 $url, S::v('uid'));
155 $log->log('carva_add', 'http://'.Env::v('url'));
156 $page->trig("Redirection activée vers <a href='http://$url'>$url</a>");
157 } elseif (Env::v('submit') == "Supprimer") {
158 XDB::execute("UPDATE auth_user_quick
159 SET redirecturl = ''
160 WHERE user_id = {?}",
161 S::v('uid'));
162 $log->log("carva_del", $url);
163 Post::kill('url');
164 $page->trig('Redirection supprimée');
165 }
166
167 $res = XDB::query('SELECT redirecturl
168 FROM auth_user_quick
169 WHERE user_id = {?}',
170 S::v('uid'));
171 $page->assign('carva', $res->fetchOneCell());
172 }
173
174 function handler_prefs_rss(&$page)
175 {
176 $page->changeTpl('platal/filrss.tpl');
177
178 $page->assign('goback', Env::v('referer', 'login'));
179
180 if (Env::v('act_rss') == 'Activer') {
181 $this->__set_rss_state(true);
182 $page->trig("Ton Fil RSS est activé.");
183 }
184 }
185
186 function handler_password(&$page)
187 {
188 if (Post::has('response2')) {
189 require_once 'secure_hash.inc.php';
190
191 $_SESSION['password'] = $password = Post::v('response2');
192
193 XDB::execute('UPDATE auth_user_md5
194 SET password={?}
195 WHERE user_id={?}', $password,
196 S::v('uid'));
197
198 $log =& S::v('log');
199 $log->log('passwd', '');
200
201 if (Cookie::v('ORGaccess')) {
202 setcookie('ORGaccess', hash_encrypt($password), (time()+25920000), '/', '' ,0);
203 }
204
205 $page->changeTpl('platal/motdepasse.success.tpl');
206 $page->run();
207 }
208
209 $page->changeTpl('platal/motdepasse.tpl');
210 $page->addJsLink('motdepasse.js');
211 $page->assign('xorg_title','Polytechnique.org - Mon mot de passe');
212 }
213
214 function handler_smtppass(&$page)
215 {
216 $page->changeTpl('platal/acces_smtp.tpl');
217 $page->assign('xorg_title','Polytechnique.org - Acces SMTP/NNTP');
218
219 require_once 'wiki.inc.php';
220 wiki_require_page('Xorg.SMTPSécurisé');
221 wiki_require_page('Xorg.NNTPSécurisé');
222
223 $uid = S::v('uid');
224 $pass = Env::v('smtppass1');
225 $log = S::v('log');
226
227 if (Env::v('op') == "Valider" && strlen($pass) >= 6
228 && Env::v('smtppass1') == Env::v('smtppass2'))
229 {
230 XDB::execute('UPDATE auth_user_md5 SET smtppass = {?}
231 WHERE user_id = {?}', $pass, $uid);
232 $page->trig('Mot de passe enregistré');
233 $log->log("passwd_ssl");
234 } elseif (Env::v('op') == "Supprimer") {
235 XDB::execute('UPDATE auth_user_md5 SET smtppass = ""
236 WHERE user_id = {?}', $uid);
237 $page->trig('Compte SMTP et NNTP supprimé');
238 $log->log("passwd_del");
239 }
240
241 $res = XDB::query("SELECT IF(smtppass != '', 'actif', '')
242 FROM auth_user_md5
243 WHERE user_id = {?}", $uid);
244 $page->assign('actif', $res->fetchOneCell());
245 }
246
247 function handler_recovery(&$page)
248 {
249 global $globals;
250
251 $page->changeTpl('platal/recovery.tpl');
252
253 if (!Env::has('login') || !Env::has('birth')) {
254 return;
255 }
256
257 if (!ereg('[0-3][0-9][0-1][0-9][1][9]([0-9]{2})', Env::v('birth'))) {
258 $page->trig('Date de naissance incorrecte ou incohérente');
259 return;
260 }
261
262 $birth = sprintf('%s-%s-%s',
263 substr(Env::v('birth'), 4, 4),
264 substr(Env::v('birth'), 2, 2),
265 substr(Env::v('birth'), 0, 2));
266
267 $mailorg = strtok(Env::v('login'), '@');
268
269 // paragraphe rajouté : si la date de naissance dans la base n'existe pas, on l'update
270 // avec celle fournie ici en espérant que c'est la bonne
271
272 $res = XDB::query(
273 "SELECT user_id, naissance
274 FROM auth_user_md5 AS u
275 INNER JOIN aliases AS a ON (u.user_id=a.id AND type != 'homonyme')
276 WHERE a.alias={?} AND u.perms IN ('admin','user') AND u.deces=0", $mailorg);
277 list($uid, $naissance) = $res->fetchOneRow();
278
279 if ($naissance == $birth) {
280 $res = XDB::query("SELECT COUNT(*)
281 FROM emails
282 WHERE uid = {?} AND flags != 'panne' AND flags != 'filter'", $uid);
283 $count = intval($res->fetchOneCell());
284 if ($count == 0) {
285 $page->assign('no_addr', true);
286 return;
287 }
288
289 $page->assign('ok', true);
290
291 $url = rand_url_id();
292 XDB::execute('INSERT INTO perte_pass (certificat,uid,created)
293 VALUES ({?},{?},NOW())', $url, $uid);
294 $res = XDB::query('SELECT email
295 FROM emails
296 WHERE uid = {?} AND email = {?}',
297 $uid, Post::v('email'));
298 if ($res->numRows()) {
299 $mails = $res->fetchOneCell();
300 } else {
301 $res = XDB::query('SELECT email
302 FROM emails
303 WHERE uid = {?} AND NOT FIND_IN_SET("filter", flags)', $uid);
304 $mails = implode(', ', $res->fetchColumn());
305 }
306 $mymail = new PlMailer();
307 $mymail->setFrom('"Gestion des mots de passe" <support+password@' . $globals->mail->domain . '>');
308 $mymail->addTo($mails);
309 $mymail->setSubject('Ton certificat d\'authentification');
310 $mymail->setTxtBody("Visite la page suivante qui expire dans six heures :
311 {$globals->baseurl}/tmpPWD/$url
312
313 Si 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.
314
315 --
316 Polytechnique.org
317 \"Le portail des élèves & anciens élèves de l'Ecole polytechnique\"
318
319 Mail envoyé à ".Env::v('login') . (Post::has('email') ? "
320 Adresse de secours : " . Post::v('email') : ""));
321 $mymail->send();
322
323 // on cree un objet logger et on log l'evenement
324 $logger = $_SESSION['log'] = new CoreLogger($uid);
325 $logger->log('recovery', $mails);
326 } else {
327 $page->trig('Les informations que tu as rentrées ne permettent pas de récupérer ton mot de passe.<br />'.
328 'Si tu as un homonyme, utilise prenom.nom.promo comme login');
329 }
330 }
331
332 function handler_tmpPWD(&$page, $certif = null)
333 {
334 XDB::execute('DELETE FROM perte_pass
335 WHERE DATE_SUB(NOW(), INTERVAL 380 MINUTE) > created');
336
337 $res = XDB::query('SELECT uid FROM perte_pass WHERE certificat={?}', $certif);
338 $ligne = $res->fetchOneAssoc();
339 if (!$ligne) {
340 $page->changeTpl('platal/index.tpl');
341 $page->kill("Cette adresse n'existe pas ou n'existe plus sur le serveur.");
342 }
343
344 $uid = $ligne["uid"];
345 if (Post::has('response2')) {
346 $password = Post::v('response2');
347 $logger = new CoreLogger($uid);
348 XDB::query('UPDATE auth_user_md5 SET password={?}
349 WHERE user_id={?} AND perms IN("admin","user")',
350 $password, $uid);
351 XDB::query('DELETE FROM perte_pass WHERE certificat={?}', $certif);
352 $logger->log("passwd","");
353 $page->changeTpl('platal/tmpPWD.success.tpl');
354 } else {
355 $page->changeTpl('platal/motdepasse.tpl');
356 $page->addJsLink('motdepasse.js');
357 }
358 }
359
360 function handler_skin(&$page)
361 {
362 global $globals;
363
364 $page->changeTpl('platal/skins.tpl');
365 $page->assign('xorg_title','Polytechnique.org - Skins');
366
367 if (Env::has('newskin')) { // formulaire soumis, traitons les données envoyées
368 XDB::execute('UPDATE auth_user_quick
369 SET skin={?} WHERE user_id={?}',
370 Env::i('newskin'), S::v('uid'));
371 S::kill('skin');
372 set_skin();
373 }
374
375 $res = XDB::query('SELECT id FROM skins WHERE skin_tpl={?}', S::v('skin'));
376 $page->assign('skin_id', $res->fetchOneCell());
377
378 $sql = "SELECT s.*,auteur,count(*) AS nb
379 FROM skins AS s
380 LEFT JOIN auth_user_quick AS a ON s.id=a.skin
381 WHERE skin_tpl != '' AND ext != ''
382 GROUP BY id ORDER BY s.date DESC";
383 $page->assign('skins', XDB::iterator($sql));
384 }
385
386 function handler_exit(&$page, $level = null)
387 {
388 if (S::has('suid')) {
389 $a4l = S::v('forlife');
390 $suid = S::v('suid');
391 $log = S::v('log');
392 $log->log("suid_stop", S::v('forlife') . " by " . $suid['forlife']);
393 $_SESSION = $suid;
394 S::kill('suid');
395 pl_redirect('admin/user/' . $a4l);
396 }
397
398 if ($level == 'forget' || $level == 'forgetall') {
399 setcookie('ORGaccess', '', time() - 3600, '/', '', 0);
400 Cookie::kill('ORGaccess');
401 if (isset($_SESSION['log']))
402 $_SESSION['log']->log("cookie_off");
403 }
404
405 if ($level == 'forgetuid' || $level == 'forgetall') {
406 setcookie('ORGuid', '', time() - 3600, '/', '', 0);
407 Cookie::kill('ORGuid');
408 setcookie('ORGdomain', '', time() - 3600, '/', '', 0);
409 Cookie::kill('ORGdomain');
410 }
411
412 if (isset($_SESSION['log'])) {
413 $ref = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
414 $_SESSION['log']->log('deconnexion',$ref);
415 }
416
417 XorgSession::destroy();
418
419 if (Get::has('redirect')) {
420 http_redirect(rawurldecode(Get::v('redirect')));
421 } else {
422 $page->changeTpl('platal/exit.tpl');
423 }
424 }
425
426 function handler_review(&$page, $action = null, $mode = null)
427 {
428 require_once 'wiki.inc.php';
429 require_once dirname(__FILE__) . '/platal/review.inc.php';
430 $dir = wiki_work_dir();
431 $dom = 'Review';
432 if (@$GLOBALS['IS_XNET_SITE']) {
433 $dom .= 'Xnet';
434 }
435 if (!is_dir($dir)) {
436 $page->kill("Impossible de trouver le wiki");
437 }
438 if (!file_exists($dir . '/' . $dom . '.Admin')) {
439 $page->kill("Impossible de trouver la page d'administration");
440 }
441 $conf = preg_grep('/^text=/', explode("\n", file_get_contents($dir . '/' . $dom . '.Admin')));
442 $conf = preg_split('/(text\=|\%0a)/', array_shift($conf), -1, PREG_SPLIT_NO_EMPTY);
443 $wiz = new PlWizard('Tour d\'horizon', 'core/plwizard.tpl', true);
444 foreach ($conf as $line) {
445 $list = preg_split('/\s*[*|]\s*/', $line, -1, PREG_SPLIT_NO_EMPTY);
446 $wiz->addPage('ReviewPage', $list[0], $list[1]);
447 }
448 $wiz->apply($page, 'review', $action, $mode);
449 }
450 }
451
452 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
453 ?>