From 6cc38600710f32a55c352991ed90434d335d6844 Mon Sep 17 00:00:00 2001 From: Ralf Lang Date: Sun, 22 Oct 2017 11:49:15 +0000 Subject: [PATCH 01/16] Add a Dummy authentication driver and unit tests --- lib/Horde/Auth/Dummy.php | 171 ++++++++++++++++++++ test/Horde/Auth/Unit/DummyCryptShowTest.php | 143 ++++++++++++++++ test/Horde/Auth/Unit/DummyCryptTest.php | 143 ++++++++++++++++ test/Horde/Auth/Unit/DummyPlainTest.php | 141 ++++++++++++++++ 4 files changed, 598 insertions(+) create mode 100644 lib/Horde/Auth/Dummy.php create mode 100644 test/Horde/Auth/Unit/DummyCryptShowTest.php create mode 100644 test/Horde/Auth/Unit/DummyCryptTest.php create mode 100644 test/Horde/Auth/Unit/DummyPlainTest.php diff --git a/lib/Horde/Auth/Dummy.php b/lib/Horde/Auth/Dummy.php new file mode 100644 index 0000000..7891492 --- /dev/null +++ b/lib/Horde/Auth/Dummy.php @@ -0,0 +1,171 @@ + + * @category Horde + * @license http://www.horde.org/licenses/lgpl21 LGPL-2.1 + * @package Auth + */ + +/** + * The Horde_Auth_Dummy class provides an in-memory user list. + * It is meant to be used for throwaway setups, satellite systems or for + * providing a source of administrative accounts in Composite or Cascading driver + * The driver can also be used as a mock-like backend for integration tests + * + * @author Ralf Lang + * @category Horde + * @copyright 2017-2018 Horde LLC + * @license http://www.horde.org/licenses/lgpl21 LGPL-2.1 + * @package Auth + */ +class Horde_Auth_Dummy extends Horde_Auth_Base +{ + /** + * An array of capabilities, so that the driver can report which + * operations it supports and which it doesn't. + * + * @var array + */ + protected $_capabilities = array( + 'authenticate' => true, + 'list' => true, + 'update' => true, + 'remove' => true, + 'add' => true, + ); + + /** + * Constructor. + * + * @param array $params Optional parameters: + *
+     * 'users' - (array) Usernames are hash keys, passwords are values
+     * 'encryption' - (string) Optionally supply an encryption or hashing
+     * 'show_encryption' - (boolean) prepend encryption info to password string
+     * 
+ */ + public function __construct(array $params = array()) + { + $params = array_merge( + array( + 'encryption' => 'plain', + 'users' => array(), + 'show_encryption' => false + ), + $params + ); + parent::__construct($params); + } + + /** + * Adds a set of authentication credentials. + * + * @param string $userId The userId to add. + * @param array $credentials The credentials to use. + * + * @throws Horde_Auth_Exception + */ + public function addUser($userId, $credentials) + { + // TODO: use persistence callback if given + if ($this->exists($userId)) { + throw new Horde_Auth_Exception('User already exists'); + } + $this->_params['users'][$userId] = Horde_Auth::getCryptedPassword( + $credentials['password'], + '', + $this->_params['encryption'], + $this->_params['show_encryption']); + } + + /** + * Lists all users in the system. + * + * @param boolean $sort Sort the users? + * + * @return mixed The array of userIds. + * @throws Horde_Auth_Exception + */ + public function listUsers($sort = false) + { + return $this->_sort(array_keys($this->_params['users']), $sort); + } + + /** + * Updates a set of authentication credentials for the life time of the driver. + * + * @param string $oldID The old userId. + * @param string $newID The new userId. + * @param array $credentials The new credentials + * + * @throws Horde_Auth_Exception + */ + public function updateUser($oldID, $newID, $credentials) + { + if (!$this->exists($oldID)) { + throw new Horde_Auth_Exception('User does not exist'); + } + if ($this->exists($newID) && $newID != $oldID) { + throw new Horde_Auth_Exception('Cannot rename to existing user name'); + } + $this->removeUser($oldID); + $this->addUser($newID, $credentials); + } + + /** + * Deletes a set of authentication credentials for the life of the driver. + * + * @param string $userId The userId to delete. + * + * @throws Horde_Auth_Exception + */ + public function removeUser($userId) + { + // TODO: use persistence callback if given + unset($this->_params['users'][$userId]); + } + + /** + * Authenticate. + * + * @param string $userId The userID to check. + * @param array $credentials An array of login credentials. + * + * @throws Horde_Auth_Exception + */ + protected function _authenticate($userId, $credentials) + { + if ($this->exists($userId)) { + if ($this->_comparePasswords( + $this->_params['users'][$userId], + $credentials['password'] + )) { + return; + } + } + throw new Horde_Auth_Exception('', Horde_Auth::REASON_BADLOGIN); + } + + /** + * Compare an encrypted password to a plaintext string to see if + * they match. + * + * @param string $encrypted The crypted password to compare against. + * @param string $plaintext The plaintext password to verify. + * + * @return boolean True if matched, false otherwise. + */ + protected function _comparePasswords($encrypted, $plaintext) + { + return $encrypted == Horde_Auth::getCryptedPassword($plaintext, + $encrypted, + $this->_params['encryption'], + $this->_params['show_encryption']); + } + +} diff --git a/test/Horde/Auth/Unit/DummyCryptShowTest.php b/test/Horde/Auth/Unit/DummyCryptShowTest.php new file mode 100644 index 0000000..ce9aa1a --- /dev/null +++ b/test/Horde/Auth/Unit/DummyCryptShowTest.php @@ -0,0 +1,143 @@ + + * @license http://www.horde.org/licenses/lgpl21 LGPL-2.1 + * @link http://pear.horde.org/index.php?package=Auth + */ +class Horde_Auth_Unit_DummyCryptShowTest extends Horde_Auth_TestCase +{ + public function setUp() + { + $this->driver = new Horde_Auth_Dummy( + array( + 'users' => array( + 'user1' => '{crypt}$1$S/EKq8Dg$OJvaV8Lu1HgCXKNqAo.wG/', + 'user2' => '{crypt}$1$aCWZiBAW$dK0DCmTGYR1gEX11pMxbi0', + 'tester' => '{crypt}$1$sjSx+Q9x$3WIEdh1Ei16QouYx1Xkct1' + ), + 'encryption' => 'crypt-md5', + 'show_encryption' => true + ) + ); + } + + public function testAuthenticate() + { + $this->assertTrue($this->driver->authenticate('user1', array('password' => 'user1pw'))); + $this->assertTrue($this->driver->authenticate('user2', array('password' => 'user2pw'))); + $this->assertTrue($this->driver->authenticate('tester', array('password' => 'WeirdPW92401#1'))); + // correct password extended by garbage + $this->assertFalse($this->driver->authenticate('user1', array('password' => 'user1pwfalse'))); + // Existing user with all kinds of garbage + $this->assertFalse($this->driver->authenticate('user1', array('password' => 'any'))); + $this->assertFalse($this->driver->authenticate('user1', array('password' => ''))); + $this->assertFalse($this->driver->authenticate('user1', array('password' => null))); + $this->assertFalse($this->driver->authenticate('user1', array('password' => '0'))); + // Unknown user with all kinds of garbage + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => 'any'))); + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => ''))); + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => null))); + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => '0'))); + } + + public function testRemoveUser() + { + // Delete somebody who doesn't exist + $this->driver->removeUser('user'); + $this->assertCount(3, $this->driver->listUsers()); + $this->driver->removeUser('user1'); + $this->assertCount(2, $this->driver->listUsers()); + $this->driver->removeUser('user2'); + $this->assertCount(1, $this->driver->listUsers()); + $this->driver->removeUser('tester'); + $this->assertCount(0, $this->driver->listUsers()); + // Restore setup + $this->setUp(); + } + + public function testAddUser() + { + // Add somebody who already exist + $this->driver->addUser('user4', array('password' => 'foo')); + $this->assertCount(4, $this->driver->listUsers()); + // Add somebody who already exist + $this->setExpectedException(Horde_Auth_Exception::class); + $this->driver->addUser('user4', array('password' => 'foo')); + $this->assertCount(4, $this->driver->listUsers()); + + // Restore setup + $this->setUp(); + } + + public function testUpdateUser() + { + // Try a password change + $this->driver->updateUser('tester', 'tester', array('password' => 'foo')); + $this->assertCount(3, $this->driver->listUsers()); + $this->assertTrue($this->driver->exists('tester')); + // Try renaming + $this->driver->updateUser('tester', 'newname', array('password' => 'foo')); + $this->assertCount(3, $this->driver->listUsers()); + $this->assertTrue($this->driver->exists('newname')); + $this->assertFalse($this->driver->exists('tester')); + $this->setUp(); + } + + public function testUpdateUserFailDoesNotExist() + { + // Try renaming unknown user + $this->setExpectedException(Horde_Auth_Exception::class); + $this->driver->updateUser('unknownuser', 'newname', array('password' => 'foo')); + $this->setUp(); + } + + public function testUpdateUserFailNewNameExists() + { + // Try renaming unknown user + $this->setExpectedException(Horde_Auth_Exception::class); + $this->driver->updateUser('tester', 'user1', array('password' => 'foo')); + $this->setUp(); + } + + + + public function testExists() + { + $this->assertTrue($this->driver->exists('user1')); + $this->assertTrue($this->driver->exists('user2')); + $this->assertTrue($this->driver->exists('tester')); + $this->assertFalse($this->driver->exists('somebody')); + $this->assertFalse($this->driver->exists('')); + $this->assertFalse($this->driver->exists(null)); + } + + /** + * This is actually a test against Horde_Auth_Base + * TODO: Copy or move to a test with a phpunit mock + */ + + public function testSearchUsers() + { + $this->assertCount(2, $this->driver->searchUsers('user')); + $this->assertCount(1, $this->driver->searchUsers('test')); + $this->assertEquals(array('tester'), $this->driver->searchUsers('test')); + } + + public function testListUsers() + { + $this->assertEquals(array('tester', 'user1', 'user2'), $this->driver->listUsers(true)); + $this->assertEquals(array('user1', 'user2', 'tester'), $this->driver->listUsers(false)); + $this->assertEquals(array('user1', 'user2', 'tester'), $this->driver->listUsers()); + } +} diff --git a/test/Horde/Auth/Unit/DummyCryptTest.php b/test/Horde/Auth/Unit/DummyCryptTest.php new file mode 100644 index 0000000..52bbe67 --- /dev/null +++ b/test/Horde/Auth/Unit/DummyCryptTest.php @@ -0,0 +1,143 @@ + + * @license http://www.horde.org/licenses/lgpl21 LGPL-2.1 + * @link http://pear.horde.org/index.php?package=Auth + */ +class Horde_Auth_Unit_DummyCryptTest extends Horde_Auth_TestCase +{ + public function setUp() + { + $this->driver = new Horde_Auth_Dummy( + array( + 'users' => array( + 'user1' => '$1$S/EKq8Dg$OJvaV8Lu1HgCXKNqAo.wG/', + 'user2' => '$1$aCWZiBAW$dK0DCmTGYR1gEX11pMxbi0', + 'tester' => '$1$sjSx+Q9x$3WIEdh1Ei16QouYx1Xkct1' + ), + 'encryption' => 'crypt-md5', + 'show_encryption' => false + ) + ); + } + + public function testAuthenticate() + { + $this->assertTrue($this->driver->authenticate('user1', array('password' => 'user1pw'))); + $this->assertTrue($this->driver->authenticate('user2', array('password' => 'user2pw'))); + $this->assertTrue($this->driver->authenticate('tester', array('password' => 'WeirdPW92401#1'))); + // correct password extended by garbage + $this->assertFalse($this->driver->authenticate('user1', array('password' => 'user1pwfalse'))); + // Existing user with all kinds of garbage + $this->assertFalse($this->driver->authenticate('user1', array('password' => 'any'))); + $this->assertFalse($this->driver->authenticate('user1', array('password' => ''))); + $this->assertFalse($this->driver->authenticate('user1', array('password' => null))); + $this->assertFalse($this->driver->authenticate('user1', array('password' => '0'))); + // Unknown user with all kinds of garbage + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => 'any'))); + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => ''))); + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => null))); + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => '0'))); + } + + public function testRemoveUser() + { + // Delete somebody who doesn't exist + $this->driver->removeUser('user'); + $this->assertCount(3, $this->driver->listUsers()); + $this->driver->removeUser('user1'); + $this->assertCount(2, $this->driver->listUsers()); + $this->driver->removeUser('user2'); + $this->assertCount(1, $this->driver->listUsers()); + $this->driver->removeUser('tester'); + $this->assertCount(0, $this->driver->listUsers()); + // Restore setup + $this->setUp(); + } + + public function testAddUser() + { + // Add somebody who already exist + $this->driver->addUser('user4', array('password' => 'foo')); + $this->assertCount(4, $this->driver->listUsers()); + // Add somebody who already exist + $this->setExpectedException(Horde_Auth_Exception::class); + $this->driver->addUser('user4', array('password' => 'foo')); + $this->assertCount(4, $this->driver->listUsers()); + + // Restore setup + $this->setUp(); + } + + public function testUpdateUser() + { + // Try a password change + $this->driver->updateUser('tester', 'tester', array('password' => 'foo')); + $this->assertCount(3, $this->driver->listUsers()); + $this->assertTrue($this->driver->exists('tester')); + // Try renaming + $this->driver->updateUser('tester', 'newname', array('password' => 'foo')); + $this->assertCount(3, $this->driver->listUsers()); + $this->assertTrue($this->driver->exists('newname')); + $this->assertFalse($this->driver->exists('tester')); + $this->setUp(); + } + + public function testUpdateUserFailDoesNotExist() + { + // Try renaming unknown user + $this->setExpectedException(Horde_Auth_Exception::class); + $this->driver->updateUser('unknownuser', 'newname', array('password' => 'foo')); + $this->setUp(); + } + + public function testUpdateUserFailNewNameExists() + { + // Try renaming unknown user + $this->setExpectedException(Horde_Auth_Exception::class); + $this->driver->updateUser('tester', 'user1', array('password' => 'foo')); + $this->setUp(); + } + + + + public function testExists() + { + $this->assertTrue($this->driver->exists('user1')); + $this->assertTrue($this->driver->exists('user2')); + $this->assertTrue($this->driver->exists('tester')); + $this->assertFalse($this->driver->exists('somebody')); + $this->assertFalse($this->driver->exists('')); + $this->assertFalse($this->driver->exists(null)); + } + + /** + * This is actually a test against Horde_Auth_Base + * TODO: Copy or move to a test with a phpunit mock + */ + + public function testSearchUsers() + { + $this->assertCount(2, $this->driver->searchUsers('user')); + $this->assertCount(1, $this->driver->searchUsers('test')); + $this->assertEquals(array('tester'), $this->driver->searchUsers('test')); + } + + public function testListUsers() + { + $this->assertEquals(array('tester', 'user1', 'user2'), $this->driver->listUsers(true)); + $this->assertEquals(array('user1', 'user2', 'tester'), $this->driver->listUsers(false)); + $this->assertEquals(array('user1', 'user2', 'tester'), $this->driver->listUsers()); + } +} diff --git a/test/Horde/Auth/Unit/DummyPlainTest.php b/test/Horde/Auth/Unit/DummyPlainTest.php new file mode 100644 index 0000000..73ef0c2 --- /dev/null +++ b/test/Horde/Auth/Unit/DummyPlainTest.php @@ -0,0 +1,141 @@ + + * @license http://www.horde.org/licenses/lgpl21 LGPL-2.1 + * @link http://pear.horde.org/index.php?package=Auth + */ +class Horde_Auth_Unit_DummyPlainTest extends Horde_Auth_TestCase +{ + public function setUp() + { + $this->driver = new Horde_Auth_Dummy( + array( + 'users' => array( + 'user1' => 'user1pw', + 'user2' => 'user2pw', + 'tester' => 'WeirdPW92401#1' + ) + ) + ); + } + + public function testAuthenticate() + { + $this->assertTrue($this->driver->authenticate('user1', array('password' => 'user1pw'))); + $this->assertTrue($this->driver->authenticate('user2', array('password' => 'user2pw'))); + $this->assertTrue($this->driver->authenticate('tester', array('password' => 'WeirdPW92401#1'))); + // correct password extended by garbage + $this->assertFalse($this->driver->authenticate('user1', array('password' => 'user1pwfalse'))); + // Existing user with all kinds of garbage + $this->assertFalse($this->driver->authenticate('user1', array('password' => 'any'))); + $this->assertFalse($this->driver->authenticate('user1', array('password' => ''))); + $this->assertFalse($this->driver->authenticate('user1', array('password' => null))); + $this->assertFalse($this->driver->authenticate('user1', array('password' => '0'))); + // Unknown user with all kinds of garbage + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => 'any'))); + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => ''))); + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => null))); + $this->assertFalse($this->driver->authenticate('unknownuser', array('password' => '0'))); + } + + public function testRemoveUser() + { + // Delete somebody who doesn't exist + $this->driver->removeUser('user'); + $this->assertCount(3, $this->driver->listUsers()); + $this->driver->removeUser('user1'); + $this->assertCount(2, $this->driver->listUsers()); + $this->driver->removeUser('user2'); + $this->assertCount(1, $this->driver->listUsers()); + $this->driver->removeUser('tester'); + $this->assertCount(0, $this->driver->listUsers()); + // Restore setup + $this->setUp(); + } + + public function testAddUser() + { + // Add somebody who already exist + $this->driver->addUser('user4', array('password' => 'foo')); + $this->assertCount(4, $this->driver->listUsers()); + // Add somebody who already exist + $this->setExpectedException(Horde_Auth_Exception::class); + $this->driver->addUser('user4', array('password' => 'foo')); + $this->assertCount(4, $this->driver->listUsers()); + + // Restore setup + $this->setUp(); + } + + public function testUpdateUser() + { + // Try a password change + $this->driver->updateUser('tester', 'tester', array('password' => 'foo')); + $this->assertCount(3, $this->driver->listUsers()); + $this->assertTrue($this->driver->exists('tester')); + // Try renaming + $this->driver->updateUser('tester', 'newname', array('password' => 'foo')); + $this->assertCount(3, $this->driver->listUsers()); + $this->assertTrue($this->driver->exists('newname')); + $this->assertFalse($this->driver->exists('tester')); + $this->setUp(); + } + + public function testUpdateUserFailDoesNotExist() + { + // Try renaming unknown user + $this->setExpectedException(Horde_Auth_Exception::class); + $this->driver->updateUser('unknownuser', 'newname', array('password' => 'foo')); + $this->setUp(); + } + + public function testUpdateUserFailNewNameExists() + { + // Try renaming unknown user + $this->setExpectedException(Horde_Auth_Exception::class); + $this->driver->updateUser('tester', 'user1', array('password' => 'foo')); + $this->setUp(); + } + + + + public function testExists() + { + $this->assertTrue($this->driver->exists('user1')); + $this->assertTrue($this->driver->exists('user2')); + $this->assertTrue($this->driver->exists('tester')); + $this->assertFalse($this->driver->exists('somebody')); + $this->assertFalse($this->driver->exists('')); + $this->assertFalse($this->driver->exists(null)); + } + + /** + * This is actually a test against Horde_Auth_Base + * TODO: Copy or move to a test with a phpunit mock + */ + + public function testSearchUsers() + { + $this->assertCount(2, $this->driver->searchUsers('user')); + $this->assertCount(1, $this->driver->searchUsers('test')); + $this->assertEquals(array('tester'), $this->driver->searchUsers('test')); + } + + public function testListUsers() + { + $this->assertEquals(array('tester', 'user1', 'user2'), $this->driver->listUsers(true)); + $this->assertEquals(array('user1', 'user2', 'tester'), $this->driver->listUsers(false)); + $this->assertEquals(array('user1', 'user2', 'tester'), $this->driver->listUsers()); + } +} From c1e79af3f983b25d4778e30bf701f7b61aa9c7cf Mon Sep 17 00:00:00 2001 From: Ralf Lang Date: Tue, 24 Oct 2017 11:44:18 +0000 Subject: [PATCH 02/16] Updated package.xml --- package.xml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/package.xml b/package.xml index f50968f..a8aeb50 100644 --- a/package.xml +++ b/package.xml @@ -23,7 +23,7 @@ slusarz@horde.org yes - 2017-10-20 + 2017-10-24 2.2.3 2.2.0 @@ -34,7 +34,7 @@ LGPL-2.1 -* +* [rla] Add a dummy authentication driver. @@ -49,6 +49,7 @@ + @@ -172,6 +173,9 @@ + + + @@ -183,6 +187,7 @@ + @@ -304,12 +309,14 @@ + + @@ -363,6 +370,9 @@ + + + @@ -1119,10 +1129,10 @@ stable stable - 2017-10-20 + 2017-10-24 LGPL-2.1 -* +* [rla] Add a dummy authentication driver. From 2485db2e437109802f570493cc7d6a606b5ee1cd Mon Sep 17 00:00:00 2001 From: Jan Schneider Date: Tue, 24 Oct 2017 14:03:36 +0200 Subject: [PATCH 03/16] PEAR on 5.6 and 7.0 is fixed. --- .travis.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1e1ebf7..7687992 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,12 +13,6 @@ matrix: - php: nightly before_script: - phpenv config-rm xdebug.ini || echo "XDebug not enabled" - - if [ "$TRAVIS_PHP_VERSION" == "5.6" ] || [ "$TRAVIS_PHP_VERSION" == "7.0" ]; - then - echo "include_path = .:$HOME/.phpenv/versions/$(phpenv version-name)/lib/php/pear" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; - pear channel-discover pear.horde.org; - fi - - pear install channel://pear.horde.org/Horde_Test - pear install -a -B package.xml script: From 2012c381b1d17dd080250cf2dc04dd012fe1d01c Mon Sep 17 00:00:00 2001 From: Jan Schneider Date: Tue, 24 Oct 2017 14:05:12 +0200 Subject: [PATCH 04/16] Enable 7.2 builds. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 7687992..8fe21b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ php: - 5.6 - 7.0 - 7.1 + - 7.2 - nightly matrix: fast_finish: true From 754c5dbffb8d3e17c70758adb72ea26414162bc6 Mon Sep 17 00:00:00 2001 From: Jan Schneider Date: Wed, 25 Oct 2017 18:19:25 +0200 Subject: [PATCH 05/16] Update composer.json. --- composer.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/composer.json b/composer.json index 1aea59c..2fc69c2 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,8 @@ "role": "lead" } ], - "version": "2.2.2", - "time": "2017-06-22", + "version": "2.2.3", + "time": "2017-10-20", "repositories": [ { "type": "pear", @@ -31,21 +31,21 @@ ], "require": { "php": "^5.3 || ^7", - "pear-pear.horde.org/Horde_Exception": "^2@stable", - "pear-pear.horde.org/Horde_Translation": "^2.2@stable", - "pear-pear.horde.org/Horde_Util": "^2@stable", + "pear-pear.horde.org/Horde_Exception": "^2", + "pear-pear.horde.org/Horde_Translation": "^2.2", + "pear-pear.horde.org/Horde_Util": "^2", "ext-hash": "*" }, "suggest": { - "pear-pear.horde.org/Horde_Db": "^2@stable", - "pear-pear.horde.org/Horde_History": "^2@stable", - "pear-pear.horde.org/Horde_Lock": "^2@stable", - "pear-pear.horde.org/Horde_Imap_Client": "^2@stable", - "pear-pear.horde.org/Horde_Kolab_Session": "^2@stable", - "pear-pear.horde.org/Horde_Ldap": "^2@stable", - "pear-pear.horde.org/Horde_Imsp": "^2@stable", - "pear-pear.horde.org/Horde_Http": "^2@stable", - "pear-pear.horde.org/Horde_Test": "^2.1@stable", + "pear-pear.horde.org/Horde_Db": "^2", + "pear-pear.horde.org/Horde_History": "^2", + "pear-pear.horde.org/Horde_Lock": "^2", + "pear-pear.horde.org/Horde_Imap_Client": "^2", + "pear-pear.horde.org/Horde_Kolab_Session": "^2", + "pear-pear.horde.org/Horde_Ldap": "^2", + "pear-pear.horde.org/Horde_Imsp": "^2", + "pear-pear.horde.org/Horde_Http": "^2", + "pear-pear.horde.org/Horde_Test": "^2.1", "pear-pecl.php.net/pam": "*", "pear-pecl.php.net/sasl": "*", "ext-ctype": "*", From 1546e75f04dd6f35e9685c5d26bb9cab927ab3e3 Mon Sep 17 00:00:00 2001 From: Jan Schneider Date: Wed, 25 Oct 2017 18:25:54 +0200 Subject: [PATCH 06/16] Update .horde.yml with extended information. --- .horde.yml | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/.horde.yml b/.horde.yml index 8628602..03231d1 100644 --- a/.horde.yml +++ b/.horde.yml @@ -7,3 +7,57 @@ description: > for the Horde authentication system. list: dev type: library +homepage: https://www.horde.org/libraries/Horde_Auth +authors: + - + name: Chuck Hagenbuch + user: chuck + email: chuck@horde.org + active: true + role: lead + - + name: Jan Schneider + user: jan + email: jan@horde.org + active: true + role: lead + - + name: Michael Slusarz + user: slusarz + email: slusarz@horde.org + active: true + role: lead +version: + release: 2.2.3 + api: 2.2.0 +state: + release: stable + api: stable +license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 +dependencies: + required: + php: ^5.3 || ^7 + pear: + pear.horde.org/Horde_Exception: ^2 + pear.horde.org/Horde_Translation: ^2.2 + pear.horde.org/Horde_Util: ^2 + ext: + hash: '*' + optional: + pear: + pear.horde.org/Horde_Db: ^2 + pear.horde.org/Horde_History: ^2 + pear.horde.org/Horde_Lock: ^2 + pear.horde.org/Horde_Imap_Client: ^2 + pear.horde.org/Horde_Kolab_Session: ^2 + pear.horde.org/Horde_Ldap: ^2 + pear.horde.org/Horde_Imsp: ^2 + pear.horde.org/Horde_Http: ^2 + pear.horde.org/Horde_Test: ^2.1 + pecl.php.net/pam: '*' + pecl.php.net/sasl: '*' + ext: + ctype: '*' + ftp: '*' From 76ee2c1d18199caf33021390e5e9c6d8e3c92065 Mon Sep 17 00:00:00 2001 From: Jan Schneider Date: Fri, 27 Oct 2017 11:04:46 +0200 Subject: [PATCH 07/16] Build changelog.yml from existing changelog(s). --- doc/Horde/Auth/changelog.yml | 630 +++++++++++++++++++++++++++++++++++ 1 file changed, 630 insertions(+) create mode 100644 doc/Horde/Auth/changelog.yml diff --git a/doc/Horde/Auth/changelog.yml b/doc/Horde/Auth/changelog.yml new file mode 100644 index 0000000..14a9b4b --- /dev/null +++ b/doc/Horde/Auth/changelog.yml @@ -0,0 +1,630 @@ +--- +2.2.3: + api: 2.2.0 + state: + release: stable + api: stable + date: 2017-10-20 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: +2.2.2: + api: 2.2.0 + state: + release: stable + api: stable + date: 2017-06-22 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add Turkish translation (İTÜ BİDB ). +2.2.1: + api: 2.2.0 + state: + release: stable + api: stable + date: 2016-12-03 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Use more efficient database access in SQL backend. +2.2.0: + api: 2.2.0 + state: + release: stable + api: stable + date: 2016-07-28 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add searchUsers() method. +2.1.12: + api: 2.1.0 + state: + release: stable + api: stable + date: 2016-04-05 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [mjr] Fix creating/removing mailbox in cyrsql driver (federico.mennite@lifeware.ch, Bug #14295). +2.1.11: + api: 2.1.0 + state: + release: stable + api: stable + date: 2016-02-01 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Mark PHP 7 as supported. +2.1.10: + api: 2.1.0 + state: + release: stable + api: stable + date: 2015-07-06 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] SECURITY: Don't allow to login to LDAP with an emtpy password. +2.1.9: + api: 2.1.0 + state: + release: stable + api: stable + date: 2015-06-29 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [mjr] Ensure we rebind as configured user after testing auth user credentials. +2.1.8: + api: 2.1.0 + state: + release: stable + api: stable + date: 2015-04-28 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Fix issues with certain locales like Turkish. +2.1.7: + api: 2.1.0 + state: + release: stable + api: stable + date: 2015-04-13 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Improve salt generation for Blowfish hashes. +2.1.6: + api: 2.1.0 + state: + release: stable + api: stable + date: 2015-01-08 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Support loading translations from Composer-installed package. + [jan] Improve PSR-2 compatibility. +2.1.5: + api: 2.1.0 + state: + release: stable + api: stable + date: 2014-06-17 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add Polish translation (Maciej Uhlig ). +2.1.4: + api: 2.1.0 + state: + release: stable + api: stable + date: 2014-05-21 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add Hungarian translation (Andras Galos ). +2.1.3: + api: 2.1.0 + state: + release: stable + api: stable + date: 2014-04-03 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add Danish translation (Erling Preben Hansen ). +2.1.2: + api: 2.1.0 + state: + release: stable + api: stable + date: 2014-03-03 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add MySQL password hashing (Request #12962). + [rla] Add joomla encrypted password format (Request #12889). + [mms] Fix parsing salted SHA256 entries (Adam James ). +2.1.1: + api: 2.1.0 + state: + release: stable + api: stable + date: 2013-10-15 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [mms] Password strength testing is now case-insensitive (delrio@mie.utoronto.ca, Request #12708). +2.1.0: + api: 2.1.0 + state: + release: stable + api: stable + date: 2013-09-02 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [mjr] Add X509 authentication driver. +2.0.6: + api: 2.0.0 + state: + release: stable + api: stable + date: 2013-07-16 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [mms] Fix adding/deleting users via IMAP administration (Bug #12426). +2.0.5: + api: 2.0.0 + state: + release: stable + api: stable + date: 2013-07-16 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add password policy for minimum number of non-alphabetic characters (Friedrich Haubensak , Request #12243). + [jan] Fix resetting passwords with LDAP driver (Bug #12317). + [mms] Fix authentication with the Http auth driver. +2.0.4: + api: 2.0.0 + state: + release: stable + api: stable + date: 2013-03-05 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Improve documentation. +2.0.3: + api: 2.0.0 + state: + release: stable + api: stable + date: 2013-01-29 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add French translation (Paul De Vlieger ). + [jan] Fix argument reading in Samba drivers (Bug #11926). + [mms] Remove call-time pass-by-reference, which was causing PAM authentication driver to fail in PHP 5.4+ (Bug #10965). +2.0.2: + api: 2.0.0 + state: + release: stable + api: stable + date: 2013-01-09 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add Basque translation (Ibon Igartua ). + [jan] Fix updating users in LDAP driver (Bug #11791). +2.0.1: + api: 2.0.0 + state: + release: stable + api: stable + date: 2012-11-19 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [mms] Use new Horde_Test layout. +2.0.0: + api: 2.0.0 + state: + release: stable + api: stable + date: 2012-10-30 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + First stable release for Horde 5. +2.0.0beta2: + api: 2.0.0beta1 + state: + release: beta + api: beta + date: 2012-10-12 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Fix setting IMAP ACLs in IMAP and Cyrsql drivers. + [mms] Fix user management in Passwd driver. + [mms] Fix setting soft expiration in SQL driver. +2.0.0beta1: + api: 2.0.0beta1 + state: + release: beta + api: beta + date: 2012-07-19 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + First beta release for Horde 5. + [rla] Use constant for permanent lock and provide more verbose feedback (Request #11254). +2.0.0alpha1: + api: 2.0.0alpha1 + state: + release: alpha + api: alpha + date: 2012-07-05 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + First alpha release for Horde 5. + [mms] Removed charset parameter for Imap and Cyrsql drivers. +1.4.10: + api: 1.4.0 + state: + release: stable + api: stable + date: 2012-03-20 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [mms] Fix Horde_Auth_Passwd#updateUser(). +1.4.9: + api: 1.4.0 + state: + release: stable + api: stable + date: 2012-03-20 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add Finnish translation (Leena Heino ). +1.4.8: + api: 1.4.0 + state: + release: stable + api: stable + date: 2012-01-31 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add optimized exists() implementation to LDAP driver (Marco Ferrante , Request #10944). + [jan] Add Spanish translation (Manuel P. Ayala ). +1.4.7: + api: 1.4.0 + state: + release: stable + api: stable + date: 2011-12-13 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add Latvian translation (Jānis Eisaks ). +1.4.6: + api: 1.4.0 + state: + release: stable + api: stable + date: 2011-12-06 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add Japanese translation (Hiromi Kimura ). +1.4.5: + api: 1.4.0 + state: + release: stable + api: stable + date: 2011-11-22 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add Estonian translation. +1.4.4: + api: 1.4.0 + state: + release: stable + api: stable + date: 2011-11-08 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Allow to run unit tests from installed package. +1.4.3: + api: 1.4.0 + state: + release: stable + api: stable + date: 2011-10-18 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Catch exceptions from imap library (Bug #10272). +1.4.2: + api: 1.4.0 + state: + release: stable + api: stable + date: 2011-10-04 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Fix detecting locale directory from PEAR installation (Bug #10589). +1.4.1: + api: 1.4.0 + state: + release: stable + api: stable + date: 2011-10-03 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add missing locale directory (Bug #10589). +1.4.0: + api: 1.4.0 + state: + release: stable + api: stable + date: 2011-09-28 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Add checkPasswordPolicy() and checkPasswordSimilarity() methods. +1.3.0: + api: 1.3.0 + state: + release: stable + api: stable + date: 2011-09-20 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Dynamically disable capabilities of Customsql authentication driver if queries are empty (Michael Gröne, Request #10510). + [jan] Fix updating users in LDAP while using preauthenticate hooks. + [jan] Add support for resetting passwords to LDAP driver. +1.2.0: + api: 1.2.0 + state: + release: stable + api: stable + date: 2011-08-31 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [rla] Add bad login blocking and account locking to the base driver. + [rla] Fix SQL driver when using soft_expiration and hard_expiration features. + [rla] No longer enforce lowercase fieldnames. +1.1.0: + api: 1.1.0 + state: + release: stable + api: stable + date: 2011-07-05 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [rla] Add sort parameter to listUsers() method. + [mms] Fix addUser() for Cyrsql driver (vilius@lnk.lt, Bug #10239). +1.0.4: + api: 1.0.0 + state: + release: stable + api: stable + date: 2011-06-08 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] SECURITY: Fix propagating failed login in composite driver (Bug #10211). +1.0.3: + api: 1.0.0 + state: + release: stable + api: stable + date: 2011-05-18 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [mms] Cyrsql driver doesn't support resetting passwords currently (Bug #10060). +1.0.2: + api: 1.0.0 + state: + release: stable + api: stable + date: 2011-05-03 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [jan] Fix listing users in Customsql driver (Bug #9963). +1.0.1: + api: 1.0.0 + state: + release: stable + api: stable + date: 2011-04-20 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + [mms] Fix default userhierarchy for Cyrsql driver (Bug #9895). + [cjh] Add crypt-sha256 and crypt-sha512 password hashes (patrickdk@patrickdk.com, Request #6991). + [mms] Fix addUser() in Customsql driver (Bug #9832). +1.0.0: + api: 1.0.0 + state: + release: stable + api: stable + date: 2011-04-06 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + First stable release for Horde 4. + [jan] Fix Cyrsql driver (Vilius Sumskas , Bug #9781). + [jan] Add SHA-256 hashing and add SHA as alias for SHA1. +1.0.0RC2: + api: 1.0.0 + state: + release: beta + api: beta + date: 2011-03-29 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + Second release candidate for Horde 4. + Remove Cyrus driver. + Remove support for pam_auth (Ticket #6860). +1.0.0RC1: + api: 1.0.0 + state: + release: beta + api: beta + date: 2011-03-22 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + First release candidate for Horde 4. +1.0.0beta1: + api: 1.0.0 + state: + release: beta + api: beta + date: 2011-03-16 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + First beta release for Horde 4. +1.0.0alpha1: + api: 1.0.0 + state: + release: alpha + api: alpha + date: 2011-03-08 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + First alpha release for Horde 4. + Remove dependency on horde/Core. + Remove all non-authentication backend related code. + Removed Krb5 driver. + Moved signup code to horde/Core. + Split Horde_Auth into Horde_Auth and Horde_Auth_Base components. +0.1.1: + api: 0.1.0 + state: + release: beta + api: beta + date: 2008-10-29 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + Imap driver now uses Horde_Imap_Client library. + Add signup drivers to package.xml (Bug #7345). + Fix the "overwriting realm info from application auth drivers" (Bug #6749) + Switched Kolab auth handling from IMAP to LDAP by using Kolab_Server. + Added "add user" capability to the Kolab driver. + Adapted the Kolab auth driver to the changes in Kolab_Server. +0.1.0: + api: 0.1.0 + state: + release: beta + api: beta + date: 2008-09-16 + license: + identifier: LGPL-2.1 + uri: http://www.horde.org/licenses/lgpl21 + notes: | + Fixed error handling when removing user data. + Retrieve password where necessary for salt calculations in the custom SQL driver (Bug #3739). + Added a query for checking existance of a user to the custom SQL driver (Request #5151). + Completed Cyrus virtual domain support in the cyrsql driver. + Fixed handling of UID logins in the Kolab driver (Bugs #1317, #4662). + Fixed case handling in the LDAP driver (Bug #2435). + Rewrote PAM driver to use PAM extension from PECL. + Fixed the PAM driver authentication so that it works with both pam and pam_auth extensions (Bug #6860). + Ensured that the LDAP driver always uses the configured filter. + Renamed Auth_sasl to Auth_peclsasl (Bug #4547). + Allow signup hooks to override the user_name and password fields (Request #2904). + Created an SQL driver for signups and allowing backends other than DataTree (Request #7161). + Added smbclient driver as an alternative to the smb driver which requires a PHP extension. + Fix handling of SSHA and SMD5 salts (ulrich-horde@topfen.net, Bug #2863). + Added readSessionData() function to get Horde authentication data from session strings. + Allow drivers to include their own isAdmin() implementations (Request #5521). + Add Active Directory extension of LDAP driver (Request #3769). + Hide the cyrus account in cyrsql driver (vilius@lnk.lt, Request #5626). + Bring the passwd driver into compliance with the Auth API. + Remove dependency on the mhash extension for some encryption types. + Add authentication against a remote HTTP Authentication endpoint (duck@obala.net). + CSRF token protections for logout links. + Call the postauthenticate hook in Horde_Auth::setAuth() instead of authenticate(). + Modified the Kolab driver to use the new Kolab_Server package. + Improved handling of multiple IMAP server setups in the Kolab driver. From c177f6cd39a5b682298e0c390a5055008af3e220 Mon Sep 17 00:00:00 2001 From: Jan Schneider Date: Fri, 27 Oct 2017 11:08:39 +0200 Subject: [PATCH 08/16] Regenerate package.xml from changelog.yml. --- package.xml | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/package.xml b/package.xml index a8aeb50..6af5f3d 100644 --- a/package.xml +++ b/package.xml @@ -23,7 +23,7 @@ slusarz@horde.org yes - 2017-10-24 + 2017-10-29 2.2.3 2.2.0 @@ -34,10 +34,18 @@ LGPL-2.1 -* [rla] Add a dummy authentication driver. +* [rla] Add Mock authentication driver. + + + + + + + + @@ -49,7 +57,6 @@ - @@ -58,6 +65,7 @@ + @@ -173,10 +181,10 @@ - - - + + + @@ -310,13 +318,14 @@ + + - @@ -326,6 +335,7 @@ + @@ -370,10 +380,10 @@ - - - + + + @@ -1129,10 +1139,10 @@ stable stable - 2017-10-24 + 2017-10-29 LGPL-2.1 -* [rla] Add a dummy authentication driver. +* [rla] Add Mock authentication driver. From a4577db09505dadb914a0ccc8c2b37322d835888 Mon Sep 17 00:00:00 2001 From: Ralf Lang Date: Sun, 29 Oct 2017 07:30:22 +0000 Subject: [PATCH 09/16] Not yet 2018 --- lib/Horde/Auth/Dummy.php | 2 +- test/Horde/Auth/Unit/DummyCryptShowTest.php | 2 +- test/Horde/Auth/Unit/DummyCryptTest.php | 2 +- test/Horde/Auth/Unit/DummyPlainTest.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Horde/Auth/Dummy.php b/lib/Horde/Auth/Dummy.php index 7891492..83154f6 100644 --- a/lib/Horde/Auth/Dummy.php +++ b/lib/Horde/Auth/Dummy.php @@ -1,6 +1,6 @@ Date: Sun, 29 Oct 2017 07:40:08 +0000 Subject: [PATCH 10/16] ws --- lib/Horde/Auth/Dummy.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/Horde/Auth/Dummy.php b/lib/Horde/Auth/Dummy.php index 83154f6..e57bf11 100644 --- a/lib/Horde/Auth/Dummy.php +++ b/lib/Horde/Auth/Dummy.php @@ -13,13 +13,14 @@ /** * The Horde_Auth_Dummy class provides an in-memory user list. + * * It is meant to be used for throwaway setups, satellite systems or for * providing a source of administrative accounts in Composite or Cascading driver * The driver can also be used as a mock-like backend for integration tests * * @author Ralf Lang * @category Horde - * @copyright 2017-2018 Horde LLC + * @copyright 2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL-2.1 * @package Auth */ @@ -77,10 +78,10 @@ public function addUser($userId, $credentials) throw new Horde_Auth_Exception('User already exists'); } $this->_params['users'][$userId] = Horde_Auth::getCryptedPassword( - $credentials['password'], - '', - $this->_params['encryption'], - $this->_params['show_encryption']); + $credentials['password'], + '', + $this->_params['encryption'], + $this->_params['show_encryption']); } /** @@ -162,10 +163,11 @@ protected function _authenticate($userId, $credentials) */ protected function _comparePasswords($encrypted, $plaintext) { - return $encrypted == Horde_Auth::getCryptedPassword($plaintext, - $encrypted, - $this->_params['encryption'], - $this->_params['show_encryption']); + return $encrypted == Horde_Auth::getCryptedPassword( + $plaintext, + $encrypted, + $this->_params['encryption'], + $this->_params['show_encryption']); } } From e9a57cf9529a2d0eee6fb4808e7b89317399b0ba Mon Sep 17 00:00:00 2001 From: Ralf Lang Date: Sun, 29 Oct 2017 07:42:55 +0000 Subject: [PATCH 11/16] Remove throws comment if the library doesn't throw anything --- lib/Horde/Auth/Dummy.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/Horde/Auth/Dummy.php b/lib/Horde/Auth/Dummy.php index e57bf11..949a347 100644 --- a/lib/Horde/Auth/Dummy.php +++ b/lib/Horde/Auth/Dummy.php @@ -90,7 +90,6 @@ public function addUser($userId, $credentials) * @param boolean $sort Sort the users? * * @return mixed The array of userIds. - * @throws Horde_Auth_Exception */ public function listUsers($sort = false) { @@ -122,8 +121,6 @@ public function updateUser($oldID, $newID, $credentials) * Deletes a set of authentication credentials for the life of the driver. * * @param string $userId The userId to delete. - * - * @throws Horde_Auth_Exception */ public function removeUser($userId) { From 224d1bb69c732ec2f22191358ef0cc7dba4f2c9b Mon Sep 17 00:00:00 2001 From: Ralf Lang Date: Sun, 29 Oct 2017 07:51:52 +0000 Subject: [PATCH 12/16] Make exception test cases php5.4 compatible Remove unnecessary comment line --- test/Horde/Auth/Unit/DummyCryptShowTest.php | 7 +++---- test/Horde/Auth/Unit/DummyCryptTest.php | 7 +++---- test/Horde/Auth/Unit/DummyPlainTest.php | 7 +++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/test/Horde/Auth/Unit/DummyCryptShowTest.php b/test/Horde/Auth/Unit/DummyCryptShowTest.php index 4da7894..d7e9cc3 100644 --- a/test/Horde/Auth/Unit/DummyCryptShowTest.php +++ b/test/Horde/Auth/Unit/DummyCryptShowTest.php @@ -1,6 +1,5 @@ driver->addUser('user4', array('password' => 'foo')); $this->assertCount(4, $this->driver->listUsers()); // Add somebody who already exist - $this->setExpectedException(Horde_Auth_Exception::class); + $this->setExpectedException('Horde_Auth_Exception'); $this->driver->addUser('user4', array('password' => 'foo')); $this->assertCount(4, $this->driver->listUsers()); @@ -97,7 +96,7 @@ public function testUpdateUser() public function testUpdateUserFailDoesNotExist() { // Try renaming unknown user - $this->setExpectedException(Horde_Auth_Exception::class); + $this->setExpectedException('Horde_Auth_Exception'); $this->driver->updateUser('unknownuser', 'newname', array('password' => 'foo')); $this->setUp(); } @@ -105,7 +104,7 @@ public function testUpdateUserFailDoesNotExist() public function testUpdateUserFailNewNameExists() { // Try renaming unknown user - $this->setExpectedException(Horde_Auth_Exception::class); + $this->setExpectedException('Horde_Auth_Exception'); $this->driver->updateUser('tester', 'user1', array('password' => 'foo')); $this->setUp(); } diff --git a/test/Horde/Auth/Unit/DummyCryptTest.php b/test/Horde/Auth/Unit/DummyCryptTest.php index 154c1b3..3b200b2 100644 --- a/test/Horde/Auth/Unit/DummyCryptTest.php +++ b/test/Horde/Auth/Unit/DummyCryptTest.php @@ -1,6 +1,5 @@ driver->addUser('user4', array('password' => 'foo')); $this->assertCount(4, $this->driver->listUsers()); // Add somebody who already exist - $this->setExpectedException(Horde_Auth_Exception::class); + $this->setExpectedException('Horde_Auth_Exception'); $this->driver->addUser('user4', array('password' => 'foo')); $this->assertCount(4, $this->driver->listUsers()); @@ -97,7 +96,7 @@ public function testUpdateUser() public function testUpdateUserFailDoesNotExist() { // Try renaming unknown user - $this->setExpectedException(Horde_Auth_Exception::class); + $this->setExpectedException('Horde_Auth_Exception'); $this->driver->updateUser('unknownuser', 'newname', array('password' => 'foo')); $this->setUp(); } @@ -105,7 +104,7 @@ public function testUpdateUserFailDoesNotExist() public function testUpdateUserFailNewNameExists() { // Try renaming unknown user - $this->setExpectedException(Horde_Auth_Exception::class); + $this->setExpectedException('Horde_Auth_Exception'); $this->driver->updateUser('tester', 'user1', array('password' => 'foo')); $this->setUp(); } diff --git a/test/Horde/Auth/Unit/DummyPlainTest.php b/test/Horde/Auth/Unit/DummyPlainTest.php index caadee8..d074423 100644 --- a/test/Horde/Auth/Unit/DummyPlainTest.php +++ b/test/Horde/Auth/Unit/DummyPlainTest.php @@ -1,6 +1,5 @@ driver->addUser('user4', array('password' => 'foo')); $this->assertCount(4, $this->driver->listUsers()); // Add somebody who already exist - $this->setExpectedException(Horde_Auth_Exception::class); + $this->setExpectedException('Horde_Auth_Exception'); $this->driver->addUser('user4', array('password' => 'foo')); $this->assertCount(4, $this->driver->listUsers()); @@ -95,7 +94,7 @@ public function testUpdateUser() public function testUpdateUserFailDoesNotExist() { // Try renaming unknown user - $this->setExpectedException(Horde_Auth_Exception::class); + $this->setExpectedException('Horde_Auth_Exception'); $this->driver->updateUser('unknownuser', 'newname', array('password' => 'foo')); $this->setUp(); } @@ -103,7 +102,7 @@ public function testUpdateUserFailDoesNotExist() public function testUpdateUserFailNewNameExists() { // Try renaming unknown user - $this->setExpectedException(Horde_Auth_Exception::class); + $this->setExpectedException('Horde_Auth_Exception'); $this->driver->updateUser('tester', 'user1', array('password' => 'foo')); $this->setUp(); } From 016b8fdf15f67f0b1bf04071f8573903787a065c Mon Sep 17 00:00:00 2001 From: Ralf Lang Date: Sun, 29 Oct 2017 08:02:53 +0000 Subject: [PATCH 13/16] Change for better readability. --- lib/Horde/Auth/Dummy.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/Horde/Auth/Dummy.php b/lib/Horde/Auth/Dummy.php index 949a347..caa2e36 100644 --- a/lib/Horde/Auth/Dummy.php +++ b/lib/Horde/Auth/Dummy.php @@ -138,15 +138,14 @@ public function removeUser($userId) */ protected function _authenticate($userId, $credentials) { - if ($this->exists($userId)) { - if ($this->_comparePasswords( + if (!$this->exists($userId) || + !$this->_comparePasswords( $this->_params['users'][$userId], $credentials['password'] )) { - return; - } + throw new Horde_Auth_Exception('', Horde_Auth::REASON_BADLOGIN); } - throw new Horde_Auth_Exception('', Horde_Auth::REASON_BADLOGIN); + return; } /** From ea59e1d5ff6e001aceeb50371d22d668a19087ec Mon Sep 17 00:00:00 2001 From: Ralf Lang Date: Sun, 29 Oct 2017 08:08:39 +0000 Subject: [PATCH 14/16] Rename the driver to mock driver --- lib/Horde/Auth/{Dummy.php => Mock.php} | 4 ++-- .../Unit/{DummyCryptShowTest.php => MockCryptShowTest.php} | 6 +++--- .../Auth/Unit/{DummyCryptTest.php => MockCryptTest.php} | 6 +++--- .../Auth/Unit/{DummyPlainTest.php => MockPlainTest.php} | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) rename lib/Horde/Auth/{Dummy.php => Mock.php} (97%) rename test/Horde/Auth/Unit/{DummyCryptShowTest.php => MockCryptShowTest.php} (97%) rename test/Horde/Auth/Unit/{DummyCryptTest.php => MockCryptTest.php} (97%) rename test/Horde/Auth/Unit/{DummyPlainTest.php => MockPlainTest.php} (97%) diff --git a/lib/Horde/Auth/Dummy.php b/lib/Horde/Auth/Mock.php similarity index 97% rename from lib/Horde/Auth/Dummy.php rename to lib/Horde/Auth/Mock.php index caa2e36..7ff5262 100644 --- a/lib/Horde/Auth/Dummy.php +++ b/lib/Horde/Auth/Mock.php @@ -12,7 +12,7 @@ */ /** - * The Horde_Auth_Dummy class provides an in-memory user list. + * The Horde_Auth_Mock class provides an in-memory user list. * * It is meant to be used for throwaway setups, satellite systems or for * providing a source of administrative accounts in Composite or Cascading driver @@ -24,7 +24,7 @@ * @license http://www.horde.org/licenses/lgpl21 LGPL-2.1 * @package Auth */ -class Horde_Auth_Dummy extends Horde_Auth_Base +class Horde_Auth_Mock extends Horde_Auth_Base { /** * An array of capabilities, so that the driver can report which diff --git a/test/Horde/Auth/Unit/DummyCryptShowTest.php b/test/Horde/Auth/Unit/MockCryptShowTest.php similarity index 97% rename from test/Horde/Auth/Unit/DummyCryptShowTest.php rename to test/Horde/Auth/Unit/MockCryptShowTest.php index d7e9cc3..7b2a164 100644 --- a/test/Horde/Auth/Unit/DummyCryptShowTest.php +++ b/test/Horde/Auth/Unit/MockCryptShowTest.php @@ -1,6 +1,6 @@ driver = new Horde_Auth_Dummy( + $this->driver = new Horde_Auth_Mock( array( 'users' => array( 'user1' => '{crypt}$1$S/EKq8Dg$OJvaV8Lu1HgCXKNqAo.wG/', diff --git a/test/Horde/Auth/Unit/DummyCryptTest.php b/test/Horde/Auth/Unit/MockCryptTest.php similarity index 97% rename from test/Horde/Auth/Unit/DummyCryptTest.php rename to test/Horde/Auth/Unit/MockCryptTest.php index 3b200b2..a0245d6 100644 --- a/test/Horde/Auth/Unit/DummyCryptTest.php +++ b/test/Horde/Auth/Unit/MockCryptTest.php @@ -1,6 +1,6 @@ driver = new Horde_Auth_Dummy( + $this->driver = new Horde_Auth_Mock( array( 'users' => array( 'user1' => '$1$S/EKq8Dg$OJvaV8Lu1HgCXKNqAo.wG/', diff --git a/test/Horde/Auth/Unit/DummyPlainTest.php b/test/Horde/Auth/Unit/MockPlainTest.php similarity index 97% rename from test/Horde/Auth/Unit/DummyPlainTest.php rename to test/Horde/Auth/Unit/MockPlainTest.php index d074423..51bea2b 100644 --- a/test/Horde/Auth/Unit/DummyPlainTest.php +++ b/test/Horde/Auth/Unit/MockPlainTest.php @@ -1,6 +1,6 @@ driver = new Horde_Auth_Dummy( + $this->driver = new Horde_Auth_Mock( array( 'users' => array( 'user1' => 'user1pw', From bd7537ccbd6ce279527692a19fe43a4846f2d56c Mon Sep 17 00:00:00 2001 From: frankflorian Date: Thu, 9 Nov 2017 12:52:47 +0100 Subject: [PATCH 15/16] Add new cascading driver and tests for it --- lib/Horde/Auth/Cascading.php | 337 +++++++++++++++++++++ test/Horde/Auth/Unit/CascadingMockTest.php | 169 +++++++++++ 2 files changed, 506 insertions(+) create mode 100644 lib/Horde/Auth/Cascading.php create mode 100644 test/Horde/Auth/Unit/CascadingMockTest.php diff --git a/lib/Horde/Auth/Cascading.php b/lib/Horde/Auth/Cascading.php new file mode 100644 index 0000000..33ea4ff --- /dev/null +++ b/lib/Horde/Auth/Cascading.php @@ -0,0 +1,337 @@ + (implementation) + * @author Ralf Lang (concept) + * @category Horde + * @license http://www.horde.org/licenses/lgpl21 LGPL-2.1 + * @package Auth + */ + +/** + * The Horde_Auth_Cascading class provides a way to combine multiple + * authentication drivers for local overrides and integration scenarios + * + * @author Florian Frank (implementation) + * @author Ralf Lang (concept) + * @category Horde + * @copyright 2017-2018 Horde LLC + * @license http://www.horde.org/licenses/lgpl21 LGPL-2.1 + * @package Auth + */ +class Horde_Auth_Cascading extends Horde_Auth_Base +{ + /** + * Constructor. + * + * @param array $params Required parameters: + *
+     * 'drivers' - array hash of (Horde_Auth_Base) The list of backend drivers.
+     * 'order' - a list of drivers indexes to define a default order.
+     * 
+ * + * 'capabilities' - defines capabilities this driver + * exposes and how to map them to the backends. + * Defaults to "order" for all drivers which support it. + * + * @throws InvalidArgumentException + */ + public function __construct(array $params = array()) + { + $this->_test = $params; + foreach (array('drivers', 'order') as $val) { + if (!isset($params[$val])) { + throw new InvalidArgumentException('Missing ' . $val . ' parameter.'); + } + } + $capabilities = array(); + // Autodetect capabilities and build a default execution order + foreach ($this->_capabilities as $capabilityKey => $capability) { + foreach ($params['order'] as $driverKey) { + if ($params['drivers'][$driverKey]->hasCapability($capabilityKey)) { + if (empty($capabilities[$capabilityKey])) { + /* TODO: resetpassword capability is debatable - + We actually call update on the backend drivers to + get the same password in all backends + Thus, automatically assign resetpassword capability + to drivers which have 'update'. + The user may override this manually. + Drivers which actually only provide resetpassword are + supported, but more than one brings unpredictable + results + */ + $capabilities[$capabilityKey] = array(); + } + array_push($capabilities[$capabilityKey], $driverKey); + } + } + } + + if (!empty($params['capabilities'])) { + // override default capabilities with provided capabilities + $capabilities = array_merge($capabilities, $params['capabilities']); + + } + $params['capabilities'] = $capabilities; + // TODO: unset order, we don't use it after initialization + // Do base initialisation + unset($params['order']); + parent::__construct($params); + } + + protected $_test = array(); //test array + + public function getParams() //test function to see all arrays + { + return($this->_test); + } + + /** + * Find out if a set of login credentials are valid. + * Valid means valid in any backend + * + * @param string $userId The userId to check. + * @param array $credentials The credentials to use. + * + * @throws Horde_Auth_Exception + */ + protected function _authenticate($userId, $credentials) + { + // Return if any driver accepts this userId and credentials as valid + foreach ($this->_params['capabilities']['authenticate'] as $driverKey) { + if ($this->_params['drivers'][$driverKey]->authenticate($userId, $credentials)) { + return; + } + } + // Otherwise throw an exception + throw new Horde_Auth_Exception('', Horde_Auth::REASON_BADLOGIN); + } + + /** + * Advertise capability if a capability has backend driver + * + * @param string $capability The capability to test for. + * + * @return boolean Whether or not the capability is supported. + */ + public function hasCapability($capability) + { + if (empty($this->_params['capabilities'][$capability])) { + return false; + } + return true; + } + + /** + * Automatic authentication. + * + * @return boolean Whether or not the client is allowed. + */ + public function transparent() + { + // TODO: Check each configured driver in $this->_params['capabilities']['transparent']. Stop and return true if successful. Throw Exception if no driver available + + if (!$this->hasCapability('transparent')) + { + throw new Horde_Auth_Exception('Unsupported.'); + } + foreach ($this->_params['capabilities']['transparent'] as $driverKey) { + try{ + if ($this->_params['drivers']['driverKey']->transparent()) { + return true; + } + }catch (Horde_Auth_Exception $e){ + } + } + return false; + } + + /** + * Add a set of authentication credentials. + * + * @param string $userId The userId to add. + * @param array $credentials The credentials to use. + * + * @throws Horde_Auth_Exception + */ + public function addUser($userId, $credentials) + { + // TODO try to add the user to all backends in $this->_params['capabilities']['add'] - throw exception if no driver available + if (!$this->hasCapability('add')) { + throw new Horde_Auth_Exception('Unsupported.'); + } + foreach ($this->_params['capabilities']['add'] as $driverKey) { + try{ + $this->_params['drivers'][$driverKey]->addUser($userId, $credentials); + }catch (Horde_Auth_Exception $e) { + } + } + } +/** + * Update a set of authentication credentials. + * + * @param string $oldID The old userId. + * @param string $newID The new userId. + * @param array $credentials The new credentials + * + * @throws Horde_Auth_Exception + */ + public function updateUser($oldID, $newID, $credentials) + { + // TODO try to add the user to all backends in $this->_params['capabilities']['update'] - throw exception if no driver available + if (!$this->hasCapability('update')) { + throw new Horde_Auth_Exception('Unsupported.'); + } + foreach ($this->_params['capabilities']['update'] as $driverKey) { + try{ + $this->_params['drivers'][$driverKey]->updateUser($oldID, $newID, $credentials); + } catch (Horde_Auth_Exception $e) { + } + } + } + + /** + * Reset a user's password. Used for example when the user does not + * remember the existing password. + * + * @param string $userId The user id for which to reset the password. + * + * @return string The new password on success. + * @throws Horde_Auth_Exception + */ + public function resetPassword($userId) + { + // Implement this later: + // Check the list of auth drivers for drivers which has resetpassword but not update capability (configured). + // If exists, remove these drivers from list and run resetPassword on these driver. Use the first returned password for all drivers which have update (see below) + // Else, do as below + + if (!$this->hasCapability('resetpassword')) { + throw new Horde_Auth_Exception('Unsupported.'); + } + $newPassword = ''; + $resetButUpdate = array(); + foreach ($this->_params['capabilities']['resetpassword'] as $resetKey) { + if (in_array($resetKey, $this->_params['capabilities']['update'])) { + array_push($resetButUpdate, $resetKey); + } + else { + try { + $newPassword = $this->_params['drivers'][$resetKey]->resetPassword($userId); + } catch (Horde_Auth_Exception $e) { + } + } + } + // Implement this first: + // Generate a random password ONCE + // Try to update the user password to all backends - throw exception if no driver available + // Return the new random password + + // inspired by https://stackoverflow.com/questions/4356289/php-random-string-generator + + if (!empty($resetButUpdate)) { + if (newPassword == '') { + $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $charactersLength = strlen($characters); + for ($i = 0; $i < 8; $i++) { + $newPassword .= $characters[rand(0, $charactersLength - 1)]; + } + } + $credentials = array('password' => $newPassword); + foreach ($resetButUpdate as $driverKey) { + try{ + $this->_params['drivers'][$driverKey]->updateUser($userId, $userId, $credentials); + } catch (Horde_Auth_Exception $e) { + } + } + } + return $newPassword; + } + + /** + * Delete a set of authentication credentials. + * + * @param string $userId The userId to delete. + * + * @throws Horde_Auth_Exception + */ + public function removeUser($userId) + { + // TODO try to remove the user from all backends in $this->_params['capabilities']['remove'] - throw exception if no driver available + if (!$this->hasCapability('remove')) { + throw new Horde_Auth_Exception('Unsupported.'); + } + $users = array(); + foreach ($this->_params['capabilities']['remove'] as $driverKey) { + try{ + $this->_params['drivers'][$driverKey]->removeUser($userId); + } catch (Horde_Auth_Exception $e) { + } + } + } + + /** + * Lists all users in the system. + * + * @param boolean $sort Sort the users? + * + * @return array The array of userIds. + * @throws Horde_Auth_Exception + */ + public function listUsers($sort = false) + { + //Todo list all users from all backends and merge them with array_unique + // Merge the results - don't list any user twice + + if (!$this->hasCapability('list')) { + throw new Horde_Auth_Exception('Unsupported.'); + } + $users = array(); + foreach ($this->_params['capabilities']['list'] as $driverKey) { + try { + $users = array_merge($users , $this->_params['drivers'][$driverKey]->listUsers($sort)); + } catch (Horde_Auth_Exception $e) { + } + } + $uniqueUsers = array_values(array_unique($users)); + return($uniqueUsers); + } + + /** + * Checks if a userId exists in the system. + * + * @param string $userId User ID to check + * + * @return boolean Whether or not the userId already exists. + */ + public function exists($userId) + { + // rotate through all backends which have list capabddlity or exists capability - return true if any backend has this user, otherwise return false. + if (!$this->hasCapability('list') and !$this->hasCapability('exists')) { + throw new Horde_Auth_Exception('Unsupported.'); + } + if ($this->hasCapability('exists')) { + foreach ($this->_params['capabilities']['exists'] as $existsKey) { + try { + if ($this->_params['drivers'][$existsKey]->exists($userId)) { + return true; + } + } catch (Horde_Auth_Exception $e) { + } + } + } + foreach ($this->_params['capabilities']['list'] as $listKey) { + try { + if (in_array($userId, $this->_params['drivers'][$listKey]->listUsers())) { + return true; + } + } catch (Horde_Auth_Exception $e) { + } + } + return false; + } +} diff --git a/test/Horde/Auth/Unit/CascadingMockTest.php b/test/Horde/Auth/Unit/CascadingMockTest.php new file mode 100644 index 0000000..b2df34d --- /dev/null +++ b/test/Horde/Auth/Unit/CascadingMockTest.php @@ -0,0 +1,169 @@ + + * @license http://www.horde.org/licenses/lgpl21 LGPL-2.1 + * @link http://pear.horde.org/index.php?package=Auth + */ + +class Horde_Auth_Unit_CascadingTest extends Horde_Auth_TestCase +{ + + function setUp() { + $d1 = new Horde_Auth_Mock(array('users' => array('user1' => 'pw1','user2' => 'pw2'))); + $d2 = new Horde_Auth_Mock(array('users' => array('user1' => 'pw3443243', 'tester2' => 'pw3323242'))); + $d3 = new Horde_Auth_Mock( + array( + 'users' => array( + 'tester1337' => '$1$W1n1f.uf$4pL90iQvvfS0PqshMaMLi.', //testpassword1 + 'tester1338' => '$1$W1n1f.uf$M3F2kPykfT3Z1ywuAqvO6.', //testpassword2 + 'tester2' => '$1$W1n1f.uf$ng08WnPr8wQuVGg2pvw2f1' //hi$M+i3Rd + ), + 'encryption' => 'crypt-md5', + 'show_encryption' => false + ) + ); + $this->cascading = new Horde_Auth_Cascading( + array( + 'drivers' => array('admins' => $d1, 'db' => $d2, 'cryptdb' => $d3), + 'order' => array('admins', 'db', 'cryptdb'), + ) + ); + } + + public function testHasCapability() + { + $this->assertFalse($this->cascading->hasCapability('transparent')); + $this->assertTrue($this->cascading->hasCapability('authenticate')); + $this->assertTrue($this->cascading->hasCapability('remove')); + $this->assertTrue($this->cascading->hasCapability('update')); + } + + public function testTransparent() + { + //throw exception if no backend provides transparent + $this->setExpectedException(Horde_Auth_Exception::class); + $this->cascading->transparent(); + } + + public function testListUsers() + { + $this->assertEquals(array('user1', 'user2', 'tester2', 'tester1337', 'tester1338'), $this->cascading->listUsers(true)); + $this->assertEquals(array('user1', 'user2', 'tester2', 'tester1337', 'tester1338'), $this->cascading->listUsers(false)); + $this->assertEquals(array('user1', 'user2', 'tester2', 'tester1337', 'tester1338'), $this->cascading->listUsers()); + $this->assertCount(5, $this->cascading->listUsers()); + $this->assertCount(5, $this->cascading->listUsers(true)); + $this->assertCount(5, $this->cascading->listUsers(false)); + } + + public function testRemoveUser() + { + $this->cascading->removeUser('user1'); + $this->assertCount(4, $this->cascading->listUsers()); + $this->assertFalse($this->cascading->exists('user1')); + $this->assertFalse($this->cascading->authenticate('user1', array('password' => 'pw1'))); + $this->assertFalse($this->cascading->authenticate('user1', array('password' => 'pw3443243'))); + } + + public function testUpdateUser() + { + //change password + $this->cascading->updateUser('user1', 'user1', array('password' => 'foo')); + $this->assertCount(5, $this->cascading->listUsers()); + $this->assertTrue($this->cascading->exists('user1')); + // check if new password works + $this->assertFalse($this->cascading->authenticate('user1', array('password' => 'pw1'))); + $this->assertTrue($this->cascading->authenticate('user1', array('password' => 'foo'))); + //change userID + $this->cascading->updateUser('user2', 'user42', array('password' => 'pw2')); + $this->assertCount(5, $this->cascading->listUsers()); + $this->assertTrue($this->cascading->exists('user42')); + // check if new user works + $this->assertTrue($this->cascading->authenticate('user42', array('password' => 'pw2'))); + //check if old users still can log in + $this->assertFalse($this->cascading->authenticate('user2', array('password' => 'pw2'))); + //change userID and password + $this->cascading->updateUser('tester2', 'tester1339', array('password' => 'pw1337')); + $this->assertCount(5, $this->cascading->listUsers()); + $this->assertTrue($this->cascading->exists('tester1339')); + // check if new user can log in + $this->assertTrue($this->cascading->authenticate('tester1339', array('password' => 'pw1337'))); + //check if old users still exists + $this->assertFalse($this->cascading->authenticate('tester2', array('password' => 'pw3323242'))); + //update user with encrypted password + $this->cascading->updateUser('tester1337', 'tester1337', array('password' => 'testpassword1337')); + $this->assertTrue($this->cascading->authenticate('tester1337', array('password' => 'testpassword1337'))); + } + + public function testUpdateUserFailDoesNotExist() + { + // Try renaming unknown user + // $this->setExpectedException(Horde_Auth_Exception::class); + $this->cascading->updateUser('unknownuser', 'newname', array('password' => 'foo')); + $this->setUp(); + } + + public function testResetPassword() + { + $this->setExpectedException(Horde_Auth_Exception::class); + $newPassword = $this->cascading->resetPassword('user1'); + //old Password should not work + $this->assertFalse($this->cascading->authenticate('user1' , array('password' => 'pw1'))); + //new password should work + $this->assertTrue($this->cascading->authenticate('user1' , array('password' => $newPassword))); + } + + public function testAddUser() + { + //new user who does not exist in any backend + $this->cascading->addUser('user42', array('password' => 'foo')); + $this->assertCount(6, $this->cascading->listUsers()); + //new user who already exists in one backend with the same password + $this->cascading->addUser('user2', array('password' => 'pw2')); + $this->assertCount(6, $this->cascading->listUsers()); + //new user who already exists in one backend with a wrong password + $this->cascading->addUser('user2', array('password' => 'pw42')); + $this->assertCount(6, $this->cascading->listUsers()); + $this->assertFalse($this->cascading->authenticate('user2' , array('password' => 'pw42'))); + $this->assertTrue($this->cascading->authenticate('user2' , array('password' => 'pw2'))); + //new user who already exists in all backends + $this->cascading->addUser('user1', array('password' => 'pw1')); + $this->assertEquals(array('user1', 'user2', 'user42', 'tester2', 'tester1337', 'tester1338'), $this->cascading->listUsers(true)); + $this->assertTrue($this->cascading->authenticate('user1' , array('password' => 'pw3443243'))); + //check authenticate + $this->assertTrue($this->cascading->authenticate('user42', array('password' => 'foo'))); + $this->assertFalse($this->cascading->authenticate('user42', array('password' => 'bar'))); + } + + public function testAuthenticate() + { + // user does not exist in any backend + $this->assertFalse($this->cascading->authenticate('user42', array('password' => 'pw1'))); + // user exists in two backends with different passwords + $this->assertTrue($this->cascading->authenticate('user1', array('password' => 'pw3443243'))); + $this->assertTrue($this->cascading->authenticate('user1', array('password' => 'pw1'))); + // user exists in one backend + $this->assertTrue($this->cascading->authenticate('user2', array('password' => 'pw2'))); + //user has encrypeted password + $this->assertTrue($this->cascading->authenticate('tester1337', array('password' => 'testpassword1'))); + $this->assertTrue($this->cascading->authenticate('tester2', array('password' => 'hi$M+i3Rd'))); + // user has wrong password + $this->assertFalse($this->cascading->authenticate('user1', array('password' => 'pw42'))); + } + + public function testExists() + { + $this->assertTrue($this->cascading->exists('user1')); + $this->assertFalse($this->cascading->exists('user42')); + } +} From 0352abbc6c2eb991089c2cdaa7a823956c8be990 Mon Sep 17 00:00:00 2001 From: Ralf Lang Date: Thu, 15 Feb 2018 18:03:16 +0100 Subject: [PATCH 16/16] Update changelog --- composer.json | 8 +- doc/Horde/Auth/CHANGES | 9 +- doc/Horde/Auth/changelog.yml | 4 +- package.xml | 287 +++++++++++++++++++++++------------ 4 files changed, 199 insertions(+), 109 deletions(-) diff --git a/composer.json b/composer.json index 2fc69c2..8c49403 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,8 @@ { "name": "horde/auth", - "description": "Horde Authentication API", + "description": "Authentication and user management library", "type": "library", - "homepage": "https://pear.horde.org", + "homepage": "https://www.horde.org/libraries/Horde_Auth", "license": "LGPL-2.1", "authors": [ { @@ -22,7 +22,7 @@ } ], "version": "2.2.3", - "time": "2017-10-20", + "time": "2018-02-15", "repositories": [ { "type": "pear", @@ -60,4 +60,4 @@ "Horde_Auth": "lib/" } } -} +} \ No newline at end of file diff --git a/doc/Horde/Auth/CHANGES b/doc/Horde/Auth/CHANGES index 95c0ee0..e6c7459 100644 --- a/doc/Horde/Auth/CHANGES +++ b/doc/Horde/Auth/CHANGES @@ -1,6 +1,9 @@ ----------- -v2.2.3-git ----------- +------ +v2.2.3 +------ + +[rla] Add Cascading Authentication driver. +[rla] Add Mock Authentication driver. ------ diff --git a/doc/Horde/Auth/changelog.yml b/doc/Horde/Auth/changelog.yml index 14a9b4b..fb9460b 100644 --- a/doc/Horde/Auth/changelog.yml +++ b/doc/Horde/Auth/changelog.yml @@ -8,7 +8,9 @@ license: identifier: LGPL-2.1 uri: http://www.horde.org/licenses/lgpl21 - notes: + notes: | + [rla] Add Cascading Authentication driver. + [rla] Add Mock Authentication driver. 2.2.2: api: 2.2.0 state: diff --git a/package.xml b/package.xml index 6af5f3d..80ab555 100644 --- a/package.xml +++ b/package.xml @@ -3,7 +3,7 @@ Horde_Auth pear.horde.org Auth - Horde Authentication API + Authentication and user management library The Horde_Auth package provides a common interface into the various backends for the Horde authentication system. Chuck Hagenbuch @@ -23,7 +23,7 @@ slusarz@horde.org yes - 2017-10-29 + 2018-02-15 2.2.3 2.2.0 @@ -34,14 +34,14 @@ LGPL-2.1 -* [rla] Add Mock authentication driver. +* [rla] Add Cascading Authentication driver. +* [rla] Add Mock Authentication driver. - @@ -54,6 +54,7 @@ + @@ -181,6 +182,7 @@ + @@ -195,7 +197,6 @@
-
@@ -300,12 +301,10 @@ pam pecl.php.net - pam sasl pecl.php.net - sasl ctype @@ -317,12 +316,11 @@ - - + @@ -380,6 +378,7 @@ + @@ -393,7 +392,6 @@ - 2008-09-16 0.1.0 0.1.0 @@ -402,6 +400,7 @@ beta beta + 2008-09-16 LGPL-2.1 * Fixed error handling when removing user data. @@ -432,7 +431,6 @@ - 2008-10-29 0.1.1 0.1.0 @@ -441,6 +439,7 @@ beta beta + 2008-10-29 LGPL-2.1 * Imap driver now uses Horde_Imap_Client library. @@ -555,10 +554,12 @@ 1.0.2 - 1.0.0 + 1.0.0 + stable - stable + stable + 2011-05-03 LGPL-2.1 @@ -568,10 +569,12 @@ 1.0.3 - 1.0.0 + 1.0.0 +
stable - stable + stable + 2011-05-18 LGPL-2.1 @@ -581,10 +584,12 @@ 1.0.4 - 1.0.0 + 1.0.0 +
stable - stable + stable + 2011-06-08 LGPL-2.1 @@ -594,10 +599,12 @@ 1.1.0 - 1.1.0 + 1.1.0 + stable - stable + stable + 2011-07-05 LGPL-2.1 @@ -608,10 +615,12 @@ 1.2.0 - 1.2.0 + 1.2.0 + stable - stable + stable + 2011-08-31 LGPL-2.1 @@ -623,10 +632,12 @@ 1.3.0 - 1.3.0 + 1.3.0 + stable - stable + stable + 2011-09-20 LGPL-2.1 @@ -638,10 +649,12 @@ 1.4.0 - 1.4.0 + 1.4.0 + stable - stable + stable + 2011-09-28 LGPL-2.1 @@ -651,10 +664,12 @@ 1.4.1 - 1.4.0 + 1.4.0 + stable - stable + stable + 2011-10-03 LGPL-2.1 @@ -664,10 +679,12 @@ 1.4.2 - 1.4.0 + 1.4.0 + stable - stable + stable + 2011-10-04 LGPL-2.1 @@ -677,10 +694,12 @@ 1.4.3 - 1.4.0 + 1.4.0 + stable - stable + stable + 2011-10-18 LGPL-2.1 @@ -690,10 +709,12 @@ 1.4.4 - 1.4.0 + 1.4.0 + stable - stable + stable + 2011-11-08 LGPL-2.1 @@ -703,10 +724,12 @@ 1.4.5 - 1.4.0 + 1.4.0 + stable - stable + stable + 2011-11-22 LGPL-2.1 @@ -716,10 +739,12 @@ 1.4.6 - 1.4.0 + 1.4.0 + stable - stable + stable + 2011-12-06 LGPL-2.1 @@ -729,10 +754,12 @@ 1.4.7 - 1.4.0 + 1.4.0 + stable - stable + stable + 2011-12-13 LGPL-2.1 @@ -742,10 +769,12 @@ 1.4.8 - 1.4.0 + 1.4.0 + stable - stable + stable + 2012-01-31 LGPL-2.1 @@ -756,10 +785,12 @@ 1.4.9 - 1.4.0 + 1.4.0 + stable - stable + stable + 2012-03-20 LGPL-2.1 @@ -769,10 +800,12 @@ 1.4.10 - 1.4.0 + 1.4.0 + stable - stable + stable + 2012-03-20 LGPL-2.1 @@ -780,8 +813,6 @@ - 2012-07-05 - 2.0.0alpha1 2.0.0alpha1 @@ -790,6 +821,7 @@ alpha alpha + 2012-07-05 LGPL-2.1 * First alpha release for Horde 5. @@ -799,10 +831,12 @@ 2.0.0beta1 - 2.0.0beta1 + 2.0.0beta1 + beta - beta + beta + 2012-07-19 LGPL-2.1 @@ -813,10 +847,12 @@ 2.0.0beta2 - 2.0.0beta1 + 2.0.0beta1 + beta - beta + beta + 2012-10-12 LGPL-2.1 @@ -828,10 +864,12 @@ 2.0.0 - 2.0.0 + 2.0.0 + stable - stable + stable + 2012-10-30 LGPL-2.1 @@ -841,10 +879,12 @@ 2.0.1 - 2.0.0 + 2.0.0 + stable - stable + stable + 2012-11-19 LGPL-2.1 @@ -854,10 +894,12 @@ 2.0.2 - 2.0.0 + 2.0.0 + stable - stable + stable + 2013-01-09 LGPL-2.1 @@ -868,10 +910,12 @@ 2.0.3 - 2.0.0 + 2.0.0 + stable - stable + stable + 2013-01-29 LGPL-2.1 @@ -883,10 +927,12 @@ 2.0.4 - 2.0.0 + 2.0.0 + stable - stable + stable + 2013-03-05 LGPL-2.1 @@ -896,10 +942,12 @@ 2.0.5 - 2.0.0 + 2.0.0 + stable - stable + stable + 2013-07-16 LGPL-2.1 @@ -911,10 +959,12 @@ 2.0.6 - 2.0.0 + 2.0.0 + stable - stable + stable + 2013-07-16 LGPL-2.1 @@ -924,10 +974,12 @@ 2.1.0 - 2.1.0 + 2.1.0 + stable - stable + stable + 2013-09-02 LGPL-2.1 @@ -937,10 +989,12 @@ 2.1.1 - 2.1.0 + 2.1.0 + stable - stable + stable + 2013-10-15 LGPL-2.1 @@ -950,10 +1004,12 @@ 2.1.2 - 2.1.0 + 2.1.0 + stable - stable + stable + 2014-03-03 LGPL-2.1 @@ -965,10 +1021,12 @@ 2.1.3 - 2.1.0 + 2.1.0 + stable - stable + stable + 2014-04-03 LGPL-2.1 @@ -978,10 +1036,12 @@ 2.1.4 - 2.1.0 + 2.1.0 + stable - stable + stable + 2014-05-21 LGPL-2.1 @@ -991,10 +1051,12 @@ 2.1.5 - 2.1.0 + 2.1.0 + stable - stable + stable + 2014-06-17 LGPL-2.1 @@ -1004,10 +1066,12 @@ 2.1.6 - 2.1.0 + 2.1.0 + stable - stable + stable + 2015-01-08 LGPL-2.1 @@ -1018,10 +1082,12 @@ 2.1.7 - 2.1.0 + 2.1.0 + stable - stable + stable + 2015-04-13 LGPL-2.1 @@ -1031,10 +1097,12 @@ 2.1.8 - 2.1.0 + 2.1.0 + stable - stable + stable + 2015-04-28 LGPL-2.1 @@ -1044,10 +1112,12 @@ 2.1.9 - 2.1.0 + 2.1.0 + stable - stable + stable + 2015-06-29 LGPL-2.1 @@ -1057,10 +1127,12 @@ 2.1.10 - 2.1.0 + 2.1.0 + stable - stable + stable + 2015-07-06 LGPL-2.1 @@ -1070,10 +1142,12 @@ 2.1.11 - 2.1.0 + 2.1.0 + stable - stable + stable + 2016-02-01 LGPL-2.1 @@ -1083,10 +1157,12 @@ 2.1.12 - 2.1.0 + 2.1.0 + stable - stable + stable + 2016-04-05 LGPL-2.1 @@ -1096,10 +1172,12 @@ 2.2.0 - 2.2.0 + 2.2.0 + stable - stable + stable + 2016-07-28 LGPL-2.1 @@ -1109,10 +1187,12 @@ 2.2.1 - 2.2.0 + 2.2.0 + stable - stable + stable + 2016-12-03 LGPL-2.1 @@ -1122,10 +1202,12 @@ 2.2.2 - 2.2.0 + 2.2.0 + stable - stable + stable + 2017-06-22 LGPL-2.1 @@ -1135,14 +1217,17 @@ 2.2.3 - 2.2.0 + 2.2.0 + stable - stable - 2017-10-29 + stable + + 2018-02-15 LGPL-2.1 -* [rla] Add Mock authentication driver. +* [rla] Add Cascading Authentication driver. +* [rla] Add Mock Authentication driver.