From 7c64e1973fdcb41758c221118c6167668a563953 Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle <bjoern@schiessle.org>
Date: Mon, 11 Jul 2016 15:51:48 +0200
Subject: [PATCH] add test for needsRebundling() check

---
 lib/private/Security/CertificateManager.php   | 12 ++-
 tests/lib/Security/CertificateManagerTest.php | 92 +++++++++++++++++++
 2 files changed, 103 insertions(+), 1 deletion(-)

diff --git a/lib/private/Security/CertificateManager.php b/lib/private/Security/CertificateManager.php
index 77d0c844b8c..1639df01a21 100644
--- a/lib/private/Security/CertificateManager.php
+++ b/lib/private/Security/CertificateManager.php
@@ -233,7 +233,7 @@ class CertificateManager implements ICertificateManager {
 		if ($uid === '') {
 			$uid = $this->uid;
 		}
-		$sourceMTimes = [filemtime(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt')];
+		$sourceMTimes = [$this->getFilemtimeOfCaBundle()];
 		$targetBundle = $this->getCertificateBundle($uid);
 		if (!$this->view->file_exists($targetBundle)) {
 			return true;
@@ -248,4 +248,14 @@ class CertificateManager implements ICertificateManager {
 		}, 0);
 		return $sourceMTime > $this->view->filemtime($targetBundle);
 	}
+
+	/**
+	 * get mtime of ca-bundle shipped by Nextcloud
+	 *
+	 * @return int
+	 */
+	protected function getFilemtimeOfCaBundle() {
+		return filemtime(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
+	}
+
 }
diff --git a/tests/lib/Security/CertificateManagerTest.php b/tests/lib/Security/CertificateManagerTest.php
index 43206569cf4..3abd3392e6c 100644
--- a/tests/lib/Security/CertificateManagerTest.php
+++ b/tests/lib/Security/CertificateManagerTest.php
@@ -118,4 +118,96 @@ class CertificateManagerTest extends \Test\TestCase {
 		$this->assertSame('/' . $this->username . '/files_external/rootcerts.crt', $this->certificateManager->getCertificateBundle());
 	}
 
+	/**
+	 * @dataProvider dataTestNeedRebundling
+	 *
+	 * @param string $uid
+	 * @param int $CaBundleMtime
+	 * @param int $systemWideMtime
+	 * @param int $targetBundleMtime
+	 * @param int $targetBundleExists
+	 * @param bool $expected
+	 */
+	function testNeedRebundling($uid,
+								$CaBundleMtime,
+								$systemWideMtime,
+								$targetBundleMtime,
+								$targetBundleExists,
+								$expected
+	) {
+
+		$view = $this->getMockBuilder('OC\Files\View')
+			->disableOriginalConstructor()->getMock();
+		$config = $this->getMock('OCP\IConfig');
+
+		/** @var CertificateManager | \PHPUnit_Framework_MockObject_MockObject $certificateManager */
+		$certificateManager = $this->getMockBuilder('OC\Security\CertificateManager')
+			->setConstructorArgs([$uid, $view, $config])
+			->setMethods(['getFilemtimeOfCaBundle', 'getCertificateBundle'])
+			->getMock();
+
+		$certificateManager->expects($this->any())->method('getFilemtimeOfCaBundle')
+			->willReturn($CaBundleMtime);
+
+		$certificateManager->expects($this->at(1))->method('getCertificateBundle')
+			->with($uid)->willReturn('targetBundlePath');
+
+		$view->expects($this->any())->method('file_exists')
+			->with('targetBundlePath')
+			->willReturn($targetBundleExists);
+
+
+		if ($uid !== null && $targetBundleExists) {
+			$certificateManager->expects($this->at(2))->method('getCertificateBundle')
+				->with(null)->willReturn('SystemBundlePath');
+
+		}
+
+		$view->expects($this->any())->method('filemtime')
+			->willReturnCallback(function($path) use ($systemWideMtime, $targetBundleMtime)  {
+				if ($path === 'SystemBundlePath') {
+					return $systemWideMtime;
+				} elseif ($path === 'targetBundlePath') {
+					return $targetBundleMtime;
+				}
+				throw new \Exception('unexpected path');
+			});
+
+
+		$this->assertSame($expected,
+			$this->invokePrivate($certificateManager, 'needsRebundling', [$uid])
+		);
+
+	}
+
+	function dataTestNeedRebundling() {
+		return [
+			//values: uid, CaBundleMtime, systemWideMtime, targetBundleMtime, targetBundleExists, expected
+
+			// compare minimum of CaBundleMtime and systemWideMtime with targetBundleMtime
+			['user1', 10, 20, 30, true, false],
+			['user1', 10, 20, 15, true, true],
+			['user1', 10, 5, 30, true, false],
+			['user1', 10, 5, 8, true, true],
+
+			// if no user exists we ignore 'systemWideMtime' because this is the bundle we re-build
+			[null, 10, 20, 30, true, false],
+			[null, 10, 20, 15, true, false],
+			[null, 10, 20, 8, true, true],
+			[null, 10, 5, 30, true, false],
+			[null, 10, 5, 8, true, true],
+
+			// if no target bundle exists we always build a new one
+			['user1', 10, 20, 30, false, true],
+			['user1', 10, 20, 15, false, true],
+			['user1', 10, 5, 30, false, true],
+			['user1', 10, 5, 8, false, true],
+			[null, 10, 20, 30, false, true],
+			[null, 10, 20, 15, false, true],
+			[null, 10, 20, 8, false, true],
+			[null, 10, 5, 30, false, true],
+			[null, 10, 5, 8, false, true],
+		];
+	}
+
 }
-- 
GitLab