diff options
-rw-r--r-- | lib/plugins/authpdo/_test/sqlite.test.php | 25 | ||||
-rw-r--r-- | lib/plugins/authpdo/auth.php | 119 | ||||
-rw-r--r-- | lib/plugins/authpdo/conf/default.php | 31 |
3 files changed, 157 insertions, 18 deletions
diff --git a/lib/plugins/authpdo/_test/sqlite.test.php b/lib/plugins/authpdo/_test/sqlite.test.php index 70e8dde98..1d9058a68 100644 --- a/lib/plugins/authpdo/_test/sqlite.test.php +++ b/lib/plugins/authpdo/_test/sqlite.test.php @@ -1,6 +1,10 @@ <?php - +/** + * Class testable_auth_plugin_authpdo + * + * makes protected methods public for testing + */ class testable_auth_plugin_authpdo extends auth_plugin_authpdo { public function getPluginName() { return 'authpdo'; @@ -13,7 +17,6 @@ class testable_auth_plugin_authpdo extends auth_plugin_authpdo { public function _insertGroup($group) { return parent::_insertGroup($group); } - } /** @@ -42,8 +45,14 @@ class sqlite_plugin_authpdo_test extends DokuWikiTest { $conf['plugin']['authpdo']['select-user-groups'] = 'SELECT * FROM member AS m, "group" AS g WHERE m.gid = g.id AND m.uid = :uid'; $conf['plugin']['authpdo']['select-groups'] = 'SELECT id AS gid, "group" FROM "group"'; $conf['plugin']['authpdo']['insert-user'] = 'INSERT INTO user (login, pass, name, mail) VALUES (:user, :hash, :name, :mail)'; + + $conf['plugin']['authpdo']['update-user-login'] = 'UPDATE user SET login = :newlogin WHERE id = :uid'; + $conf['plugin']['authpdo']['update-user-info'] = 'UPDATE user SET name = :name, mail = :mail WHERE id = :uid'; + $conf['plugin']['authpdo']['update-user-pass'] = 'UPDATE user SET pass = :hash WHERE id = :uid'; + $conf['plugin']['authpdo']['insert-group'] = 'INSERT INTO "group" ("group") VALUES (:group)'; $conf['plugin']['authpdo']['join-group'] = 'INSERT INTO member (uid, gid) VALUES (:uid, :gid)'; + $conf['plugin']['authpdo']['leave-group'] = 'DELETE FROM member WHERE uid = :uid AND gid = :gid'; } public function tearDown() { @@ -101,6 +110,18 @@ class sqlite_plugin_authpdo_test extends DokuWikiTest { $this->assertEquals('test@example.com', $info['mail']); $this->assertEquals(array('newgroup', 'user'), $info['grps']); $this->assertEquals(array('admin', 'newgroup', 'user'), $auth->retrieveGroups()); + + // user modification + $auth->modifyUser('test', array('user' => 'tester', 'name' => 'The Test User', 'pass' => 'secret')); + $info = $auth->getUserData('tester'); + $this->assertEquals('tester', $info['user']); + $this->assertEquals('The Test User', $info['name']); + $this->assertTrue($auth->checkPass('tester','secret')); + + // move user to different groups + $auth->modifyUser('tester', array('grps' => array('user', 'admin', 'another'))); + $info = $auth->getUserData('tester'); + $this->assertEquals(array('admin', 'another', 'user'), $info['grps']); } } diff --git a/lib/plugins/authpdo/auth.php b/lib/plugins/authpdo/auth.php index 3bd487371..020b44546 100644 --- a/lib/plugins/authpdo/auth.php +++ b/lib/plugins/authpdo/auth.php @@ -70,8 +70,6 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin { /** * Check user+password * - * May be ommited if trustExternal is used. - * * @param string $user the user name * @param string $pass the clear text password * @return bool @@ -189,18 +187,93 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin { } /** - * Modify user data [implement only where required/possible] - * - * Set the mod* capabilities according to the implemented features + * Modify user data * * @param string $user nick of the user to be changed * @param array $changes array of field/value pairs to be changed (password will be clear text) * @return bool */ - //public function modifyUser($user, $changes) { - // FIXME implement - // return false; - //} + public function modifyUser($user, $changes) { + // secure everything in transaction + $this->pdo->beginTransaction(); + { + $olddata = $this->getUserData($user); + $oldgroups = $olddata['grps']; + unset($olddata['grps']); + + // changing the user name? + if(isset($changes['user'])) { + if($this->getUserData($changes['user'], false)) goto FAIL; + $params = $olddata; + $params['newlogin'] = $changes['user']; + + $ok = $this->_query($this->getConf('update-user-login'), $params); + if($ok === false) goto FAIL; + } + + // changing the password? + if(isset($changes['pass'])) { + $params = $olddata; + $params['clear'] = $changes['pass']; + $params['hash'] = auth_cryptPassword($changes['pass']); + + $ok = $this->_query($this->getConf('update-user-pass'), $params); + if($ok === false) goto FAIL; + } + + // changing info? + if(isset($changes['mail']) || isset($changes['name'])) { + $params = $olddata; + if(isset($changes['mail'])) $params['mail'] = $changes['mail']; + if(isset($changes['name'])) $params['name'] = $changes['name']; + + $ok = $this->_query($this->getConf('update-user-info'), $params); + if($ok === false) goto FAIL; + } + + // changing groups? + if(isset($changes['grps'])) { + $allgroups = $this->_selectGroups(); + + // remove membership for previous groups + foreach($oldgroups as $group) { + if(!in_array($group, $changes['grps'])) { + $ok = $this->_leaveGroup($olddata, $allgroups[$group]); + if($ok === false) goto FAIL; + } + } + + // create all new groups that are missing + $added = 0; + foreach($changes['grps'] as $group) { + if(!isset($allgroups[$group])) { + $ok = $this->_insertGroup($group); + if($ok === false) goto FAIL; + $added++; + } + } + // reload group info + if($added > 0) $allgroups = $this->_selectGroups(); + + // add membership for new groups + foreach($changes['grps'] as $group) { + if(!in_array($group, $oldgroups)) { + $ok = $this->_joinGroup($olddata, $allgroups[$group]); + if($ok === false) goto FAIL; + } + } + } + + } + $this->pdo->commit(); + return true; + + // something went wrong, rollback + FAIL: + $this->pdo->rollBack(); + $this->_debug('Transaction rolled back', 0, __LINE__); + return false; // return error + } /** * Delete one or more users [implement only where required/possible] @@ -386,7 +459,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin { } /** - * Enters the user to the group + * Adds the user to the group * * @param array $userdata all the user data * @param array $groupdata all the group data @@ -401,6 +474,21 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin { } /** + * Removes the user from the group + * + * @param array $userdata all the user data + * @param array $groupdata all the group data + * @return bool + */ + protected function _leaveGroup($userdata, $groupdata) { + $data = array_merge($userdata, $groupdata); + $sql = $this->getConf('leave-group'); + $result = $this->_query($sql, $data); + if($result === false) return false; + return true; + } + + /** * Executes a query * * @param string $sql The SQL statement to execute @@ -428,9 +516,12 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin { $sth->execute($params); $result = $sth->fetchAll(); } catch(Exception $e) { + // report the caller's line + $trace = debug_backtrace(); + $line = $trace[0]['line']; $dsql = $this->_debugSQL($sql, $params, !defined('DOKU_UNITTEST')); - $this->_debug($e); - $this->_debug("SQL: <pre>$dsql</pre>", -1, $e->getLine()); + $this->_debug($e, -1, $line); + $this->_debug("SQL: <pre>$dsql</pre>", -1, $line); $result = false; } finally { $sth->closeCursor(); @@ -451,8 +542,8 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin { if(!$this->getConf('debug')) return; if(is_a($message, 'Exception')) { $err = -1; - $line = $message->getLine(); $msg = $message->getMessage(); + if(!$line) $line = $message->getLine(); } else { $msg = $message; } @@ -488,7 +579,7 @@ class auth_plugin_authpdo extends DokuWiki_Auth_Plugin { * @param bool $htmlescape Should the result be escaped for output in HTML? * @return string */ - protected function _debugSQL($sql, $params, $htmlescape=true) { + protected function _debugSQL($sql, $params, $htmlescape = true) { foreach($params as $key => $val) { if(is_int($val)) { $val = $this->pdo->quote($val, PDO::PARAM_INT); diff --git a/lib/plugins/authpdo/conf/default.php b/lib/plugins/authpdo/conf/default.php index c7bc9e70b..fd91456f5 100644 --- a/lib/plugins/authpdo/conf/default.php +++ b/lib/plugins/authpdo/conf/default.php @@ -5,7 +5,6 @@ * @author Andreas Gohr <andi@splitbrain.org> */ -//$conf['fixme'] = 'FIXME'; $conf['debug'] = 0; $conf['dsn'] = ''; @@ -30,11 +29,32 @@ $conf['select-group'] = ''; /** * Create a new user * - * input: :user, :name, :mail, (:clear,:hash) + * input: :user, :name, :mail, (:clear|:hash) */ $conf['insert-user'] = ''; /** + * Update user data (except password and user name) + * + * input: :user, :name, :mail, [:uid], [*] + */ +$conf['update-user-info'] = ''; + +/** + * Update user name aka login + * + * input: :user, :newlogin, [:uid], [*] + */ +$conf['update-user-login'] = ''; + +/** + * Update user password + * + * input: :user, :clear, :hash, [:uid], [*] + */ +$conf['update-user-pass'] = ''; + +/** * Create a new group * * input: :group @@ -47,3 +67,10 @@ $conf['insert-group'] = ''; * input: :user, [:uid], group, [:gid], [*] */ $conf['join-group'] = ''; + +/** + * Make user leave group + * + * input: :user, [:uid], group, [:gid], [*] + */ +$conf['leave-group'] = ''; |