Password recovery for xnet accounts.
authorStéphane Jacob <sj@m4x.org>
Mon, 21 Mar 2011 12:23:56 +0000 (13:23 +0100)
committerStéphane Jacob <sj@m4x.org>
Mon, 21 Mar 2011 12:23:56 +0000 (13:23 +0100)
Signed-off-by: Stéphane Jacob <sj@m4x.org>
modules/xnet.php
templates/xnet/login.tpl
templates/xnet/recovery.tpl [new file with mode: 0644]
upgrade/1.1.0/17_recovery_ext.sql [new file with mode: 0644]

index 818a9bd..3645faa 100644 (file)
@@ -35,6 +35,8 @@ class XnetModule extends PLModule
             'autologin'   => $this->make_hook('autologin', AUTH_MDP),
             'login/ext'   => $this->make_hook('login_ext', AUTH_PUBLIC),
             'register/ext' => $this->make_hook('register_ext', AUTH_PUBLIC),
+            'recovery/ext' => $this->make_hook('recovery_ext', AUTH_PUBLIC),
+            'tmpPWD/ext'  => $this->make_hook('tmpPWD_ext', AUTH_PUBLIC),
             'edit'        => $this->make_hook('edit',      AUTH_MDP, 'user'),
             'password'    => $this->make_hook('password',  AUTH_MDP, 'user'),
 
@@ -276,6 +278,98 @@ class XnetModule extends PLModule
         }
     }
 
