123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- <?php
- /**
- * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
- * SPDX-License-Identifier: AGPL-3.0-only
- */
- namespace OCA\User_LDAP\Tests;
- use OC\ServerNotAvailableException;
- use OCA\User_LDAP\Connection;
- use OCA\User_LDAP\ILDAPWrapper;
- /**
- * Class Test_Connection
- *
- * @group DB
- *
- * @package OCA\User_LDAP\Tests
- */
- class ConnectionTest extends \Test\TestCase {
- /** @var ILDAPWrapper|\PHPUnit\Framework\MockObject\MockObject */
- protected $ldap;
- /** @var Connection */
- protected $connection;
- protected function setUp(): void {
- parent::setUp();
- $this->ldap = $this->createMock(ILDAPWrapper::class);
- // we use a mock here to replace the cache mechanism, due to missing DI in LDAP backend.
- $this->connection = $this->getMockBuilder('OCA\User_LDAP\Connection')
- ->setMethods(['getFromCache', 'writeToCache'])
- ->setConstructorArgs([$this->ldap, '', null])
- ->getMock();
- $this->ldap->expects($this->any())
- ->method('areLDAPFunctionsAvailable')
- ->willReturn(true);
- }
- public function testOriginalAgentUnchangedOnClone(): void {
- //background: upon login a bind is done with the user credentials
- //which is valid for the whole LDAP resource. It needs to be reset
- //to the agent's credentials
- $lw = $this->createMock(ILDAPWrapper::class);
- $connection = new Connection($lw, '', null);
- $agent = [
- 'ldapAgentName' => 'agent',
- 'ldapAgentPassword' => '123456',
- ];
- $connection->setConfiguration($agent);
- $testConnection = clone $connection;
- $user = [
- 'ldapAgentName' => 'user',
- 'ldapAgentPassword' => 'password',
- ];
- $testConnection->setConfiguration($user);
- $agentName = $connection->ldapAgentName;
- $agentPawd = $connection->ldapAgentPassword;
- $this->assertSame($agentName, $agent['ldapAgentName']);
- $this->assertSame($agentPawd, $agent['ldapAgentPassword']);
- }
- public function testUseBackupServer(): void {
- $mainHost = 'ldap://nixda.ldap';
- $backupHost = 'ldap://fallback.ldap';
- $config = [
- 'ldapConfigurationActive' => true,
- 'ldapHost' => $mainHost,
- 'ldapPort' => 389,
- 'ldapBackupHost' => $backupHost,
- 'ldapBackupPort' => 389,
- 'ldapAgentName' => 'uid=agent',
- 'ldapAgentPassword' => 'SuchASecret'
- ];
- $this->connection->setIgnoreValidation(true);
- $this->connection->setConfiguration($config);
- $this->ldap->expects($this->any())
- ->method('isResource')
- ->willReturn(true);
- $this->ldap->expects($this->any())
- ->method('setOption')
- ->willReturn(true);
- $this->ldap->expects($this->exactly(3))
- ->method('connect')
- ->willReturn(ldap_connect('ldap://example.com'));
- $this->ldap->expects($this->any())
- ->method('errno')
- ->willReturn(0);
- // Not called often enough? Then, the fallback to the backup server is broken.
- $this->connection->expects($this->exactly(2))
- ->method('getFromCache')
- ->with('overrideMainServer')
- ->will($this->onConsecutiveCalls(false, false, true, true));
- $this->connection->expects($this->once())
- ->method('writeToCache')
- ->with('overrideMainServer', true);
- $isThrown = false;
- $this->ldap->expects($this->exactly(3))
- ->method('bind')
- ->willReturnCallback(function () use (&$isThrown) {
- if (!$isThrown) {
- $isThrown = true;
- throw new ServerNotAvailableException();
- }
- return true;
- });
- $this->connection->init();
- $this->connection->resetConnectionResource();
- // with the second init() we test whether caching works
- $this->connection->init();
- }
- public function testDontUseBackupServerOnFailedAuth(): void {
- $mainHost = 'ldap://nixda.ldap';
- $backupHost = 'ldap://fallback.ldap';
- $config = [
- 'ldapConfigurationActive' => true,
- 'ldapHost' => $mainHost,
- 'ldapPort' => 389,
- 'ldapBackupHost' => $backupHost,
- 'ldapBackupPort' => 389,
- 'ldapAgentName' => 'uid=agent',
- 'ldapAgentPassword' => 'SuchASecret'
- ];
- $this->connection->setIgnoreValidation(true);
- $this->connection->setConfiguration($config);
- $this->ldap->expects($this->any())
- ->method('isResource')
- ->willReturn(true);
- $this->ldap->expects($this->any())
- ->method('setOption')
- ->willReturn(true);
- $this->ldap->expects($this->once())
- ->method('connect')
- ->willReturn(ldap_connect('ldap://example.com'));
- $this->ldap->expects($this->any())
- ->method('errno')
- ->willReturn(49);
- $this->connection->expects($this->any())
- ->method('getFromCache')
- ->with('overrideMainServer')
- ->willReturn(false);
- $this->connection->expects($this->never())
- ->method('writeToCache');
- $this->ldap->expects($this->exactly(1))
- ->method('bind')
- ->willReturn(false);
- $this->connection->init();
- }
- public function testBindWithInvalidCredentials(): void {
- // background: Bind with invalid credentials should return false
- // and not throw a ServerNotAvailableException.
- $host = 'ldap://nixda.ldap';
- $config = [
- 'ldapConfigurationActive' => true,
- 'ldapHost' => $host,
- 'ldapPort' => 389,
- 'ldapBackupHost' => '',
- 'ldapAgentName' => 'user',
- 'ldapAgentPassword' => 'password'
- ];
- $this->connection->setIgnoreValidation(true);
- $this->connection->setConfiguration($config);
- $this->ldap->expects($this->any())
- ->method('isResource')
- ->willReturn(true);
- $this->ldap->expects($this->any())
- ->method('setOption')
- ->willReturn(true);
- $this->ldap->expects($this->any())
- ->method('connect')
- ->willReturn(ldap_connect('ldap://example.com'));
- $this->ldap->expects($this->once())
- ->method('bind')
- ->willReturn(false);
- // LDAP_INVALID_CREDENTIALS
- $this->ldap->expects($this->any())
- ->method('errno')
- ->willReturn(0x31);
- try {
- $this->assertFalse($this->connection->bind(), 'Connection::bind() should not return true with invalid credentials.');
- } catch (ServerNotAvailableException $e) {
- $this->fail('Failed asserting that exception of type "OC\ServerNotAvailableException" is not thrown.');
- }
- }
- public function testStartTlsNegotiationFailure(): void {
- // background: If Start TLS negotiation fails,
- // a ServerNotAvailableException should be thrown.
- $host = 'ldap://nixda.ldap';
- $port = 389;
- $config = [
- 'ldapConfigurationActive' => true,
- 'ldapHost' => $host,
- 'ldapPort' => $port,
- 'ldapTLS' => true,
- 'ldapBackupHost' => '',
- 'ldapAgentName' => 'user',
- 'ldapAgentPassword' => 'password'
- ];
- $this->connection->setIgnoreValidation(true);
- $this->connection->setConfiguration($config);
- $this->ldap->expects($this->any())
- ->method('isResource')
- ->willReturn(true);
- $this->ldap->expects($this->any())
- ->method('connect')
- ->willReturn(ldap_connect('ldap://example.com'));
- $this->ldap->expects($this->any())
- ->method('setOption')
- ->willReturn(true);
- $this->ldap->expects($this->any())
- ->method('bind')
- ->willReturn(true);
- $this->ldap->expects($this->any())
- ->method('errno')
- ->willReturn(0);
- $this->ldap->expects($this->any())
- ->method('startTls')
- ->willReturn(false);
- $this->expectException(ServerNotAvailableException::class);
- $this->expectExceptionMessage('Start TLS failed, when connecting to LDAP host ' . $host . '.');
- $this->connection->init();
- }
- }
|