1f4476bd9SJan Schumann<?php 2f4476bd9SJan Schumann 3f4476bd9SJan Schumann/** 4f4476bd9SJan Schumann * Plaintext authentication backend 5f4476bd9SJan Schumann * 6f4476bd9SJan Schumann * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7f4476bd9SJan Schumann * @author Andreas Gohr <andi@splitbrain.org> 8f4476bd9SJan Schumann * @author Chris Smith <chris@jalakai.co.uk> 9f4476bd9SJan Schumann * @author Jan Schumann <js@schumann-it.com> 10f4476bd9SJan Schumann */ 1193a7873eSAndreas Gohrclass auth_plugin_authplain extends DokuWiki_Auth_Plugin { 12311f4603SAndreas Gohr /** @var array user cache */ 13311f4603SAndreas Gohr protected $users = null; 14311f4603SAndreas Gohr 15311f4603SAndreas Gohr /** @var array filter pattern */ 16311f4603SAndreas Gohr protected $_pattern = array(); 17f4476bd9SJan Schumann 186c8c1f46SChristopher Smith /** @var bool safe version of preg_split */ 196c8c1f46SChristopher Smith protected $_pregsplit_safe = false; 206c8c1f46SChristopher Smith 21f4476bd9SJan Schumann /** 22f4476bd9SJan Schumann * Constructor 23f4476bd9SJan Schumann * 24f4476bd9SJan Schumann * Carry out sanity checks to ensure the object is 25f4476bd9SJan Schumann * able to operate. Set capabilities. 26f4476bd9SJan Schumann * 27f4476bd9SJan Schumann * @author Christopher Smith <chris@jalakai.co.uk> 28f4476bd9SJan Schumann */ 29311f4603SAndreas Gohr public function __construct() { 30454d868bSAndreas Gohr parent::__construct(); 31f4476bd9SJan Schumann global $config_cascade; 32f4476bd9SJan Schumann 33f4476bd9SJan Schumann if(!@is_readable($config_cascade['plainauth.users']['default'])) { 34f4476bd9SJan Schumann $this->success = false; 35f4476bd9SJan Schumann } else { 36f4476bd9SJan Schumann if(@is_writable($config_cascade['plainauth.users']['default'])) { 37f4476bd9SJan Schumann $this->cando['addUser'] = true; 38f4476bd9SJan Schumann $this->cando['delUser'] = true; 39f4476bd9SJan Schumann $this->cando['modLogin'] = true; 40f4476bd9SJan Schumann $this->cando['modPass'] = true; 41f4476bd9SJan Schumann $this->cando['modName'] = true; 42f4476bd9SJan Schumann $this->cando['modMail'] = true; 43f4476bd9SJan Schumann $this->cando['modGroups'] = true; 44f4476bd9SJan Schumann } 45f4476bd9SJan Schumann $this->cando['getUsers'] = true; 46f4476bd9SJan Schumann $this->cando['getUserCount'] = true; 47f4476bd9SJan Schumann } 486c8c1f46SChristopher Smith 496c8c1f46SChristopher Smith $this->_pregsplit_safe = version_compare(PCRE_VERSION,'6.7','>='); 50f4476bd9SJan Schumann } 51f4476bd9SJan Schumann 52f4476bd9SJan Schumann /** 53311f4603SAndreas Gohr * Check user+password 54f4476bd9SJan Schumann * 55f4476bd9SJan Schumann * Checks if the given user exists and the given 56f4476bd9SJan Schumann * plaintext password is correct 57f4476bd9SJan Schumann * 58f4476bd9SJan Schumann * @author Andreas Gohr <andi@splitbrain.org> 59311f4603SAndreas Gohr * @param string $user 60311f4603SAndreas Gohr * @param string $pass 61f4476bd9SJan Schumann * @return bool 62f4476bd9SJan Schumann */ 63311f4603SAndreas Gohr public function checkPass($user, $pass) { 64f4476bd9SJan Schumann $userinfo = $this->getUserData($user); 65f4476bd9SJan Schumann if($userinfo === false) return false; 66f4476bd9SJan Schumann 67f4476bd9SJan Schumann return auth_verifyPassword($pass, $this->users[$user]['pass']); 68f4476bd9SJan Schumann } 69f4476bd9SJan Schumann 70f4476bd9SJan Schumann /** 71f4476bd9SJan Schumann * Return user info 72f4476bd9SJan Schumann * 73f4476bd9SJan Schumann * Returns info about the given user needs to contain 74f4476bd9SJan Schumann * at least these fields: 75f4476bd9SJan Schumann * 76f4476bd9SJan Schumann * name string full name of the user 77f4476bd9SJan Schumann * mail string email addres of the user 78f4476bd9SJan Schumann * grps array list of groups the user is in 79f4476bd9SJan Schumann * 80f4476bd9SJan Schumann * @author Andreas Gohr <andi@splitbrain.org> 81311f4603SAndreas Gohr * @param string $user 822046a654SChristopher Smith * @param bool $requireGroups (optional) ignored by this plugin, grps info always supplied 83253d4b48SGerrit Uitslag * @return array|false 84f4476bd9SJan Schumann */ 852046a654SChristopher Smith public function getUserData($user, $requireGroups=true) { 86f4476bd9SJan Schumann if($this->users === null) $this->_loadUserData(); 87f4476bd9SJan Schumann return isset($this->users[$user]) ? $this->users[$user] : false; 88f4476bd9SJan Schumann } 89f4476bd9SJan Schumann 90f4476bd9SJan Schumann /** 91f95ecbbfSAngus Gratton * Creates a string suitable for saving as a line 92f95ecbbfSAngus Gratton * in the file database 93f95ecbbfSAngus Gratton * (delimiters escaped, etc.) 94f95ecbbfSAngus Gratton * 95f95ecbbfSAngus Gratton * @param string $user 96f95ecbbfSAngus Gratton * @param string $pass 97f95ecbbfSAngus Gratton * @param string $name 98f95ecbbfSAngus Gratton * @param string $mail 99f95ecbbfSAngus Gratton * @param array $grps list of groups the user is in 100f95ecbbfSAngus Gratton * @return string 101f95ecbbfSAngus Gratton */ 102f95ecbbfSAngus Gratton protected function _createUserLine($user, $pass, $name, $mail, $grps) { 103f95ecbbfSAngus Gratton $groups = join(',', $grps); 104f95ecbbfSAngus Gratton $userline = array($user, $pass, $name, $mail, $groups); 105f95ecbbfSAngus Gratton $userline = str_replace('\\', '\\\\', $userline); // escape \ as \\ 106f95ecbbfSAngus Gratton $userline = str_replace(':', '\\:', $userline); // escape : as \: 107f95ecbbfSAngus Gratton $userline = join(':', $userline)."\n"; 108f95ecbbfSAngus Gratton return $userline; 109f95ecbbfSAngus Gratton } 110f95ecbbfSAngus Gratton 111f95ecbbfSAngus Gratton /** 112f4476bd9SJan Schumann * Create a new User 113f4476bd9SJan Schumann * 114f4476bd9SJan Schumann * Returns false if the user already exists, null when an error 115f4476bd9SJan Schumann * occurred and true if everything went well. 116f4476bd9SJan Schumann * 117f4476bd9SJan Schumann * The new user will be added to the default group by this 118f4476bd9SJan Schumann * function if grps are not specified (default behaviour). 119f4476bd9SJan Schumann * 120f4476bd9SJan Schumann * @author Andreas Gohr <andi@splitbrain.org> 121f4476bd9SJan Schumann * @author Chris Smith <chris@jalakai.co.uk> 122311f4603SAndreas Gohr * 123311f4603SAndreas Gohr * @param string $user 124311f4603SAndreas Gohr * @param string $pwd 125311f4603SAndreas Gohr * @param string $name 126311f4603SAndreas Gohr * @param string $mail 127311f4603SAndreas Gohr * @param array $grps 128311f4603SAndreas Gohr * @return bool|null|string 129f4476bd9SJan Schumann */ 130311f4603SAndreas Gohr public function createUser($user, $pwd, $name, $mail, $grps = null) { 131f4476bd9SJan Schumann global $conf; 132f4476bd9SJan Schumann global $config_cascade; 133f4476bd9SJan Schumann 134f4476bd9SJan Schumann // user mustn't already exist 135db9faf02SPatrick Brown if($this->getUserData($user) !== false) { 136db9faf02SPatrick Brown msg($this->getLang('userexists'), -1); 137db9faf02SPatrick Brown return false; 138db9faf02SPatrick Brown } 139f4476bd9SJan Schumann 140f4476bd9SJan Schumann $pass = auth_cryptPassword($pwd); 141f4476bd9SJan Schumann 142f4476bd9SJan Schumann // set default group if no groups specified 143f4476bd9SJan Schumann if(!is_array($grps)) $grps = array($conf['defaultgroup']); 144f4476bd9SJan Schumann 145f4476bd9SJan Schumann // prepare user line 146f95ecbbfSAngus Gratton $userline = $this->_createUserLine($user, $pass, $name, $mail, $grps); 147f4476bd9SJan Schumann 148db9faf02SPatrick Brown if(!io_saveFile($config_cascade['plainauth.users']['default'], $userline, true)) { 149db9faf02SPatrick Brown msg($this->getLang('writefail'), -1); 150db9faf02SPatrick Brown return null; 151f4476bd9SJan Schumann } 152f4476bd9SJan Schumann 153db9faf02SPatrick Brown $this->users[$user] = compact('pass', 'name', 'mail', 'grps'); 154db9faf02SPatrick Brown return $pwd; 155f4476bd9SJan Schumann } 156f4476bd9SJan Schumann 157f4476bd9SJan Schumann /** 158f4476bd9SJan Schumann * Modify user data 159f4476bd9SJan Schumann * 160f4476bd9SJan Schumann * @author Chris Smith <chris@jalakai.co.uk> 161311f4603SAndreas Gohr * @param string $user nick of the user to be changed 162311f4603SAndreas Gohr * @param array $changes array of field/value pairs to be changed (password will be clear text) 163f4476bd9SJan Schumann * @return bool 164f4476bd9SJan Schumann */ 165311f4603SAndreas Gohr public function modifyUser($user, $changes) { 166f4476bd9SJan Schumann global $ACT; 167f4476bd9SJan Schumann global $config_cascade; 168f4476bd9SJan Schumann 169f4476bd9SJan Schumann // sanity checks, user must already exist and there must be something to change 170db9faf02SPatrick Brown if(($userinfo = $this->getUserData($user)) === false) { 171db9faf02SPatrick Brown msg($this->getLang('usernotexists'), -1); 172db9faf02SPatrick Brown return false; 173db9faf02SPatrick Brown } 17442cbd322SAndreas Gohr 17542cbd322SAndreas Gohr // don't modify protected users 17642cbd322SAndreas Gohr if(!empty($userinfo['protected'])) { 17742cbd322SAndreas Gohr msg(sprintf($this->getLang('protected'), hsc($user)), -1); 17842cbd322SAndreas Gohr return false; 17942cbd322SAndreas Gohr } 18042cbd322SAndreas Gohr 181f4476bd9SJan Schumann if(!is_array($changes) || !count($changes)) return true; 182f4476bd9SJan Schumann 183f4476bd9SJan Schumann // update userinfo with new data, remembering to encrypt any password 184f4476bd9SJan Schumann $newuser = $user; 185f4476bd9SJan Schumann foreach($changes as $field => $value) { 186f4476bd9SJan Schumann if($field == 'user') { 187f4476bd9SJan Schumann $newuser = $value; 188f4476bd9SJan Schumann continue; 189f4476bd9SJan Schumann } 190f4476bd9SJan Schumann if($field == 'pass') $value = auth_cryptPassword($value); 191f4476bd9SJan Schumann $userinfo[$field] = $value; 192f4476bd9SJan Schumann } 193f4476bd9SJan Schumann 194*64159a61SAndreas Gohr $userline = $this->_createUserLine( 195*64159a61SAndreas Gohr $newuser, 196*64159a61SAndreas Gohr $userinfo['pass'], 197*64159a61SAndreas Gohr $userinfo['name'], 198*64159a61SAndreas Gohr $userinfo['mail'], 199*64159a61SAndreas Gohr $userinfo['grps'] 200*64159a61SAndreas Gohr ); 201f4476bd9SJan Schumann 202699e3c49SPatrick Brown if(!io_replaceInFile($config_cascade['plainauth.users']['default'], '/^'.$user.':/', $userline, true)) { 203699e3c49SPatrick Brown msg('There was an error modifying your user data. You may need to register again.', -1); 204699e3c49SPatrick Brown // FIXME, io functions should be fail-safe so existing data isn't lost 205311f4603SAndreas Gohr $ACT = 'register'; 206f4476bd9SJan Schumann return false; 207f4476bd9SJan Schumann } 208f4476bd9SJan Schumann 209f4476bd9SJan Schumann $this->users[$newuser] = $userinfo; 210f4476bd9SJan Schumann return true; 211f4476bd9SJan Schumann } 212f4476bd9SJan Schumann 213f4476bd9SJan Schumann /** 214f4476bd9SJan Schumann * Remove one or more users from the list of registered users 215f4476bd9SJan Schumann * 216f4476bd9SJan Schumann * @author Christopher Smith <chris@jalakai.co.uk> 217f4476bd9SJan Schumann * @param array $users array of users to be deleted 218f4476bd9SJan Schumann * @return int the number of users deleted 219f4476bd9SJan Schumann */ 220311f4603SAndreas Gohr public function deleteUsers($users) { 221f4476bd9SJan Schumann global $config_cascade; 222f4476bd9SJan Schumann 223f4476bd9SJan Schumann if(!is_array($users) || empty($users)) return 0; 224f4476bd9SJan Schumann 225f4476bd9SJan Schumann if($this->users === null) $this->_loadUserData(); 226f4476bd9SJan Schumann 227f4476bd9SJan Schumann $deleted = array(); 228f4476bd9SJan Schumann foreach($users as $user) { 22942cbd322SAndreas Gohr // don't delete protected users 23042cbd322SAndreas Gohr if(!empty($this->users[$user]['protected'])) { 23142cbd322SAndreas Gohr msg(sprintf($this->getLang('protected'), hsc($user)), -1); 23242cbd322SAndreas Gohr continue; 23342cbd322SAndreas Gohr } 234f4476bd9SJan Schumann if(isset($this->users[$user])) $deleted[] = preg_quote($user, '/'); 235f4476bd9SJan Schumann } 236f4476bd9SJan Schumann 237f4476bd9SJan Schumann if(empty($deleted)) return 0; 238f4476bd9SJan Schumann 239f4476bd9SJan Schumann $pattern = '/^('.join('|', $deleted).'):/'; 240db9faf02SPatrick Brown if (!io_deleteFromFile($config_cascade['plainauth.users']['default'], $pattern, true)) { 241db9faf02SPatrick Brown msg($this->getLang('writefail'), -1); 242db9faf02SPatrick Brown return 0; 243db9faf02SPatrick Brown } 244f4476bd9SJan Schumann 2459d24536dSAndreas Gohr // reload the user list and count the difference 246f4476bd9SJan Schumann $count = count($this->users); 247f4476bd9SJan Schumann $this->_loadUserData(); 248f4476bd9SJan Schumann $count -= count($this->users); 249f4476bd9SJan Schumann return $count; 250f4476bd9SJan Schumann } 251f4476bd9SJan Schumann 252f4476bd9SJan Schumann /** 253f4476bd9SJan Schumann * Return a count of the number of user which meet $filter criteria 254f4476bd9SJan Schumann * 255f4476bd9SJan Schumann * @author Chris Smith <chris@jalakai.co.uk> 256311f4603SAndreas Gohr * 257311f4603SAndreas Gohr * @param array $filter 258311f4603SAndreas Gohr * @return int 259f4476bd9SJan Schumann */ 260311f4603SAndreas Gohr public function getUserCount($filter = array()) { 261f4476bd9SJan Schumann 262f4476bd9SJan Schumann if($this->users === null) $this->_loadUserData(); 263f4476bd9SJan Schumann 264f4476bd9SJan Schumann if(!count($filter)) return count($this->users); 265f4476bd9SJan Schumann 266f4476bd9SJan Schumann $count = 0; 267f4476bd9SJan Schumann $this->_constructPattern($filter); 268f4476bd9SJan Schumann 269f4476bd9SJan Schumann foreach($this->users as $user => $info) { 270f4476bd9SJan Schumann $count += $this->_filter($user, $info); 271f4476bd9SJan Schumann } 272f4476bd9SJan Schumann 273f4476bd9SJan Schumann return $count; 274f4476bd9SJan Schumann } 275f4476bd9SJan Schumann 276f4476bd9SJan Schumann /** 277f4476bd9SJan Schumann * Bulk retrieval of user data 278f4476bd9SJan Schumann * 279f4476bd9SJan Schumann * @author Chris Smith <chris@jalakai.co.uk> 280311f4603SAndreas Gohr * 281311f4603SAndreas Gohr * @param int $start index of first user to be returned 282311f4603SAndreas Gohr * @param int $limit max number of users to be returned 283311f4603SAndreas Gohr * @param array $filter array of field/pattern pairs 284311f4603SAndreas Gohr * @return array userinfo (refer getUserData for internal userinfo details) 285f4476bd9SJan Schumann */ 286311f4603SAndreas Gohr public function retrieveUsers($start = 0, $limit = 0, $filter = array()) { 287f4476bd9SJan Schumann 288f4476bd9SJan Schumann if($this->users === null) $this->_loadUserData(); 289f4476bd9SJan Schumann 290f4476bd9SJan Schumann ksort($this->users); 291f4476bd9SJan Schumann 292f4476bd9SJan Schumann $i = 0; 293f4476bd9SJan Schumann $count = 0; 294f4476bd9SJan Schumann $out = array(); 295f4476bd9SJan Schumann $this->_constructPattern($filter); 296f4476bd9SJan Schumann 297f4476bd9SJan Schumann foreach($this->users as $user => $info) { 298f4476bd9SJan Schumann if($this->_filter($user, $info)) { 299f4476bd9SJan Schumann if($i >= $start) { 300f4476bd9SJan Schumann $out[$user] = $info; 301f4476bd9SJan Schumann $count++; 302f4476bd9SJan Schumann if(($limit > 0) && ($count >= $limit)) break; 303f4476bd9SJan Schumann } 304f4476bd9SJan Schumann $i++; 305f4476bd9SJan Schumann } 306f4476bd9SJan Schumann } 307f4476bd9SJan Schumann 308f4476bd9SJan Schumann return $out; 309f4476bd9SJan Schumann } 310f4476bd9SJan Schumann 311f4476bd9SJan Schumann /** 312f4476bd9SJan Schumann * Only valid pageid's (no namespaces) for usernames 313311f4603SAndreas Gohr * 314311f4603SAndreas Gohr * @param string $user 315311f4603SAndreas Gohr * @return string 316f4476bd9SJan Schumann */ 317311f4603SAndreas Gohr public function cleanUser($user) { 318f4476bd9SJan Schumann global $conf; 319f4476bd9SJan Schumann return cleanID(str_replace(':', $conf['sepchar'], $user)); 320f4476bd9SJan Schumann } 321f4476bd9SJan Schumann 322f4476bd9SJan Schumann /** 323f4476bd9SJan Schumann * Only valid pageid's (no namespaces) for groupnames 324311f4603SAndreas Gohr * 325311f4603SAndreas Gohr * @param string $group 326311f4603SAndreas Gohr * @return string 327f4476bd9SJan Schumann */ 328311f4603SAndreas Gohr public function cleanGroup($group) { 329f4476bd9SJan Schumann global $conf; 330f4476bd9SJan Schumann return cleanID(str_replace(':', $conf['sepchar'], $group)); 331f4476bd9SJan Schumann } 332f4476bd9SJan Schumann 333f4476bd9SJan Schumann /** 334f4476bd9SJan Schumann * Load all user data 335f4476bd9SJan Schumann * 336f4476bd9SJan Schumann * loads the user file into a datastructure 337f4476bd9SJan Schumann * 338f4476bd9SJan Schumann * @author Andreas Gohr <andi@splitbrain.org> 339f4476bd9SJan Schumann */ 340311f4603SAndreas Gohr protected function _loadUserData() { 341f4476bd9SJan Schumann global $config_cascade; 342f4476bd9SJan Schumann 34342cbd322SAndreas Gohr $this->users = $this->_readUserFile($config_cascade['plainauth.users']['default']); 344f4476bd9SJan Schumann 34542cbd322SAndreas Gohr // support protected users 34642cbd322SAndreas Gohr if(!empty($config_cascade['plainauth.users']['protected'])) { 34742cbd322SAndreas Gohr $protected = $this->_readUserFile($config_cascade['plainauth.users']['protected']); 34842cbd322SAndreas Gohr foreach(array_keys($protected) as $key) { 34942cbd322SAndreas Gohr $protected[$key]['protected'] = true; 35042cbd322SAndreas Gohr } 35142cbd322SAndreas Gohr $this->users = array_merge($this->users, $protected); 35242cbd322SAndreas Gohr } 35342cbd322SAndreas Gohr } 354f4476bd9SJan Schumann 35542cbd322SAndreas Gohr /** 35642cbd322SAndreas Gohr * Read user data from given file 35742cbd322SAndreas Gohr * 35842cbd322SAndreas Gohr * ignores non existing files 35942cbd322SAndreas Gohr * 36042cbd322SAndreas Gohr * @param string $file the file to load data from 36142cbd322SAndreas Gohr * @return array 36242cbd322SAndreas Gohr */ 36342cbd322SAndreas Gohr protected function _readUserFile($file) { 36442cbd322SAndreas Gohr $users = array(); 36542cbd322SAndreas Gohr if(!file_exists($file)) return $users; 36642cbd322SAndreas Gohr 36742cbd322SAndreas Gohr $lines = file($file); 368f4476bd9SJan Schumann foreach($lines as $line) { 369f4476bd9SJan Schumann $line = preg_replace('/#.*$/', '', $line); //ignore comments 370f4476bd9SJan Schumann $line = trim($line); 371f4476bd9SJan Schumann if(empty($line)) continue; 372f4476bd9SJan Schumann 3736c8c1f46SChristopher Smith $row = $this->_splitUserData($line); 374f95ecbbfSAngus Gratton $row = str_replace('\\:', ':', $row); 375f95ecbbfSAngus Gratton $row = str_replace('\\\\', '\\', $row); 376f95ecbbfSAngus Gratton 377f4476bd9SJan Schumann $groups = array_values(array_filter(explode(",", $row[4]))); 378f4476bd9SJan Schumann 37942cbd322SAndreas Gohr $users[$row[0]]['pass'] = $row[1]; 38042cbd322SAndreas Gohr $users[$row[0]]['name'] = urldecode($row[2]); 38142cbd322SAndreas Gohr $users[$row[0]]['mail'] = $row[3]; 38242cbd322SAndreas Gohr $users[$row[0]]['grps'] = $groups; 383f4476bd9SJan Schumann } 38442cbd322SAndreas Gohr return $users; 385f4476bd9SJan Schumann } 386f4476bd9SJan Schumann 3876c8c1f46SChristopher Smith protected function _splitUserData($line){ 3886c8c1f46SChristopher Smith // due to a bug in PCRE 6.6, preg_split will fail with the regex we use here 3896c8c1f46SChristopher Smith // refer github issues 877 & 885 3906c8c1f46SChristopher Smith if ($this->_pregsplit_safe){ 3916c8c1f46SChristopher Smith return preg_split('/(?<![^\\\\]\\\\)\:/', $line, 5); // allow for : escaped as \: 3926c8c1f46SChristopher Smith } 3936c8c1f46SChristopher Smith 3946c8c1f46SChristopher Smith $row = array(); 3956c8c1f46SChristopher Smith $piece = ''; 3969d846ff4SChristopher Smith $len = strlen($line); 3979d846ff4SChristopher Smith for($i=0; $i<$len; $i++){ 3986c8c1f46SChristopher Smith if ($line[$i]=='\\'){ 3999d846ff4SChristopher Smith $piece .= $line[$i]; 4006c8c1f46SChristopher Smith $i++; 4019d846ff4SChristopher Smith if ($i>=$len) break; 4026c8c1f46SChristopher Smith } else if ($line[$i]==':'){ 4036c8c1f46SChristopher Smith $row[] = $piece; 4046c8c1f46SChristopher Smith $piece = ''; 4056c8c1f46SChristopher Smith continue; 4066c8c1f46SChristopher Smith } 4076c8c1f46SChristopher Smith $piece .= $line[$i]; 4086c8c1f46SChristopher Smith } 4096c8c1f46SChristopher Smith $row[] = $piece; 4106c8c1f46SChristopher Smith 4116c8c1f46SChristopher Smith return $row; 4126c8c1f46SChristopher Smith } 4136c8c1f46SChristopher Smith 414f4476bd9SJan Schumann /** 415311f4603SAndreas Gohr * return true if $user + $info match $filter criteria, false otherwise 416f4476bd9SJan Schumann * 417f4476bd9SJan Schumann * @author Chris Smith <chris@jalakai.co.uk> 418311f4603SAndreas Gohr * 419311f4603SAndreas Gohr * @param string $user User login 420311f4603SAndreas Gohr * @param array $info User's userinfo array 421311f4603SAndreas Gohr * @return bool 422f4476bd9SJan Schumann */ 423311f4603SAndreas Gohr protected function _filter($user, $info) { 424f4476bd9SJan Schumann foreach($this->_pattern as $item => $pattern) { 425f4476bd9SJan Schumann if($item == 'user') { 426311f4603SAndreas Gohr if(!preg_match($pattern, $user)) return false; 427f4476bd9SJan Schumann } else if($item == 'grps') { 428311f4603SAndreas Gohr if(!count(preg_grep($pattern, $info['grps']))) return false; 429f4476bd9SJan Schumann } else { 430311f4603SAndreas Gohr if(!preg_match($pattern, $info[$item])) return false; 431f4476bd9SJan Schumann } 432f4476bd9SJan Schumann } 433311f4603SAndreas Gohr return true; 434f4476bd9SJan Schumann } 435f4476bd9SJan Schumann 436311f4603SAndreas Gohr /** 437311f4603SAndreas Gohr * construct a filter pattern 438311f4603SAndreas Gohr * 439311f4603SAndreas Gohr * @param array $filter 440311f4603SAndreas Gohr */ 441311f4603SAndreas Gohr protected function _constructPattern($filter) { 442f4476bd9SJan Schumann $this->_pattern = array(); 443f4476bd9SJan Schumann foreach($filter as $item => $pattern) { 444f4476bd9SJan Schumann $this->_pattern[$item] = '/'.str_replace('/', '\/', $pattern).'/i'; // allow regex characters 445f4476bd9SJan Schumann } 446f4476bd9SJan Schumann } 447f4476bd9SJan Schumann} 448