[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/auth/ -> pgsql.class.php (source)

   1  <?php
   2  /**
   3   * PgSQL authentication backend
   4   *
   5   * This class inherits much functionality from the MySQL class
   6   * and just reimplements the Postgres specific parts.
   7   *
   8   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   9   * @author     Andreas Gohr <andi@splitbrain.org>
  10   * @author     Chris Smith <chris@jalakai.co.uk>
  11   * @author     Matthias Grimm <matthias.grimmm@sourceforge.net>
  12  */
  13  
  14  define('DOKU_AUTH', dirname(__FILE__));
  15  require_once (DOKU_AUTH.'/mysql.class.php');
  16  
  17  class auth_pgsql extends auth_mysql {
  18  
  19      /**
  20       * Constructor
  21       *
  22       * checks if the pgsql interface is available, otherwise it will
  23       * set the variable $success of the basis class to false
  24       *
  25       * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
  26       * @author Andreas Gohr <andi@splitbrain.org>
  27       */
  28      function auth_pgsql() {
  29        global $conf;
  30        $this->cnf          = $conf['auth']['pgsql'];
  31        if(!$this->cnf['port']) $this->cnf['port'] = 5432;
  32  
  33        if (method_exists($this, 'auth_basic'))
  34          parent::auth_basic();
  35  
  36        if(!function_exists('pg_connect')) {
  37          if ($this->cnf['debug'])
  38            msg("PgSQL err: PHP Postgres extension not found.",-1);
  39          $this->success = false;
  40          return;
  41        }
  42  
  43        $this->defaultgroup = $conf['defaultgroup'];
  44  
  45        // set capabilities based upon config strings set
  46        if (empty($this->cnf['user']) ||
  47            empty($this->cnf['password']) || empty($this->cnf['database'])){
  48          if ($this->cnf['debug'])
  49            msg("PgSQL err: insufficient configuration.",-1,__LINE__,__FILE__);
  50          $this->success = false;
  51          return;
  52        }
  53  
  54        $this->cando['addUser']      = $this->_chkcnf(array('getUserInfo',
  55                                                            'getGroups',
  56                                                            'addUser',
  57                                                            'getUserID',
  58                                                            'getGroupID',
  59                                                            'addGroup',
  60                                                            'addUserGroup'));
  61        $this->cando['delUser']      = $this->_chkcnf(array('getUserID',
  62                                                            'delUser',
  63                                                            'delUserRefs'));
  64        $this->cando['modLogin']     = $this->_chkcnf(array('getUserID',
  65                                                            'updateUser',
  66                                                            'UpdateTarget'));
  67        $this->cando['modPass']      = $this->cando['modLogin'];
  68        $this->cando['modName']      = $this->cando['modLogin'];
  69        $this->cando['modMail']      = $this->cando['modLogin'];
  70        $this->cando['modGroups']    = $this->_chkcnf(array('getUserID',
  71                                                            'getGroups',
  72                                                            'getGroupID',
  73                                                            'addGroup',
  74                                                            'addUserGroup',
  75                                                            'delGroup',
  76                                                            'getGroupID',
  77                                                            'delUserGroup'));
  78        /* getGroups is not yet supported
  79        $this->cando['getGroups']    = $this->_chkcnf(array('getGroups',
  80                                                            'getGroupID')); */
  81        $this->cando['getUsers']     = $this->_chkcnf(array('getUsers',
  82                                                            'getUserInfo',
  83                                                            'getGroups'));
  84        $this->cando['getUserCount'] = $this->_chkcnf(array('getUsers'));
  85      }
  86  
  87      /**
  88       * Check if the given config strings are set
  89       *
  90       * @author  Matthias Grimm <matthiasgrimm@users.sourceforge.net>
  91       * @return  bool
  92       */
  93      function _chkcnf($keys, $wop=false){
  94        foreach ($keys as $key){
  95          if (empty($this->cnf[$key])) return false;
  96        }
  97        return true;
  98      }
  99  
 100      // @inherit function checkPass($user,$pass)
 101      // @inherit function getUserData($user)
 102      // @inherit function createUser($user,$pwd,$name,$mail,$grps=null)
 103      // @inherit function modifyUser($user, $changes)
 104      // @inherit function deleteUsers($users)
 105  
 106  
 107      /**
 108       * [public function]
 109       *
 110       * Counts users which meet certain $filter criteria.
 111       *
 112       * @param  array  $filter  filter criteria in item/pattern pairs
 113       * @return count of found users.
 114       *
 115       * @author  Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 116       */
 117      function getUserCount($filter=array()) {
 118        $rc = 0;
 119  
 120        if($this->_openDB()) {
 121          $sql = $this->_createSQLFilter($this->cnf['getUsers'], $filter);
 122  
 123          // no equivalent of SQL_CALC_FOUND_ROWS in pgsql?
 124          if (($result = $this->_queryDB($sql))){
 125            $rc = count($result);
 126          }
 127          $this->_closeDB();
 128        }
 129        return $rc;
 130      }
 131  
 132      /**
 133       * Bulk retrieval of user data. [public function]
 134       *
 135       * @param   first     index of first user to be returned
 136       * @param   limit     max number of users to be returned
 137       * @param   filter    array of field/pattern pairs
 138       * @return  array of userinfo (refer getUserData for internal userinfo details)
 139       *
 140       * @author  Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 141       */
 142      function retrieveUsers($first=0,$limit=10,$filter=array()) {
 143        $out   = array();
 144  
 145        if($this->_openDB()) {
 146          $this->_lockTables("READ");
 147          $sql  = $this->_createSQLFilter($this->cnf['getUsers'], $filter);
 148          $sql .= " ".$this->cnf['SortOrder']." LIMIT $limit OFFSET $first";
 149          $result = $this->_queryDB($sql);
 150  
 151          foreach ($result as $user)
 152            if (($info = $this->_getUserInfo($user['user'])))
 153              $out[$user['user']] = $info;
 154  
 155          $this->_unlockTables();
 156          $this->_closeDB();
 157        }
 158        return $out;
 159      }
 160  
 161      // @inherit function joinGroup($user, $group)
 162      // @inherit function leaveGroup($user, $group) {
 163  
 164      /**
 165       * Adds a user to a group.
 166       *
 167       * If $force is set to '1' non existing groups would be created.
 168       *
 169       * The database connection must already be established. Otherwise
 170       * this function does nothing and returns 'false'.
 171       *
 172       * @param   $user    user to add to a group
 173       * @param   $group   name of the group
 174       * @param   $force   '1' create missing groups
 175       * @return  bool     'true' on success, 'false' on error
 176       *
 177       * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 178       * @author Andreas Gohr   <andi@splitbrain.org>
 179       */
 180      function _addUserToGroup($user, $group, $force=0) {
 181        $newgroup = 0;
 182  
 183        if (($this->dbcon) && ($user)) {
 184          $gid = $this->_getGroupID($group);
 185          if (!$gid) {
 186            if ($force) {  // create missing groups
 187              $sql = str_replace('%{group}',addslashes($group),$this->cnf['addGroup']);
 188              $this->_modifyDB($sql);
 189              //group should now exists try again to fetch it
 190              $gid = $this->_getGroupID($group);
 191              $newgroup = 1;  // group newly created
 192            }
 193          }
 194          if (!$gid) return false; // group didn't exist and can't be created
 195  
 196          $sql = $this->cnf['addUserGroup'];
 197          if(strpos($sql,'%{uid}') !== false){
 198              $uid = $this->_getUserID($user);
 199              $sql = str_replace('%{uid}', $sql);
 200          }
 201          $sql = str_replace('%{user}', addslashes($user),$sql);
 202          $sql = str_replace('%{gid}',  addslashes($gid),$sql);
 203          $sql = str_replace('%{group}',addslashes($group),$sql);
 204          if ($this->_modifyDB($sql) !== false) return true;
 205  
 206          if ($newgroup) { // remove previously created group on error
 207            $sql = str_replace('%{gid}',  addslashes($gid),$this->cnf['delGroup']);
 208            $sql = str_replace('%{group}',addslashes($group),$sql);
 209            $this->_modifyDB($sql);
 210          }
 211        }
 212        return false;
 213      }
 214  
 215      // @inherit function _delUserFromGroup($user $group)
 216      // @inherit function _getGroups($user)
 217      // @inherit function _getUserID($user)
 218  
 219      /**
 220       * Adds a new User to the database.
 221       *
 222       * The database connection must already be established
 223       * for this function to work. Otherwise it will return
 224       * 'false'.
 225       *
 226       * @param  $user  login of the user
 227       * @param  $pwd   encrypted password
 228       * @param  $name  full name of the user
 229       * @param  $mail  email address
 230       * @param  $grps  array of groups the user should become member of
 231       * @return bool
 232       *
 233       * @author  Andreas Gohr <andi@splitbrain.org>
 234       * @author  Chris Smith <chris@jalakai.co.uk>
 235       * @author  Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 236       */
 237      function _addUser($user,$pwd,$name,$mail,$grps){
 238        if($this->dbcon && is_array($grps)) {
 239          $sql = str_replace('%{user}', addslashes($user),$this->cnf['addUser']);
 240          $sql = str_replace('%{pass}', addslashes($pwd),$sql);
 241          $sql = str_replace('%{name}', addslashes($name),$sql);
 242          $sql = str_replace('%{email}',addslashes($mail),$sql);
 243          if($this->_modifyDB($sql)){
 244            $uid = $this->_getUserID($user);
 245          }else{
 246            return false;
 247          }
 248  
 249          if ($uid) {
 250            foreach($grps as $group) {
 251              $gid = $this->_addUserToGroup($user, $group, 1);
 252              if ($gid === false) break;
 253            }
 254  
 255            if ($gid) return true;
 256            else {
 257              /* remove the new user and all group relations if a group can't
 258               * be assigned. Newly created groups will remain in the database
 259               * and won't be removed. This might create orphaned groups but
 260               * is not a big issue so we ignore this problem here.
 261               */
 262              $this->_delUser($user);
 263              if ($this->cnf['debug'])
 264                msg("PgSQL err: Adding user '$user' to group '$group' failed.",-1,__LINE__,__FILE__);
 265            }
 266          }
 267        }
 268        return false;
 269      }
 270  
 271      // @inherit function _delUser($user)
 272      // @inherit function _getUserInfo($user)
 273      // @inherit function _updateUserInfo($changes, $uid)
 274      // @inherit function _getGroupID($group)
 275  
 276      /**
 277       * Opens a connection to a database and saves the handle for further
 278       * usage in the object. The successful call to this functions is
 279       * essential for most functions in this object.
 280       *
 281       * @return bool
 282       *
 283       * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 284       */
 285      function _openDB() {
 286        if (!$this->dbcon) {
 287          $dsn  = $this->cnf['server'] ? 'host='.$this->cnf['server'] : '';
 288          $dsn .= ' port='.$this->cnf['port'];
 289          $dsn .= ' dbname='.$this->cnf['database'];
 290          $dsn .= ' user='.$this->cnf['user'];
 291          $dsn .= ' password='.$this->cnf['password'];
 292  
 293          $con = @pg_connect($dsn);
 294          if ($con) {
 295              $this->dbcon = $con;
 296              return true;   // connection and database successfully opened
 297          } else if ($this->cnf['debug']){
 298              msg ("PgSQL err: Connection to {$this->cnf['user']}@{$this->cnf['server']} not possible.",
 299                    -1,__LINE__,__FILE__);
 300          }
 301          return false;  // connection failed
 302        }
 303        return true;  // connection already open
 304      }
 305  
 306      /**
 307       * Closes a database connection.
 308       *
 309       * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 310       */
 311      function _closeDB() {
 312        if ($this->dbcon) {
 313          pg_close ($this->dbcon);
 314          $this->dbcon = 0;
 315        }
 316      }
 317  
 318      /**
 319       * Sends a SQL query to the database and transforms the result into
 320       * an associative array.
 321       *
 322       * This function is only able to handle queries that returns a
 323       * table such as SELECT.
 324       *
 325       * @param $query  SQL string that contains the query
 326       * @return array with the result table
 327       *
 328       * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 329       */
 330      function _queryDB($query) {
 331        if ($this->dbcon) {
 332          $result = @pg_query($this->dbcon,$query);
 333          if ($result) {
 334            while (($t = pg_fetch_assoc($result)) !== false)
 335              $resultarray[]=$t;
 336            pg_free_result ($result);
 337            return $resultarray;
 338          }elseif ($this->cnf['debug'])
 339            msg('PgSQL err: '.pg_last_error($this->dbcon),-1,__LINE__,__FILE__);
 340        }
 341        return false;
 342      }
 343  
 344      /**
 345       * Executes an update or insert query. This differs from the
 346       * MySQL one because it does NOT return the last insertID
 347       *
 348       * @author Andreas Gohr
 349       */
 350      function _modifyDB($query) {
 351        if ($this->dbcon) {
 352          $result = @pg_query($this->dbcon,$query);
 353          if ($result) {
 354            pg_free_result ($result);
 355            return true;
 356          }
 357          if ($this->cnf['debug']){
 358            msg('PgSQL err: '.pg_last_error($this->dbcon),-1,__LINE__,__FILE__);
 359          }
 360        }
 361        return false;
 362      }
 363  
 364      /**
 365       * Start a transaction
 366       *
 367       * @param $mode  could be 'READ' or 'WRITE'
 368       * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 369       */
 370      function _lockTables($mode) {
 371        if ($this->dbcon) {
 372          $this->_modifyDB('BEGIN');
 373          return true;
 374        }
 375        return false;
 376      }
 377  
 378      /**
 379       * Commit a transaction
 380       *
 381       * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
 382       */
 383      function _unlockTables() {
 384        if ($this->dbcon) {
 385          $this->_modifyDB('COMMIT');
 386          return true;
 387        }
 388        return false;
 389      }
 390  
 391      // @inherit function _createSQLFilter($sql, $filter)
 392  
 393  
 394      /**
 395       * Escape a string for insertion into the database
 396       *
 397       * @author Andreas Gohr <andi@splitbrain.org>
 398       * @param  string  $string The string to escape
 399       * @param  boolean $like   Escape wildcard chars as well?
 400       */
 401      function _escape($string,$like=false){
 402        $string = pg_escape_string($string);
 403        if($like){
 404          $string = addcslashes($string,'%_');
 405        }
 406        return $string;
 407      }
 408  
 409  }
 410  
 411  //Setup VIM: ex: et ts=2 enc=utf-8 :


Generated: Fri Nov 21 01:30:02 2008 Cross-referenced by PHPXref 0.7