ManagerTest.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
  5. *
  6. * @license GNU AGPL version 3 or any later version
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License as
  10. * published by the Free Software Foundation, either version 3 of the
  11. * License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. namespace Test\Security\IdentityProof;
  23. use OC\Files\AppData\AppData;
  24. use OC\Files\AppData\Factory;
  25. use OC\Security\IdentityProof\Key;
  26. use OC\Security\IdentityProof\Manager;
  27. use OCP\Files\IAppData;
  28. use OCP\Files\SimpleFS\ISimpleFile;
  29. use OCP\Files\SimpleFS\ISimpleFolder;
  30. use OCP\IConfig;
  31. use OCP\IUser;
  32. use OCP\Security\ICrypto;
  33. use PHPUnit\Framework\MockObject\MockObject;
  34. use Psr\Log\LoggerInterface;
  35. use Test\TestCase;
  36. class ManagerTest extends TestCase {
  37. /** @var Factory|MockObject */
  38. private $factory;
  39. /** @var IAppData|MockObject */
  40. private $appData;
  41. /** @var ICrypto|MockObject */
  42. private $crypto;
  43. /** @var Manager|MockObject */
  44. private $manager;
  45. /** @var IConfig|MockObject */
  46. private $config;
  47. /** @var LoggerInterface|MockObject */
  48. private $logger;
  49. protected function setUp(): void {
  50. parent::setUp();
  51. /** @var Factory|\PHPUnit\Framework\MockObject\MockObject $factory */
  52. $this->factory = $this->createMock(Factory::class);
  53. $this->appData = $this->createMock(AppData::class);
  54. $this->config = $this->createMock(IConfig::class);
  55. $this->factory->expects($this->any())
  56. ->method('get')
  57. ->with('identityproof')
  58. ->willReturn($this->appData);
  59. $this->logger = $this->createMock(LoggerInterface::class);
  60. $this->crypto = $this->createMock(ICrypto::class);
  61. $this->manager = $this->getManager(['generateKeyPair']);
  62. }
  63. /**
  64. * create manager object
  65. *
  66. * @param array $setMethods
  67. * @return Manager|\PHPUnit\Framework\MockObject\MockObject
  68. */
  69. protected function getManager($setMethods = []) {
  70. if (empty($setMethods)) {
  71. return new Manager(
  72. $this->factory,
  73. $this->crypto,
  74. $this->config,
  75. $this->logger
  76. );
  77. } else {
  78. return $this->getMockBuilder(Manager::class)
  79. ->setConstructorArgs([
  80. $this->factory,
  81. $this->crypto,
  82. $this->config,
  83. $this->logger
  84. ])->setMethods($setMethods)->getMock();
  85. }
  86. }
  87. public function testGetKeyWithExistingKey() {
  88. $user = $this->createMock(IUser::class);
  89. $user
  90. ->expects($this->once())
  91. ->method('getUID')
  92. ->willReturn('MyUid');
  93. $folder = $this->createMock(ISimpleFolder::class);
  94. $privateFile = $this->createMock(ISimpleFile::class);
  95. $privateFile
  96. ->expects($this->once())
  97. ->method('getContent')
  98. ->willReturn('EncryptedPrivateKey');
  99. $publicFile = $this->createMock(ISimpleFile::class);
  100. $publicFile
  101. ->expects($this->once())
  102. ->method('getContent')
  103. ->willReturn('MyPublicKey');
  104. $this->crypto
  105. ->expects($this->once())
  106. ->method('decrypt')
  107. ->with('EncryptedPrivateKey')
  108. ->willReturn('MyPrivateKey');
  109. $folder
  110. ->expects($this->exactly(2))
  111. ->method('getFile')
  112. ->withConsecutive(
  113. ['private'],
  114. ['public']
  115. )
  116. ->willReturnOnConsecutiveCalls(
  117. $privateFile,
  118. $publicFile
  119. );
  120. $this->appData
  121. ->expects($this->once())
  122. ->method('getFolder')
  123. ->with('user-MyUid')
  124. ->willReturn($folder);
  125. $expected = new Key('MyPublicKey', 'MyPrivateKey');
  126. $this->assertEquals($expected, $this->manager->getKey($user));
  127. }
  128. public function testGetKeyWithNotExistingKey() {
  129. $user = $this->createMock(IUser::class);
  130. $user
  131. ->expects($this->once())
  132. ->method('getUID')
  133. ->willReturn('MyUid');
  134. $this->manager
  135. ->expects($this->once())
  136. ->method('generateKeyPair')
  137. ->willReturn(['MyNewPublicKey', 'MyNewPrivateKey']);
  138. $this->appData
  139. ->expects($this->once())
  140. ->method('newFolder')
  141. ->with('user-MyUid');
  142. $folder = $this->createMock(ISimpleFolder::class);
  143. $this->crypto
  144. ->expects($this->once())
  145. ->method('encrypt')
  146. ->with('MyNewPrivateKey')
  147. ->willReturn('MyNewEncryptedPrivateKey');
  148. $privateFile = $this->createMock(ISimpleFile::class);
  149. $privateFile
  150. ->expects($this->once())
  151. ->method('putContent')
  152. ->with('MyNewEncryptedPrivateKey');
  153. $publicFile = $this->createMock(ISimpleFile::class);
  154. $publicFile
  155. ->expects($this->once())
  156. ->method('putContent')
  157. ->with('MyNewPublicKey');
  158. $folder
  159. ->expects($this->exactly(2))
  160. ->method('newFile')
  161. ->withConsecutive(
  162. ['private'],
  163. ['public']
  164. )
  165. ->willReturnOnConsecutiveCalls(
  166. $privateFile,
  167. $publicFile
  168. );
  169. $this->appData
  170. ->expects($this->exactly(2))
  171. ->method('getFolder')
  172. ->with('user-MyUid')
  173. ->willReturnOnConsecutiveCalls(
  174. $this->throwException(new \Exception()),
  175. $folder
  176. );
  177. $expected = new Key('MyNewPublicKey', 'MyNewPrivateKey');
  178. $this->assertEquals($expected, $this->manager->getKey($user));
  179. }
  180. public function testGenerateKeyPair() {
  181. $manager = $this->getManager();
  182. $data = 'MyTestData';
  183. [$resultPublicKey, $resultPrivateKey] = self::invokePrivate($manager, 'generateKeyPair');
  184. openssl_sign($data, $signature, $resultPrivateKey);
  185. $details = openssl_pkey_get_details(openssl_pkey_get_public($resultPublicKey));
  186. $this->assertSame(1, openssl_verify($data, $signature, $resultPublicKey));
  187. $this->assertSame(2048, $details['bits']);
  188. }
  189. public function testGetSystemKey() {
  190. $manager = $this->getManager(['retrieveKey']);
  191. /** @var Key|\PHPUnit\Framework\MockObject\MockObject $key */
  192. $key = $this->createMock(Key::class);
  193. $this->config->expects($this->once())->method('getSystemValue')
  194. ->with('instanceid', null)->willReturn('instanceId');
  195. $manager->expects($this->once())->method('retrieveKey')->with('system-instanceId')
  196. ->willReturn($key);
  197. $this->assertSame($key, $manager->getSystemKey());
  198. }
  199. public function testGetSystemKeyFailure() {
  200. $this->expectException(\RuntimeException::class);
  201. $manager = $this->getManager(['retrieveKey']);
  202. /** @var Key|\PHPUnit\Framework\MockObject\MockObject $key */
  203. $key = $this->createMock(Key::class);
  204. $this->config->expects($this->once())->method('getSystemValue')
  205. ->with('instanceid', null)->willReturn(null);
  206. $manager->getSystemKey();
  207. }
  208. }