diff options
Diffstat (limited to 'lib/plugins/authplain')
-rw-r--r-- | lib/plugins/authplain/_test/conf/auth.users.php | 16 | ||||
-rw-r--r-- | lib/plugins/authplain/_test/escaping.test.php | 6 | ||||
-rw-r--r-- | lib/plugins/authplain/_test/userdata.test.php | 64 | ||||
-rw-r--r-- | lib/plugins/authplain/auth.php | 205 | ||||
-rw-r--r-- | lib/plugins/authplain/lang/da/lang.php | 3 | ||||
-rw-r--r-- | lib/plugins/authplain/lang/is/lang.php | 3 | ||||
-rw-r--r-- | lib/plugins/authplain/lang/lt/lang.php | 3 | ||||
-rw-r--r-- | lib/plugins/authplain/lang/pt/lang.php | 2 |
8 files changed, 220 insertions, 82 deletions
diff --git a/lib/plugins/authplain/_test/conf/auth.users.php b/lib/plugins/authplain/_test/conf/auth.users.php new file mode 100644 index 000000000..87f54fedb --- /dev/null +++ b/lib/plugins/authplain/_test/conf/auth.users.php @@ -0,0 +1,16 @@ +# users.auth.php +# <?php exit()?> +# Don't modify the lines above +# +# Userfile +# +# Format: +# +# login:passwordhash:Real Name:email:groups,comma,separated + + +user_1:$1$tGu7CW5z$VpsMjRIx5tbyOJaQ2SP23.:Admin:admin@example.com:user,first_group +user_2:$1$2uJ5C3ib$edo0EDEb/yLAFHme7RK851:User 2:user2@example.com:user,second_group,third_group +user_3:$1$yqnlDqgZ$Sste968uKhuxH6wIQt6/D/:User 3:user3@example.com:user,fourth_group,first_group,third_group +user_4:$1$tXjajS9s$peoGPBQep.P245H1Lfloj0:User 4:user4@example.com:user,third_group +user_5:$1$IWrqdhol$xXOmufjZ2hW1aAVp7zDP.1:User 5:user5@example.com:user,second_group,fifth_group diff --git a/lib/plugins/authplain/_test/escaping.test.php b/lib/plugins/authplain/_test/escaping.test.php index a38940e1a..be4d06b4e 100644 --- a/lib/plugins/authplain/_test/escaping.test.php +++ b/lib/plugins/authplain/_test/escaping.test.php @@ -114,14 +114,14 @@ class auth_plugin_authplainharness extends auth_plugin_authplain { * @param boolean $bool */ public function setPregsplit_safe($bool) { - $this->_pregsplit_safe = $bool; + $this->pregsplit_safe = $bool; } /** * @return bool|mixed */ public function getPregsplit_safe(){ - return $this->_pregsplit_safe; + return $this->pregsplit_safe; } /** @@ -129,6 +129,6 @@ class auth_plugin_authplainharness extends auth_plugin_authplain { * @return array */ public function splitUserData($line){ - return $this->_splitUserData($line); + return parent::splitUserData($line); } } diff --git a/lib/plugins/authplain/_test/userdata.test.php b/lib/plugins/authplain/_test/userdata.test.php new file mode 100644 index 000000000..b80b39349 --- /dev/null +++ b/lib/plugins/authplain/_test/userdata.test.php @@ -0,0 +1,64 @@ +<?php + +/** + * Class userdata_test + * + * Test group retrieval + * + * @group plugins + */ +class userdata_test extends DokuWikiTest +{ + /** @var auth_plugin_authplain */ + protected $auth; + + /** + * Load auth with test conf + * @throws Exception + */ + public function setUp() + { + parent::setUp(); + global $config_cascade; + $config_cascade['plainauth.users']['default'] = __DIR__ . '/conf/auth.users.php'; + $this->auth = new auth_plugin_authplain(); + } + + /** + * Test that all groups are retrieved in the correct order, without duplicates + */ + public function test_retrieve_groups() + { + $expected = ['user', 'first_group', 'second_group', 'third_group', 'fourth_group', 'fifth_group']; + $actual = $this->auth->retrieveGroups(); + $this->assertEquals($expected, $actual); + } + + /** + * Test with small and large limits + */ + public function test_retrieve_groups_limit() + { + $expected = ['user', 'first_group']; + $actual = $this->auth->retrieveGroups(0, 2); + $this->assertEquals($expected, $actual); + + $expected = ['user', 'first_group', 'second_group', 'third_group', 'fourth_group', 'fifth_group']; + $actual = $this->auth->retrieveGroups(0, 20); + $this->assertEquals($expected, $actual); + } + + /** + * Test with small and large offsets + */ + public function test_retrieve_groups_offset() + { + $expected = ['third_group', 'fourth_group', 'fifth_group']; + $actual = $this->auth->retrieveGroups(3,10); + $this->assertEquals($expected, $actual); + + $expected = []; + $actual = $this->auth->retrieveGroups(10,3); + $this->assertEquals($expected, $actual); + } +} diff --git a/lib/plugins/authplain/auth.php b/lib/plugins/authplain/auth.php index 7dfa43a4f..421af8847 100644 --- a/lib/plugins/authplain/auth.php +++ b/lib/plugins/authplain/auth.php @@ -1,6 +1,4 @@ <?php -// must be run within Dokuwiki -if(!defined('DOKU_INC')) die(); /** * Plaintext authentication backend @@ -10,15 +8,16 @@ if(!defined('DOKU_INC')) die(); * @author Chris Smith <chris@jalakai.co.uk> * @author Jan Schumann <js@schumann-it.com> */ -class auth_plugin_authplain extends DokuWiki_Auth_Plugin { +class auth_plugin_authplain extends DokuWiki_Auth_Plugin +{ /** @var array user cache */ protected $users = null; /** @var array filter pattern */ - protected $_pattern = array(); + protected $pattern = array(); /** @var bool safe version of preg_split */ - protected $_pregsplit_safe = false; + protected $pregsplit_safe = false; /** * Constructor @@ -28,14 +27,15 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * * @author Christopher Smith <chris@jalakai.co.uk> */ - public function __construct() { + public function __construct() + { parent::__construct(); global $config_cascade; - if(!@is_readable($config_cascade['plainauth.users']['default'])) { + if (!@is_readable($config_cascade['plainauth.users']['default'])) { $this->success = false; } else { - if(@is_writable($config_cascade['plainauth.users']['default'])) { + if (@is_writable($config_cascade['plainauth.users']['default'])) { $this->cando['addUser'] = true; $this->cando['delUser'] = true; $this->cando['modLogin'] = true; @@ -46,9 +46,10 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { } $this->cando['getUsers'] = true; $this->cando['getUserCount'] = true; + $this->cando['getGroups'] = true; } - $this->_pregsplit_safe = version_compare(PCRE_VERSION,'6.7','>='); + $this->pregsplit_safe = version_compare(PCRE_VERSION, '6.7', '>='); } /** @@ -62,9 +63,10 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * @param string $pass * @return bool */ - public function checkPass($user, $pass) { + public function checkPass($user, $pass) + { $userinfo = $this->getUserData($user); - if($userinfo === false) return false; + if ($userinfo === false) return false; return auth_verifyPassword($pass, $this->users[$user]['pass']); } @@ -84,8 +86,9 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * @param bool $requireGroups (optional) ignored by this plugin, grps info always supplied * @return array|false */ - public function getUserData($user, $requireGroups=true) { - if($this->users === null) $this->_loadUserData(); + public function getUserData($user, $requireGroups = true) + { + if ($this->users === null) $this->loadUserData(); return isset($this->users[$user]) ? $this->users[$user] : false; } @@ -101,7 +104,8 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * @param array $grps list of groups the user is in * @return string */ - protected function _createUserLine($user, $pass, $name, $mail, $grps) { + protected function createUserLine($user, $pass, $name, $mail, $grps) + { $groups = join(',', $grps); $userline = array($user, $pass, $name, $mail, $groups); $userline = str_replace('\\', '\\\\', $userline); // escape \ as \\ @@ -129,12 +133,13 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * @param array $grps * @return bool|null|string */ - public function createUser($user, $pwd, $name, $mail, $grps = null) { + public function createUser($user, $pwd, $name, $mail, $grps = null) + { global $conf; global $config_cascade; // user mustn't already exist - if($this->getUserData($user) !== false) { + if ($this->getUserData($user) !== false) { msg($this->getLang('userexists'), -1); return false; } @@ -142,12 +147,12 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { $pass = auth_cryptPassword($pwd); // set default group if no groups specified - if(!is_array($grps)) $grps = array($conf['defaultgroup']); + if (!is_array($grps)) $grps = array($conf['defaultgroup']); // prepare user line - $userline = $this->_createUserLine($user, $pass, $name, $mail, $grps); + $userline = $this->createUserLine($user, $pass, $name, $mail, $grps); - if(!io_saveFile($config_cascade['plainauth.users']['default'], $userline, true)) { + if (!io_saveFile($config_cascade['plainauth.users']['default'], $userline, true)) { msg($this->getLang('writefail'), -1); return null; } @@ -164,38 +169,45 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * @param array $changes array of field/value pairs to be changed (password will be clear text) * @return bool */ - public function modifyUser($user, $changes) { + public function modifyUser($user, $changes) + { global $ACT; global $config_cascade; // sanity checks, user must already exist and there must be something to change - if(($userinfo = $this->getUserData($user)) === false) { + if (($userinfo = $this->getUserData($user)) === false) { msg($this->getLang('usernotexists'), -1); return false; } // don't modify protected users - if(!empty($userinfo['protected'])) { + if (!empty($userinfo['protected'])) { msg(sprintf($this->getLang('protected'), hsc($user)), -1); return false; } - if(!is_array($changes) || !count($changes)) return true; + if (!is_array($changes) || !count($changes)) return true; // update userinfo with new data, remembering to encrypt any password $newuser = $user; - foreach($changes as $field => $value) { - if($field == 'user') { + foreach ($changes as $field => $value) { + if ($field == 'user') { $newuser = $value; continue; } - if($field == 'pass') $value = auth_cryptPassword($value); + if ($field == 'pass') $value = auth_cryptPassword($value); $userinfo[$field] = $value; } - $userline = $this->_createUserLine($newuser, $userinfo['pass'], $userinfo['name'], $userinfo['mail'], $userinfo['grps']); + $userline = $this->createUserLine( + $newuser, + $userinfo['pass'], + $userinfo['name'], + $userinfo['mail'], + $userinfo['grps'] + ); - if(!io_replaceInFile($config_cascade['plainauth.users']['default'], '/^'.$user.':/', $userline, true)) { + if (!io_replaceInFile($config_cascade['plainauth.users']['default'], '/^'.$user.':/', $userline, true)) { msg('There was an error modifying your user data. You may need to register again.', -1); // FIXME, io functions should be fail-safe so existing data isn't lost $ACT = 'register'; @@ -213,24 +225,25 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * @param array $users array of users to be deleted * @return int the number of users deleted */ - public function deleteUsers($users) { + public function deleteUsers($users) + { global $config_cascade; - if(!is_array($users) || empty($users)) return 0; + if (!is_array($users) || empty($users)) return 0; - if($this->users === null) $this->_loadUserData(); + if ($this->users === null) $this->loadUserData(); $deleted = array(); - foreach($users as $user) { + foreach ($users as $user) { // don't delete protected users - if(!empty($this->users[$user]['protected'])) { + if (!empty($this->users[$user]['protected'])) { msg(sprintf($this->getLang('protected'), hsc($user)), -1); continue; } - if(isset($this->users[$user])) $deleted[] = preg_quote($user, '/'); + if (isset($this->users[$user])) $deleted[] = preg_quote($user, '/'); } - if(empty($deleted)) return 0; + if (empty($deleted)) return 0; $pattern = '/^('.join('|', $deleted).'):/'; if (!io_deleteFromFile($config_cascade['plainauth.users']['default'], $pattern, true)) { @@ -240,7 +253,7 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { // reload the user list and count the difference $count = count($this->users); - $this->_loadUserData(); + $this->loadUserData(); $count -= count($this->users); return $count; } @@ -253,17 +266,18 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * @param array $filter * @return int */ - public function getUserCount($filter = array()) { + public function getUserCount($filter = array()) + { - if($this->users === null) $this->_loadUserData(); + if ($this->users === null) $this->loadUserData(); - if(!count($filter)) return count($this->users); + if (!count($filter)) return count($this->users); $count = 0; - $this->_constructPattern($filter); + $this->constructPattern($filter); - foreach($this->users as $user => $info) { - $count += $this->_filter($user, $info); + foreach ($this->users as $user => $info) { + $count += $this->filter($user, $info); } return $count; @@ -279,23 +293,24 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * @param array $filter array of field/pattern pairs * @return array userinfo (refer getUserData for internal userinfo details) */ - public function retrieveUsers($start = 0, $limit = 0, $filter = array()) { + public function retrieveUsers($start = 0, $limit = 0, $filter = array()) + { - if($this->users === null) $this->_loadUserData(); + if ($this->users === null) $this->loadUserData(); ksort($this->users); $i = 0; $count = 0; $out = array(); - $this->_constructPattern($filter); + $this->constructPattern($filter); - foreach($this->users as $user => $info) { - if($this->_filter($user, $info)) { - if($i >= $start) { + foreach ($this->users as $user => $info) { + if ($this->filter($user, $info)) { + if ($i >= $start) { $out[$user] = $info; $count++; - if(($limit > 0) && ($count >= $limit)) break; + if (($limit > 0) && ($count >= $limit)) break; } $i++; } @@ -305,12 +320,36 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { } /** + * Retrieves groups. + * Loads complete user data into memory before searching for groups. + * + * @param int $start index of first group to be returned + * @param int $limit max number of groups to be returned + * @return array + */ + public function retrieveGroups($start = 0, $limit = 0) + { + $groups = []; + + if ($this->users === null) $this->loadUserData(); + foreach($this->users as $user => $info) { + $groups = array_merge($groups, array_diff($info['grps'], $groups)); + } + + if($limit > 0) { + return array_splice($groups, $start, $limit); + } + return array_splice($groups, $start); + } + + /** * Only valid pageid's (no namespaces) for usernames * * @param string $user * @return string */ - public function cleanUser($user) { + public function cleanUser($user) + { global $conf; return cleanID(str_replace(':', $conf['sepchar'], $user)); } @@ -321,7 +360,8 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * @param string $group * @return string */ - public function cleanGroup($group) { + public function cleanGroup($group) + { global $conf; return cleanID(str_replace(':', $conf['sepchar'], $group)); } @@ -333,15 +373,16 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * * @author Andreas Gohr <andi@splitbrain.org> */ - protected function _loadUserData() { + protected function loadUserData() + { global $config_cascade; - $this->users = $this->_readUserFile($config_cascade['plainauth.users']['default']); + $this->users = $this->readUserFile($config_cascade['plainauth.users']['default']); // support protected users - if(!empty($config_cascade['plainauth.users']['protected'])) { - $protected = $this->_readUserFile($config_cascade['plainauth.users']['protected']); - foreach(array_keys($protected) as $key) { + if (!empty($config_cascade['plainauth.users']['protected'])) { + $protected = $this->readUserFile($config_cascade['plainauth.users']['protected']); + foreach (array_keys($protected) as $key) { $protected[$key]['protected'] = true; } $this->users = array_merge($this->users, $protected); @@ -356,17 +397,18 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * @param string $file the file to load data from * @return array */ - protected function _readUserFile($file) { + protected function readUserFile($file) + { $users = array(); - if(!file_exists($file)) return $users; + if (!file_exists($file)) return $users; $lines = file($file); - foreach($lines as $line) { + foreach ($lines as $line) { $line = preg_replace('/#.*$/', '', $line); //ignore comments $line = trim($line); - if(empty($line)) continue; + if (empty($line)) continue; - $row = $this->_splitUserData($line); + $row = $this->splitUserData($line); $row = str_replace('\\:', ':', $row); $row = str_replace('\\\\', '\\', $row); @@ -380,22 +422,29 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { return $users; } - protected function _splitUserData($line){ + /** + * Get the user line split into it's parts + * + * @param string $line + * @return string[] + */ + protected function splitUserData($line) + { // due to a bug in PCRE 6.6, preg_split will fail with the regex we use here // refer github issues 877 & 885 - if ($this->_pregsplit_safe){ + if ($this->pregsplit_safe) { return preg_split('/(?<![^\\\\]\\\\)\:/', $line, 5); // allow for : escaped as \: } $row = array(); $piece = ''; $len = strlen($line); - for($i=0; $i<$len; $i++){ - if ($line[$i]=='\\'){ + for ($i=0; $i<$len; $i++) { + if ($line[$i]=='\\') { $piece .= $line[$i]; $i++; if ($i>=$len) break; - } else if ($line[$i]==':'){ + } elseif ($line[$i]==':') { $row[] = $piece; $piece = ''; continue; @@ -416,14 +465,15 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * @param array $info User's userinfo array * @return bool */ - protected function _filter($user, $info) { - foreach($this->_pattern as $item => $pattern) { - if($item == 'user') { - if(!preg_match($pattern, $user)) return false; - } else if($item == 'grps') { - if(!count(preg_grep($pattern, $info['grps']))) return false; + protected function filter($user, $info) + { + foreach ($this->pattern as $item => $pattern) { + if ($item == 'user') { + if (!preg_match($pattern, $user)) return false; + } elseif ($item == 'grps') { + if (!count(preg_grep($pattern, $info['grps']))) return false; } else { - if(!preg_match($pattern, $info[$item])) return false; + if (!preg_match($pattern, $info[$item])) return false; } } return true; @@ -434,10 +484,11 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * * @param array $filter */ - protected function _constructPattern($filter) { - $this->_pattern = array(); - foreach($filter as $item => $pattern) { - $this->_pattern[$item] = '/'.str_replace('/', '\/', $pattern).'/i'; // allow regex characters + protected function constructPattern($filter) + { + $this->pattern = array(); + foreach ($filter as $item => $pattern) { + $this->pattern[$item] = '/'.str_replace('/', '\/', $pattern).'/i'; // allow regex characters } } } diff --git a/lib/plugins/authplain/lang/da/lang.php b/lib/plugins/authplain/lang/da/lang.php index ff683ed38..dea4ea321 100644 --- a/lib/plugins/authplain/lang/da/lang.php +++ b/lib/plugins/authplain/lang/da/lang.php @@ -3,7 +3,10 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * + * @author Jacob Palm <mail@jacobpalm.dk> * @author Kenneth Schack Banner <kescba@gmail.com> */ $lang['userexists'] = 'Dette brugernavn er allerede i brug.'; +$lang['usernotexists'] = 'Beklager, brugeren eksisterer ikke.'; $lang['writefail'] = 'Ude af stand til at redigere bruger data. Kontakt venligst Wiki-Administratoren'; +$lang['protected'] = 'Data for brugeren %s er beskyttet, og kan ikke ændres eller slettes.'; diff --git a/lib/plugins/authplain/lang/is/lang.php b/lib/plugins/authplain/lang/is/lang.php index 21392ee5e..82088ddd2 100644 --- a/lib/plugins/authplain/lang/is/lang.php +++ b/lib/plugins/authplain/lang/is/lang.php @@ -1,6 +1,7 @@ <?php + /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * */ -$lang['userexists'] = 'Afsakið, notandi með þessu nafni er þegar skráður inn.'; +$lang['userexists'] = 'Afsakið, notandi með þessu nafni er þegar skráður inn.'; diff --git a/lib/plugins/authplain/lang/lt/lang.php b/lib/plugins/authplain/lang/lt/lang.php index 5ad435a04..b1834360f 100644 --- a/lib/plugins/authplain/lang/lt/lang.php +++ b/lib/plugins/authplain/lang/lt/lang.php @@ -1,6 +1,7 @@ <?php + /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * */ -$lang['userexists'] = 'Vartotojas su pasirinktu prisijungimo vardu jau egzistuoja.'; +$lang['userexists'] = 'Vartotojas su pasirinktu prisijungimo vardu jau egzistuoja.'; diff --git a/lib/plugins/authplain/lang/pt/lang.php b/lib/plugins/authplain/lang/pt/lang.php index 3334ea667..d43e4f1e0 100644 --- a/lib/plugins/authplain/lang/pt/lang.php +++ b/lib/plugins/authplain/lang/pt/lang.php @@ -3,9 +3,11 @@ /** * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * + * @author Paulo Ricardo Schopf <pschopf@gmail.com> * @author Paulo Carmino <contato@paulocarmino.com> * @author Guilherme Sá <guilherme.sa@hotmail.com> */ $lang['userexists'] = 'Este utilizador já está inscrito. Por favor escolha outro nome de utilizador.'; $lang['usernotexists'] = 'Desculpe, esse login não existe.'; $lang['writefail'] = 'Incapaz de modificar dados do usuário. Favor informar ao Wiki-Admin.'; +$lang['protected'] = 'Os dados do usuário %s estão protegidos e não podem ser modificados ou excluídos.'; |