Merge commit 'origin/master' into hruid.
authorVincent Zanotti <vincent.zanotti@polytechnique.org>
Fri, 27 Jun 2008 21:16:19 +0000 (23:16 +0200)
committerVincent Zanotti <vincent.zanotti@polytechnique.org>
Fri, 27 Jun 2008 21:16:19 +0000 (23:16 +0200)
Branch hruid is now broken -- will be repaired shortly.

Conflicts:

classes/session.php
classes/xnetsession.php
include/user.func.inc.php
include/xorg/session.inc.php
modules/profile.php

Signed-off-by: Vincent Zanotti <vincent.zanotti@polytechnique.org>
26 files changed:
classes/pluser.php [new file with mode: 0644]
classes/user.php [new file with mode: 0644]
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/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/carnet.php
modules/forums.php
modules/googleapps.php
modules/lists.php
modules/marketing.php
modules/platal.php
modules/profile.php
modules/register.php
modules/xnetgrp.php
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/pluser.php b/classes/pluser.php
new file mode 100644 (file)
index 0000000..1454884
--- /dev/null
@@ -0,0 +1,156 @@
+<?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                *
+ ***************************************************************************/
+
+// PlUserNotFound is raised when a given id cannot be linked to an existing user.
+// The @p results give the list hruids (useful when several users are found).
+class UserNotFoundException extends Exception
+{
+    public function __construct($results = array())
+    {
+        $this->results = $results;
+        parent::__construct();
+    }
+}
+
+// Represents an user of the system, with a special focus on its identification
+// (hruid, forlife, and bestalias).
+// Note: each implementation of platal-core MUST create a subclass 'User' of
+// this abstract PlUser class.
+abstract class PlUser
+{
+    // User's data storage. By convention, null means the information hasn't
+    // been fetched yet, and false means the information is not available.
+
+    // Main (unique) identifiers.
+    protected $user_id = null;
+    protected $hruid = null;
+
+    // User's emails (bestalias should be preferred when sending emails).
+    protected $forlife = null;
+    protected $bestalias = null;
+
+
+    // Constructs the object from an identifier (hruid/uid/email alias/email
+    // redirection) and an optionnal array of known user properties.
+    public function __construct($login, $values = array())
+    {
+        $this->fillFromArray($values);
+        if (!isset($this->user_id) || !isset($this->hruid)) {
+            list($this->user_id, $this->hruid) = $this->getLogin($login);
+        }
+    }
+
+
+    // Properties accessors.
+    public function id() { return $this->user_id; }
+    public function login() { return $this->hruid; }
+    abstract public function bestEmail();
+    abstract public function forlifeEmail();
+
+
+    // Determines if the @p id is a valid identifier; if so, returns the user_id
+    // and the hruid. Otherwise raises UserNotFoundException.
+    abstract protected function getLogin($login);
+
+    // Fills the object from associative arrays containing our data.
+    // The use case is for arrays got directly from anoter SQL request.
+    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'];
+        }
+
+        foreach ($values as $key => $value) {
+            if (property_exists($this, $key) && !isset($this->$key)) {
+                $this->$key = $value;
+            }
+        }
+    }
+
+
+    // Returns a valid User object built from the @p id and optionnal @p values,
+    // or returns false and calls the callback if the @p id is not valid.
+    public static function get($login, $callback = false)
+    {
+        return User::getWithValues($login, array(), $callback);
+    }
+
+    public static function getWithValues($login, $values, $callback = false)
+    {
+        if (!$callback) {
+            $callback = array('User', '_default_user_callback');
+        }
+
+        try {
+            return new User($login, $values);
+        } catch (UserNotFoundException $e) {
+            return call_user_func($callback, $login, $e->results);
+        }
+    }
+
+    // Alias on get() with the silent callback.
+    public static function getSilent($login)
+    {
+        return User::getWithValues($login, array(), array('User', '_silent_user_callback'));
+    }
+
+    // Returns the forlife emails for @p members. If @p strict mode is enabled,
+    // it returns the list of validated forlife emails. If strict mode is not,
+    // it also returns unvalidated values (but still call the callback for them).
+    public static function getBulkForlifeEmails($logins, $strict = true, $callback = false)
+    {
+        if (!is_array($logins)) {
+            if (strlen(trim($logins)) == 0) {
+                return null;
+            }
+            $logins = explode(' ', $logins);
+        }
+
+        if ($logins) {
+            $list = array();
+            foreach ($logins as $i => $login) {
+                if (($user = User::get($login, $callback))) {
+                    $list[$i] = $user->forlifeEmail();
+                } else if(!$strict) {
+                    $list[$i] = $login;
+                }
+            }
+            return $list;
+        }
+        return null;
+    }
+
+    // Silent callback for the user lookup -- does nothing.
+    public static function _silent_user_callback($login, $results)
+    {
+        return;
+    }
+
+    // Default callback for user lookup -- displays an error message w.r.t. the
+    // number of matching users found.
+    abstract public static function _default_user_callback($login, $results);
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
diff --git a/classes/user.php b/classes/user.php
new file mode 100644 (file)
index 0000000..2d41c43
--- /dev/null
@@ -0,0 +1,150 @@
+<?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 properties accessors.
+    public function bestEmail()
+    {
+        if (!isset($this->bestalias)) {
+            global $globals;
+            $res = XDB::query("SELECT  CONCAT(alias, '@{$globals->mail->domain}')
+                                 FROM  aliases
+                                WHERE  FIND_IN_SET('bestalias', flags)
+                                       AND id = {?}", $this->user_id);
+            $this->bestalias = $res->numRows() ? $res->fetchOneCell() : false;
+        }
+        return $this->bestalias;
+    }
+
+    public function forlifeEmail()
+    {
+        if (!isset($this->forlife)) {
+            global $globals;
+            $res = XDB::query("SELECT  CONCAT(alias, '@{$globals->mail->domain}')
+                                 FROM  aliases
+                                WHERE  type = 'a_vie' AND id = {?}", $this->user_id);
+            $this->forlife = $res->numRows() ? $res->fetchOneCell() : false;
+        }
+        return $this->forlife;
+    }
+
+    // Implementation of the login to array(user_id, hruid) function.
+    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, hruid FROM auth_user_md5 WHERE user_id = {?}", $login);
+            if ($res->numRows()) {
+                return $res->fetchOneRow();
+            }
+
+            throw new UserNotFoundException();
+        }
+
+        // Checks whether $login is a valid hruid or not.
+        $res = XDB::query("SELECT user_id, hruid FROM auth_user_md5 WHERE hruid = {?}", $login);
+        if ($res->numRows()) {
+            return $res->fetchOneRow();
+        }
+
+        // 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, u.hruid
+                                 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->fetchOneRow();
+            }
+
+            if (preg_match('/^(.*)\.([0-9]{4})$/u', $mbox, $matches)) {
+                $res = XDB::query("SELECT  u.user_id, u.hruid
+                                     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->fetchOneRow();
+                }
+            }
+
+            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, 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->fetchOneRow();
+                }
+            }
+
+            throw new UserNotFoundException();
+        }
+
+        // Otherwise, we do suppose $login is an email redirection.
+        $res = XDB::query("SELECT  u.user_id, u.hruid
+                             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->fetchOneRow();
+        }
+
+        throw new UserNotFoundException($res->fetchColumn(1));
+    }
+
+    // Implementation of the default user callback.
+    public static function _default_user_callback($login, $results)
+    {
+        global $page;
+
+        $result_count = count($results);
+        if ($result_count == 0 || !S::has_perms()) {
+            $page->trigError("Il n'y a pas d'utilisateur avec l'identifiant : $login");
+        } else {
+            $page->trigError("Il y a $result_count utilisateurs avec cet identifiant : " . join(', ', $results));
+        }
+    }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
index 6cd9f77..25d8caf 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';
@@ -73,7 +73,7 @@ class ForumsBanana extends Banana
                             WHERE  uid={?}", S::i('uid'));
         if (!(list($nom,$mail,$sig,$disp,$maj) = $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;
@@ -131,13 +131,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);
     }
