Merge branch 'xorg/maint' into xorg/master
[platal.git] / modules / xnet.php
1 <?php
2 /***************************************************************************
3 * Copyright (C) 2003-2011 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 class XnetModule extends PLModule
23 {
24 function handlers()
25 {
26 return array(
27 'index' => $this->make_hook('index', AUTH_PUBLIC),
28 'exit' => $this->make_hook('exit', AUTH_PUBLIC),
29
30 'admin' => $this->make_hook('admin', AUTH_MDP, 'admin'),
31 'groups' => $this->make_hook('groups', AUTH_PUBLIC),
32 'groupes.php' => $this->make_hook('groups2', AUTH_PUBLIC),
33 'plan' => $this->make_hook('plan', AUTH_PUBLIC),
34 'photo' => $this->make_hook('photo', AUTH_MDP),
35 'autologin' => $this->make_hook('autologin', AUTH_MDP),
36 'login/ext' => $this->make_hook('login_ext', AUTH_PUBLIC),
37 'register/ext' => $this->make_hook('register_ext', AUTH_PUBLIC),
38 'recovery/ext' => $this->make_hook('recovery_ext', AUTH_PUBLIC),
39 'tmpPWD/ext' => $this->make_hook('tmpPWD_ext', AUTH_PUBLIC),
40 'edit' => $this->make_hook('edit', AUTH_MDP, 'user'),
41 'password' => $this->make_hook('password', AUTH_MDP, 'user'),
42
43 'Xnet' => $this->make_wiki_hook(),
44 );
45 }
46
47 function handler_photo($page, $x = null)
48 {
49 if (!$x || !($profile = Profile::get($x))) {
50 return PL_NOT_FOUND;
51 }
52
53 // Retrieve the photo and its mime type.
54 $photo = $profile->getPhoto(true, true);
55
56 // Display the photo, or a default one when not available.
57 $photo->send();
58 }
59
60 function handler_index($page)
61 {
62 $page->nomenu = true;
63 $page->changeTpl('xnet/index.tpl');
64 }
65
66 function handler_exit($page)
67 {
68 Platal::session()->stopSUID();
69 Platal::session()->destroy();
70 $page->changeTpl('xnet/deconnexion.tpl');
71 }
72
73 function handler_admin($page)
74 {
75 $page->changeTpl('xnet/admin.tpl');
76
77 if (Get::has('del')) {
78 $res = XDB::query('SELECT id, nom, mail_domain
79 FROM groups WHERE diminutif={?}',
80 Get::v('del'));
81 list($id, $nom, $domain) = $res->fetchOneRow();
82 $page->assign('nom', $nom);
83 if ($id && Post::has('del')) {
84 S::assert_xsrf_token();
85
86 XDB::query('DELETE FROM group_members WHERE asso_id={?}', $id);
87 $page->trigSuccess('membres supprimés');
88
89 if ($domain) {
90 XDB::execute('DELETE v
91 FROM email_virtual AS v
92 INNER JOIN email_virtual_domains AS d ON (v.domain = d.id)
93 WHERE d.name = {?}',
94 $domain);
95 XDB::execute('DELETE FROM email_virtual_domains
96 WHERE name = {?}', $domain);
97 $page->trigSuccess('suppression des alias mails');
98
99 $mmlist = new MMList(S::v('uid'), S::v('password'), $domain);
100 if ($listes = $mmlist->get_lists()) {
101 foreach ($listes as $l) {
102 $mmlist->delete_list($l['list'], true);
103 }
104 $page->trigSuccess('mail lists surpprimées');
105 }
106 }
107
108 XDB::query('DELETE FROM groups WHERE id={?}', $id);
109 $page->trigSuccess("Groupe $nom supprimé");
110 Get::kill('del');
111 }
112 if (!$id) {
113 Get::kill('del');
114 }
115 }
116
117 if (Post::has('diminutif') && Post::v('diminutif') != "") {
118 S::assert_xsrf_token();
119
120 $res = XDB::query('SELECT COUNT(*)
121 FROM groups
122 WHERE diminutif = {?}',
123 Post::v('diminutif'));
124
125 if ($res->fetchOneCell() == 0) {
126 XDB::execute('INSERT INTO groups (id, diminutif)
127 VALUES (NULL, {?})',
128 Post::v('diminutif'));
129 pl_redirect(Post::v('diminutif') . '/edit');
130 } else {
131 $page->trigError('Le diminutif demandé est déjà pris.');
132 }
133 }
134
135 $res = XDB::query('SELECT nom, diminutif
136 FROM groups
137 ORDER BY nom');
138 $page->assign('assos', $res->fetchAllAssoc());
139 }
140
141 function handler_plan($page)
142 {
143 $page->changeTpl('xnet/plan.tpl');
144
145 $page->setType('plan');
146
147 $res = XDB::iterator(
148 'SELECT dom.id, dom.nom as domnom, groups.diminutif, groups.nom
149 FROM group_dom AS dom
150 INNER JOIN groups ON dom.id = groups.dom
151 WHERE FIND_IN_SET("GroupesX", dom.cat) AND FIND_IN_SET("GroupesX", groups.cat)
152 ORDER BY dom.nom, groups.nom');
153 $groupesx = array();
154 while ($tmp = $res->next()) { $groupesx[$tmp['id']][] = $tmp; }
155 $page->assign('groupesx', $groupesx);
156
157 $res = XDB::iterator(
158 'SELECT dom.id, dom.nom as domnom, groups.diminutif, groups.nom
159 FROM group_dom AS dom
160 INNER JOIN groups ON dom.id = groups.dom
161 WHERE FIND_IN_SET("Binets", dom.cat) AND FIND_IN_SET("Binets", groups.cat)
162 ORDER BY dom.nom, groups.nom');
163 $binets = array();
164 while ($tmp = $res->next()) { $binets[$tmp['id']][] = $tmp; }
165 $page->assign('binets', $binets);
166
167 $res = XDB::iterator(
168 'SELECT diminutif, nom
169 FROM groups
170 WHERE cat LIKE "%Promotions%"
171 ORDER BY diminutif');
172 $page->assign('promos', $res);
173
174 $res = XDB::iterator(
175 'SELECT diminutif, nom
176 FROM groups
177 WHERE FIND_IN_SET("Institutions", cat)
178 ORDER BY diminutif');
179 $page->assign('inst', $res);
180 }
181
182 function handler_groups2($page)
183 {
184 $this->handler_groups($page, Get::v('cat'), Get::v('dom'));
185 }
186
187 function handler_groups($page, $cat = null, $dom = null)
188 {
189 if (!$cat) {
190 $this->handler_index($page);
191 }
192
193 $cat = mb_strtolower($cat);
194
195 $page->changeTpl('xnet/groupes.tpl');
196 $page->assign('cat', $cat);
197 $page->assign('dom', $dom);
198
199 $res = XDB::query("SELECT id,nom
200 FROM group_dom
201 WHERE FIND_IN_SET({?}, cat)
202 ORDER BY nom", $cat);
203 $doms = $res->fetchAllAssoc();
204 $page->assign('doms', $doms);
205
206 if (empty($doms)) {
207 $res = XDB::query("SELECT diminutif, nom, site
208 FROM groups
209 WHERE FIND_IN_SET({?}, cat)
210 ORDER BY nom", $cat);
211 $page->assign('gps', $res->fetchAllAssoc());
212 } elseif (!is_null($dom)) {
213 $res = XDB::query("SELECT diminutif, nom, site
214 FROM groups
215 WHERE FIND_IN_SET({?}, cat) AND dom={?}
216 ORDER BY nom", $cat, $dom);
217 $page->assign('gps', $res->fetchAllAssoc());
218 }
219
220 $page->setType($cat);
221 }
222
223 function handler_autologin($page)
224 {
225 $allkeys = func_get_args();
226 unset($allkeys[0]);
227 $url = join('/',$allkeys);
228 pl_content_headers("text/javascript");
229 echo '$.ajax({ url: "'.$url.'?forceXml=1", dataType: "xml", success: function(xml) { $("body",xml).insertBefore("body"); $("body:eq(1)").remove(); }});';
230 exit;
231 }
232
233 function handler_login_ext($page)
234 {
235 if (!S::logged()) {
236 $page->changeTpl('xnet/login.tpl');
237 } else {
238 pl_redirect('');
239 }
240 }
241
242 function handler_register_ext($page, $hash = null)
243 {
244 XDB::execute('DELETE FROM register_pending_xnet
245 WHERE DATE_SUB(NOW(), INTERVAL 1 MONTH) > date');
246 $res = XDB::fetchOneAssoc('SELECT uid, hruid
247 FROM register_pending_xnet
248 WHERE hash = {?}',
249 $hash);
250
251 if (is_null($hash) || is_null($res)) {
252 $page->trigErrorRedirect('Cette adresse n\'existe pas ou n\'existe plus sur le serveur.', '');
253 }
254
255 if (Post::has('pwhash') && Post::t('pwhash')) {
256 XDB::query('UPDATE accounts
257 SET password = {?}, state = \'active\'
258 WHERE uid = {?} AND state = \'pending\' AND type = \'xnet\'',
259 Post::t('pwhash'), $res['uid']);
260 XDB::query('DELETE FROM register_pending_xnet
261 WHERE uid = {?}',
262 $res['uid']);
263
264 S::logger($res['uid'])->log('passwd', '');
265
266 // Try to start a session (so the user don't have to log in); we will use
267 // the password available in Post:: to authenticate the user.
268 Post::kill('wait');
269 Platal::session()->startAvailableAuth();
270
271 $page->changeTpl('xnet/register.success.tpl');
272 $page->assign('hruid', $res['hruid']);
273 } else {
274 $page->changeTpl('platal/password.tpl');
275 $page->assign('xnet', true);
276 $page->assign('hruid', $res['hruid']);
277 $page->assign('do_auth', 1);
278 }
279 }
280
281 function handler_recovery_ext($page)
282 {
283 $page->changeTpl('xnet/recovery.tpl');
284
285 if (!Post::has('login')) {
286 return;
287 }
288
289 $user = User::getSilent(Post::t('login'));
290 if (is_null($user)) {
291 $page->trigError('Le compte n\'existe pas.');
292 return;
293 }
294 if ($user->state != 'active') {
295 $page->trigError('Ton compte n\'est pas activé.');
296 return;
297 }
298
299 $page->assign('ok', true);
300
301 $hash = rand_url_id();
302 XDB::execute('INSERT INTO account_xnet_lost_passwords (uid, date, hash)
303 VALUES ({?}, NOW(), {?})',
304 $user->id(), $hash);
305
306 $mymail = new PlMailer();
307 $mymail->setFrom('"Gestion des mots de passe" <support+password@' . Platal::globals()->mail->domain . '>');
308 $mymail->addTo($user);
309 $mymail->setSubject("Votre certificat d'authentification");
310 $mymail->setTxtBody("Visitez la page suivante qui expire dans six heures :
311 http://polytechnique.net/tmpPWD/$hash
312
313 Si en cliquant dessus vous n'y arrivez pas, copiez intégralement l'adresse dans la barre de votre navigateur. Si vous n'avez pas utilisé ce lien dans six heures, vous pouvez tout simplement recommencer cette procédure.
314
315 --
316 Polytechnique.org
317 \"Le portail des élèves & anciens élèves de l'École polytechnique\"
318
319 Email envoyé à " . Post::t('login'));
320 $mymail->send();
321
322 S::logger($user->id())->log('recovery', $user->bestEmail());
323 }
324
325 function handler_tmpPWD_ext($page, $hash = null)
326 {
327 global $globals;
328 XDB::execute('DELETE FROM account_xnet_lost_passwords
329 WHERE DATE_SUB(NOW(), INTERVAL 380 MINUTE) > date');
330
331 $uid = XDB::fetchOneCell('SELECT uid
332 FROM account_xnet_lost_passwords
333 WHERE hash = {?}',
334 $hash);
335 if (is_null($uid)) {
336 $page->trigErrorRedirect("Cette adresse n'existe pas ou n'existe plus sur le serveur.", '');
337 }
338
339 $hruid = XDB::fetchOneCell('SELECT hruid
340 FROM accounts
341 WHERE uid = {?}',
342 $uid);
343
344 if (Post::has('pwhash') && Post::t('pwhash')) {
345 $password = Post::t('pwhash');
346 XDB::query('UPDATE accounts
347 SET password = {?}
348 WHERE uid = {?} AND state = \'active\'',
349 $password, $uid);
350 XDB::query('DELETE FROM account_xnet_lost_passwords
351 WHERE hash = {?}',
352 $hash);
353
354 S::logger($uid)->log('passwd', '');
355
356 // Try to start a session (so the user don't have to log in); we will use
357 // the password available in Post:: to authenticate the user.
358 Post::kill('wait');
359 Platal::session()->startAvailableAuth();
360
361 $page->changeTpl('xnet/register.success.tpl');
362 $page->assign('hruid', $hruid);
363 } else {
364 $page->changeTpl('platal/password.tpl');
365 $page->assign('xnet_reset', true);
366 $page->assign('hruid', $hruid);
367 $page->assign('do_auth', 1);
368 }
369 }
370
371
372
373 function handler_edit($page)
374 {
375 global $globals;
376
377 $user = S::user();
378 if (empty($user)) {
379 return PL_NOT_FOUND;
380 }
381 if ($user->type != 'xnet') {
382 pl_redirect('index');
383 }
384
385 $page->changeTpl('xnet/edit.tpl');
386 if (Post::has('change')) {
387 S::assert_xsrf_token();
388
389 // Convert user status to X
390 if (!Post::blank('login_X')) {
391 $forlife = $this->changeLogin($page, $user, Post::t('login_X'));
392 if ($forlife) {
393 pl_redirect('index');
394 }
395 }
396
397 // Update user info
398 XDB::query('UPDATE accounts
399 SET full_name = {?}, directory_name = {?}, display_name = {?},
400 sex = {?}, email = {?}
401 WHERE uid = {?}',
402 Post::t('full_name'), Post::t('directory_name'), Post::t('display_name'),
403 (Post::t('sex') == 'male') ? 'male' : 'female', Post::t('email'), $user->id());
404 if (XDB::affectedRows()) {
405 require_once 'emails.inc.php';
406 if (require_email_update($user, Post::t('email'))) {
407 $listClient = new MMList(S::user());
408 $listClient->change_user_email($user->forlifeEmail(), Post::t('email'));
409 update_alias_user($user->forlifeEmail(), Post::t('email'));
410 }
411 $user = User::getWithUID($user->id());
412 S::set('user', $user);
413 $page->trigSuccess('Données mises à jour.');
414 }
415 }
416
417 $page->addJsLink('password.js');
418 $page->assign('user', $user);
419 }
420
421 function handler_password ($page)
422 {
423 if (Post::has('pwhash') && Post::t('pwhash')) {
424 S::assert_xsrf_token();
425
426 S::set('password', $password = Post::t('pwhash'));
427 XDB::execute('UPDATE accounts
428 SET password = {?}
429 WHERE uid={?}', $password,
430 S::i('uid'));
431 S::logger()->log('passwd');
432 Platal::session()->setAccessCookie(true);
433 $page->changeTpl('platal/password.success.tpl');
434 $page->run();
435 }
436
437 $page->changeTpl('platal/password.tpl');
438 $page->assign('xnet_reset', true);
439 $page->assign('do_auth', 0);
440 }
441 }
442
443 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
444 ?>