ManagerTest.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test\Security\IdentityProof;
  8. use OC\Files\AppData\AppData;
  9. use OC\Files\AppData\Factory;
  10. use OC\Security\IdentityProof\Key;
  11. use OC\Security\IdentityProof\Manager;
  12. use OCP\Files\IAppData;
  13. use OCP\Files\SimpleFS\ISimpleFile;
  14. use OCP\Files\SimpleFS\ISimpleFolder;
  15. use OCP\IConfig;
  16. use OCP\IUser;
  17. use OCP\Security\ICrypto;
  18. use PHPUnit\Framework\MockObject\MockObject;
  19. use Psr\Log\LoggerInterface;
  20. use Test\TestCase;
  21. class ManagerTest extends TestCase {
  22. /** @var Factory|MockObject */
  23. private $factory;
  24. /** @var IAppData|MockObject */
  25. private $appData;
  26. /** @var ICrypto|MockObject */
  27. private $crypto;
  28. /** @var Manager|MockObject */
  29. private $manager;
  30. /** @var IConfig|MockObject */
  31. private $config;
  32. /** @var LoggerInterface|MockObject */
  33. private $logger;
  34. protected function setUp(): void {
  35. parent::setUp();
  36. /** @var Factory|\PHPUnit\Framework\MockObject\MockObject $factory */
  37. $this->factory = $this->createMock(Factory::class);
  38. $this->appData = $this->createMock(AppData::class);
  39. $this->config = $this->createMock(IConfig::class);
  40. $this->factory->expects($this->any())
  41. ->method('get')
  42. ->with('identityproof')
  43. ->willReturn($this->appData);
  44. $this->logger = $this->createMock(LoggerInterface::class);
  45. $this->crypto = $this->createMock(ICrypto::class);
  46. $this->manager = $this->getManager(['generateKeyPair']);
  47. }
  48. /**
  49. * create manager object
  50. *
  51. * @param array $setMethods
  52. * @return Manager|\PHPUnit\Framework\MockObject\MockObject
  53. */
  54. protected function getManager($setMethods = []) {
  55. if (empty($setMethods)) {
  56. return new Manager(
  57. $this->factory,
  58. $this->crypto,
  59. $this->config,
  60. $this->logger
  61. );
  62. } else {
  63. return $this->getMockBuilder(Manager::class)
  64. ->setConstructorArgs([
  65. $this->factory,
  66. $this->crypto,
  67. $this->config,
  68. $this->logger
  69. ])->setMethods($setMethods)->getMock();
  70. }
  71. }
  72. public function testGetKeyWithExistingKey() {
  73. $user = $this->createMock(IUser::class);
  74. $user
  75. ->expects($this->once())
  76. ->method('getUID')
  77. ->willReturn('MyUid');
  78. $folder = $this->createMock(ISimpleFolder::class);
  79. $privateFile = $this->createMock(ISimpleFile::class);
  80. $privateFile
  81. ->expects($this->once())
  82. ->method('getContent')
  83. ->willReturn('EncryptedPrivateKey');
  84. $publicFile = $this->createMock(ISimpleFile::class);
  85. $publicFile
  86. ->expects($this->once())
  87. ->method('getContent')
  88. ->willReturn('MyPublicKey');
  89. $this->crypto
  90. ->expects($this->once())
  91. ->method('decrypt')
  92. ->with('EncryptedPrivateKey')
  93. ->willReturn('MyPrivateKey');
  94. $folder
  95. ->expects($this->exactly(2))
  96. ->method('getFile')
  97. ->withConsecutive(
  98. ['private'],
  99. ['public']
  100. )
  101. ->willReturnOnConsecutiveCalls(
  102. $privateFile,
  103. $publicFile
  104. );
  105. $this->appData
  106. ->expects($this->once())
  107. ->method('getFolder')
  108. ->with('user-MyUid')
  109. ->willReturn($folder);
  110. $expected = new Key('MyPublicKey', 'MyPrivateKey');
  111. $this->assertEquals($expected, $this->manager->getKey($user));
  112. }
  113. public function testGetKeyWithNotExistingKey() {
  114. $user = $this->createMock(IUser::class);
  115. $user
  116. ->expects($this->once())
  117. ->method('getUID')
  118. ->willReturn('MyUid');
  119. $this->manager
  120. ->expects($this->once())
  121. ->method('generateKeyPair')
  122. ->willReturn(['MyNewPublicKey', 'MyNewPrivateKey']);
  123. $this->appData
  124. ->expects($this->once())
  125. ->method('newFolder')
  126. ->with('user-MyUid');
  127. $folder = $this->createMock(ISimpleFolder::class);
  128. $this->crypto
  129. ->expects($this->once())
  130. ->method('encrypt')
  131. ->with('MyNewPrivateKey')
  132. ->willReturn('MyNewEncryptedPrivateKey');
  133. $privateFile = $this->createMock(ISimpleFile::class);
  134. $privateFile
  135. ->expects($this->once())
  136. ->method('putContent')
  137. ->with('MyNewEncryptedPrivateKey');
  138. $publicFile = $this->createMock(ISimpleFile::class);
  139. $publicFile
  140. ->expects($this->once())
  141. ->method('putContent')
  142. ->with('MyNewPublicKey');
  143. $folder
  144. ->expects($this->exactly(2))
  145. ->method('newFile')
  146. ->withConsecutive(
  147. ['private'],
  148. ['public']
  149. )
  150. ->willReturnOnConsecutiveCalls(
  151. $privateFile,
  152. $publicFile
  153. );
  154. $this->appData
  155. ->expects($this->exactly(2))
  156. ->method('getFolder')
  157. ->with('user-MyUid')
  158. ->willReturnOnConsecutiveCalls(
  159. $this->throwException(new \Exception()),
  160. $folder
  161. );
  162. $expected = new Key('MyNewPublicKey', 'MyNewPrivateKey');
  163. $this->assertEquals($expected, $this->manager->getKey($user));
  164. }
  165. public function testGenerateKeyPair() {
  166. $manager = $this->getManager();
  167. $data = 'MyTestData';
  168. [$resultPublicKey, $resultPrivateKey] = self::invokePrivate($manager, 'generateKeyPair');
  169. openssl_sign($data, $signature, $resultPrivateKey);
  170. $details = openssl_pkey_get_details(openssl_pkey_get_public($resultPublicKey));
  171. $this->assertSame(1, openssl_verify($data, $signature, $resultPublicKey));
  172. $this->assertSame(2048, $details['bits']);
  173. }
  174. public function testGetSystemKey() {
  175. $manager = $this->getManager(['retrieveKey']);
  176. /** @var Key|\PHPUnit\Framework\MockObject\MockObject $key */
  177. $key = $this->createMock(Key::class);
  178. $this->config->expects($this->once())->method('getSystemValue')
  179. ->with('instanceid', null)->willReturn('instanceId');
  180. $manager->expects($this->once())->method('retrieveKey')->with('system-instanceId')
  181. ->willReturn($key);
  182. $this->assertSame($key, $manager->getSystemKey());
  183. }
  184. public function testGetSystemKeyFailure() {
  185. $this->expectException(\RuntimeException::class);
  186. $manager = $this->getManager(['retrieveKey']);
  187. /** @var Key|\PHPUnit\Framework\MockObject\MockObject $key */
  188. $key = $this->createMock(Key::class);
  189. $this->config->expects($this->once())->method('getSystemValue')
  190. ->with('instanceid', null)->willReturn(null);
  191. $manager->getSystemKey();
  192. }
  193. }