1
0

KeyManagerTest.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\Encryption\Tests;
  8. use OC\Files\FileInfo;
  9. use OC\Files\View;
  10. use OCA\Encryption\Crypto\Crypt;
  11. use OCA\Encryption\Crypto\Encryption;
  12. use OCA\Encryption\Exceptions\PrivateKeyMissingException;
  13. use OCA\Encryption\Exceptions\PublicKeyMissingException;
  14. use OCA\Encryption\KeyManager;
  15. use OCA\Encryption\Session;
  16. use OCA\Encryption\Util;
  17. use OCP\Encryption\Keys\IStorage;
  18. use OCP\Files\Cache\ICache;
  19. use OCP\Files\Storage\IStorage as FilesIStorage;
  20. use OCP\IConfig;
  21. use OCP\IUserSession;
  22. use OCP\Lock\ILockingProvider;
  23. use OCP\Lock\LockedException;
  24. use PHPUnit\Framework\MockObject\MockObject;
  25. use Psr\Log\LoggerInterface;
  26. use Test\TestCase;
  27. class KeyManagerTest extends TestCase {
  28. /**
  29. * @var KeyManager
  30. */
  31. private $instance;
  32. /**
  33. * @var string
  34. */
  35. private $userId;
  36. /** @var string */
  37. private $systemKeyId;
  38. /** @var \OCP\Encryption\Keys\IStorage|\PHPUnit\Framework\MockObject\MockObject */
  39. private $keyStorageMock;
  40. /** @var Crypt|\PHPUnit\Framework\MockObject\MockObject */
  41. private $cryptMock;
  42. /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
  43. private $userMock;
  44. /** @var Session|\PHPUnit\Framework\MockObject\MockObject */
  45. private $sessionMock;
  46. /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
  47. private $logMock;
  48. /** @var Util|\PHPUnit\Framework\MockObject\MockObject */
  49. private $utilMock;
  50. /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
  51. private $configMock;
  52. /** @var ILockingProvider|MockObject */
  53. private $lockingProviderMock;
  54. protected function setUp(): void {
  55. parent::setUp();
  56. $this->userId = 'user1';
  57. $this->systemKeyId = 'systemKeyId';
  58. $this->keyStorageMock = $this->createMock(IStorage::class);
  59. $this->cryptMock = $this->getMockBuilder(Crypt::class)
  60. ->disableOriginalConstructor()
  61. ->getMock();
  62. $this->configMock = $this->createMock(IConfig::class);
  63. $this->configMock->expects($this->any())
  64. ->method('getAppValue')
  65. ->willReturn($this->systemKeyId);
  66. $this->userMock = $this->createMock(IUserSession::class);
  67. $this->sessionMock = $this->getMockBuilder(Session::class)
  68. ->disableOriginalConstructor()
  69. ->getMock();
  70. $this->logMock = $this->createMock(LoggerInterface::class);
  71. $this->utilMock = $this->getMockBuilder(Util::class)
  72. ->disableOriginalConstructor()
  73. ->getMock();
  74. $this->lockingProviderMock = $this->createMock(ILockingProvider::class);
  75. $this->instance = new KeyManager(
  76. $this->keyStorageMock,
  77. $this->cryptMock,
  78. $this->configMock,
  79. $this->userMock,
  80. $this->sessionMock,
  81. $this->logMock,
  82. $this->utilMock,
  83. $this->lockingProviderMock
  84. );
  85. }
  86. public function testDeleteShareKey(): void {
  87. $this->keyStorageMock->expects($this->any())
  88. ->method('deleteFileKey')
  89. ->with($this->equalTo('/path'), $this->equalTo('keyId.shareKey'))
  90. ->willReturn(true);
  91. $this->assertTrue(
  92. $this->instance->deleteShareKey('/path', 'keyId')
  93. );
  94. }
  95. public function testGetPrivateKey(): void {
  96. $this->keyStorageMock->expects($this->any())
  97. ->method('getUserKey')
  98. ->with($this->equalTo($this->userId), $this->equalTo('privateKey'))
  99. ->willReturn('privateKey');
  100. $this->assertSame('privateKey',
  101. $this->instance->getPrivateKey($this->userId)
  102. );
  103. }
  104. public function testGetPublicKey(): void {
  105. $this->keyStorageMock->expects($this->any())
  106. ->method('getUserKey')
  107. ->with($this->equalTo($this->userId), $this->equalTo('publicKey'))
  108. ->willReturn('publicKey');
  109. $this->assertSame('publicKey',
  110. $this->instance->getPublicKey($this->userId)
  111. );
  112. }
  113. public function testRecoveryKeyExists(): void {
  114. $this->keyStorageMock->expects($this->any())
  115. ->method('getSystemUserKey')
  116. ->with($this->equalTo($this->systemKeyId . '.publicKey'))
  117. ->willReturn('recoveryKey');
  118. $this->assertTrue($this->instance->recoveryKeyExists());
  119. }
  120. public function testCheckRecoveryKeyPassword(): void {
  121. $this->keyStorageMock->expects($this->any())
  122. ->method('getSystemUserKey')
  123. ->with($this->equalTo($this->systemKeyId . '.privateKey'))
  124. ->willReturn('recoveryKey');
  125. $this->cryptMock->expects($this->any())
  126. ->method('decryptPrivateKey')
  127. ->with($this->equalTo('recoveryKey'), $this->equalTo('pass'))
  128. ->willReturn('decryptedRecoveryKey');
  129. $this->assertTrue($this->instance->checkRecoveryPassword('pass'));
  130. }
  131. public function testSetPublicKey(): void {
  132. $this->keyStorageMock->expects($this->any())
  133. ->method('setUserKey')
  134. ->with(
  135. $this->equalTo($this->userId),
  136. $this->equalTo('publicKey'),
  137. $this->equalTo('key'))
  138. ->willReturn(true);
  139. $this->assertTrue(
  140. $this->instance->setPublicKey($this->userId, 'key')
  141. );
  142. }
  143. public function testSetPrivateKey(): void {
  144. $this->keyStorageMock->expects($this->any())
  145. ->method('setUserKey')
  146. ->with(
  147. $this->equalTo($this->userId),
  148. $this->equalTo('privateKey'),
  149. $this->equalTo('key'))
  150. ->willReturn(true);
  151. $this->assertTrue(
  152. $this->instance->setPrivateKey($this->userId, 'key')
  153. );
  154. }
  155. /**
  156. * @dataProvider dataTestUserHasKeys
  157. */
  158. public function testUserHasKeys($key, $expected): void {
  159. $this->keyStorageMock->expects($this->exactly(2))
  160. ->method('getUserKey')
  161. ->with($this->equalTo($this->userId), $this->anything())
  162. ->willReturn($key);
  163. $this->assertSame($expected,
  164. $this->instance->userHasKeys($this->userId)
  165. );
  166. }
  167. public function dataTestUserHasKeys() {
  168. return [
  169. ['key', true],
  170. ['', false]
  171. ];
  172. }
  173. public function testUserHasKeysMissingPrivateKey(): void {
  174. $this->expectException(PrivateKeyMissingException::class);
  175. $this->keyStorageMock->expects($this->exactly(2))
  176. ->method('getUserKey')
  177. ->willReturnCallback(function ($uid, $keyID, $encryptionModuleId) {
  178. if ($keyID === 'privateKey') {
  179. return '';
  180. }
  181. return 'key';
  182. });
  183. $this->instance->userHasKeys($this->userId);
  184. }
  185. public function testUserHasKeysMissingPublicKey(): void {
  186. $this->expectException(PublicKeyMissingException::class);
  187. $this->keyStorageMock->expects($this->exactly(2))
  188. ->method('getUserKey')
  189. ->willReturnCallback(function ($uid, $keyID, $encryptionModuleId) {
  190. if ($keyID === 'publicKey') {
  191. return '';
  192. }
  193. return 'key';
  194. });
  195. $this->instance->userHasKeys($this->userId);
  196. }
  197. /**
  198. * @dataProvider dataTestInit
  199. *
  200. * @param bool $useMasterKey
  201. */
  202. public function testInit($useMasterKey): void {
  203. /** @var KeyManager|\PHPUnit\Framework\MockObject\MockObject $instance */
  204. $instance = $this->getMockBuilder(KeyManager::class)
  205. ->setConstructorArgs(
  206. [
  207. $this->keyStorageMock,
  208. $this->cryptMock,
  209. $this->configMock,
  210. $this->userMock,
  211. $this->sessionMock,
  212. $this->logMock,
  213. $this->utilMock,
  214. $this->lockingProviderMock
  215. ]
  216. )->setMethods(['getMasterKeyId', 'getMasterKeyPassword', 'getSystemPrivateKey', 'getPrivateKey'])
  217. ->getMock();
  218. $this->utilMock->expects($this->once())->method('isMasterKeyEnabled')
  219. ->willReturn($useMasterKey);
  220. $this->sessionMock->expects($this->exactly(2))->method('setStatus')
  221. ->withConsecutive(
  222. [Session::INIT_EXECUTED],
  223. [Session::INIT_SUCCESSFUL],
  224. );
  225. $instance->expects($this->any())->method('getMasterKeyId')->willReturn('masterKeyId');
  226. $instance->expects($this->any())->method('getMasterKeyPassword')->willReturn('masterKeyPassword');
  227. $instance->expects($this->any())->method('getSystemPrivateKey')->with('masterKeyId')->willReturn('privateMasterKey');
  228. $instance->expects($this->any())->method('getPrivateKey')->with($this->userId)->willReturn('privateUserKey');
  229. if ($useMasterKey) {
  230. $this->cryptMock->expects($this->once())->method('decryptPrivateKey')
  231. ->with('privateMasterKey', 'masterKeyPassword', 'masterKeyId')
  232. ->willReturn('key');
  233. } else {
  234. $this->cryptMock->expects($this->once())->method('decryptPrivateKey')
  235. ->with('privateUserKey', 'pass', $this->userId)
  236. ->willReturn('key');
  237. }
  238. $this->sessionMock->expects($this->once())->method('setPrivateKey')
  239. ->with('key');
  240. $this->assertTrue($instance->init($this->userId, 'pass'));
  241. }
  242. public function dataTestInit() {
  243. return [
  244. [true],
  245. [false]
  246. ];
  247. }
  248. public function testSetRecoveryKey(): void {
  249. $this->keyStorageMock->expects($this->exactly(2))
  250. ->method('setSystemUserKey')
  251. ->willReturn(true);
  252. $this->cryptMock->expects($this->any())
  253. ->method('encryptPrivateKey')
  254. ->with($this->equalTo('privateKey'), $this->equalTo('pass'))
  255. ->willReturn('decryptedPrivateKey');
  256. $this->assertTrue(
  257. $this->instance->setRecoveryKey('pass',
  258. ['publicKey' => 'publicKey', 'privateKey' => 'privateKey'])
  259. );
  260. }
  261. public function testSetSystemPrivateKey(): void {
  262. $this->keyStorageMock->expects($this->exactly(1))
  263. ->method('setSystemUserKey')
  264. ->with($this->equalTo('keyId.privateKey'), $this->equalTo('key'))
  265. ->willReturn(true);
  266. $this->assertTrue(
  267. $this->instance->setSystemPrivateKey('keyId', 'key')
  268. );
  269. }
  270. public function testGetSystemPrivateKey(): void {
  271. $this->keyStorageMock->expects($this->exactly(1))
  272. ->method('getSystemUserKey')
  273. ->with($this->equalTo('keyId.privateKey'))
  274. ->willReturn('systemPrivateKey');
  275. $this->assertSame('systemPrivateKey',
  276. $this->instance->getSystemPrivateKey('keyId')
  277. );
  278. }
  279. public function testGetEncryptedFileKey(): void {
  280. $this->keyStorageMock->expects($this->once())
  281. ->method('getFileKey')
  282. ->with('/', 'fileKey')
  283. ->willReturn(true);
  284. $this->assertTrue($this->instance->getEncryptedFileKey('/'));
  285. }
  286. public function dataTestGetFileKey() {
  287. return [
  288. ['user1', false, 'privateKey', 'legacyKey', 'multiKeyDecryptResult'],
  289. ['user1', false, 'privateKey', '', 'multiKeyDecryptResult'],
  290. ['user1', false, false, 'legacyKey', ''],
  291. ['user1', false, false, '', ''],
  292. ['user1', true, 'privateKey', 'legacyKey', 'multiKeyDecryptResult'],
  293. ['user1', true, 'privateKey', '', 'multiKeyDecryptResult'],
  294. ['user1', true, false, 'legacyKey', ''],
  295. ['user1', true, false, '', ''],
  296. [null, false, 'privateKey', 'legacyKey', 'multiKeyDecryptResult'],
  297. [null, false, 'privateKey', '', 'multiKeyDecryptResult'],
  298. [null, false, false, 'legacyKey', ''],
  299. [null, false, false, '', ''],
  300. [null, true, 'privateKey', 'legacyKey', 'multiKeyDecryptResult'],
  301. [null, true, 'privateKey', '', 'multiKeyDecryptResult'],
  302. [null, true, false, 'legacyKey', ''],
  303. [null, true, false, '', ''],
  304. ];
  305. }
  306. /**
  307. * @dataProvider dataTestGetFileKey
  308. *
  309. * @param $uid
  310. * @param $isMasterKeyEnabled
  311. * @param $privateKey
  312. * @param $expected
  313. */
  314. public function testGetFileKey($uid, $isMasterKeyEnabled, $privateKey, $encryptedFileKey, $expected): void {
  315. $path = '/foo.txt';
  316. if ($isMasterKeyEnabled) {
  317. $expectedUid = 'masterKeyId';
  318. $this->configMock->expects($this->any())->method('getSystemValue')->with('secret')
  319. ->willReturn('password');
  320. } elseif (!$uid) {
  321. $expectedUid = 'systemKeyId';
  322. } else {
  323. $expectedUid = $uid;
  324. }
  325. $this->invokePrivate($this->instance, 'masterKeyId', ['masterKeyId']);
  326. $this->keyStorageMock->expects($this->exactly(2))
  327. ->method('getFileKey')
  328. ->withConsecutive(
  329. [$path, 'fileKey', 'OC_DEFAULT_MODULE'],
  330. [$path, $expectedUid . '.shareKey', 'OC_DEFAULT_MODULE'],
  331. )
  332. ->willReturnOnConsecutiveCalls(
  333. $encryptedFileKey,
  334. 'fileKey',
  335. );
  336. $this->utilMock->expects($this->any())->method('isMasterKeyEnabled')
  337. ->willReturn($isMasterKeyEnabled);
  338. if (is_null($uid)) {
  339. $this->keyStorageMock->expects($this->once())
  340. ->method('getSystemUserKey')
  341. ->willReturn(true);
  342. $this->cryptMock->expects($this->once())
  343. ->method('decryptPrivateKey')
  344. ->willReturn($privateKey);
  345. } else {
  346. $this->keyStorageMock->expects($this->never())
  347. ->method('getSystemUserKey');
  348. $this->sessionMock->expects($this->once())->method('getPrivateKey')->willReturn($privateKey);
  349. }
  350. if (!empty($encryptedFileKey)) {
  351. $this->cryptMock->expects($this->never())
  352. ->method('multiKeyDecrypt');
  353. if ($privateKey) {
  354. $this->cryptMock->expects($this->once())
  355. ->method('multiKeyDecryptLegacy')
  356. ->willReturn('multiKeyDecryptResult');
  357. } else {
  358. $this->cryptMock->expects($this->never())
  359. ->method('multiKeyDecryptLegacy');
  360. }
  361. } else {
  362. $this->cryptMock->expects($this->never())
  363. ->method('multiKeyDecryptLegacy');
  364. if ($privateKey) {
  365. $this->cryptMock->expects($this->once())
  366. ->method('multiKeyDecrypt')
  367. ->willReturn('multiKeyDecryptResult');
  368. } else {
  369. $this->cryptMock->expects($this->never())
  370. ->method('multiKeyDecrypt');
  371. }
  372. }
  373. $this->assertSame($expected,
  374. $this->instance->getFileKey($path, $uid, null)
  375. );
  376. }
  377. public function testDeletePrivateKey(): void {
  378. $this->keyStorageMock->expects($this->once())
  379. ->method('deleteUserKey')
  380. ->with('user1', 'privateKey')
  381. ->willReturn(true);
  382. $this->assertTrue(self::invokePrivate($this->instance,
  383. 'deletePrivateKey',
  384. [$this->userId]));
  385. }
  386. public function testDeleteAllFileKeys(): void {
  387. $this->keyStorageMock->expects($this->once())
  388. ->method('deleteAllFileKeys')
  389. ->willReturn(true);
  390. $this->assertTrue($this->instance->deleteAllFileKeys('/'));
  391. }
  392. /**
  393. * test add public share key and or recovery key to the list of public keys
  394. *
  395. * @dataProvider dataTestAddSystemKeys
  396. *
  397. * @param array $accessList
  398. * @param array $publicKeys
  399. * @param string $uid
  400. * @param array $expectedKeys
  401. */
  402. public function testAddSystemKeys($accessList, $publicKeys, $uid, $expectedKeys): void {
  403. $publicShareKeyId = 'publicShareKey';
  404. $recoveryKeyId = 'recoveryKey';
  405. $this->keyStorageMock->expects($this->any())
  406. ->method('getSystemUserKey')
  407. ->willReturnCallback(function ($keyId, $encryptionModuleId) {
  408. return $keyId;
  409. });
  410. $this->utilMock->expects($this->any())
  411. ->method('isRecoveryEnabledForUser')
  412. ->willReturnCallback(function ($uid) {
  413. if ($uid === 'user1') {
  414. return true;
  415. }
  416. return false;
  417. });
  418. // set key IDs
  419. self::invokePrivate($this->instance, 'publicShareKeyId', [$publicShareKeyId]);
  420. self::invokePrivate($this->instance, 'recoveryKeyId', [$recoveryKeyId]);
  421. $result = $this->instance->addSystemKeys($accessList, $publicKeys, $uid);
  422. foreach ($expectedKeys as $expected) {
  423. $this->assertArrayHasKey($expected, $result);
  424. }
  425. $this->assertSameSize($expectedKeys, $result);
  426. }
  427. /**
  428. * data provider for testAddSystemKeys()
  429. *
  430. * @return array
  431. */
  432. public function dataTestAddSystemKeys() {
  433. return [
  434. [['public' => true],[], 'user1', ['publicShareKey', 'recoveryKey']],
  435. [['public' => false], [], 'user1', ['recoveryKey']],
  436. [['public' => true],[], 'user2', ['publicShareKey']],
  437. [['public' => false], [], 'user2', []],
  438. ];
  439. }
  440. public function testGetMasterKeyId(): void {
  441. $this->assertSame('systemKeyId', $this->instance->getMasterKeyId());
  442. }
  443. public function testGetPublicMasterKey(): void {
  444. $this->keyStorageMock->expects($this->once())->method('getSystemUserKey')
  445. ->with('systemKeyId.publicKey', Encryption::ID)
  446. ->willReturn(true);
  447. $this->assertTrue(
  448. $this->instance->getPublicMasterKey()
  449. );
  450. }
  451. public function testGetMasterKeyPassword(): void {
  452. $this->configMock->expects($this->once())->method('getSystemValue')->with('secret')
  453. ->willReturn('password');
  454. $this->assertSame('password',
  455. $this->invokePrivate($this->instance, 'getMasterKeyPassword', [])
  456. );
  457. }
  458. public function testGetMasterKeyPasswordException(): void {
  459. $this->expectException(\Exception::class);
  460. $this->configMock->expects($this->once())->method('getSystemValue')->with('secret')
  461. ->willReturn('');
  462. $this->invokePrivate($this->instance, 'getMasterKeyPassword', []);
  463. }
  464. /**
  465. * @dataProvider dataTestValidateMasterKey
  466. *
  467. * @param $masterKey
  468. */
  469. public function testValidateMasterKey($masterKey): void {
  470. /** @var KeyManager|\PHPUnit\Framework\MockObject\MockObject $instance */
  471. $instance = $this->getMockBuilder(KeyManager::class)
  472. ->setConstructorArgs(
  473. [
  474. $this->keyStorageMock,
  475. $this->cryptMock,
  476. $this->configMock,
  477. $this->userMock,
  478. $this->sessionMock,
  479. $this->logMock,
  480. $this->utilMock,
  481. $this->lockingProviderMock
  482. ]
  483. )->setMethods(['getPublicMasterKey', 'setSystemPrivateKey', 'getMasterKeyPassword'])
  484. ->getMock();
  485. $this->utilMock->expects($this->once())->method('isMasterKeyEnabled')
  486. ->willReturn(true);
  487. $instance->expects($this->once())->method('getPublicMasterKey')
  488. ->willReturn($masterKey);
  489. $instance->expects($this->any())->method('getMasterKeyPassword')->willReturn('masterKeyPassword');
  490. $this->cryptMock->expects($this->any())->method('generateHeader')->willReturn('header');
  491. if (empty($masterKey)) {
  492. $this->cryptMock->expects($this->once())->method('createKeyPair')
  493. ->willReturn(['publicKey' => 'public', 'privateKey' => 'private']);
  494. $this->keyStorageMock->expects($this->once())->method('setSystemUserKey')
  495. ->with('systemKeyId.publicKey', 'public', Encryption::ID);
  496. $this->cryptMock->expects($this->once())->method('encryptPrivateKey')
  497. ->with('private', 'masterKeyPassword', 'systemKeyId')
  498. ->willReturn('EncryptedKey');
  499. $this->lockingProviderMock->expects($this->once())
  500. ->method('acquireLock');
  501. $instance->expects($this->once())->method('setSystemPrivateKey')
  502. ->with('systemKeyId', 'headerEncryptedKey');
  503. } else {
  504. $this->cryptMock->expects($this->never())->method('createKeyPair');
  505. $this->keyStorageMock->expects($this->never())->method('setSystemUserKey');
  506. $this->cryptMock->expects($this->never())->method('encryptPrivateKey');
  507. $instance->expects($this->never())->method('setSystemPrivateKey');
  508. }
  509. $instance->validateMasterKey();
  510. }
  511. public function testValidateMasterKeyLocked(): void {
  512. /** @var KeyManager|\PHPUnit_Framework_MockObject_MockObject $instance */
  513. $instance = $this->getMockBuilder(KeyManager::class)
  514. ->setConstructorArgs(
  515. [
  516. $this->keyStorageMock,
  517. $this->cryptMock,
  518. $this->configMock,
  519. $this->userMock,
  520. $this->sessionMock,
  521. $this->logMock,
  522. $this->utilMock,
  523. $this->lockingProviderMock
  524. ]
  525. )->setMethods(['getPublicMasterKey', 'getPrivateMasterKey', 'setSystemPrivateKey', 'getMasterKeyPassword'])
  526. ->getMock();
  527. $this->utilMock->expects($this->once())->method('isMasterKeyEnabled')
  528. ->willReturn(true);
  529. $instance->expects($this->once())->method('getPublicMasterKey')
  530. ->willReturn('');
  531. $instance->expects($this->once())->method('getPrivateMasterKey')
  532. ->willReturn('');
  533. $instance->expects($this->any())->method('getMasterKeyPassword')->willReturn('masterKeyPassword');
  534. $this->cryptMock->expects($this->any())->method('generateHeader')->willReturn('header');
  535. $this->lockingProviderMock->expects($this->once())
  536. ->method('acquireLock')
  537. ->willThrowException(new LockedException('encryption-generateMasterKey'));
  538. $this->expectException(LockedException::class);
  539. $instance->validateMasterKey();
  540. }
  541. public function dataTestValidateMasterKey() {
  542. return [
  543. ['masterKey'],
  544. ['']
  545. ];
  546. }
  547. public function testGetVersionWithoutFileInfo(): void {
  548. $view = $this->getMockBuilder(View::class)
  549. ->disableOriginalConstructor()->getMock();
  550. $view->expects($this->once())
  551. ->method('getFileInfo')
  552. ->with('/admin/files/myfile.txt')
  553. ->willReturn(false);
  554. /** @var View $view */
  555. $this->assertSame(0, $this->instance->getVersion('/admin/files/myfile.txt', $view));
  556. }
  557. public function testGetVersionWithFileInfo(): void {
  558. $view = $this->getMockBuilder(View::class)
  559. ->disableOriginalConstructor()->getMock();
  560. $fileInfo = $this->getMockBuilder(FileInfo::class)
  561. ->disableOriginalConstructor()->getMock();
  562. $fileInfo->expects($this->once())
  563. ->method('getEncryptedVersion')
  564. ->willReturn(1337);
  565. $view->expects($this->once())
  566. ->method('getFileInfo')
  567. ->with('/admin/files/myfile.txt')
  568. ->willReturn($fileInfo);
  569. /** @var View $view */
  570. $this->assertSame(1337, $this->instance->getVersion('/admin/files/myfile.txt', $view));
  571. }
  572. public function testSetVersionWithFileInfo(): void {
  573. $view = $this->getMockBuilder(View::class)
  574. ->disableOriginalConstructor()->getMock();
  575. $cache = $this->getMockBuilder(ICache::class)
  576. ->disableOriginalConstructor()->getMock();
  577. $cache->expects($this->once())
  578. ->method('update')
  579. ->with(123, ['encrypted' => 5, 'encryptedVersion' => 5]);
  580. $storage = $this->getMockBuilder(FilesIStorage::class)
  581. ->disableOriginalConstructor()->getMock();
  582. $storage->expects($this->once())
  583. ->method('getCache')
  584. ->willReturn($cache);
  585. $fileInfo = $this->getMockBuilder(FileInfo::class)
  586. ->disableOriginalConstructor()->getMock();
  587. $fileInfo->expects($this->once())
  588. ->method('getStorage')
  589. ->willReturn($storage);
  590. $fileInfo->expects($this->once())
  591. ->method('getId')
  592. ->willReturn(123);
  593. $view->expects($this->once())
  594. ->method('getFileInfo')
  595. ->with('/admin/files/myfile.txt')
  596. ->willReturn($fileInfo);
  597. /** @var View $view */
  598. $this->instance->setVersion('/admin/files/myfile.txt', 5, $view);
  599. }
  600. public function testSetVersionWithoutFileInfo(): void {
  601. $view = $this->getMockBuilder(View::class)
  602. ->disableOriginalConstructor()->getMock();
  603. $view->expects($this->once())
  604. ->method('getFileInfo')
  605. ->with('/admin/files/myfile.txt')
  606. ->willReturn(false);
  607. /** @var View $view */
  608. $this->instance->setVersion('/admin/files/myfile.txt', 5, $view);
  609. }
  610. public function testBackupUserKeys(): void {
  611. $this->keyStorageMock->expects($this->once())->method('backupUserKeys')
  612. ->with('OC_DEFAULT_MODULE', 'test', 'user1');
  613. $this->instance->backupUserKeys('test', 'user1');
  614. }
  615. }