Updates plat/al implementation of PlUser for the newest plat/al-core repository format.
authorVincent Zanotti <vincent.zanotti@polytechnique.org>
Sat, 19 Jul 2008 13:27:30 +0000 (15:27 +0200)
committerVincent Zanotti <vincent.zanotti@polytechnique.org>
Sun, 20 Jul 2008 01:50:14 +0000 (03:50 +0200)
Signed-off-by: Vincent Zanotti <vincent.zanotti@polytechnique.org>
classes/pluser.php [deleted file]
classes/user.php
classes/xnetsession.php
classes/xorgsession.php
core

diff --git a/classes/pluser.php b/classes/pluser.php
deleted file mode 100644 (file)
index 1454884..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-<?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:
-?>
index 2d41c43..b99b2dd 100644 (file)
 
 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.
+    // 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, hruid FROM auth_user_md5 WHERE user_id = {?}", $login);
+            $res = XDB::query("SELECT user_id FROM auth_user_md5 WHERE user_id = {?}", $login);
             if ($res->numRows()) {
-                return $res->fetchOneRow();
+                return $res->fetchOneCell();
             }
 
             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);
+        $res = XDB::query("SELECT user_id FROM auth_user_md5 WHERE hruid = {?}", $login);
         if ($res->numRows()) {
-            return $res->fetchOneRow();
+            return $res->fetchOneCell();
         }
 
         // From now, $login can only by an email alias, or an email redirection.
@@ -78,21 +52,21 @@ class User extends PlUser
         // 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
+            $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->fetchOneRow();
+                return $res->fetchOneCell();
             }
 
             if (preg_match('/^(.*)\.([0-9]{4})$/u', $mbox, $matches)) {
-                $res = XDB::query("SELECT  u.user_id, u.hruid
+                $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->fetchOneRow();
+                    return $res->fetchOneCell();
                 }
             }
 
@@ -108,12 +82,12 @@ class User extends PlUser
             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
+                $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->fetchOneRow();
+                    return $res->fetchOneCell();
                 }
             }
 
@@ -121,29 +95,89 @@ class User extends PlUser
         }
 
         // Otherwise, we do suppose $login is an email redirection.
-        $res = XDB::query("SELECT  u.user_id, u.hruid
+        $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->fetchOneRow();
+            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) {
+            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
+                             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);
+    }
+
     // 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");
+            Platal::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));
+            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 73dd844..155b765 100644 (file)
@@ -103,14 +103,16 @@ 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']);
index 49481d6..49d3a6a 100644 (file)
@@ -184,17 +184,20 @@ class XorgSession extends PlSession
             S::set('auth', AUTH_COOKIE);
         }
         unset($_SESSION['log']);
-        $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']);
diff --git a/core b/core
index c12e921..5421ab0 160000 (submodule)
--- a/core
+++ b/core
@@ -1 +1 @@
-Subproject commit c12e921105fecafcf2be1fce956d54dc7a148bfb
+Subproject commit 5421ab0971fa76a0ae98afbeffe899318c07780e