Merge commit 'origin/master' into hruid
authorVincent Zanotti <vincent.zanotti@polytechnique.org>
Sat, 9 Aug 2008 17:55:06 +0000 (19:55 +0200)
committerVincent Zanotti <vincent.zanotti@polytechnique.org>
Sat, 9 Aug 2008 17:55:06 +0000 (19:55 +0200)
Signed-off-by: Vincent Zanotti <vincent.zanotti@polytechnique.org>
50 files changed:
classes/user.php [new file with mode: 0644]
classes/xnetsession.php
classes/xorgsession.php
core
include/banana/forum.inc.php
include/banana/hooks.inc.php
include/banana/ml.inc.php
include/banana/moderate.inc.php
include/googleapps.inc.php
include/massmailer.inc.php
include/rss.inc.php
include/user.func.inc.php
include/validations/evts.inc.php
include/validations/googleapps.inc.php
include/validations/nomusage.inc.php
include/vcard.inc.php
modules/admin.php
modules/axletter.php
modules/axletter/axletter.inc.php
modules/carnet.php
modules/forums.php
modules/googleapps.php
modules/lists.php
modules/marketing.php
modules/newsletter.php
modules/platal.php
modules/profile.php
modules/register.php
modules/search.php
modules/xnetevents/xnetevents.inc.php
modules/xnetgrp.php
templates/admin/utilisateurs.tpl
templates/skin/default.tpl
templates/skin/espace.tpl
templates/skin/humlinux.tpl
templates/skin/keynote.tpl
templates/skin/linux.tpl
templates/skin/liteskin.tpl
templates/skin/nbviolet.tpl
templates/skin/newxorg.tpl
templates/skin/oldtimes.tpl
templates/skin/openweb.tpl
templates/skin/register.tpl
templates/skin/sharky.tpl
templates/skin/spectral.tpl
templates/skin/trapped.tpl
upgrade/hruid/03_hruid.sql [new file with mode: 0644]
upgrade/hruid/connect.db.inc.php [new file with mode: 0644]
upgrade/hruid/hruid.update.php [new file with mode: 0755]
upgrade/hruid/update.sh [new file with mode: 0755]

