From 01d12ec74e97d2657baaf3e27b448b763fee1a0f Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 16 Mar 2016 00:45:30 +0100 Subject: fix writing to cache when fallback server should be used immediately --- apps/user_ldap/lib/connection.php | 14 ++++++- apps/user_ldap/tests/connection.php | 78 ++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index e0ee4d5780b..2ab1a0fc6c2 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -178,6 +178,16 @@ class Connection extends LDAPUtility { return $this->ldapConnectionRes; } + /** + * resets the connection resource + */ + public function resetConnectionResource() { + if(!is_null($this->ldapConnectionRes)) { + @$this->ldap->unbind($this->ldapConnectionRes); + $this->ldapConnectionRes = null; + } + } + /** * @param string|null $key * @return string @@ -529,7 +539,7 @@ class Connection extends LDAPUtility { } $bindStatus = false; - $error = null; + $error = -1; try { if (!$this->configuration->ldapOverrideMainServer && !$this->getFromCache('overrideMainServer') @@ -557,7 +567,7 @@ class Connection extends LDAPUtility { $this->doConnect($this->configuration->ldapBackupHost, $this->configuration->ldapBackupPort); $bindStatus = $this->bind(); - if($bindStatus && $error === -1) { + if($bindStatus && $error === -1 && !$this->getFromCache('overrideMainServer')) { //when bind to backup server succeeded and failed to main server, //skip contacting him until next cache refresh $this->writeToCache('overrideMainServer', true); diff --git a/apps/user_ldap/tests/connection.php b/apps/user_ldap/tests/connection.php index b0b4b78ce4d..bf42b2605fd 100644 --- a/apps/user_ldap/tests/connection.php +++ b/apps/user_ldap/tests/connection.php @@ -22,8 +22,29 @@ */ namespace OCA\user_ldap\tests; +use OCA\user_ldap\lib\Connection; class Test_Connection extends \Test\TestCase { + /** @var \OCA\user_ldap\lib\ILDAPWrapper */ + protected $ldap; + + /** @var Connection */ + protected $connection; + + public function setUp() { + parent::setUp(); + + $this->ldap = $this->getMock('\OCA\user_ldap\lib\ILDAPWrapper'); + // we use a mock here to replace the cache mechanism, due to missing DI in LDAP backend. + $this->connection = $this->getMockBuilder('OCA\user_ldap\lib\Connection') + ->setMethods(['getFromCache', 'writeToCache']) + ->setConstructorArgs([$this->ldap, '', null]) + ->getMock(); + + $this->ldap->expects($this->any()) + ->method('areLDAPFunctionsAvailable') + ->will($this->returnValue(true)); + } public function testOriginalAgentUnchangedOnClone() { //background: upon login a bind is done with the user credentials @@ -31,7 +52,7 @@ class Test_Connection extends \Test\TestCase { //to the agent's credentials $lw = $this->getMock('\OCA\user_ldap\lib\ILDAPWrapper'); - $connection = new \OCA\user_ldap\lib\Connection($lw, '', null); + $connection = new Connection($lw, '', null); $agent = array( 'ldapAgentName' => 'agent', 'ldapAgentPassword' => '123456', @@ -52,4 +73,59 @@ class Test_Connection extends \Test\TestCase { $this->assertSame($agentPawd, $agent['ldapAgentPassword']); } + public function testUseBackupServer() { + $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') + ->will($this->returnValue(true)); + + $this->ldap->expects($this->any()) + ->method('setOption') + ->will($this->returnValue(true)); + + $this->ldap->expects($this->exactly(3)) + ->method('connect') + ->will($this->returnValue('ldapResource')); + + // Not called often enough? Then, the fallback to the backup server is broken. + $this->connection->expects($this->exactly(4)) + ->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') + ->will($this->returnCallback(function () use (&$isThrown) { + if(!$isThrown) { + $isThrown = true; + throw new \OC\ServerNotAvailableException(); + } + return true; + })); + + $this->connection->init(); + $this->connection->resetConnectionResource(); + // with the second init() we test whether caching works + $this->connection->init(); + } + } \ No newline at end of file -- cgit v1.2.3