| [ Index ] |
|
Code source de DokuWiki 2006-11-06 |
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['server']) || 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 $uid user id 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($uid, $group, $force=0) { 181 $newgroup = 0; 182 183 if (($this->dbcon) && ($uid)) { 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 195 if (!$gid) return false; // group didn't exist and can't be created 196 197 $sql = str_replace('%{uid}', addslashes($uid),$this->cnf['addUserGroup']); 198 $sql = str_replace('%{user}', addslashes($user),$sql); 199 $sql = str_replace('%{gid}', addslashes($gid),$sql); 200 $sql = str_replace('%{group}',addslashes($group),$sql); 201 if ($this->_modifyDB($sql) !== false) return true; 202 203 if ($newgroup) { // remove previously created group on error 204 $sql = str_replace('%{gid}', addslashes($gid),$this->cnf['delGroup']); 205 $sql = str_replace('%{group}',addslashes($group),$sql); 206 $this->_modifyDB($sql); 207 } 208 } 209 return false; 210 } 211 212 // @inherit function _delUserFromGroup($uid, $group) 213 // @inherit function _getGroups($user) 214 // @inherit function _getUserID($user) 215 216 /** 217 * Adds a new User to the database. 218 * 219 * The database connection must already be established 220 * for this function to work. Otherwise it will return 221 * 'false'. 222 * 223 * @param $user login of the user 224 * @param $pwd encrypted password 225 * @param $name full name of the user 226 * @param $mail email address 227 * @param $grps array of groups the user should become member of 228 * @return bool 229 * 230 * @author Andreas Gohr <andi@splitbrain.org> 231 * @author Chris Smith <chris@jalakai.co.uk> 232 * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 233 */ 234 function _addUser($user,$pwd,$name,$mail,$grps){ 235 if($this->dbcon && is_array($grps)) { 236 $sql = str_replace('%{user}', addslashes($user),$this->cnf['addUser']); 237 $sql = str_replace('%{pass}', addslashes($pwd),$sql); 238 $sql = str_replace('%{name}', addslashes($name),$sql); 239 $sql = str_replace('%{email}',addslashes($mail),$sql); 240 if($this->_modifyDB($sql)){ 241 $uid = $this->_getUserID($user); 242 }else{ 243 return false; 244 } 245 246 if ($uid) { 247 foreach($grps as $group) { 248 $gid = $this->_addUserToGroup($uid, $group, 1); 249 if ($gid === false) break; 250 } 251 252 if ($gid) return true; 253 else { 254 /* remove the new user and all group relations if a group can't 255 * be assigned. Newly created groups will remain in the database 256 * and won't be removed. This might create orphaned groups but 257 * is not a big issue so we ignore this problem here. 258 */ 259 $this->_delUser($user); 260 if ($this->cnf['debug']) 261 msg("PgSQL err: Adding user '$user' to group '$group' failed.",-1,__LINE__,__FILE__); 262 } 263 } 264 } 265 return false; 266 } 267 268 // @inherit function _delUser($user) 269 // @inherit function _getUserInfo($user) 270 // @inherit function _updateUserInfo($changes, $uid) 271 // @inherit function _getGroupID($group) 272 273 /** 274 * Opens a connection to a database and saves the handle for further 275 * usage in the object. The successful call to this functions is 276 * essential for most functions in this object. 277 * 278 * @return bool 279 * 280 * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 281 */ 282 function _openDB() { 283 if (!$this->dbcon) { 284 $dsn = 'host='.$this->cnf['server']; 285 $dsn .= ' port='.$this->cnf['port']; 286 $dsn .= ' dbname='.$this->cnf['database']; 287 $dsn .= ' user='.$this->cnf['user']; 288 $dsn .= ' password='.$this->cnf['password']; 289 290 $con = @pg_connect($dsn); 291 if ($con) { 292 $this->dbcon = $con; 293 return true; // connection and database successfully opened 294 } else if ($this->cnf['debug']){ 295 msg ("PgSQL err: Connection to {$this->cnf['user']}@{$this->cnf['server']} not possible.", 296 -1,__LINE__,__FILE__); 297 } 298 return false; // connection failed 299 } 300 return true; // connection already open 301 } 302 303 /** 304 * Closes a database connection. 305 * 306 * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 307 */ 308 function _closeDB() { 309 if ($this->dbcon) { 310 pg_close ($this->dbcon); 311 $this->dbcon = 0; 312 } 313 } 314 315 /** 316 * Sends a SQL query to the database and transforms the result into 317 * an associative array. 318 * 319 * This function is only able to handle queries that returns a 320 * table such as SELECT. 321 * 322 * @param $query SQL string that contains the query 323 * @return array with the result table 324 * 325 * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 326 */ 327 function _queryDB($query) { 328 if ($this->dbcon) { 329 $result = @pg_query($this->dbcon,$query); 330 if ($result) { 331 while (($t = pg_fetch_assoc($result)) !== false) 332 $resultarray[]=$t; 333 pg_free_result ($result); 334 return $resultarray; 335 }elseif ($this->cnf['debug']) 336 msg('PgSQL err: '.pg_last_error($this->dbcon),-1,__LINE__,__FILE__); 337 } 338 return false; 339 } 340 341 /** 342 * Executes an update or insert query. This differs from the 343 * MySQL one because it does NOT return the last insertID 344 * 345 * @author Andreas Gohr 346 */ 347 function _modifyDB($query) { 348 if ($this->dbcon) { 349 $result = @pg_query($this->dbcon,$query); 350 if ($result) { 351 pg_free_result ($result); 352 return true; 353 } 354 if ($this->cnf['debug']){ 355 msg('PgSQL err: '.pg_last_error($this->dbcon),-1,__LINE__,__FILE__); 356 } 357 } 358 return false; 359 } 360 361 /** 362 * Start a transaction 363 * 364 * @param $mode could be 'READ' or 'WRITE' 365 * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 366 */ 367 function _lockTables($mode) { 368 if ($this->dbcon) { 369 $this->_modifyDB('BEGIN'); 370 return true; 371 } 372 return false; 373 } 374 375 /** 376 * Commit a transaction 377 * 378 * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 379 */ 380 function _unlockTables() { 381 if ($this->dbcon) { 382 $this->_modifyDB('COMMIT'); 383 return true; 384 } 385 return false; 386 } 387 388 // @inherit function _createSQLFilter($sql, $filter) 389 390 391 /** 392 * Escape a string for insertion into the database 393 * 394 * @author Andreas Gohr <andi@splitbrain.org> 395 * @param string $string The string to escape 396 * @param boolean $like Escape wildcard chars as well? 397 */ 398 function _escape($string,$like=false){ 399 $string = pg_escape_string($string); 400 if($like){ 401 $string = addcslashes($string,'%_'); 402 } 403 return $string; 404 } 405 406 } 407 408 //Setup VIM: ex: et ts=2 enc=utf-8 :
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Tue Apr 3 20:47:31 2007 | par Balluche grâce à PHPXref 0.7 |