@@ -210,7 +208,7 @@ class ForumsBanana extends Banana
              WHERE  uid = {?}", S::v('uid'));
         if (!(list($nom, $mail, $sig, $disp, $maj, $xface) = $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 1a5413f..f17e02a 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();
 
         // Build user profile
         Banana::$profile['headers']['From']         = "$nom <$mail>";
index 62c2dbc..ffc5eb5 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)
     {
         global $globals;
         ModerationBanana::$client = $params['client'];
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 1f8a698..6e4edae 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,113 +96,158 @@ 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 = explode(' ', $members);
     }
+
     if ($members) {
         $list = array();
         foreach ($members as $i => $alias) {
-            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;
@@ -214,6 +259,38 @@ function get_users_forlife_list($members, $strict = false, $callback = '_default
 }
 
 // }}}
+// {{{ function get_user_forlife()
+
+function get_user_forlife($data, $callback = '_default_user_callback')
+{
+    return get_user_login($data, true, $callback);
+}
+
+// }}}
+// {{{ 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 cba4092..a26153e 100644 (file)
@@ -36,7 +36,7 @@ class VCardIterator implements PlIterator
 
     public function add_user($user)
     {
-        $this->user_list[] = get_user_forlife($user);
+        $this->user_list[] = User::get($user);
         $this->count++;
     }
 
@@ -62,7 +62,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']);
@@ -93,10 +93,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 a5a23c3..086efc9 100644 (file)
@@ -601,7 +601,7 @@ class AdminModule extends PLModule
                         // and the password was changed, updates the Google Apps password as well.
                         if ($globals->mailstorage->googleapps_domain && Env::v('newpass_clair') != "********") {
                             require_once 'googleapps.inc.php';
-                            $account = new GoogleAppsAccount($mr['user_id'], $mr['forlife']);
+                            $account = new GoogleAppsAccount(User::get($mr['forlife']));
                             if ($account->active() && $account->sync_password) {
                                 $account->set_password($pass_encrypted);
                             }
@@ -612,7 +612,7 @@ class AdminModule extends PLModule
                             $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::get($mr['forlife']));
                             $account->suspend();
                         }
                         break;
index 277e2dc..86a3fe2 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 4e5d009..57e7373 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 d7871d6..ae15cd5 100644 (file)
@@ -44,7 +44,7 @@ class GoogleAppsModule extends PLModule
         $page->addJsLink('motdepasse.js');
         $page->setTitle('Polytechnique.org - 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 dac625d..e4c5d17 100644 (file)
@@ -407,7 +407,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 74ee081..deb12be 100644 (file)
@@ -165,33 +165,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')) {
@@ -200,22 +200,21 @@ class MarketingModule extends PLModule
         }
         if (Post::has('valide') && isvalid_email_redirection($email)) {
             // 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 f50edef..fc87b7e 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);
                 }
@@ -367,7 +367,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);
                 }
index 72a6ea0..e30eb8a 100644 (file)
@@ -190,19 +190,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;
@@ -214,11 +210,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'] );
@@ -273,18 +269,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 04f4ffc..9ad8457 100644 (file)
@@ -405,11 +405,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 543c8d3..c6a79ec 100644 (file)
@@ -1201,7 +1201,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));
                 }*/
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
+
+###########################################################
+