diff --git a/apps/user_ldap/lib/Access.php b/apps/user_ldap/lib/Access.php index f06f76bb91..d88378c188 100644 --- a/apps/user_ldap/lib/Access.php +++ b/apps/user_ldap/lib/Access.php @@ -226,9 +226,12 @@ class Access extends LDAPUtility implements IUserTools { /** * Set password for an LDAP user identified by a DN + * * @param string $userDN the user in question * @param string $password the new password * @return bool + * @throws HintException + * @throws \Exception */ public function setPassword($userDN, $password) { if(intval($this->connection->turnOnPasswordChange) !== 1) { diff --git a/apps/user_ldap/lib/Connection.php b/apps/user_ldap/lib/Connection.php index 6028486e8b..d74afa42fe 100644 --- a/apps/user_ldap/lib/Connection.php +++ b/apps/user_ldap/lib/Connection.php @@ -42,6 +42,7 @@ use OC\ServerNotAvailableException; * @property string ldapUserFilter * @property string ldapUserDisplayName * @property string ldapUserDisplayName2 + * @property boolean turnOnPasswordChange * @property boolean hasPagedResultSupport * @property string[] ldapBaseUsers * @property int|string ldapPagingSize holds an integer diff --git a/apps/user_ldap/lib/LDAP.php b/apps/user_ldap/lib/LDAP.php index 0d491396ee..cac09f2599 100644 --- a/apps/user_ldap/lib/LDAP.php +++ b/apps/user_ldap/lib/LDAP.php @@ -260,7 +260,7 @@ class LDAP implements ILDAPWrapper { /** * @return mixed */ - private function invokeLDAPMethod() { + protected function invokeLDAPMethod() { $arguments = func_get_args(); $func = 'ldap_' . array_shift($arguments); if(function_exists($func)) { diff --git a/apps/user_ldap/tests/AccessTest.php b/apps/user_ldap/tests/AccessTest.php index d7d04e31d0..271e8eb605 100644 --- a/apps/user_ldap/tests/AccessTest.php +++ b/apps/user_ldap/tests/AccessTest.php @@ -1,12 +1,14 @@ * * @author Andreas Fischer * @author Arthur Schiwon * @author Joas Schilling * @author Morris Jobke * @author Thomas Müller + * @author Lukas Reschke * * @license AGPL-3.0 * @@ -28,9 +30,11 @@ namespace OCA\User_LDAP\Tests; use OCA\User_LDAP\Access; use OCA\User_LDAP\Connection; +use OCA\User_LDAP\Exceptions\ConstraintViolationException; use OCA\User_LDAP\FilesystemHelper; use OCA\User_LDAP\Helper; use OCA\User_LDAP\ILDAPWrapper; +use OCA\User_LDAP\LDAP; use OCA\User_LDAP\LogWrapper; use OCA\User_LDAP\User\Manager; use OCP\IAvatarManager; @@ -47,6 +51,31 @@ use OCP\IUserManager; * @package OCA\User_LDAP\Tests */ class AccessTest extends \Test\TestCase { + /** @var Connection|\PHPUnit_Framework_MockObject_MockObject */ + private $connection; + /** @var LDAP|\PHPUnit_Framework_MockObject_MockObject */ + private $ldap; + /** @var Manager|\PHPUnit_Framework_MockObject_MockObject */ + private $userManager; + /** @var Helper|\PHPUnit_Framework_MockObject_MockObject */ + private $helper; + /** @var Access */ + private $access; + + public function setUp() { + $this->connection = $this->createMock(Connection::class); + $this->ldap = $this->createMock(LDAP::class); + $this->userManager = $this->createMock(Manager::class); + $this->helper = $this->createMock(Helper::class); + + $this->access = new Access( + $this->connection, + $this->ldap, + $this->userManager, + $this->helper + ); + } + private function getConnectorAndLdapMock() { $lw = $this->createMock(ILDAPWrapper::class); $connector = $this->getMockBuilder(Connection::class) @@ -317,4 +346,84 @@ class AccessTest extends \Test\TestCase { $values = $access->readAttribute('uid=whoever,dc=example,dc=org', $attribute); $this->assertSame($values[0], strtolower($dnFromServer)); } + + /** + * @expectedException \Exception + * @expectedExceptionMessage LDAP password changes are disabled + */ + public function testSetPasswordWithDisabledChanges() { + $this->connection + ->method('__get') + ->willReturn(false); + + $this->access->setPassword('CN=foo', 'MyPassword'); + } + + public function testSetPasswordWithLdapNotAvailable() { + $this->connection + ->method('__get') + ->willReturn(true); + $connection = $this->createMock(LDAP::class); + $this->connection + ->expects($this->once()) + ->method('getConnectionResource') + ->willReturn($connection); + $this->ldap + ->expects($this->once()) + ->method('isResource') + ->with($connection) + ->willReturn(false); + + $this->assertFalse($this->access->setPassword('CN=foo', 'MyPassword')); + } + + /** + * @expectedException \OC\HintException + * @expectedExceptionMessage Password change rejected. + */ + public function testSetPasswordWithRejectedChange() { + $this->connection + ->method('__get') + ->willReturn(true); + $connection = $this->createMock(LDAP::class); + $this->connection + ->expects($this->once()) + ->method('getConnectionResource') + ->willReturn($connection); + $this->ldap + ->expects($this->once()) + ->method('isResource') + ->with($connection) + ->willReturn(true); + $this->ldap + ->expects($this->once()) + ->method('modReplace') + ->with($connection, 'CN=foo', 'MyPassword') + ->willThrowException(new ConstraintViolationException()); + + $this->access->setPassword('CN=foo', 'MyPassword'); + } + + public function testSetPassword() { + $this->connection + ->method('__get') + ->willReturn(true); + $connection = $this->createMock(LDAP::class); + $this->connection + ->expects($this->once()) + ->method('getConnectionResource') + ->willReturn($connection); + $this->ldap + ->expects($this->once()) + ->method('isResource') + ->with($connection) + ->willReturn(true); + $this->ldap + ->expects($this->once()) + ->method('modReplace') + ->with($connection, 'CN=foo', 'MyPassword') + ->willReturn(true); + + $this->assertTrue($this->access->setPassword('CN=foo', 'MyPassword')); + } } diff --git a/apps/user_ldap/tests/LDAPTest.php b/apps/user_ldap/tests/LDAPTest.php new file mode 100644 index 0000000000..1ac8cef12d --- /dev/null +++ b/apps/user_ldap/tests/LDAPTest.php @@ -0,0 +1,50 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\User_LDAP\Tests; + +use OCA\User_LDAP\LDAP; +use Test\TestCase; + +class LDAPTest extends TestCase { + /** @var LDAP|\PHPUnit_Framework_MockObject_MockObject */ + private $ldap; + + public function setUp() { + parent::setUp(); + $this->ldap = $this->getMockBuilder(LDAP::class) + ->setMethods(['invokeLDAPMethod']) + ->getMock(); + } + + public function testModReplace() { + $link = $this->createMock(LDAP::class); + $userDN = 'CN=user'; + $password = 'MyPassword'; + $this->ldap + ->expects($this->once()) + ->method('invokeLDAPMethod') + ->with('mod_replace', $link, $userDN, array('userPassword' => $password)) + ->willReturn(true); + + $this->assertTrue($this->ldap->modReplace($link, $userDN, $password)); + } +} diff --git a/apps/user_ldap/tests/User_LDAPTest.php b/apps/user_ldap/tests/User_LDAPTest.php index 958d0b5197..606eff4e7a 100644 --- a/apps/user_ldap/tests/User_LDAPTest.php +++ b/apps/user_ldap/tests/User_LDAPTest.php @@ -38,7 +38,9 @@ use OCA\User_LDAP\LogWrapper; use OCA\User_LDAP\User\Manager; use OCA\User_LDAP\User\OfflineUser; use OC\HintException; +use OCA\User_LDAP\User\User; use OCA\User_LDAP\User_LDAP as UserLDAP; +use OCA\User_LDAP\User_LDAP; use OCP\IAvatarManager; use OCP\IConfig; use OCP\IDBConnection; @@ -1058,4 +1060,45 @@ class User_LDAPTest extends TestCase { $this->assertFalse(\OC_User::setPassword('roland', 'dt12234$')); } + + /** + * @expectedException \Exception + * @expectedExceptionMessage LDAP setPassword: Could not get user object for uid NotExistingUser. Maybe the LDAP entry has no set display name attribute? + */ + public function testSetPasswordWithInvalidUser() { + $access = $this->createMock(Access::class); + $access->userManager = $this->createMock(IUserManager::class); + $access->userManager + ->expects($this->once()) + ->method('get') + ->with('NotExistingUser') + ->willReturn(null); + $config = $this->createMock(IConfig::class); + $ldap = new User_LDAP( + $access, + $config + ); + $ldap->setPassword('NotExistingUser', 'Password'); + } + + public function testSetPasswordWithUsernameFalse() { + $user = $this->createMock(User::class); + $user + ->expects($this->once()) + ->method('getUsername') + ->willReturn(false); + $access = $this->createMock(Access::class); + $access->userManager = $this->createMock(IUserManager::class); + $access->userManager + ->expects($this->once()) + ->method('get') + ->with('NotExistingUser') + ->willReturn($user); + $config = $this->createMock(IConfig::class); + $ldap = new User_LDAP( + $access, + $config + ); + $this->assertFalse($ldap->setPassword('NotExistingUser', 'Password')); + } } diff --git a/apps/user_ldap/tests/User_ProxyTest.php b/apps/user_ldap/tests/User_ProxyTest.php new file mode 100644 index 0000000000..6d779d758e --- /dev/null +++ b/apps/user_ldap/tests/User_ProxyTest.php @@ -0,0 +1,61 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\User_LDAP\Tests; + +use OCA\User_LDAP\ILDAPWrapper; +use OCA\User_LDAP\User_Proxy; +use OCP\IConfig; +use Test\TestCase; + +class User_ProxyTest extends TestCase { + /** @var ILDAPWrapper|\PHPUnit_Framework_MockObject_MockObject */ + private $ldapWrapper; + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + private $config; + /** @var User_Proxy|\PHPUnit_Framework_MockObject_MockObject */ + private $proxy; + + public function setUp() { + parent::setUp(); + + $this->ldapWrapper = $this->createMock(ILDAPWrapper::class); + $this->config = $this->createMock(IConfig::class); + $this->proxy = $this->getMockBuilder(User_Proxy::class) + ->setConstructorArgs([ + [], + $this->ldapWrapper, + $this->config, + ]) + ->setMethods(['handleRequest']) + ->getMock(); + } + + public function testSetPassword() { + $this->proxy + ->expects($this->once()) + ->method('handleRequest') + ->with('MyUid', 'setPassword', ['MyUid', 'MyPassword']) + ->willReturn(true); + + $this->assertTrue($this->proxy->setPassword('MyUid', 'MyPassword')); + } +}