diff --git a/classes/user.php b/classes/user.php
new file mode 100644 (file)
index 0000000..a6da9bc
--- /dev/null
@@ -0,0 +1,213 @@
+<?php
+/***************************************************************************
+ *  Copyright (C) 2003-2008 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                *
+ ***************************************************************************/
+
+class User extends PlUser
+{
+    // Implementation of the login to uid method.
+    protected function getLogin($login)
+    {
+        global $globals;
+
+        // If $data is an integer, fetches directly the result.
+        if (is_numeric($login)) {
+            $res = XDB::query("SELECT user_id FROM auth_user_md5 WHERE user_id = {?}", $login);
+            if ($res->numRows()) {
+                return $res->fetchOneCell();
+            }
+
+            throw new UserNotFoundException();
+        }
+
+        // Checks whether $login is a valid hruid or not.
+        $res = XDB::query("SELECT user_id FROM auth_user_md5 WHERE hruid = {?}", $login);
+        if ($res->numRows()) {
+            return $res->fetchOneCell();
+        }
+
+        // From now, $login can only by an email alias, or an email redirection.
+        // If it doesn't look like a valid address, appends the plat/al's main domain.
+        $login = trim(strtolower($login));
+        if (strstr($login, '@') === false) {
+            $login = $login . '@' . $globals->mail->domain;
+        }
+
+        // Checks if $login is a valid alias on the main domains.
+        list($mbox, $fqdn) = explode('@', $login);
+        if ($fqdn == $globals->mail->domain || $fqdn == $globals->mail->domain2) {
+            $res = XDB::query("SELECT  u.user_id
+                                 FROM  auth_user_md5 AS u
+                           INNER JOIN  aliases AS a ON (a.id = u.user_id AND a.type IN ('alias', 'a_vie'))
+                                WHERE  a.alias = {?}", $mbox);
+            if ($res->numRows()) {
+                return $res->fetchOneCell();
+            }
+
+            if (preg_match('/^(.*)\.([0-9]{4})$/u', $mbox, $matches)) {
+                $res = XDB::query("SELECT  u.user_id
+                                     FROM  auth_user_md5 AS u
+                               INNER JOIN  aliases AS a ON (a.id = u.user_id AND a.type IN ('alias', 'a_vie'))
+                                    WHERE  a.alias = {?} AND u.promo = {?}", $matches[1], $matches[2]);
+                if ($res->numRows() == 1) {
+                    return $res->fetchOneCell();
+                }
+            }
+
+            throw new UserNotFoundException();
+        }
+
+        // Looks for $login as an email alias from the dedicated alias domain.
+        if ($fqdn == $globals->mail->alias_dom || $fqdn == $globals->mail->alias_dom2) {
+            $res = XDB::query("SELECT  redirect
+                                 FROM  virtual_redirect
+                           INNER JOIN  virtual USING(vid)
+                                WHERE  alias = {?}", $mbox . '@' . $globals->mail->alias_dom);
+            if ($redir = $res->fetchOneCell()) {
+                // We now have a valid alias, which has to be translated to an hruid.
+                list($alias, $alias_fqdn) = explode('@', $redir);
+                $res = XDB::query("SELECT  u.user_id
+                                     FROM  auth_user_md5 AS u
+                                LEFT JOIN  aliases AS a ON (a.id = u.user_id AND a.type IN ('alias', 'a_vie'))
+                                    WHERE  a.alias = {?}", $alias);
+                if ($res->numRows()) {
+                    return $res->fetchOneCell();
+                }
+            }
+
+            throw new UserNotFoundException();
+        }
+
+        // Otherwise, we do suppose $login is an email redirection.
+        $res = XDB::query("SELECT  u.user_id
+                             FROM  auth_user_md5 AS u
+                        LEFT JOIN  emails AS e ON (e.uid = u.user_id)
+                            WHERE  e.email = {?}", $login);
+        if ($res->numRows() == 1) {
+            return $res->fetchOneCell();
+        }
+
+        throw new UserNotFoundException($res->fetchColumn(1));
+    }
+
+    // Implementation of the data loader.
+    protected function loadMainFields()
+    {
+        if ($this->hruid !== null && $this->forlife !== null &&
+            $this->bestalias !== null && $this->display_name !== null &&
+            $this->full_name !== null && $this->promo !== null && $this->perms !== null) {
+            return;
+        }
+
+        global $globals;
+        $res = XDB::query("SELECT  u.hruid, u.promo,
+                                   CONCAT(af.alias, '@{$globals->mail->domain}') AS forlife,
+                                   CONCAT(ab.alias, '@{$globals->mail->domain}') AS bestalias,
+                                   CONCAT(u.prenom, ' ', u.nom) AS full_name,
+                                   IF(u.prenom != '', u.prenom, u.nom) AS display_name,
+                                   u.perms
+                             FROM  auth_user_md5 AS u
+                        LEFT JOIN  aliases AS af ON (af.id = u.user_id AND af.type = 'a_vie')
+                        LEFT JOIN  aliases AS ab ON (ab.id = u.user_id AND FIND_IN_SET('bestalias', ab.flags))
+                            WHERE  u.user_id = {?}", $this->user_id);
+        $this->fillFromArray($res->fetchOneAssoc());
+    }
+
+    // Specialization of the fillFromArray method, to implement hacks to enable
+    // lazy loading of user's main properties from the session.
+    protected function fillFromArray(array $values)
+    {
+        // It might happen that the 'user_id' field is called uid in some places
+        // (eg. in sessions), so we hard link uid to user_id to prevent useless
+        // SQL requests.
+        if (!isset($values['user_id']) && isset($values['uid'])) {
+            $values['user_id'] = $values['uid'];
+        }
+
+        // Also, if display_name and full_name are not known, but the user's
+        // surname and last name are, we can construct the former two.
+        if (isset($values['prenom']) && isset($values['nom'])) {
+            if (!isset($values['display_name'])) {
+                $values['display_name'] = ($values['prenom'] ? $values['prenom'] : $values['nom']);
+            }
+            if (!isset($values['full_name'])) {
+                $values['full_name'] = $values['prenom'] . ' ' . $values['nom'];
+            }
+        }
+
+        parent::fillFromArray($values);
+    }
+
+    // Specialization of the buildPerms method
+    // This function build 'generic' permissions for the user. It does not take
+    // into account page specific permissions (e.g X.net group permissions)
+    protected function buildPerms()
+    {
+        if (!is_null($this->perm_flags)) {
+            return;
+        }
+        if ($this->perms === null) {
+             $this->loadMainFields();
+        }
+        $this->perm_flags = self::makePerms($this->perms);
+    }
+
+    // Return permission flags for a given permission level.
+    public static function makePerms($perms)
+    {
+        $flags = new PlFlagSet();
+        if (is_null($flags) || $perms == 'disabled' || $perms == 'ext') {
+            return $flags;
+        }
+        $flags->addFlag(PERMS_USER);
+        if ($perms == 'admin') {
+            $flags->addFlag(PERMS_ADMIN);
+        }
+        return $flags;
+    }
+
+    // Implementation of the default user callback.
+    public static function _default_user_callback($login, $results)
+    {
+        $result_count = count($results);
+        if ($result_count == 0 || !S::has_perms()) {
+            Platal::page()->trigError("Il n'y a pas d'utilisateur avec l'identifiant : $login");
+        } else {
+            Platal::page()->trigError("Il y a $result_count utilisateurs avec cet identifiant : " . join(', ', $results));
+        }
+    }
+
+    // Implementation of the static email locality checker.
+    public static function isForeignEmailAddress($email)
+    {
+        global $globals;
+        if (strpos($email, '@') === false) {
+            return false;
+        }
+
+        list($user, $dom) = explode('@', $email);
+        return $dom != $globals->mail->domain &&
+               $dom != $globals->mail->domain2 &&
+               $dom != $globals->mail->alias_dom &&
+               $dom != $globals->mail->alias_dom2;
+    }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
index 3f9dca1..0183a76 100644 (file)
@@ -103,19 +103,21 @@ class XnetSession extends PlSession
         if ($level == -1) {
             S::set('auth', AUTH_MDP);
         }
-        $res  = XDB::query('SELECT  u.user_id AS uid, prenom, nom, perms, promo, password, FIND_IN_SET(\'femme\', u.flags) AS femme,
-                                    a.alias AS forlife, a2.alias AS bestalias, q.core_mail_fmt AS mail_fmt, q.core_rss_hash
+        $res  = XDB::query("SELECT  u.user_id AS uid, u.hruid, prenom, nom, perms, promo, password, FIND_IN_SET('femme', u.flags) AS femme,
+                                    CONCAT(a.alias, '@{$globals->mail->domain}') AS forlife,
+                                    CONCAT(a2.alias, '@{$globals->mail->domain}') AS bestalias,
+                                    q.core_mail_fmt AS mail_fmt, q.core_rss_hash
                               FROM  auth_user_md5   AS u
                         INNER JOIN  auth_user_quick AS q  USING(user_id)
-                        INNER JOIN  aliases         AS a  ON (u.user_id = a.id AND a.type = \'a_vie\')
-                        INNER JOIN  aliases         AS a2 ON (u.user_id = a2.id AND FIND_IN_SET(\'bestalias\', a2.flags))
-                             WHERE  u.user_id = {?} AND u.perms IN(\'admin\', \'user\')
-                             LIMIT  1', $user);
+                        INNER JOIN  aliases         AS a  ON (u.user_id = a.id AND a.type = 'a_vie')
+                        INNER JOIN  aliases         AS a2 ON (u.user_id = a2.id AND FIND_IN_SET('bestalias', a2.flags))
+                             WHERE  u.user_id = {?} AND u.perms IN('admin', 'user')
+                             LIMIT  1", $user);
         $sess = $res->fetchOneAssoc();
         $perms = $sess['perms'];
         unset($sess['perms']);
         $_SESSION = array_merge($_SESSION, $sess);
-        $this->makePerms($perms);
+        S::set('perms', User::makePerms($perms));
         S::kill('challenge');
         S::kill('loginX');
         S::kill('may_update');
@@ -132,26 +134,14 @@ class XnetSession extends PlSession
 
     public function tokenAuth($login, $token)
     {
-        // FIXME: we broke the session here because some RSS feeds (mainly wiki feeds) require
-        // a valid nome and checks the permissions. When the PlUser object will be ready, we'll
-        // be able to return a simple 'PlUser' object here without trying to alterate the
-        // session.
-        $res = XDB::query('SELECT  u.user_id AS uid, u.perms, u.nom, u.nom_usage, u.prenom, u.promo, FIND_IN_SET(\'femme\', u.flags) AS sexe
+        $res = XDB::query('SELECT  u.hruid
                              FROM  aliases         AS a
                        INNER JOIN  auth_user_md5   AS u ON (a.id = u.user_id AND u.perms IN ("admin", "user"))
                        INNER JOIN  auth_user_quick AS q ON (a.id = q.user_id AND q.core_rss_hash = {?})
                             WHERE  a.alias = {?} AND a.type != "homonyme"', $token, $login);
         if ($res->numRows() == 1) {
-            $sess = $res->fetchOneAssoc();
-            if (!S::has('uid')) {
-                $_SESSION = $sess;
-                $this->makePerms($sess['perms']);
-                return S::i('uid');
-            } else if (S::i('uid') == $sess['uid']) {
-                return S::i('uid');
-            } else {
-                Platal::page()->kill('Invalid state. To be fixed when hruid is ready');
-            }
+            $data = $res->fetchOneAssoc();
+            return new User($res->fetchOneCell());
         }
         return null;
     }
@@ -161,7 +151,7 @@ class XnetSession extends PlSession
         if (!$this->startSUID(S::i('uid'))) {
             return false;
         }
-        $this->makePerms('user');
+        S::set('perms', User::makePerms('user'));
         return true;
     }
 
@@ -179,22 +169,6 @@ class XnetSession extends PlSession
         return true;
     }
 
-    public function makePerms($perm)
-    {
-        $flags = new PlFlagSet();
-        if ($perm == 'disabled' || $perm == 'ext') {
-            S::set('perms', $flags);
-            S::set('perms_backup', $flags);
-            return;
-        }
-        $flags->addFlag(PERMS_USER);
-        if ($perm == 'admin') {
-            $flags->addFlag(PERMS_ADMIN);
-        }
-        S::set('perms', $flags);
-        S::set('perms_backup', $flags);
-    }
-
     public function sureLevel()
     {
         return AUTH_MDP;
index 48a2664..4a15365 100644 (file)
@@ -186,17 +186,19 @@ class XorgSession extends PlSession
         unset($_SESSION['log']);
 
         // Retrieves main user properties.
-        $res  = XDB::query('SELECT  u.user_id AS uid, prenom, prenom_ini, nom, nom_ini, nom_usage, perms, promo, promo_sortie,
-                                    matricule, password, FIND_IN_SET(\'femme\', u.flags) AS femme,
-                                    a.alias AS forlife, a2.alias AS bestalias,
+        global $globals;
+        $res  = XDB::query("SELECT  u.user_id AS uid, u.hruid, prenom, prenom_ini, nom, nom_ini, nom_usage, perms, promo, promo_sortie,
+                                    matricule, password, FIND_IN_SET('femme', u.flags) AS femme,
+                                    CONCAT(a.alias, '@{$globals->mail->domain}') AS forlife,
+                                    CONCAT(a2.alias, '@{$globals->mail->domain}') AS bestalias,
                                     q.core_mail_fmt AS mail_fmt, UNIX_TIMESTAMP(q.banana_last) AS banana_last, q.watch_last, q.core_rss_hash,
-                                    FIND_IN_SET(\'watch\', u.flags) AS watch_account, q.last_version, g.g_account_name IS NOT NULL AS googleapps
+                                    FIND_IN_SET('watch', u.flags) AS watch_account, q.last_version, g.g_account_name IS NOT NULL AS googleapps
                               FROM  auth_user_md5   AS u
                         INNER JOIN  auth_user_quick AS q  USING(user_id)
-                        INNER JOIN  aliases         AS a  ON (u.user_id = a.id AND a.type = \'a_vie\')
-                        INNER JOIN  aliases         AS a2 ON (u.user_id = a2.id AND FIND_IN_SET(\'bestalias\', a2.flags))
-                         LEFT JOIN  gapps_accounts  AS g  ON (u.user_id = g.l_userid AND g.g_status = \'active\')
-                             WHERE  u.user_id = {?} AND u.perms IN(\'admin\', \'user\')', $uid);
+                        INNER JOIN  aliases         AS a  ON (u.user_id = a.id AND a.type = 'a_vie')
+                        INNER JOIN  aliases         AS a2 ON (u.user_id = a2.id AND FIND_IN_SET('bestalias', a2.flags))
+                         LEFT JOIN  gapps_accounts  AS g  ON (u.user_id = g.l_userid AND g.g_status = 'active')
+                             WHERE  u.user_id = {?} AND u.perms IN('admin', 'user')", $uid);
         $sess = $res->fetchOneAssoc();
         $perms = $sess['perms'];
         unset($sess['perms']);
@@ -218,7 +220,7 @@ class XorgSession extends PlSession
         if (S::has('suid')) {
             $suid = S::v('suid');
             $logger = S::logger($uid);
-            $logger->log("suid_start", S::v('forlife') . " by " . $suid['uid']);
+            $logger->log("suid_start", S::v('hruid') . " by " . $suid['hruid']);
         } else {
             $logger = S::logger($uid);
             setcookie('ORGuid', $uid, (time() + 25920000), '/', '', 0);
@@ -237,7 +239,7 @@ class XorgSession extends PlSession
         }
 
         // Finalizes the session setup.
-        $this->makePerms($perms);
+        S::set('perms', User::makePerms($perms));
         $this->securityChecks();
         $this->setSkin();
         $this->updateNbNotifs();
@@ -269,46 +271,18 @@ class XorgSession extends PlSession
 
     public function tokenAuth($login, $token)
     {
-        // FIXME: we broke the session here because some RSS feeds (mainly wiki feeds) require
-        // a valid nome and checks the permissions. When the PlUser object will be ready, we'll
-        // be able to return a simple 'PlUser' object here without trying to alterate the
-        // session.
-        $res = XDB::query('SELECT  u.user_id AS uid, u.perms, u.nom, u.nom_usage, u.prenom, u.promo, FIND_IN_SET(\'femme\', u.flags) AS sexe
+        $res = XDB::query('SELECT  u.hruid
                              FROM  aliases         AS a
                        INNER JOIN  auth_user_md5   AS u ON (a.id = u.user_id AND u.perms IN ("admin", "user"))
                        INNER JOIN  auth_user_quick AS q ON (a.id = q.user_id AND q.core_rss_hash = {?})
                             WHERE  a.alias = {?} AND a.type != "homonyme"', $token, $login);
         if ($res->numRows() == 1) {
-            $sess = $res->fetchOneAssoc();
-            if (!S::has('uid')) {
-                $_SESSION = $sess;
-                $this->makePerms($sess['perms']);
-                return S::i('uid');
-            } else if (S::i('uid') == $sess['uid']) {
-                return S::i('uid');
-            } else {
-                Platal::page()->kill('Invalid state. To be fixed when hruid is ready');
-            }
+            $data = $res->fetchOneAssoc();
+            return new User($data['hruid'], $data);
         }
         return null;
     }
 
-    public function makePerms($perm)
-    {
-        $flags = new PlFlagSet();
-        if ($perm == 'disabled' || $perm == 'ext') {
-            S::set('perms', $flags);
-            S::set('perms_backup', $flags);
-            return;
-        }
-        $flags->addFlag(PERMS_USER);
-        if ($perm == 'admin') {
-            $flags->addFlag(PERMS_ADMIN);
-        }
-        S::set('perms', $flags);
-        S::set('perms_backup', $flags);
-    }
-
     public function setSkin()
     {
         global $globals;
diff --git a/core b/core
index 12ccfec..f8b161a 160000 (submodule)
--- a/core
+++ b/core
@@ -1 +1 @@
-Subproject commit 12ccfec732e22546728674652a0a4caeeec08f60
+Subproject commit f8b161ad3b2bd9aa5f176328fe9f2ee1b6ca9ee9
index 53d01c6..e9dff7e 100644 (file)
@@ -24,22 +24,22 @@ require_once 'banana/hooks.inc.php';
 
 function hook_checkcancel($_headers)
 {
-    return ($_headers['x-org-id'] == S::v('forlife') or S::has_perms());
+    return ($_headers['x-org-id'] == S::v('hruid') or S::has_perms());
 }
 
 class ForumsBanana extends Banana
 {
-    private $forlife;
+    private $user;
 
-    public function __construct($forlife, $params = null)
+    public function __construct(User &$user, $params = null)
     {
-        $this->forlife = $forlife;
+        $this->user = &$user;
 
         global $globals;
         Banana::$msgedit_canattach = false;
         Banana::$spool_root = $globals->banana->spool_root;
         array_push(Banana::$msgparse_headers, 'x-org-id', 'x-org-mail');
-        Banana::$nntp_host = 'news://web_'.$forlife
+        Banana::$nntp_host = 'news://web_' . $user->login()
                            . ":{$globals->banana->password}@{$globals->banana->server}:{$globals->banana->port}/";
         if (S::has_perms()) {
             Banana::$msgshow_mimeparts[] = 'source';
@@ -74,7 +74,7 @@ class ForumsBanana extends Banana
                             WHERE  uid={?}", S::i('uid'));
         if (!(list($nom, $mail, $sig, $disp, $maj, $unread, $read) = $req->fetchOneRow())) {
             $nom  = S::v('prenom')." ".S::v('nom');
-            $mail = S::v('forlife')."@" . $globals->mail->domain;
+            $mail = $this->user->forlifeEmail();
             $sig  = $nom." (".S::v('promo').")";
             $disp = 0;
             $maj  = 1;
@@ -136,13 +136,11 @@ class ForumsBanana extends Banana
     public function post($dest, $reply, $subject, $body)
     {
         global $globals;
-        $res = XDB::query('SELECT  nom, prenom, promo, b.alias AS bestalias
+        $res = XDB::query('SELECT  nom, prenom, promo
                              FROM  auth_user_md5 AS u
-                       INNER JOIN  aliases       AS a ON (a.id = u.user_id)
-                       INNER JOIN  aliases       AS b ON (b.id = a.id AND FIND_IN_SET(\'bestalias\', b.flags))
-                            WHERE  a.alias = {?}', $this->forlife);
-        list($nom, $prenom, $promo, $bestalias) = $res->fetchOneRow();
-        Banana::$profile['headers']['From']         = "$prenom $nom ($promo) <$bestalias@{$globals->mail->domain}>";
+                            WHERE  u.user_id = {?}', $this->user->id());
+        list($nom, $prenom, $promo) = $res->fetchOneRow();
+        Banana::$profile['headers']['From']         = "$prenom $nom ($promo) <{$this->user->bestEmail()}>";
         Banana::$profile['headers']['Organization'] = make_Organization();
         return parent::post($dest, $reply, $subject, $body);
     }
@@ -227,7 +225,7 @@ class ForumsBanana extends Banana
              WHERE  uid = {?}", S::v('uid'));
         if (!(list($nom, $mail, $sig, $disp, $maj, $xface, $unread, $read) = $req->fetchOneRow())) {
             $nom   = S::v('prenom').' '.S::v('nom');
-            $mail  = S::v('forlife').'@'.$globals->mail->domain;
+            $mail  = S::user()->forlifeEmail();
             $sig   = $nom.' ('.S::v('promo').')';
             $disp  = 0;
             $maj   = 0;
index aa44917..5259177 100644 (file)
@@ -76,7 +76,7 @@ function hook_platalRSS($group)
     } else {
         $group = '';
     }
-    return '/rss/' . $group . S::v('forlife') . '/' . S::v('core_rss_hash') . '/rss.xml';
+    return '/rss/' . $group . S::v('hruid') . '/' . S::v('core_rss_hash') . '/rss.xml';
 }
 
 function hook_platalMessageLink($params)
@@ -322,7 +322,7 @@ class BananaHandler
 
 function run_banana(&$page, $class, array $args)
 {
-    $banana = new $class(S::v('forlife'), $args);
+    $banana = new $class(S::user(), $args);
     $page->assign('banana', $banana->run());
     $page->addCssInline($banana->css());
     $page->addCssLink('banana.css');
index c2eea5c..9a3174f 100644 (file)
@@ -45,10 +45,13 @@ class MLBanana extends Banana
 {
     static public $listname;
     static public $domain;
+    private $user;
 
-    function __construct($forlife, $params = null)
+    function __construct(User &$user, $params = null)
     {
         global $globals;
+        $this->user = &$user;
+
         Banana::$spool_root = $globals->banana->spool_root;
         Banana::$spool_boxlist = false;
         Banana::$msgedit_canattach = true;
@@ -75,9 +78,9 @@ class MLBanana extends Banana
         global $platal, $globals;
 
         $nom  = S::v('prenom') . ' ' . S::v('nom');
-        $mail = S::v('bestalias') . '@' . $globals->mail->domain;
+        $mail = $this->user->bestEmail();
         $sig  = $nom . ' (' . S::v('promo') . ')';
-        Banana::$msgedit_headers['X-Org-Mail'] = S::v('forlife') . '@' . $globals->mail->domain;
+        Banana::$msgedit_headers['X-Org-Mail'] = $this->user->forlifeEmail();
 
         // Tree color
         $req = XDB::query("SELECT  tree_unread, tree_read
index 9e5588a..a6439b0 100644 (file)
@@ -25,7 +25,7 @@ require_once 'banana/hooks.inc.php';
 
 function hook_checkcancel($_headers)
 {
-    return ($_headers['x-org-id'] == S::v('forlife') or S::has_perms());
+    return ($_headers['x-org-id'] == S::v('hruid') or S::has_perms());
 }
 
 function hook_makeLink($params)
@@ -57,7 +57,7 @@ class ModerationBanana extends Banana
     static public $domain;
     static public $client;
 
-    function __construct($forlife, $params = null)
+    function __construct(User &$user, $params = null)
     {
         ini_set('memory_limit', '128M'); 
 
index 28d9459..45337d4 100644 (file)
 function post_queue_u_create($job) {
     global $globals;
 
-    // Retrieves the user parameters (userid and forlife).
+    // Retrieves the user parameters (GoogleApps username and user_id).
     $parameters = json_decode($job['j_parameters'], true);
-    $forlife = isset($parameters['username']) ? $parameters['username'] : null;
-    $userid = $job['q_recipient_id'];
-    if (!$forlife || !$userid) {
+    $username = isset($parameters['username']) ? $parameters['username'] : null;
+    if (!($user = User::getSilent($username))) {
         return;
     }
 
     // Adds a redirection to the Google Apps delivery address, if requested by
     // the user at creation time.
-    $account = new GoogleAppsAccount($userid, $forlife);
+    $account = new GoogleAppsAccount($user);
     if ($account->activate_mail_redirection) {
         require_once('emails.inc.php');
-        $storage = new EmailStorage($userid, 'googleapps');
+        $storage = new EmailStorage($user->id(), 'googleapps');
         $storage->activate();
     }
 
@@ -44,14 +43,12 @@ function post_queue_u_create($job) {
     $res = XDB::query(
         "SELECT  FIND_IN_SET('femme', u.flags), prenom
            FROM  auth_user_md5 AS u
-     INNER JOIN  aliases AS a ON (a.id = u.user_id)
-          WHERE  a.alias = {?}",
-        $forlife);
+          WHERE  u.user_id = {?}", $user->id());
     list($sexe, $prenom) = $res->fetchOneRow();
 
     $mailer = new PlMailer('googleapps/create.mail.tpl');
     $mailer->assign('account', $account);
-    $mailer->assign('email', $forlife . '@' . $globals->mail->domain);
+    $mailer->assign('email', $user->bestEmail());
     $mailer->assign('googleapps_domain', $globals->mailstorage->googleapps_domain);
     $mailer->assign('prenom', $prenom);
     $mailer->assign('sexe', $sexe);
@@ -66,19 +63,18 @@ function post_queue_u_update($job) {
     // to the Google Apps delivery address, provided the account is active (it might
     // have been deleted between the unsuspension and the post-queue processing).
     $parameters = json_decode($job['j_parameters'], true);
-    $forlife = isset($parameters['username']) ? $parameters['username'] : null;
-    $userid = $job['q_recipient_id'];
-    if (!$forlife || !$userid) {
+    $username = isset($parameters['username']) ? $parameters['username'] : null;
+    if (!($user = User::getSilent($username))) {
         return;
     }
 
     if (isset($parameters['suspended']) && $parameters['suspended'] == false) {
         require_once('emails.inc.php');
-        $account = new GoogleAppsAccount($userid, $forlife);
+        $account = new GoogleAppsAccount($user);
         if ($account->active()) {
             // Re-adds the email redirection (if the user did request it).
             if ($account->activate_mail_redirection) {
-                $storage = new EmailStorage($userid, 'googleapps');
+                $storage = new EmailStorage($user->id, 'googleapps');
                 $storage->activate();
             }
 
@@ -86,14 +82,12 @@ function post_queue_u_update($job) {
             $res = XDB::query(
                 "SELECT  FIND_IN_SET('femme', u.flags), prenom
                    FROM  auth_user_md5 AS u
-             INNER JOIN  aliases AS a ON (a.id = u.user_id)
-                  WHERE  a.alias = {?}",
-                $forlife);
+                  WHERE  u.user_id = {?}", $user->id());
             list($sexe, $prenom) = $res->fetchOneRow();
 
             $mailer = new PlMailer('googleapps/unsuspend.mail.tpl');
             $mailer->assign('account', $account);
-            $mailer->assign('email', $forlife . '@' . $globals->mail->domain);
+            $mailer->assign('email', $user->bestEmail());
             $mailer->assign('prenom', $prenom);
             $mailer->assign('sexe', $sexe);
             $mailer->send();
@@ -108,7 +102,7 @@ function post_queue_u_update($job) {
 class GoogleAppsAccount
 {
     // User identification: user id, and forlife.
-    private $uid;
+    private $user;
     public $g_account_name;
 
     // Local account parameters.
@@ -139,19 +133,17 @@ class GoogleAppsAccount
 
     // Constructs the account object, by retrieving all informations from the
     // GApps account table, from GApps job queue, and from plat/al validation queue.
-    public function __construct($uid, $account_name = NULL)
+    public function __construct(User &$user)
     {
-        if ($account_name == NULL) {
-            require_once 'user.func.inc.php';
-            $account_name = get_user_forlife($uid, '_silent_user_callback');
+        $this->user = &$user;
+        if (!$this->user || !$this->user->login()) {
+            return;
         }
 
-        $this->uid = $uid;
-        $this->g_account_name = $account_name;
+        // TODO: switch to multi-domain Google Apps, and use $this->user->forlifeEmail()
+        // as Google Apps idenfiant (requires changes in gappsd).
+        $this->g_account_name = $this->user->login();
         $this->g_status = NULL;
-        if (!$this->g_account_name) {
-            return;
-        }
 
         $res = XDB::query(
             "SELECT  l_sync_password, l_activate_mail_redirection,
@@ -160,8 +152,7 @@ class GoogleAppsAccount
                      UNIX_TIMESTAMP(r_last_login) as r_last_login,
                      UNIX_TIMESTAMP(r_last_webmail) as r_last_webmail
                FROM  gapps_accounts
-              WHERE  g_account_name = {?}",
-            $account_name);
+              WHERE  g_account_name = {?}", $this->g_account_name);
         if ($account = $res->fetchOneAssoc()) {
             $this->sync_password = $account['l_sync_password'];
             $this->activate_mail_redirection = $account['l_activate_mail_redirection'];
@@ -195,8 +186,7 @@ class GoogleAppsAccount
                FROM  gapps_queue
               WHERE  q_recipient_id = {?} AND
                      p_status IN ('idle', 'active', 'softfail')
-           GROUP BY  j_type",
-            $this->uid);
+           GROUP BY  j_type", $this->user->id());
         $pending = $res->fetchOneAssoc();
         $this->pending_create = $pending['pending_create'];
         $this->pending_update = $pending['pending_update'];
@@ -214,7 +204,7 @@ class GoogleAppsAccount
     {
         require_once('validations.inc.php');
         $this->pending_validation_unsuspend =
-            Validate::get_typed_requests_count($this->uid, 'gapps-unsuspend');
+            Validate::get_typed_requests_count($this->user->id(), 'gapps-unsuspend');
     }
 
     // Retrieves all the pending update job in the gappsd queue for the current
@@ -227,8 +217,7 @@ class GoogleAppsAccount
                FROM  gapps_queue
               WHERE  q_recipient_id = {?} AND
                      p_status IN ('idle', 'active', 'softfail') AND
-                     j_type = 'u_update'",
-            $this->uid);
+                     j_type = 'u_update'", $this->user->id());
         while ($update = $res->next()) {
             $update_data = json_decode($update["j_parameters"], true);
 
@@ -258,7 +247,7 @@ class GoogleAppsAccount
                      p_priority = 'immediate',
                      j_type = {?}, j_parameters = {?}",
             S::v('uid'),
-            $this->uid,
+            $this->user->id(),
             $type,
             json_encode($parameters));
     }
@@ -347,7 +336,7 @@ class GoogleAppsAccount
 
         if (!$this->pending_update_suspension && !$this->pending_validation_unsuspend) {
             require_once('validations.inc.php');
-            $unsuspend = new GoogleAppsUnsuspendReq($this->uid);
+            $unsuspend = new GoogleAppsUnsuspendReq($this->user->id());
             $unsuspend->submit();
             $this->pending_validation_unsuspend = true;
         }
@@ -365,8 +354,7 @@ class GoogleAppsAccount
                 $res = XDB::query(
                     "SELECT  password
                        FROM  auth_user_md5
-                      WHERE  user_id = {?}",
-                    $this->uid);
+                      WHERE  user_id = {?}", $this->user->id());
                 $password = ($res->numRows() > 0 ? $res->fetchOneCell() : false);
             } else {
                 $password = false;
@@ -394,8 +382,7 @@ class GoogleAppsAccount
             $res = XDB::query(
                 "SELECT  nom, nom_usage, prenom
                    FROM  auth_user_md5
-                  WHERE  user_id = {?}",
-                $this->uid);
+                  WHERE  user_id = {?}", $this->user->id());
             list($nom, $nom_usage, $prenom) = $res->fetchOneRow();
 
             // Adds an 'unprovisioned' entry in the gapps_accounts table.
@@ -408,7 +395,7 @@ class GoogleAppsAccount
                          g_first_name = {?},
                          g_last_name = {?},
                          g_status = 'unprovisioned'",
-                $this->uid,
+                $this->user->id(),
                 $password_sync,
                 $redirect_mails,
                 $this->g_account_name,
@@ -426,7 +413,7 @@ class GoogleAppsAccount
                 ));
 
             // Updates the GoogleAppsAccount status.
-            $this->__construct($this->uid, $this->g_account_name);
+            $this->__construct($this->user);
         }
     }
 
index a1d49f3..261fb8b 100644 (file)
@@ -157,26 +157,25 @@ abstract class MassMailer
         return $hash;
     }
 
-    public function sendTo($prenom, $nom, $login, $sexe, $html, $hash = 0)
+    public function sendTo($hruid, $email, $prenom, $nom, $sexe, $html, $hash = 0)
     {
-        global $globals;
-        $alias = $login;
-        if (strpos($login, '@') === false) {
-            $login = "$login@{$globals->mail->domain}";
-        }
-        require_once('user.func.inc.php');
-        $forlife = get_user_forlife($login, '_silent_user_callback');
-        if ($forlife) {
-            $alias = $forlife;
+        // If $email is not a real email address, tries to compute it up from
+        // the hruid. Otherwise, we suppose that caller will have used a valid
+        // and canonical email address.
+        if (strpos($email, '@') === false) {
+            if (!($user = User::getSilent($email))) {
+                Platal::page()->trigError("'$email' is neither a valid email address nor a valid login; did not send the email.");
+            }
+            $email = $user->bestEmail();
         }
-        if (strpos($alias, '@') === false && (is_null($hash) || $hash == 0)) {
 
-            $hash = $this->createHash(array($prenom, $nom, $login, $sexe, $html, rand(), "X.org rulez"));
+        if ($hruid && (is_null($hash) || $hash == 0)) {
+            $hash = $this->createHash(array($email, $prenom, $nom, $sexe, $html, rand(), "X.org rulez"));
             XDB::query("UPDATE  {$this->_subscriptionTable} as ni
-                    INNER JOIN  aliases AS a ON (ni.user_id = a.id)
+                    INNER JOIN  auth_user_md5 AS u USING (user_id)
                            SET  ni.hash = {?}
-                         WHERE  ni.user_id != 0 AND a.alias = {?}",
-                       $hash, $alias);
+                         WHERE  ni.user_id != 0 AND u.hruid = {?}",
+                       $hash, $hruid);
         }
 
         $mailer = new PlMailer($this->_tpl);
@@ -187,16 +186,16 @@ abstract class MassMailer
         $mailer->assign('sexe',    $sexe);
         $mailer->assign('prefix',  null);
         $mailer->assign('hash',    $hash);
-        $mailer->assign('email',   $login);
-        $mailer->assign('alias',   $alias);
-        $mailer->addTo("\"$prenom $nom\" <$login>");
+        $mailer->assign('email',   $email);
+        $mailer->assign('alias',   $hruid);
+        $mailer->addTo("\"$prenom $nom\" <$email>");
         $mailer->send($html);
     }
 
     protected function getAllRecipients()
     {
         global $globals;
-        return  "SELECT  u.user_id, CONCAT(a.alias, '@{$globals->mail->domain}'),
+        return  "SELECT  u.user_id, u.hruid, CONCAT(a.alias, '@{$globals->mail->domain}'),
                          u.prenom, IF(u.nom_usage='', u.nom, u.nom_usage),
                          FIND_IN_SET('femme', u.flags),
                          q.core_mail_fmt AS pref, ni.hash AS hash
@@ -220,9 +219,9 @@ abstract class MassMailer
                 return;
             }
             $sent = array();
-            while (list($uid, $bestalias, $prenom, $nom, $sexe, $fmt, $hash) = $res->next()) {
-                $sent[] = "(user_id='$uid'" . (!$uid ? " AND email='$bestalias')": ')');
-                $this->sendTo($prenom, $nom, $bestalias, $sexe, $fmt=='html', $hash);
+            while (list($uid, $hruid, $email, $prenom, $nom, $sexe, $fmt, $hash) = $res->next()) {
+                $sent[] = "(user_id='$uid'" . (!$uid ? " AND email='$email')": ')');
+                $this->sendTo($hruid, $email, $prenom, $nom, $sexe, $fmt=='html', $hash);
             }
             XDB::execute("UPDATE  {$this->_subscriptionTable}
                              SET  last = {?}
index 9d38d31..e45a822 100644 (file)
@@ -23,12 +23,12 @@ function init_rss($template, $alias, $hash, $require_uid = true)
 {
     $page =& Platal::page();
     $page->changeTpl($template, NO_SKIN);
-    $uid = Platal::session()->tokenAuth($alias, $hash);
-    if (empty($uid)) {
+    $user = Platal::session()->tokenAuth($alias, $hash);
+    if (is_null($user)) {
         if ($require_uid) {
             exit;
         } else {
-            $uid = null;
+            $user = null;
         }
     }
 
@@ -36,7 +36,7 @@ function init_rss($template, $alias, $hash, $require_uid = true)
         $page->assign('rss_hash', $hash);
         header('Content-Type: application/rss+xml; charset=utf8');
     }
-    return $uid;
+    return is_null($user) ? null : $user->id();
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
index 21bcbb5..c3db0f7 100644 (file)
@@ -32,9 +32,9 @@ function user_clear_all_subs($user_id, $really_del=true)
     // + delete maillists
 
     global $globals;
-    $uid   = intval($user_id);
-    $res   = XDB::query("SELECT alias FROM aliases WHERE type='a_vie' AND id={?}", $uid);
-    $alias = $res->fetchOneCell();
+    $uid = intval($user_id);
+    $user = User::getSilent($uid);
+    list($alias) = explode('@', $user->forlifeEmail());
 
     $tables_to_clear = array('uid' => array('competences_ins', 'entreprises', 'langues_ins', 'mentor_pays',
                                             'mentor_secteurs', 'mentor', 'perte_pass', 'watch_sub'),
@@ -75,7 +75,7 @@ function user_clear_all_subs($user_id, $really_del=true)
     if ($globals->mailstorage->googleapps_domain) {
         require_once 'googleapps.inc.php';
         if (GoogleAppsAccount::account_status($uid)) {
-            $account = new GoogleAppsAccount($uid, $alias);
+            $account = new GoogleAppsAccount($user);
             $account->suspend();
         }
     }
@@ -96,109 +96,154 @@ function _silent_user_callback($login)
     return;
 }
 
+// Returns an unique identifier corresponding to the @p data. This piece of data
+// can be a numerical id, an hruid, an email alias (any), or a redirection
+// email address. If @p get_forlife is set to true, the user's forlife is
+// returned, otherwise the user's hruid is returned.
+// When no user is found, calls @p callback, and eventually returns false.
 function get_user_login($data, $get_forlife = false, $callback = '_default_user_callback')
 {
     global $globals;
 
+    // In order to reduce the code size & complexity, we define once for all the
+    // field to be returned. By convention if will be "u.hruid" for the hruid
+    // (thus implying the auth_user_md5 will be aliased on u), and "a.alias" for
+    // the forlife (thus implying the forlife aliases table will be aliased on a).
+    $field = ($get_forlife ? "CONCAT(a.alias, '@" . $globals->mail->domain . "')" : "u.hruid");
+
+    // If $data is an integer, fetches directly the result.
     if (is_numeric($data)) {
-        $res = XDB::query("SELECT alias FROM aliases WHERE type='a_vie' AND id={?}", $data);
+        $res = XDB::query("SELECT  $field
+                             FROM  auth_user_md5 AS u
+                        LEFT JOIN  aliases AS a ON (a.id = u.user_id AND type = 'a_vie')
+                            WHERE  u.user_id = {?}", $data);
         if ($res->numRows()) {
             return $res->fetchOneCell();
-        } else {
-            call_user_func($callback, $data);
-            return false;
         }
+
+        call_user_func($callback, $data);
+        return false;
     }
 
-    $data = trim(strtolower($data));
+    // Checks whether $data is a valid hruid or not.
+    $res = XDB::query("SELECT  $field
+                         FROM  auth_user_md5 AS u
+                    LEFT JOIN  aliases AS a ON (a.id = u.user_id AND a.type = 'a_vie')
+                        WHERE  u.hruid = {?}", $data);
+    if ($res->numRows()) {
+        return $res->fetchOneCell();
+    }
 
+    // From now, $data can only by an email alias, or an email redirection.
+    // If it doesn't look like a valid address, appends the plat/al's main domain.
+    $data = trim(strtolower($data));
     if (strstr($data, '@')===false) {
-        $data = $data.'@'.$globals->mail->domain;
+        $data = $data . '@' . $globals->mail->domain;
     }
 
+    // Checks if $data is a valid alias on the main domains.
     list($mbox, $fqdn) = explode('@', $data);
     if ($fqdn == $globals->mail->domain || $fqdn == $globals->mail->domain2) {
-
-        $res = XDB::query("SELECT  a.alias
-                             FROM  aliases AS a
-                       INNER JOIN  aliases AS b ON (a.id = b.id AND b.type IN ('alias', 'a_vie') AND b.alias={?})
-                            WHERE  a.type = 'a_vie'", $mbox);
+        $res = XDB::query("SELECT  $field
+                             FROM  auth_user_md5 AS u
+                       INNER JOIN  aliases AS a ON (a.id = u.user_id AND a.type = 'a_vie')
+                       INNER JOIN  aliases AS b ON (b.id = u.user_id AND b.type IN ('alias', 'a_vie'))
+                            WHERE  b.alias = {?}", $mbox);
         if ($res->numRows()) {
-            return $get_forlife ? $res->fetchOneCell() : $mbox;
+            return $res->fetchOneCell();
         }
 
         if (preg_match('/^(.*)\.([0-9]{4})$/u', $mbox, $matches)) {
             $res = XDB::query("SELECT  a.alias
-                                 FROM  aliases AS a
-                           INNER JOIN  aliases AS b ON (a.id = b.id AND b.type IN ('alias', 'a_vie') AND b.alias={?})
-                           INNER JOIN  auth_user_md5 AS u ON (a.id = u.user_id AND promo = {?})
-                                WHERE  a.type = 'a_vie'", $matches[1], $matches[2]);
+                                 FROM  auth_user_md5 AS u
+                           INNER JOIN  aliases AS a ON (a.id = u.user_id AND a.type = 'a_vie')
+                           INNER JOIN  aliases AS b ON (b.id = u.user_id AND b.type IN ('alias', 'a_vie'))
+                                WHERE  b.alias = {?} AND u.promo = {?}", $matches[1], $matches[2]);
             if ($res->numRows() == 1) {
                 return $res->fetchOneCell();
             }
         }
+
         call_user_func($callback, $data);
         return false;
 
+    // Looks for $data as an email alias from the dedicated alias domain.
     } elseif ($fqdn == $globals->mail->alias_dom || $fqdn == $globals->mail->alias_dom2) {
-
         $res = XDB::query("SELECT  redirect
                              FROM  virtual_redirect
                        INNER JOIN  virtual USING(vid)
-                            WHERE  alias={?}", $mbox.'@'.$globals->mail->alias_dom);
+                            WHERE  alias = {?}", $mbox . '@' . $globals->mail->alias_dom);
         if ($redir = $res->fetchOneCell()) {
-            list($alias) = explode('@', $redir);
-        } else {
-            call_user_func($callback, $data);
-            $alias = false;
-        }
-        return $alias;
-    } else {
-
-        $res = XDB::query("SELECT  alias
-                                       FROM  aliases AS a
-                                 INNER JOIN  emails  AS e ON e.uid=a.id
-                                      WHERE  e.email={?} AND a.type='a_vie'", $data);
-        switch ($i = $res->numRows()) {
-            case 0:
-                call_user_func($callback, $data);
-                return false;
+            list($alias, $alias_fqdn) = explode('@', $redir);
+            if ($get_forlife) {
+                // It might happen that the "secondary" forlife alias (the one
+                // based on the secondary domaine name) is used as a target; we
+                // then need to canonicalize it to the main domain.
+                if ($alias_fqdn == $globals->mail->domain2) {
+                    return $alias . "@" . $globals->mail->domain;
+                }
+                return $redir;
+            }
 
-            case 1:
+            // We now have a valid alias, which has to be translated to an hruid.
+            $res = XDB::query("SELECT  u.hruid
+                                 FROM  auth_user_md5 AS u
+                            LEFT JOIN  aliases AS a ON (a.id = u.user_id AND a.type IN ('alias', 'a_vie'))
+                                WHERE  a.alias = {?}", $alias);
+            if ($res->numRows()) {
                 return $res->fetchOneCell();
+            }
+        }
 
-            default:
-                if (S::has_perms()) {
-                    $aliases = $res->fetchColumn();
-                    Platal::page()->trigError("Il y a $i utilisateurs avec cette adresse mail : ".join(', ', $aliases));
-                } else {
-                    $res->free();
-                }
+        call_user_func($callback, $data);
+        return false;
+
+    // Otherwise, we do suppose $data is an email redirection.
+    } else {
+        $res = XDB::query("SELECT  $field
+                             FROM  auth_user_md5 AS u
+                        LEFT JOIN  aliases AS a ON (a.id = u.user_id AND a.type = 'a_vie')
+                        LEFT JOIN  emails AS e ON (e.uid = u.user_id)
+                            WHERE  e.email = {?}", $data);
+        if ($res->numRows() == 1) {
+            return $res->fetchOneCell();
+        } else if ($res->numRows() > 0) {
+            if (S::has_perms()) {
+                Platal::page()->trigError("Il y a $user_count utilisateurs avec cette adresse mail : " . join(', ', $res->fetchColumn()));
+            } else {
+                $res->free();
+            }
+        } else {
+            call_user_func($callback, $data);
         }
+
+        return false;
     }
 
     return false;
 }
 
 // }}}
-// {{{ function get_user_forlife()
-
-function get_user_forlife($data, $callback = '_default_user_callback')
+// {{{ function get_users_login_list()
+
+// Returns an array of valid forlife/hruid based on the @p members list. The
+// list can be an array (in this case the ouput will retain the keys), or a
+// space separated list.
+// The @p strict indicates if the input alias should be retain in output when
+// no valid forlife is found (incompatible with $get_forlife = false).
+function get_users_login_list($members, $strict = false, $get_forlife = false, $callback = '_default_user_callback')
 {
-    return get_user_login($data, true, $callback);
-}
-
-// }}}
-// {{{ function get_users_forlife_list()
+    if (!$get_forlife) {
+        $strict = true;
+    }
 
-function get_users_forlife_list($members, $strict = false, $callback = '_default_user_callback')
-{
     if (!is_array($members)) {
         if (strlen(trim($members)) == 0) {
             return null;
         }
         $members = split("[; ,\r\n\|]+", $members);
     }
+
     if ($members) {
         $list = array();
         foreach ($members as $i => $alias) {
@@ -206,7 +251,7 @@ function get_users_forlife_list($members, $strict = false, $callback = '_default
             if (empty($alias)) {
                 continue;
             }
-            if (($login = get_user_forlife($alias, $callback)) !== false) {
+            if (($login = get_user_login($alias, $get_forlife, $callback)) !== false) {
                 $list[$i] = $login;
             } else if (!$strict) {
                 $list[$i] = $alias;
@@ -226,6 +271,30 @@ function get_users_forlife_list($members, $strict = false, $callback = '_default
 }
 
 // }}}
+// {{{ function get_users_forlife_list()
+
+function get_users_forlife_list($members, $strict = false, $callback = '_default_user_callback')
+{
+    return get_users_login_list($members, $strict, true, $callback);
+}
+
+// }}}
+// {{{ function get_user_hruid()
+
+function get_user_hruid($data, $callback = '_default_user_callback')
+{
+    return get_user_login($data, false, $callback);
+}
+
+// }}}
+// {{{ function get_users_hruid_list()
+
+function get_users_hruid_list($members, $strict = false, $callback = '_default_user_callback')
+{
+    return get_users_login_list($members, true, false, $callback);
+}
+
+// }}}
 // {{{ function has_user_right()
 function has_user_right($pub, $view = 'private') {
     if ($pub == $view) return true;
index c33ce5e..f409530 100644 (file)
@@ -147,10 +147,8 @@ class EvtReq extends Validate
             }
             global $globals;
             if ($globals->banana->event_forum) {
-                require_once 'user.func.inc.php';
-                $forlife = get_user_forlife($this->uid);
                 require_once 'banana/forum.inc.php';
-                $banana = new ForumsBanana($forlife);
+                $banana = new ForumsBanana(User::getSilent($this->uid));
                 $post = $banana->post($globals->banana->event_forum,
                                       $globals->banana->event_reply,
                                       $this->titre, MiniWiki::wikiToText($this->texte, false, 0, 80));
index 7413d73..52a008f 100644 (file)
@@ -61,7 +61,7 @@ class GoogleAppsUnsuspendReq extends Validate
     public function commit()
     {
         require_once dirname(__FILE__) . '/../googleapps.inc.php';
-        $account = new GoogleAppsAccount($this->uid, $this->forlife);
+        $account = new GoogleAppsAccount(User::get($this->forlife));
         return $account->do_unsuspend();
     }
 
index 788d7c6..b69fb43 100644 (file)
@@ -93,7 +93,7 @@ class UsageReq extends Validate
             }
             if ($globals->mailstorage->googleapps_domain) {
                 require_once 'googleapps.inc.php';
-                $account = new GoogleAppsAccount($this->uid, $this->forlife);
+                $account = new GoogleAppsAccount(User::get($this->uid));
                 if ($account->active()) {
                     $res .= "\n\n  Si tu utilises Google Apps, tu peux changer ton nom d'usage sur https://mail.google.com/a/polytechnique.org/#settings/accounts";
                 }
index 6083b25..0671343 100644 (file)
@@ -36,9 +36,9 @@ class VCardIterator implements PlIterator
 
     public function add_user($user)
     {
-        $forlife = get_user_forlife($user, '_silent_user_callback');
-        if ($forlife) {
-            $this->user_list[] = get_user_forlife($user);
+        $user = User::getSilent($user);
+        if ($user) {
+            $this->user_list[] = $user;
             $this->count++;
         }
     }
@@ -65,7 +65,7 @@ class VCardIterator implements PlIterator
         }
         global $globals;
         $login = array_shift($this->user_list);
-        $user  = get_user_details($login);
+        $user  = get_user_details($login->login());
 
         if (strlen(trim($user['freetext']))) {
             $user['freetext'] = pl_entity_decode($user['freetext']);
@@ -96,10 +96,9 @@ class VCardIterator implements PlIterator
         // get photo
         if ($this->photos) {
             $res = XDB::query(
-                    "SELECT attach, attachmime
-                       FROM photo   AS p
-                 INNER JOIN aliases AS a ON (a.id = p.uid AND a.type = 'a_vie')
-                      WHERE a.alias = {?}", $login);
+                    "SELECT  attach, attachmime
+                       FROM  photo AS p
+                      WHERE  u.user_id = {?}", $login->id());
             if ($res->numRows()) {
                 $user['photo'] = $res->fetchOneAssoc();
             }
index 9cf0c46..e1e5709 100644 (file)
@@ -356,330 +356,333 @@ class AdminModule extends PLModule
         $page->changeTpl('admin/utilisateurs.tpl');
         $page->setTitle('Administration - Edit/Su/Log');
         require_once("emails.inc.php");
-        require_once("user.func.inc.php");
 
         if (S::has('suid')) {
             $page->kill("Déjà en SUID !!!");
         }
 
-        if (Env::has('user_id')) {
-            $login = get_user_forlife(Env::i('user_id'));
-            if (empty($login)) {
-                $login = Env::i('user_id');
-            }
-        } elseif (Env::has('login')) {
-            $login = get_user_forlife(Env::v('login'));
+        // Loads the user identity using the environment.
+        if ($login) {
+            $user = User::get($login);
+        } else if (Env::has('user_id')) {
+            $user = User::get(Env::i('user_id'));
+        } else if (Env::has('login')) {
+            $user = User::get(Env::v('login'));
         }
 
-        if(Env::has('logs_button') && $login) {
-            pl_redirect("admin/logger?loguser=$login&year=".date('Y')."&month=".date('m'));
+        if ($user) {
+            $login = $user->login();
+            $registered = ($user->forlifeEmail() != null);
+        } else {
+            return;
         }
 
-        if (Env::has('ax_button') && $login) {
-            pl_redirect("admin/synchro_ax/$login");
+        // Handles specific requests (AX sync, su, ...).
+        if(Env::has('logs_button') && $registered) {
+            pl_redirect("admin/logger?loguser=$login&year=".date('Y')."&month=".date('m'));
         }
 
-        if(Env::has('suid_button') && $login) {
-            S::logger()->log("suid_start", "login by ".S::v('forlife'));
-            $r = XDB::query("SELECT  id
-                               FROM  aliases
-                              WHERE  alias={?}", $login);
-            if($uid = $r->fetchOneCell()) {
-                if (!Platal::session()->startSUID($uid)) {
-                    $page->trigError('Impossible d\'effectuer un SUID sur ' . $uid);
-                } else {
-                    $page->kill("coucou");
-                    pl_redirect("");
-                }
-            }
+        if (Env::has('ax_button') && $registered) {
+            pl_redirect("admin/synchro_ax/" . $user->login());
         }
 
-        if ($login) {
-            if (is_numeric($login)) {
-                $r = XDB::query("SELECT *, a.alias AS forlife,
-                                        FIND_IN_SET('watch', u.flags) AS watch, FIND_IN_SET('femme', u.flags) AS sexe,
-                                        (year(naissance) > promo - 15 or year(naissance) < promo - 25) AS naiss_err
-                                   FROM auth_user_md5 AS u
-                              LEFT JOIN aliases       AS a ON (a.id = u.user_id AND type= 'a_vie')
-                                  WHERE u.user_id = {?}", $login);
+        if(Env::has('suid_button') && $registered) {
+            S::logger()->log("suid_start", "login on " . $user->login());
+            if (!Platal::session()->startSUID($user->id())) {
+                $page->trigError('Impossible d\'effectuer un SUID sur ' . $user->id());
             } else {
-                $r  = XDB::query("SELECT  *, a.alias AS forlife,
-                                          FIND_IN_SET('watch', u.flags) AS watch, FIND_IN_SET('femme', u.flags) AS sexe,
-                                          (year(naissance) > promo - 15 or year(naissance) < promo - 25) AS naiss_err
-                                    FROM  auth_user_md5 AS u
-                              INNER JOIN  aliases       AS a ON ( a.id = u.user_id AND a.alias={?} AND type!='homonyme' )", $login);
+                pl_redirect("");
             }
-            $mr = $r->fetchOneAssoc();
+        }
 
-            // Checks the user has a forlife, as non-registered user can't have redirections.
-            if ($mr['forlife']) {
-                $redirect = new Redirect($mr['user_id']);
-            }
+        // Fetches user data.
+        $userinfo_query = "SELECT  *, FIND_IN_SET('watch', flags) AS watch, FIND_IN_SET('femme', flags) AS sexe,
+                                   (year(naissance) > promo - 15 or year(naissance) < promo - 25) AS naiss_err
+                             FROM  auth_user_md5
+                            WHERE  user_id = {?}";
+        $mr = XDB::query($userinfo_query, $user->id())->fetchOneAssoc();
+        $redirect = ($registered ? new Redirect($user->id()) : null);
 
-            // Check if there was a submission
-            foreach($_POST as $key => $val) {
-                S::assert_xsrf_token();
+        // Processes admin requests, if any.
+        foreach($_POST as $key => $val) {
+            S::assert_xsrf_token();
 
-                switch ($key) {
-                    case "add_fwd":
-                        $email = trim(Env::v('email'));
-                        if (!isvalid_email_redirection($email)) {
-                            $page->trigError("Email non valide: $email");
-                        } else {
-                            $redirect->add_email($email);
-                            $page->trigSuccess("Ajout de $email effectué");
-                        }
-                        break;
+            switch ($key) {
+                // Email redirection actions.
+                case "add_fwd":
+                    $email = trim(Env::v('email'));
+                    if (!isvalid_email_redirection($email)) {
+                        $page->trigError("Email non valide: $email");
+                    } else {
+                        $redirect->add_email($email);
+                        $page->trigSuccess("Ajout de $email effectué");
+                    }
+                    break;
 
-                    case "del_fwd":
-                        if (!empty($val)) {
-                            $redirect->delete_email($val);
-                        }
-                        break;
+                case "del_fwd":
+                    if (!empty($val)) {
+                        $redirect->delete_email($val);
+                    }
+                    break;
 
-                    case "del_alias":
-                        if (!empty($val)) {
-                            XDB::execute("DELETE FROM aliases
-                                                WHERE id={?} AND alias={?}
-                                                      AND type!='a_vie' AND type!='homonyme'", $mr['user_id'], $val);
-                            XDB::execute("UPDATE emails
-                                             SET rewrite = ''
-                                           WHERE uid = {?} AND rewrite LIKE CONCAT({?}, '@%')",
-                                         $mr['user_id'], $val);
-                            fix_bestalias($mr['user_id']);
-                            $page->trigSuccess($val." a Ã©té supprimé");
-                        }
-                        break;
-                    case "activate_fwd":
-                        if (!empty($val)) {
-                            $redirect->modify_one_email($val, true);
-                        }
-                        break;
-                    case "deactivate_fwd":
-                        if (!empty($val)) {
-                            $redirect->modify_one_email($val, false);
-                        }
-                        break;
-                    case "disable_fwd":
-                        $redirect->disable();
-                        break;
-                    case "enable_fwd":
-                        $redirect->enable();
-                        break;
-                    case "clean_fwd":
-                        if (!empty($val)) {
-                            $redirect->clean_errors($val);
-                        }
-                        break;
-                    case "add_alias":
-                        global $globals;
-                        $alias = trim(Env::v('email'));
-                        if (strpos($alias, '@') !== false) {
-                            list($alias, $domain) = explode('@', $alias);
+                case "activate_fwd":
+                    if (!empty($val)) {
+                        $redirect->modify_one_email($val, true);
+                    }
+                    break;
+                case "deactivate_fwd":
+                    if (!empty($val)) {
+                        $redirect->modify_one_email($val, false);
+                    }
+                    break;
+                case "disable_fwd":
+                    $redirect->disable();
+                    break;
+                case "enable_fwd":
+                    $redirect->enable();
+                    break;
+                case "clean_fwd":
+                    if (!empty($val)) {
+                        $redirect->clean_errors($val);
+                    }
+                    break;
+
+                // Alias actions.
+                case "add_alias":
+                    global $globals;
+
+                    // Splits new alias in user and fqdn.
+                    $alias = trim(Env::v('email'));
+                    if (strpos($alias, '@') !== false) {
+                        list($alias, $domain) = explode('@', $alias);
+                    } else {
+                        $domain = $globals->mail->domain;
+                    }
+
+                    // Checks for alias' user validity.
+                    if (!preg_match('/[-a-z0-9\.]+/s', $alias)) {
+                        $page->trigError("'$alias' n'est pas un alias valide");
+                    }
+
+                    // Eventually adds the alias to the right domain.
+                    if ($domain == $globals->mail->alias_dom || $domain == $globals->mail->alias_dom2) {
+                        $req = new AliasReq($user->id(), $alias, 'Admin request', false);
+                        if ($req->commit()) {
+                            $page->trigSuccess("Nouvel alias '$alias@$domain' attribué");
                         } else {
-                            $domain = $globals->mail->domain;
-                        }
-                        if (!preg_match('/[-a-z0-9\.]+/s', $alias)) {
-                            $page->trigError("'$alias' n'est pas un alias valide");
+                            $page->trigError("Impossible d'ajouter l'alias '$alias@$domain', il est probablement déjà attribué");
                         }
-                        if ($domain == $globals->mail->alias_dom || $domain == $globals->mail->alias_dom2) {
-                            $req = new AliasReq($mr['user_id'], $alias, 'Admin request', false);
-                            if ($req->commit()) {
-                                $page->trigSuccess("Nouvel alias '$alias@$domain' attribué");
-                            } else {
-                                $page->trigError("Impossible d'ajouter l'alias '$alias@$domain', il est probablement déjà attribué");
-                            }
-                        } elseif ($domain == $globals->mail->domain || $domain == $globals->mail->domain2) {
-                            if (XDB::execute("INSERT INTO  aliases (id,alias,type) VALUES  ({?}, {?}, 'alias')",
-                                    $mr['user_id'], $alias)) {
-                                $page->trigSuccess("Nouvel alias '$alias' ajouté");
-                            } else {
-                                $page->trigError("Impossible d'ajouter l'alias '$alias', il est probablement déjà attribué");
-                            }
+                    } elseif ($domain == $globals->mail->domain || $domain == $globals->mail->domain2) {
+                        $res = XDB::execute("INSERT INTO aliases (id,alias,type) VALUES ({?}, {?}, 'alias')",
+                                            $user->id(), $alias);
+                        if ($res) {
+                            $page->trigSuccess("Nouvel alias '$alias' ajouté");
                         } else {
-                            $page->trigError("Le domaine '$domain' n'est pas valide");
+                            $page->trigError("Impossible d'ajouter l'alias '$alias', il est probablement déjà attribué");
                         }
-                        break;
+                    } else {
+                        $page->trigError("Le domaine '$domain' n'est pas valide");
+                    }
+                    break;
 
-                    case "best":
-                        // 'bestalias' is the first bit of the set : 1
-                        // 255 is the max for flags (8 sets max)
-                        XDB::execute("UPDATE  aliases SET flags= flags & (255 - 1) WHERE id={?}", $mr['user_id']);
-                        XDB::execute("UPDATE  aliases
-                                                   SET  flags= flags | 1
-                                                WHERE  id={?} AND alias={?}", $mr['user_id'], $val);
-                        break;
+                case "del_alias":
+                    if (!empty($val)) {
+                        XDB::execute("DELETE FROM  aliases
+                                            WHERE  id = {?} AND alias = {?} AND
+                                                   type NOT IN ('a_vie', 'homonyme')",
+                                     $user->id(), $val);
+                        XDB::execute("UPDATE  emails
+                                         SET  rewrite = ''
+                                       WHERE  uid = {?} AND rewrite LIKE CONCAT({?}, '@%')",
+                                     $user->id(), $val);
+                        fix_bestalias($user->id());
+                        $page->trigSuccess("L'alias '$val' a Ã©té supprimé");
+                    }
+                    break;
 
+                case "best":
+                    XDB::execute("UPDATE  aliases
+                                     SET  flags = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', flags, ','), ',bestalias,', ','))
+                                   WHERE  id = {?}", $user->id());
+                    XDB::execute("UPDATE  aliases
+                                     SET  flags = CONCAT_WS(',', IF(flags = '', NULL, flags), 'bestalias')
+                                   WHERE  id = {?} AND alias = {?}", $user->id(), $val);
+
+                    // As having a non-null bestalias value is critical in
+                    // plat/al's code, we do an a posteriori check on the
+                    // validity of the bestalias.
+                    fix_bestalias($user->id());
+                    break;
 
-                    // Editer un profil
-                    case "u_edit":
-                        require_once('secure_hash.inc.php');
-                        $pass_encrypted = Env::v('newpass_clair') != "********" ? hash_encrypt(Env::v('newpass_clair')) : Env::v('passw');
-                        $naiss    = Env::v('naissanceN');
-                        $deces    = Env::v('decesN');
-                        $perms    = Env::v('permsN');
-                        $prenm    = Env::v('prenomN');
-                        $nom      = Env::v('nomN');
-                        $nomusage = Env::v('nomusageN');
-                        $promo    = Env::i('promoN');
-                        $sexe     = Env::v('sexeN');
-                        $comm     = trim(Env::v('commentN'));
-                        $watch    = Env::v('watchN');
-                        $flags    = '';
-                        if ($sexe) {
-                            $flags = 'femme';
-                        }
-                        if ($watch) {
-                            if ($flags) {
-                                $flags .= ',';
-                            }
-                            $flags .= 'watch';
-                        }
+                // Profile edition.
+                case "u_edit":
+                    // Loads new values from environment.
+                    require_once('secure_hash.inc.php');
+                    $pass_encrypted = Env::v('newpass_clair') != "********" ? hash_encrypt(Env::v('newpass_clair')) : Env::v('passw');
+                    $naiss    = Env::v('naissanceN');
+                    $deces    = Env::v('decesN');
+                    $perms    = Env::v('permsN');
+                    $prenom    = Env::v('prenomN');
+                    $nom      = Env::v('nomN');
+                    $nomusage = Env::v('nomusageN');
+                    $promo    = Env::i('promoN');
+                    $sexe     = Env::v('sexeN');
+                    $comm     = trim(Env::v('commentN'));
+                    $watch    = Env::v('watchN');
+
+                    $flags    = ($sexe ? 'femme' : '');
+                    if ($watch) {
+                        $flags .= ($flags ? ',watch' : 'watch');
+                    }
+                    if ($watch && !$comm) {
+                        $page->trigError("Il est nécessaire de mettre un commentaire pour surveiller un compte");
+                        break;
+                    }
 
-                        if ($watch && !$comm) {
-                            $page->trigError("Il est nécessaire de mettre un commentaire pour surveiller un compte");
-                            break;
-                        }
+                    // Fetches fields to watch for changes.
+                    $watch_query = "SELECT  naissance, deces, password, perms, nom_usage,
+                                           prenom, nom, flags, promo, comment
+                                      FROM  auth_user_md5
+                                     WHERE user_id = {?}";
+                    $old_fields = XDB::query($watch_query, $user->id())->fetchOneAssoc();
+
+                    // If user was newly banned, we need to ensure her php session
+                    // is killed. This hack is ugly (and largely overkill); it should
+                    // however suits our needs.
+                    if ($perms == 'disabled' && $old_fields['perms'] != 'disabled') {
+                        kill_sessions();
+                    }
 
-                        $watch = 'SELECT naissance, deces, password, perms, nom_usage,
-                                         prenom, nom, flags, promo, comment
-                                    FROM auth_user_md5
-                                   WHERE user_id = ' . $mr['user_id'];
-                        $res = XDB::query($watch);
-                        $old_fields = $res->fetchOneAssoc();
-                        $query = "UPDATE auth_user_md5 SET
-                                         naissance = '$naiss',
-                                         deces     = '$deces',
-                                         password  = '$pass_encrypted',
-                                         perms     = '$perms',
-                                         prenom    = '".addslashes($prenm)."',
-                                         nom       = '".addslashes($nom)."',
-                                         nom_usage = '".addslashes($nomusage)."',
-                                         flags     = '$flags',
-                                         promo     = $promo,
-                                         comment   = '".addslashes($comm)."'
-                                   WHERE user_id = '{$mr['user_id']}'";
-                        if ($perms == 'disabled' && $old_fields['perms'] != 'disabled') {
-                            // A user has been banned ==> ensure his php session has been killed
-                            // This solution is ugly and overkill, but, it should be efficient.
-                            kill_sessions();
-                        }
-                        if (XDB::execute($query)) {
-                            user_reindex($mr['user_id']);
+                    // Updates the user profile with the new values.
+                    $res = XDB::execute("UPDATE  auth_user_md5
+                                            SET  naissance = {?}, deces = {?}, password = {?},
+                                                 perms = {?}, prenom = {?}, nom = {?}, nom_usage = {?},
+                                                 flags = {?}, promo = {?}, comment = {?}
+                                          WHERE  user_id = {?}",
+                                        $naiss, $deces, $pass_encrypted,
+                                        $perms, $prenom, $nom, $nomusage,
+                                        $flags, $promo, $comm, $user->id());
+                    if ($res) {
+                        require_once("user.func.inc.php");
+                        user_reindex($user->id());
+                        $new_fields = XDB::query($watch_query, $user->id())->fetchOneAssoc();
 
-                            $res = XDB::query($watch);
-                            $new_fields = $res->fetchOneAssoc();
+                        $mailer = new PlMailer("admin/useredit.mail.tpl");
+                        $mailer->assign("admin", S::user()->login());
+                        $mailer->assign("user", $user->login());
+                        $mailer->assign('old', $old_fields);
+                        $mailer->assign('new', $new_fields);
+                        $mailer->send();
 
-                            $mailer = new PlMailer("admin/useredit.mail.tpl");
-                            $mailer->assign("admin", S::v('forlife'));
-                            $mailer->assign("user", $mr['forlife']);
-                            $mailer->assign('old', $old_fields);
-                            $mailer->assign('new', $new_fields);
-                            $mailer->send();
+                        $globals->updateNbIns();
+                        $page->trigSuccess("Update was successful.");
+                    } else {
+                        $page->trigError("Update failed, please double check your values.");
+                    }
 
-                            // update number of subscribers (perms or deceased may have changed)
-                            $globals->updateNbIns();
+                    // Checks for changes, and updates other tables of plat/al.
+                    if (Env::v('nomusageN') != $mr['nom_usage']) {
+                        set_new_usage($user->id(), Env::v('nomusageN'), make_username(Env::v('prenomN'), Env::v('nomusageN')));
+                    }
+                    if (Env::v('decesN') != $mr['deces']) {
+                        require_once 'notifs.inc.php';
+                        register_watch_op($user->id(), WATCH_DEATH, $mr['deces']);
+                        user_clear_all_subs($user->id(), false);
+                    }
 
-                            $page->trigSuccess("updaté correctement.");
-                        }
-                        if (Env::v('nomusageN') != $mr['nom_usage']) {
-                            set_new_usage($mr['user_id'], Env::v('nomusageN'), make_username(Env::v('prenomN'), Env::v('nomusageN')));
-                        }
-                        if (Env::v('decesN') != $mr['deces']) {
-                            require_once 'notifs.inc.php';
-                            register_watch_op($mr['user_id'], WATCH_DEATH, $mr['deces']);
-                            user_clear_all_subs($mr['user_id'], false);
-                        }
-                        $r = XDB::query("SELECT *, a.alias AS forlife,
-                                                FIND_IN_SET('watch', u.flags) AS watch, FIND_IN_SET('femme', u.flags) AS sexe
-                                           FROM auth_user_md5 AS u
-                                      LEFT JOIN aliases       AS a ON (a.id = u.user_id AND type= 'a_vie')
-                                          WHERE u.user_id = {?}", $mr['user_id']);
-                        $mr = $r->fetchOneAssoc();
-
-                        // If GoogleApps is enabled, the user did choose to use synchronized passwords,
-                        // and the password was changed, updates the Google Apps password as well.
-                        if ($globals->mailstorage->googleapps_domain && Env::v('newpass_clair') != "********") {
+                    // Eventually updates the Google Apps account.
+                    if ($globals->mailstorage->googleapps_domain) {
+                        // If the user did choose to use synchronized passwords,
+                        // and the password was changed, updates the Google Apps
+                        // password as well.
+                        if (Env::v('newpass_clair') != "********") {
                             require_once 'googleapps.inc.php';
-                            $account = new GoogleAppsAccount($mr['user_id'], $mr['forlife']);
+                            $account = new GoogleAppsAccount($user);
                             if ($account->active() && $account->sync_password) {
                                 $account->set_password($pass_encrypted);
                             }
                         }
 
-                        // If GoogleApps is enabled, and the user is now disabled, disables the Google Apps account as well.
-                        if ($globals->mailstorage->googleapps_domain &&
-                            $new_fields['perms'] == 'disabled' &&
-                            $new_fields['perms'] != $old_fields['perms']) {
+                        // If the update did disable the user account, disables
+                        // the Google Apps account as well.
+                        if ($new_fields['perms'] == 'disabled' && $new_fields['perms'] != $old_fields['perms']) {
                             require_once 'googleapps.inc.php';
-                            $account = new GoogleAppsAccount($mr['user_id'], $mr['forlife']);
+                            $account = new GoogleAppsAccount($user);
                             $account->suspend();
                         }
-                        break;
+                    }
 
-                    // DELETE FROM auth_user_md5
-                    case "u_kill":
-                        user_clear_all_subs($mr['user_id']);
-                        // update number of subscribers (perms or deceased may have changed)
-                        $globals->updateNbIns();
-                        $page->trigSuccess("'{$mr['user_id']}' a Ã©té désinscrit !");
-                        $mailer = new PlMailer("admin/useredit.mail.tpl");
-                        $mailer->assign("admin", S::v('forlife'));
-                        $mailer->assign("user", $mr['forlife']);
-                        $mailer->assign("deletion", true);
-                        $mailer->send();
-                        break;
 
-                    case "b_edit":
-                        XDB::execute("DELETE FROM forums.innd WHERE uid = {?}", $mr['user_id']);
-                        if (Env::v('write_perm') != "" || Env::v('read_perm') != ""  || Env::v('commentaire') != "" ) {
-                          XDB::execute("INSERT INTO forums.innd
-                                                SET ipmin = '0',
-                                                    ipmax = '4294967295',
-                                                    write_perm = {?},
-                                                    read_perm = {?},
-                                                    comment = {?},
-                                                    priority = '200',
-                                                    uid = {?}",
-                                       Env::v('write_perm'), Env::v('read_perm'), Env::v('comment'), $mr['user_id']);
-                        }
-                        break;
-                }
-            }
+                    // Reloads the user profile, to ensure the latest version will
+                    // be served to the administrator.
+                    $mr = XDB::query($userinfo_query, $user->id())->fetchOneAssoc();
 
-            $res = XDB::query("SELECT  start, host
-                                 FROM  logger.sessions
-                                WHERE  uid={?} AND suid=0
-                             ORDER BY  start DESC
-                                LIMIT  1", $mr['user_id']);
-            list($lastlogin,$host) = $res->fetchOneRow();
-            $page->assign('lastlogin', $lastlogin);
-            $page->assign('host', $host);
-
-            $res = XDB::iterator("SELECT  alias
-                                    FROM  virtual
-                              INNER JOIN  virtual_redirect USING(vid)
-                                   WHERE  type = 'user' AND redirect LIKE '" . $mr['forlife'] . "@%'");
-            $page->assign('virtuals', $res);
-
-            $page->assign('aliases', XDB::iterator(
-                        "SELECT  alias, type='a_vie' AS for_life,FIND_IN_SET('bestalias',flags) AS best,expire
-                           FROM  aliases
-                          WHERE  id = {?} AND type!='homonyme'
-                       ORDER BY  type!= 'a_vie'", $mr["user_id"]));
-            if ($mr['perms'] != 'pending' && isset($redirect)) {
-                $page->assign('emails', $redirect->emails);
-            }
+                    break;
 
-            $page->assign('mr',$mr);
+                // User re-registration.
+                case "u_kill":
+                    user_clear_all_subs($user->id());
+                    $globals->updateNbIns();
+                    $page->trigSuccess("'" . $user->id() . "' a Ã©té désinscrit !");
+
+                    $mailer = new PlMailer("admin/useredit.mail.tpl");
+                    $mailer->assign("admin", S::user()->login());
+                    $mailer->assign("user", $user->login());
+                    $mailer->assign("deletion", true);
+                    $mailer->send();
+                    break;
 
-            // Bans forums
-            $res = XDB::query("SELECT  write_perm, read_perm, comment
-                                 FROM  forums.innd
-                                WHERE  uid = {?}", $mr['user_id']);
-            $bans = $res->fetchOneAssoc();
-            $page->assign('bans', $bans);
+                // Forum ban update.
+                case "b_edit":
+                    XDB::execute("DELETE FROM forums.innd WHERE uid = {?}", $user->id());
+                    if (Env::v('write_perm') != "" || Env::v('read_perm') != ""  || Env::v('commentaire') != "" ) {
+                        XDB::execute("INSERT INTO  forums.innd
+                                              SET  ipmin = '0', ipmax = '4294967295',
+                                                   write_perm = {?}, read_perm = {?},
+                                                   comment = {?}, priority = '200', uid = {?}",
+                                     Env::v('write_perm'), Env::v('read_perm'), Env::v('comment'), $user->id());
+                    }
+                    break;
+            }
         }
+
+        // Displays last login and last host information.
+        $res = XDB::query("SELECT  start, host
+                             FROM  logger.sessions
+                            WHERE  uid = {?} AND suid = 0
+                         ORDER BY  start DESC
+                            LIMIT  1", $user->id());
+        list($lastlogin,$host) = $res->fetchOneRow();
+        $page->assign('lastlogin', $lastlogin);
+        $page->assign('host', $host);
+
+        // Display active aliases.
+        $page->assign('virtuals', XDB::iterator(
+                "SELECT  alias
+                   FROM  virtual
+             INNER JOIN  virtual_redirect USING (vid)
+                  WHERE  type = 'user' AND redirect LIKE CONCAT({?}, '@%')", $user->id()));
+
+        $page->assign('aliases', XDB::iterator(
+                "SELECT  alias, type='a_vie' AS for_life,FIND_IN_SET('bestalias',flags) AS best,expire
+                   FROM  aliases
+                  WHERE  id = {?} AND type != 'homonyme'
+               ORDER BY  type != 'a_vie'", $user->id()));
+
+        // Displays email redirection and the general profile.
+        if ($registered && $redirect) {
+            $page->assign('emails', $redirect->emails);
+        }
+
+        $page->assign('mr', $mr);
+        $page->assign('user', $user);
+
+        // Displays forum bans.
+        $res = XDB::query("SELECT  write_perm, read_perm, comment
+                             FROM  forums.innd
+                            WHERE  uid = {?}", $user->id());
+        $bans = $res->fetchOneAssoc();
+        $page->assign('bans', $bans);
     }
 
     function getMatricule($line, $key)
@@ -876,51 +879,41 @@ class AdminModule extends PLModule
         $page->assign('dead', $res);
     }
 
-    function handler_synchro_ax(&$page, $user = null, $action = null) {
+    function handler_synchro_ax(&$page, $login = null, $action = null) {
         $page->changeTpl('admin/synchro_ax.tpl');
         $page->setTitle('Administration - Synchro AX');
 
+        // Checks for synchronization requirements.
         require_once('synchro_ax.inc.php');
-
         if (is_ax_key_missing()) {
             $page->assign('no_private_key', true);
             $page->run();
         }
 
-        require_once('user.func.inc.php');
-
-        if ($user)
-            $login = get_user_forlife($user);
-
-        if (Env::has('user')) {
-            $login = get_user_forlife(Env::v('user'));
-            if ($login === false) {
-                return;
-            }
+        // Determines user identity using environment.
+        if ($login) {
+            $user = User::get($login);
+        } else if (Env::has('user')) {
+            $user = User::get(Env::v('user'));
+        } else if (Env::has('mat')) {
+            $res = XDB::query("SELECT user_id FROM auth_user_md5 WHERE matricule = {?}", Env::i('mat'));
+            $user = User::get($res->fetchOneCell());
+        } else {
+            return;
         }
 
-        if (Env::has('mat')) {
-            $res = XDB::query(
-                    "SELECT  alias
-                       FROM  aliases       AS a
-                 INNER JOIN  auth_user_md5 AS u ON (a.id=u.user_id AND a.type='a_vie')
-                      WHERE  matricule={?}", Env::i('mat'));
-            $login = $res->fetchOneCell();
+        // Finally synchronizes the AX and plat/al information.
+        if ($action == 'import') {
+            ax_synchronize($user->login(), S::v('uid'));
         }
 
-        if ($login) {
-            if ($action == 'import') {
-                ax_synchronize($login, S::v('uid'));
-            }
-            // get details from user, but looking only info that can be seen by ax
-            $user  = get_user_details($login, S::v('uid'), 'ax');
-            $userax= get_user_ax($user['matricule_ax']);
-            require_once 'profil.func.inc.php';
-            $diff = diff_user_details($userax, $user, 'ax');
-
-            $page->assign('x', $user);
-            $page->assign('diff', $diff);
-        }
+        require_once 'profil.func.inc.php';
+        $userxorg = get_user_details($user->login(), S::v('uid'), 'ax');
+        $userax = get_user_ax($userxorg['matricule_ax']);
+        $diff = diff_user_details($userax, $userxorg, 'ax');
+
+        $page->assign('x', $userxorg);
+        $page->assign('diff', $diff);
     }
 
     function handler_validate(&$page, $action = 'list', $id = null)
index 41978e1..24e7201 100644 (file)
@@ -275,9 +275,9 @@ class AXLetterModule extends PLModule
             $nl->toHtml($page, S::v('prenom'), S::v('nom'), S::v('femme'));
         }
         if (Post::has('send')) {
-            $nl->sendTo(S::v('prenom'), S::v('nom'),
-                        S::v('bestalias'), S::v('femme'),
-                        S::v('mail_fmt') != 'texte');
+            $nl->sendTo(S::user()->login(), S::user()->bestEmail(),
+                        S::v('prenom'), S::v('nom'),
+                        S::v('femme'), S::v('mail_fmt') != 'texte');
         }
     }
 
index f8c7ca1..eed37b6 100644 (file)
@@ -99,7 +99,9 @@ class AXLetter extends MassMailer
 
     protected function getAllRecipients()
     {
-        return "SELECT  ni.user_id, IF(ni.user_id = 0, ni.email, a.alias) AS alias,
+        global $globals;
+        return "SELECT  ni.user_id, IF(ni.user_id = 0, NULL, u.hruid) AS hruid,
+                        IF(ni.user_id = 0, ni.email, CONCAT(a.alias, '@{$globals->mail->domain}')) AS alias,
                         IF(ni.user_id = 0, ni.prenom, u.prenom) AS prenom,
                         IF(ni.user_id = 0, ni.nom, IF(u.nom_usage='', u.nom, u.nom_usage)) AS nom,
                         FIND_IN_SET('femme', IF(ni.user_id = 0, ni.flag, u.flags)) AS sexe,
index 56f0580..1d72774 100644 (file)
@@ -215,39 +215,24 @@ class CarnetModule extends PLModule
         }
         switch (Env::v('action')) {
             case 'retirer':
-                if (is_numeric($user)) {
-                    if (XDB::execute('DELETE FROM contacts
-                                       WHERE uid = {?} AND contact = {?}',
-                                     $uid, $user))
-                    {
-                        $page->trigSuccess("Contact retiré !");
-                    }
-                } else {
-                    if (XDB::execute(
-                                'DELETE FROM  c
-                                       USING  contacts AS c
-                                  INNER JOIN  aliases  AS a ON (c.contact=a.id and a.type!="homonyme")
-                                       WHERE  c.uid = {?} AND a.alias={?}', $uid, $user))
-                    {
+                if (($user = User::get(Env::v('user')))) {
+                    if (XDB::execute("DELETE FROM  contacts
+                                            WHERE  uid = {?} AND contact = {?}", $uid, $user->id())) {
                         $page->trigSuccess("Contact retiré !");
                     }
                 }
                 break;
 
             case 'ajouter':
-                require_once('user.func.inc.php');
-                if (($login = get_user_login($user)) !== false) {
-                    if (XDB::execute(
-                                'REPLACE INTO  contacts (uid, contact)
-                                       SELECT  {?}, id
-                                         FROM  aliases
-                                        WHERE  alias = {?}', $uid, $login))
-                    {
+                if (($user = User::get(Env::v('user')))) {
+                    if (XDB::execute("REPLACE INTO  contacts (uid, contact)
+                                            VALUES  ({?}, {?})", $uid, $user->id())) {
                         $page->trigSuccess('Contact ajouté !');
                     } else {
                         $page->trigWarning('Contact déjà dans la liste !');
                     }
                 }
+                break;
         }
 
         $search = false;
index 80ea2fd..67a454e 100644 (file)
@@ -90,7 +90,7 @@ class ForumsModule extends PLModule
         $_SESSION = array_merge($row, $_SESSION);
 
         require_once 'banana/forum.inc.php';
-        $banana = new ForumsBanana(S::v('forlife'), array('group' => $group, 'action' => 'rss2'));
+        $banana = new ForumsBanana(S::user(), array('group' => $group, 'action' => 'rss2'));
         $banana->run();
         exit;
     }
index 553aeaf..c2c4e53 100644 (file)
@@ -44,7 +44,7 @@ class GoogleAppsModule extends PLModule
         $page->addJsLink('motdepasse.js');
         $page->setTitle('Compte Google Apps');
 
-        $account = new GoogleAppsAccount(S::v('uid'), S::v('forlife'));
+        $account = new GoogleAppsAccount(S::user());
 
         // Fills up the 'is Google Apps redirection active' variable.
         $page->assign('redirect_active', false);
@@ -189,34 +189,31 @@ class GoogleAppsModule extends PLModule
         if (!$user && Post::has('login')) {
             $user = Post::v('login');
         }
-        if ($user && !is_numeric($user)) {
-            $res = XDB::query("SELECT id FROM aliases WHERE alias = {?} AND type != 'homonyme'", $user);
-            $user = $res->fetchOneCell();
-        }
+        $user = User::get($user);
 
         if ($user) {
             $account = new GoogleAppsAccount($user);
-            $storage = new EmailStorage($user, 'googleapps');
+            $storage = new EmailStorage($user->id(), 'googleapps');
 
             // Force synchronization of plat/al and Google Apps passwords.
             if ($action == 'forcesync' && $account->sync_password) {
-                $res = XDB::query("SELECT password FROM auth_user_md5 WHERE user_id = {?}", $user);
+                $res = XDB::query("SELECT password FROM auth_user_md5 WHERE user_id = {?}", $user->id());
                 $account->set_password($res->fetchOneCell());
                 $page->trigSuccess('Le mot de passe a Ã©té synchronisé.');
             }
 
             // Displays basic account information.
             $page->assign('account', $account);
-            $page->assign('admin_account', GoogleAppsAccount::is_administrator($user));
+            $page->assign('admin_account', GoogleAppsAccount::is_administrator($user->id()));
             $page->assign('googleapps_storage', $storage->active);
-            $page->assign('user', $user);
+            $page->assign('user', $user->id());
 
             // Retrieves user's pending requests.
             $res = XDB::iterator(
                 "SELECT  q_id, q_recipient_id, p_status, j_type, UNIX_TIMESTAMP(p_entry_date) AS p_entry_date
                    FROM  gapps_queue
                   WHERE  q_recipient_id = {?}
-               ORDER BY  p_entry_date DESC", $user);
+               ORDER BY  p_entry_date DESC", $user->id());
             $page->assign('requests', $res);
         }
     }
index 7165237..a0b68ec 100644 (file)
@@ -444,7 +444,7 @@ class ListsModule extends PLModule
                 exit;
             }
             require_once('banana/ml.inc.php');
-            $banana = new MLBanana(S::v('forlife'), Array('listname' => $liste, 'domain' => $domain, 'action' => 'rss2'));
+            $banana = new MLBanana(S::user(), Array('listname' => $liste, 'domain' => $domain, 'action' => 'rss2'));
             $banana->run();
         }
         exit;
index c854069..9cf8a9a 100644 (file)
@@ -169,33 +169,33 @@ class MarketingModule extends PLModule
 
     function handler_broken(&$page, $uid = null)
     {
-        require_once('user.func.inc.php');
         $page->changeTpl('marketing/broken.tpl');
 
         if (is_null($uid)) {
             return PL_NOT_FOUND;
         }
-        $forlife = get_user_forlife($uid);
-        if (!$forlife) {
+
+        $user = User::get($uid);
+        if (!$user) {
             return PL_NOT_FOUND;
-        } elseif ($forlife == S::v('forlife')) {
+        } elseif ($user->login() == S::user()->login()) {
             pl_redirect('emails/redirect');
         }
 
         $res = Xdb::query("SELECT  u.nom, u.prenom, u.promo, FIND_IN_SET('femme', u.flags) AS sexe,
-                                   u.deces = '0000-00-00' AS alive, a.alias AS forlife, b.alias AS bestalias,
+                                   u.deces = '0000-00-00' AS alive, u.hruid, a.alias AS forlife, b.alias AS bestalias,
                                    IF(e.email IS NOT NULL, e.email, IF(FIND_IN_SET('googleapps', u.mail_storage), 'googleapps', NULL)) AS email, e.last
                              FROM  auth_user_md5 AS u
                        INNER JOIN  aliases       AS a ON (a.id = u.user_id AND a.type = 'a_vie')
                        INNER JOIN  aliases       AS b ON (b.id = u.user_id AND FIND_IN_SET('bestalias', b.flags))
                         LEFT JOIN  emails        AS e ON (e.flags = 'active' AND e.uid = u.user_id)
-                            WHERE  a.alias = {?}
-                         ORDER BY  e.panne_level, e.last", $forlife);
+                            WHERE  u.hruid = {?}
+                         ORDER BY  e.panne_level, e.last", $user->login());
         if (!$res->numRows()) {
             return PL_NOT_FOUND;
         }
-        $user = $res->fetchOneAssoc();
-        $page->assign('user', $user);
+        $user_data = $res->fetchOneAssoc();
+        $page->assign('user', $user_data);
 
         $email = null;
         if (Post::has('mail')) {
@@ -206,22 +206,21 @@ class MarketingModule extends PLModule
             S::assert_xsrf_token();
 
             // security stuff
-            check_email($email, "Proposition d'une adresse surveillee pour " . $user['forlife'] . " par " . S::v('forlife'));
-            $res = XDB::query("SELECT  e.flags
-                                 FROM  emails   AS e
-                           INNER JOIN  aliases  AS a ON (a.id = e.uid)
-                                WHERE  e.email = {?} AND a.alias = {?}", $email, $user['forlife']);
+            check_email($email, "Proposition d'une adresse surveillee pour " . $user->login() . " par " . S::user()->login());
+            $res = XDB::query("SELECT  flags
+                                 FROM  emails
+                                WHERE  email = {?} AND uid = {?}", $email, $user->id());
             $state = $res->numRows() ? $res->fetchOneCell() : null;
             if ($state == 'panne') {
-                $page->trigWarning("L'adresse que tu as fournie est l'adresse actuelle de {$user['prenom']} et est en panne.");
+                $page->trigWarning("L'adresse que tu as fournie est l'adresse actuelle de {$user_data['prenom']} et est en panne.");
             } elseif ($state == 'active') {
-                $page->trigWarning("L'adresse que tu as fournie est l'adresse actuelle de {$user['prenom']}");
-            } elseif ($user['email'] && !trim(Post::v('comment'))) {
+                $page->trigWarning("L'adresse que tu as fournie est l'adresse actuelle de {$user_data['prenom']}");
+            } elseif ($user_data['email'] && !trim(Post::v('comment'))) {
                 $page->trigError("Il faut que tu ajoutes un commentaire Ã  ta proposition pour justifier le "
-                           ."besoin de changer la redirection de " . $user['prenom']);
+                               . "besoin de changer la redirection de " . $user_data['prenom']);
             } else {
                 require_once 'validations.inc.php';
-                $valid = new BrokenReq(S::i('uid'), $user, $email, trim(Post::v('comment')));
+                $valid = new BrokenReq(S::i('uid'), $user_data, $email, trim(Post::v('comment')));
                 $valid->submit();
                 $page->assign('sent', true);
             }
index 9dfe318..cb7b60c 100644 (file)
@@ -64,9 +64,9 @@ class NewsletterModule extends PLModule
         }
         if (Post::has('send')) {
             $res = XDB::query("SELECT hash FROM newsletter_ins WHERE user_id = {?}", S::i('uid'));
-            $nl->sendTo(S::v('prenom'), S::v('nom'),
-                        S::v('bestalias'), S::v('femme'),
-                        S::v('mail_fmt') != 'texte',
+            $nl->sendTo(S::user()->login(), S::user()->bestEmail(),
+                        S::v('prenom'), S::v('nom'),
+                        S::v('femme'), S::v('mail_fmt') != 'texte',
                         $res->fetchOneCell());
         }
     }
index d72c110..1f96e68 100644 (file)
@@ -202,7 +202,7 @@ class PlatalModule extends PLModule
             // updates the Google Apps password as well.
             if ($globals->mailstorage->googleapps_domain) {
                 require_once 'googleapps.inc.php';
-                $account = new GoogleAppsAccount(S::v('uid'), S::v('forlife'));
+                $account = new GoogleAppsAccount(S::user());
                 if ($account->active() && $account->sync_password) {
                     $account->set_password($password);
                 }
@@ -368,7 +368,7 @@ Adresse de secours : " . Post::v('email') : ""));
             // updates the Google Apps password as well.
             if ($globals->mailstorage->googleapps_domain) {
                 require_once 'googleapps.inc.php';
-                $account = new GoogleAppsAccount($uid);
+                $account = new GoogleAppsAccount(User::getSilent($uid));
                 if ($account->active() && $account->sync_password) {
                     $account->set_password($password);
                 }
@@ -412,12 +412,11 @@ Adresse de secours : " . Post::v('email') : ""));
     function handler_exit(&$page, $level = null)
     {
         if (S::has('suid')) {
-            $a4l  = S::v('forlife');
             $suid = S::v('suid');
             $log  = S::v('log');
-            S::logger()->log("suid_stop", S::v('forlife') . " by " . $suid['forlife']);
+            S::logger()->log("suid_stop", S::user()->login() . " by " . $suid['hruid']);
             Platal::session()->stopSUID();
-            pl_redirect('admin/user/' . $a4l);
+            pl_redirect('admin/user/' . S::user()->login());
         }
 
         if ($level == 'forget' || $level == 'forgetall') {
index 5e1a3cf..9ba75ef 100644 (file)
@@ -198,19 +198,15 @@ class ProfileModule extends PLModule
         if (!S::logged() || Env::v('view') == 'public') $view = 'public';
         if (S::logged() && Env::v('view') == 'ax')      $view = 'ax';
 
-        if (is_numeric($x)) {
-            $res = XDB::query(
-                    "SELECT  alias
-                       FROM  aliases       AS a
-                 INNER JOIN  auth_user_md5 AS u ON (a.id=u.user_id AND a.type='a_vie')
-                      WHERE  matricule={?}", $x);
-            $login = $res->fetchOneCell();
-        } else {
-            $login = get_user_forlife($x, S::logged() ? '_default_user_callback'
-                                                      : '_silent_user_callback');
+        $login = S::logged() ? User::get($x) : User::getSilent($x);
+        if (!$login) {
+            return PL_NOT_FOUND;
         }
 
-        if (empty($login)) {
+        $res = XDB::query("SELECT  perms IN ('admin','user','disabled')
+                             FROM  auth_user_md5
+                            WHERE  user_id = {?}", $login->id());
+        if (!$res->fetchOneCell()) {
             $user = get_not_registered_user($x, true);
             if ($user->total() != 1) {
                 return PL_NOT_FOUND;
@@ -222,11 +218,11 @@ class ProfileModule extends PLModule
             $user['forlife'] = $x;
         } else {
             $new   = Env::v('modif') == 'new';
-            $user  = get_user_details($login, S::v('uid'), $view);
+            $user  = get_user_details($login->login(), S::v('uid'), $view);
         }
 
         if (S::logged()) {
-            S::logger()->log('view_profile', $login);
+            S::logger()->log('view_profile', $login->login());
         }
 
         $title = $user['prenom'] . ' ' . ( empty($user['nom_usage']) ? $user['nom'] : $user['nom_usage'] );
@@ -281,18 +277,17 @@ class ProfileModule extends PLModule
 
     function handler_ax(&$page, $user = null)
     {
-        require_once 'user.func.inc.php';
-        $user = get_user_forlife($user);
+        $user = User::get($user);
         if (!$user) {
             return PL_NOT_FOUND;
         }
-        $res = XDB::query('SELECT matricule_ax
-                             FROM auth_user_md5 AS u
-                       INNER JOIN aliases       AS a ON (a.type = "a_vie" AND a.id = u.user_id)
-                            WHERE a.alias = {?}', $user);
+
+        $res = XDB::query("SELECT  matricule_ax
+                             FROM  auth_user_md5
+                            WHERE  user_id = {?}", $user->id());
         $mat = $res->fetchOneCell();
         if (!intval($mat)) {
-            $page->kill("Le matricule AX de $user est inconnu");
+            $page->kill("Le matricule AX de {$user->login()} est inconnu");
         }
         http_redirect("http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&anc_id=$mat");
     }
index cb15051..a226c98 100644 (file)
@@ -406,11 +406,11 @@ class RegisterModule extends PLModule
                                    S::v('uid'));
 
             // If GoogleApps is enabled, and the user did choose to use synchronized passwords,
-            // and if the (stupid) user has decided to user /register/success another time,
+            // and if the (stupid) user has decided to use /register/success another time,
             // updates the Google Apps password as well.
             if ($globals->mailstorage->googleapps_domain) {
                 require_once 'googleapps.inc.php';
-                $account = new GoogleAppsAccount(S::v('uid'), S::v('forlife'));
+                $account = new GoogleAppsAccount(S::user());
                 if ($account->active() && $account->sync_password) {
                     $account->set_password($password);
                 }
index a21500c..4bbbfc0 100644 (file)
@@ -94,7 +94,7 @@ class SearchModule extends PLModule
                 $list .= '|admin|adm|ax';
             }
             if (preg_match('/^(' . $list . '):([-a-z]+(\.[-a-z]+(\.\d{2,4})?)?)$/', replace_accent($quick), $matches)) {
-                $forlife = $matches[2];
+                $login = $matches[2];
                 switch($matches[1]) {
                   case 'admin': case 'adm':
                     $base = 'admin/user/';
@@ -110,10 +110,9 @@ class SearchModule extends PLModule
                     break;
                 }
 
-                require_once 'user.func.inc.php';
-                $login = get_user_forlife($forlife, '_silent_user_callback');
-                if ($login) {
-                    pl_redirect($base . $login);
+                $user = User::getSilent($login);
+                if ($user) {
+                    pl_redirect($base . $user->login());
                 }
                 $_REQUEST['quick'] = $forlife;
                 $_GET['quick'] = $forlife;
index 4a69b7a..8e74de6 100644 (file)
@@ -201,17 +201,15 @@ function get_event_participants(&$evt, $item_id, $tri, $limit = '') {
 //  {{{ function subscribe_lists_event()
 function subscribe_lists_event($participate, $uid, $evt)
 {
-    require_once('user.func.inc.php');
     global $globals;
     $page =& Platal::page();
 
     $participant_list = $evt['participant_list'];
     $absent_list      = $evt['absent_list'];
 
-    $email = get_user_forlife($uid, '_silent_user_callback');
-
-    if ($email) {
-        $email .= '@'.$globals->mail->domain;
+    $user = User::getSilent($uid);
+    if ($user) {
+        $email = $user->forlifeEmail();
     } else {
         $res = XDB::query("SELECT email
                              FROM groupex.membres
index 56da844..00bc86e 100644 (file)
@@ -790,26 +790,13 @@ class XnetGrpModule extends PLModule
             S::assert_xsrf_token();
         }
 
-        if (strpos($email, '@') === false) {
-            $x = true;
-        } else {
-            list(,$fqdn) = explode('@', $email, 2);
-            $fqdn = strtolower($fqdn);
-            $x = ($fqdn == 'polytechnique.org' || $fqdn == 'melix.org' ||
-                  $fqdn == 'm4x.org' || $fqdn == 'melix.net');
-        }
-        if ($x) {
-            require_once 'user.func.inc.php';
-            if ($forlife = get_user_forlife($email)) {
-                XDB::execute(
-                    'INSERT INTO  groupex.membres (uid,asso_id,origine)
-                          SELECT  user_id,{?},"X"
-                            FROM  auth_user_md5 AS u
-                      INNER JOIN  aliases       AS a ON (u.user_id = a.id)
-                           WHERE  a.alias={?}', $globals->asso('id'), $forlife);
-                pl_redirect("member/$forlife");
-            } else {
-                $page->trigError($email." n'est pas un alias polytechnique.org valide.");
+        if (!User::isForeignEmailAddress($email)) {
+            $user = User::get($email);
+            if ($user) {
+                XDB::execute("REPLACE INTO  groupex.membres (uid, asso_id, origine)
+                                    VALUES  ({?}, {?}, 'X')",
+                             $user->id(), $globals->asso('id'));
+                pl_redirect("member/" . $user->login());
             }
         } else {
             if (isvalid_email($email)) {
@@ -1331,7 +1318,7 @@ class XnetGrpModule extends PLModule
                 $post = null;/*
                 if ($globals->asso('forum')) {
                     require_once 'banana/forum.inc.php';
-                    $banana = new ForumsBanana(S::v('forlife'));
+                    $banana = new ForumsBanana(S::user());
                     $post = $banana->post($globals->asso('forum'), null,
                                           $art['titre'], MiniWiki::wikiToText($fulltext, false, 0, 80));
                 }*/
index ff2e34f..67fdaa9 100644 (file)
@@ -45,7 +45,7 @@
         Administrer
       </th>
     </tr>
-    {if !$smarty.request.login && !$mr.forlife}
+    {if !$smarty.request.login && !$mr.hruid}
     <tr class="pair">
       <td class="center">
         Il est possible d'entrer ici n'importe quelle adresse email&nbsp;: redirection, melix, ou alias.
@@ -54,7 +54,7 @@
     {/if}
     <tr>
       <td class="center">
-        <input type="text" name="login" size="40" maxlength="255" value="{$smarty.request.login|default:$mr.forlife}" />
+        <input type="text" name="login" size="40" maxlength="255" value="{$smarty.request.login|default:$mr.hruid}" />
       </td>
     </tr>
     <tr>
@@ -257,7 +257,7 @@ function ban_read()
     {else}
     <tr class="center">
       <td>
-        <a href="profile/{$mr.forlife}" class="popup2">[Voir fiche]</a>
+        <a href="profile/{$mr.hruid}" class="popup2">[Voir fiche]</a>
       </td>
       <td>
         <input onclick="doEditUser(); return true;" type="submit" name="u_edit" value="UPDATE" />
@@ -375,7 +375,7 @@ Pour ceci changer ses permissions en 'disabled'.
 </form>
 
 {javascript name="ajax"}
-{test_email forlife=$mr.forlife}
+{test_email forlife=$user->forlifeEmail()}
 
 <form id="fwds" method="post" action="admin/user#fwds">
   {xsrf_token_field}
@@ -409,7 +409,7 @@ Pour ceci changer ses permissions en 'disabled'.
       </td>
       <td>
         {if $mail->broken}<span style="color: #f00">{/if}
-        {if $mail->email == 'googleapps'}<a href="admin/googleapps/user/{$mr.forlife}">{/if}
+        {if $mail->email == 'googleapps'}<a href="admin/googleapps/user/{$mr.hruid}">{/if}
         {$mail->display_email}
         {if $mail->email == 'googleapps'}</a>{/if}
         {if $mail->broken}<em> (en panne)</em></span>{/if}
index 67096d0..9b509dc 100644 (file)
@@ -33,7 +33,7 @@
     {if $smarty.session.suid}
     <div id="suid">
       <a href="exit">
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()})
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()})
       </a>
     </div>
     {/if}
index d7f74cc..0dc1684 100644 (file)
@@ -34,7 +34,7 @@
     {if $smarty.session.suid}
     <div id="suid">
       <a href="exit">
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()})
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()})
       </a>
     </div>
     {/if}
index 4c98b24..42a6b00 100644 (file)
@@ -34,7 +34,7 @@
     {if $smarty.session.suid}
     <div id="suid">
       <a href="exit">
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()})
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()})
       </a>
     </div>
     {/if}
index fb21d00..f77d251 100644 (file)
@@ -33,7 +33,7 @@
     {if $smarty.session.suid}
     <div id="suid">
       <a href="exit">
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()})
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()})
       </a>
     </div>
     {/if}
index 0bf94c1..d1de067 100644 (file)
@@ -34,7 +34,7 @@
     {if $smarty.session.suid}
     <div id="suid">
       <a href="exit">
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()})
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()})
       </a>
     </div>
     {/if}
index aae8664..21ba9e1 100644 (file)
@@ -34,7 +34,7 @@
     {if $smarty.session.suid}
     <div id="suid">
       <a href="exit">
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()})
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()})
       </a>
     </div>
     {/if}
index bee60d7..730fbee 100644 (file)
@@ -34,7 +34,7 @@
     {if $smarty.session.suid}
     <div id="suid">
       <a href="exit">
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()})
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()})
       </a>
     </div>
     {/if}
index 41a54c4..035c0c5 100644 (file)
@@ -34,7 +34,7 @@
     {if $smarty.session.suid}
     <div id="suid">
       <a href="exit">
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()})
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()})
       </a>
     </div>
     {/if}
index dce826d..5c9914b 100644 (file)
@@ -33,7 +33,7 @@
     <table id="suid" cellpadding="0" cellspacing="0">
       <tr>
         <td>
-          {$smarty.session.suid} ({$smarty.session.forlife})
+          {$smarty.session.suid} ({$smarty.session.hruid})
           [<a href="exit">exit</a>]
         </td>
       </tr>
index b634ca7..9c424f1 100644 (file)
@@ -34,7 +34,7 @@
     {if $smarty.session.suid} 
     <div id="suid"> 
       <a href="exit"> 
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()}) 
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()}) 
       </a> 
     </div> 
     {/if} 
index 74049ab..8988cfd 100644 (file)
@@ -33,7 +33,7 @@
     {if $smarty.session.suid}
     <div id="suid">
       <a href="exit">
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()})
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()})
       </a>
     </div>
     {/if}
index 4696bc4..33c893b 100644 (file)
@@ -33,7 +33,7 @@
     <table id="suid" cellpadding="0" cellspacing="0">
       <tr>
         <td>
-          {$smarty.session.suid} ({$smarty.session.forlife})
+          {$smarty.session.suid} ({$smarty.session.hruid})
           [<a href="exit">exit</a>]
         </td>
       </tr>
index 9144454..8a0e715 100644 (file)
@@ -34,7 +34,7 @@
     {if $smarty.session.suid}
     <div id="suid">
       <a href="exit">
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()})
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()})
       </a>
     </div>
     {/if}
index cee1f4e..0a11efd 100644 (file)
@@ -34,7 +34,7 @@
     {if $smarty.session.suid}
     <div id="suid">
       <a href="exit">
-        Quitter le SU sur {$smarty.session.forlife} ({$smarty.session.perms->flags()})
+        Quitter le SU sur {$smarty.session.hruid} ({$smarty.session.perms->flags()})
       </a>
     </div>
     {/if}
diff --git a/upgrade/hruid/03_hruid.sql b/upgrade/hruid/03_hruid.sql
new file mode 100644 (file)
index 0000000..49b0f78
--- /dev/null
@@ -0,0 +1,13 @@
+# Creates a new column for the hruid field, and adds an index on it.
+ALTER TABLE auth_user_md5
+    ADD COLUMN hruid VARCHAR(255) DEFAULT NULL AFTER user_id,
+    ADD UNIQUE INDEX hruid(hruid);
+
+
+# Pre-fills the hruid field with the current forlife.
+   UPDATE  auth_user_md5 AS u
+LEFT JOIN  aliases AS a ON (a.id = u.user_id AND a.type = 'a_vie')
+      SET  u.hruid = a.alias
+    WHERE  a.alias IS NOT NULL AND u.hruid IS NULL;
+
+# vim:set syntax=mysql:
diff --git a/upgrade/hruid/connect.db.inc.php b/upgrade/hruid/connect.db.inc.php
new file mode 100644 (file)
index 0000000..2e66895
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+/***************************************************************************
+ *  Copyright (C) 2003-2008 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                *
+ ***************************************************************************/
+
+ini_set('include_path', dirname(__FILE__).'/../../include:' . dirname(__FILE__).'/../../classes:/usr/share/php');
+
+require_once 'xorg.inc.php';
+require_once 'xdb.php';
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
diff --git a/upgrade/hruid/hruid.update.php b/upgrade/hruid/hruid.update.php
new file mode 100755 (executable)
index 0000000..8edb887
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/php5
+<?php
+
+require_once 'connect.db.inc.php';
+require_once 'xorg.misc.inc.php';
+
+// Fetches the list of unregistered users.
+$users = XDB::iterRow(
+    "SELECT  user_id, prenom, nom, promo
+       FROM  auth_user_md5
+      WHERE  hruid IS NULL");
+
+// Creates missing human readable uids.
+while (list($user_id, $prenom, $nom, $promo) = $users->next()) {
+    $forlife = make_forlife($prenom, $nom, $promo);
+    if (!XDB::execute("UPDATE auth_user_md5 SET hruid = {?} WHERE user_id = {?}", $forlife, $user_id)) {
+        echo "WARNING: Duplicate forlife for user $user_id and forlife '$forlife'. Please check manually the entry.\n";
+    }
+}
+?>
diff --git a/upgrade/hruid/update.sh b/upgrade/hruid/update.sh
new file mode 100755 (executable)
index 0000000..0e99620
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+. ../inc/pervasive.sh
+
+mailman_stop
+mailman_templates
+mailman_start
+
+
+###########################################################
+for sql in *.sql
+do
+    echo -n $sql
+    $MYSQL x4dat < $sql &>/dev/null || echo -n " ERROR"
+    echo .
+done
+
+###########################################################
+echo "Creating forlife ids for unregistered user (takes a while)."
+
+./hruid.update.php
+
+###########################################################
+