+    function handler_recovery_ext($page)
+    {
+        $page->changeTpl('xnet/recovery.tpl');
+
+        if (!Post::has('login')) {
+            return;
+        }
+
+        $user = User::getSilent(Post::t('login'));
+        if (is_null($user)) {
+            $page->trigError('Le compte n\'existe pas.');
+            return;
+        }
+        if ($user->state != 'active') {
+            $page->trigError('Ton compte n\'est pas activé.');
+            return;
+        }
+
+        $page->assign('ok', true);
+
+        $hash = rand_url_id();
+        XDB::execute('INSERT INTO  account_xnet_lost_passwords (uid, date, hash)
+                           VALUES  ({?}, NOW(), {?})',
+                     $user->id(), $hash);
+
+        $mymail = new PlMailer();
+        $mymail->setFrom('"Gestion des mots de passe" <support+password@' . Platal::globals()->mail->domain . '>');
+        $mymail->addTo($user);
+        $mymail->setSubject("Votre certificat d'authentification");
+        $mymail->setTxtBody("Visitez la page suivante qui expire dans six heures :
+http://polytechnique.net/tmpPWD/$hash
+
+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.
+
+--
+Polytechnique.org
+\"Le portail des élèves & anciens élèves de l'École polytechnique\"
+
+Email envoyé à " . Post::t('login'));
+        $mymail->send();
+
+        S::logger($user->id())->log('recovery', $user->bestEmail());
+    }
+
+    function handler_tmpPWD_ext($page, $hash = null)
+    {
+        global $globals;
+        XDB::execute('DELETE FROM  account_xnet_lost_passwords
+                            WHERE  DATE_SUB(NOW(), INTERVAL 380 MINUTE) > date');
+
+        $uid = XDB::fetchOneCell('SELECT  uid
+                                    FROM  account_xnet_lost_passwords
+                                   WHERE  hash = {?}',
+                                 $hash);
+        if (is_null($uid)) {
+            $page->trigErrorRedirect("Cette adresse n'existe pas ou n'existe plus sur le serveur.", '');
+        }
+
+        $hruid = XDB::fetchOneCell('SELECT  hruid
+                                      FROM  accounts
+                                     WHERE  uid = {?}',
+                                   $uid);
+
+        if (Post::has('pwhash') && Post::t('pwhash')) {
+            $password = Post::t('pwhash');
+            XDB::query('UPDATE  accounts
+                           SET  password = {?}
+                         WHERE  uid = {?} AND state = \'active\'',
+                       $password, $uid);
+            XDB::query('DELETE FROM  account_xnet_lost_passwords
+                              WHERE  hash = {?}',
+                       $hash);
+
+            S::logger($uid)->log('passwd', '');
+
+            // Try to start a session (so the user don't have to log in); we will use
+            // the password available in Post:: to authenticate the user.
+            Post::kill('wait');
+            Platal::session()->startAvailableAuth();
+
+            $page->changeTpl('xnet/register.success.tpl');
+            $page->assign('hruid', $hruid);
+        } else {
+            $page->changeTpl('platal/password.tpl');
+            $page->assign('xnet_reset', true);
+            $page->assign('hruid', $hruid);
+            $page->assign('do_auth', true);
+        }
+    }
+
+
+
     function handler_edit($page)
     {
         global $globals;
index 749c243..396f1ab 100644 (file)
@@ -41,6 +41,8 @@
         <label><input type="checkbox" name="remember" checked="checked" />
           Garder l'accès aux services après déconnexion.
         </label>
+        <br />
+        <a href="recovery/ext">Mot de passe perdu&nbsp;?</a>
       </td>
     </tr>
     <tr>
diff --git a/templates/xnet/recovery.tpl b/templates/xnet/recovery.tpl
new file mode 100644 (file)
index 0000000..fd337c9
--- /dev/null
@@ -0,0 +1,77 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2011 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+
+<h1>Perte du mot de passe</h1>
+
+
+{if $ok}
+
+<p>
+<strong>Un certificat d'authentification</strong> vient de vous être attribué et envoyé.
+Ce certificat permet d'accéder à un formulaire de changement de mot de passe.
+<span class="erreur"> Il expire dans six heures.</span> Vous devez donc <strong>consulter vos emails avant son
+expiration</strong> et utiliser le certificat comme expliqué dans l'email pour changer votre mot de passe.
+</p>
+<p>
+Si vous n'accéder pas à cet email dans les 6 heures, sollicitez un nouveau certificat sur cette page.
+</p>
+
+{else}
+
+<form action="{$platal->ns}recovery/ext" method="post">
+  <p>
+  Il est impossible de récupérer le mot de passe perdu car nous n'avons que le résultat après un
+  chiffrement irréversible de votre mot de passe. La procédure suivante va vous permettre de choisir un
+  nouveau mot de passe.
+  </p>
+  <p>
+  Après avoir complété les informations suivantes, vous recevrez un
+  email vous permettant de choisir un nouveau mot de passe.  </p>
+  <p>
+  Si vous ne recevez pas cet email, n'hésitez pas à contacter
+  <a href="mailto:support@{#globals.mail.domain#}">le support technique</a>.
+  </p>
+  <table class="tinybicol" cellpadding="3" cellspacing="0" summary="Récupération du mot de passe">
+    <tr>
+      <th colspan="2">
+        Perte de mot de passe
+      </th>
+    </tr>
+    <tr>
+      <td class="titre">
+        Identifiant&nbsp;:
+      </td>
+      <td>
+        <input type="text" size="20" maxlength="255" name="login" />
+      </td>
+    </tr>
+    <tr>
+      <td colspan="2" class="center">
+        <input type="submit" value="Continuer" name="submit" />
+      </td>
+    </tr>
+  </table>
+</form>
+{/if}
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
diff --git a/upgrade/1.1.0/17_recovery_ext.sql b/upgrade/1.1.0/17_recovery_ext.sql
new file mode 100644 (file)
index 0000000..0b985a2
--- /dev/null
@@ -0,0 +1,12 @@
+DROP TABLE IF EXISTS account_xnet_lost_passwords;
+
+CREATE TABLE account_xnet_lost_passwords (
+  uid INT(11) UNSIGNED NOT NULL DEFAULT 0,
+  date DATETIME NULL DEFAULT NULL,
+  hash CHAR(32) NOT NULL DEFAULT '',
+  PRIMARY KEY (uid),
+  KEY hash (hash),
+  FOREIGN KEY (uid) REFERENCES accounts (uid) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB, CHARSET=utf8;
+
+-- vim:set syntax=mysql: