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