GetSharedSecretTest.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  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\Federation\Tests\BackgroundJob;
  8. use GuzzleHttp\Exception\ConnectException;
  9. use OCA\Federation\BackgroundJob\GetSharedSecret;
  10. use OCA\Federation\TrustedServers;
  11. use OCA\Files_Sharing\Tests\TestCase;
  12. use OCP\AppFramework\Http;
  13. use OCP\AppFramework\Utility\ITimeFactory;
  14. use OCP\BackgroundJob\IJobList;
  15. use OCP\Http\Client\IClient;
  16. use OCP\Http\Client\IClientService;
  17. use OCP\Http\Client\IResponse;
  18. use OCP\IURLGenerator;
  19. use OCP\OCS\IDiscoveryService;
  20. use Psr\Log\LoggerInterface;
  21. /**
  22. * Class GetSharedSecretTest
  23. *
  24. * @group DB
  25. *
  26. * @package OCA\Federation\Tests\BackgroundJob
  27. */
  28. class GetSharedSecretTest extends TestCase {
  29. /** @var \PHPUnit\Framework\MockObject\MockObject|IClient */
  30. private $httpClient;
  31. /** @var \PHPUnit\Framework\MockObject\MockObject|IClientService */
  32. private $httpClientService;
  33. /** @var \PHPUnit\Framework\MockObject\MockObject|IJobList */
  34. private $jobList;
  35. /** @var \PHPUnit\Framework\MockObject\MockObject|IURLGenerator */
  36. private $urlGenerator;
  37. /** @var \PHPUnit\Framework\MockObject\MockObject|TrustedServers */
  38. private $trustedServers;
  39. /** @var \PHPUnit\Framework\MockObject\MockObject|LoggerInterface */
  40. private $logger;
  41. /** @var \PHPUnit\Framework\MockObject\MockObject|IResponse */
  42. private $response;
  43. /** @var \PHPUnit\Framework\MockObject\MockObject|IDiscoveryService */
  44. private $discoverService;
  45. /** @var \PHPUnit\Framework\MockObject\MockObject|ITimeFactory */
  46. private $timeFactory;
  47. private GetSharedSecret $getSharedSecret;
  48. protected function setUp(): void {
  49. parent::setUp();
  50. $this->httpClientService = $this->createMock(IClientService::class);
  51. $this->httpClient = $this->getMockBuilder(IClient::class)->getMock();
  52. $this->jobList = $this->getMockBuilder(IJobList::class)->getMock();
  53. $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class)->getMock();
  54. $this->trustedServers = $this->getMockBuilder(TrustedServers::class)
  55. ->disableOriginalConstructor()->getMock();
  56. $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
  57. $this->response = $this->getMockBuilder(IResponse::class)->getMock();
  58. $this->discoverService = $this->getMockBuilder(IDiscoveryService::class)->getMock();
  59. $this->timeFactory = $this->createMock(ITimeFactory::class);
  60. $this->discoverService->expects($this->any())->method('discover')->willReturn([]);
  61. $this->httpClientService->expects($this->any())->method('newClient')->willReturn($this->httpClient);
  62. $this->getSharedSecret = new GetSharedSecret(
  63. $this->httpClientService,
  64. $this->urlGenerator,
  65. $this->jobList,
  66. $this->trustedServers,
  67. $this->logger,
  68. $this->discoverService,
  69. $this->timeFactory
  70. );
  71. }
  72. /**
  73. * @dataProvider dataTestExecute
  74. *
  75. * @param bool $isTrustedServer
  76. * @param bool $retainBackgroundJob
  77. */
  78. public function testExecute(bool $isTrustedServer, bool $retainBackgroundJob): void {
  79. /** @var GetSharedSecret |\PHPUnit\Framework\MockObject\MockObject $getSharedSecret */
  80. $getSharedSecret = $this->getMockBuilder(GetSharedSecret::class)
  81. ->setConstructorArgs(
  82. [
  83. $this->httpClientService,
  84. $this->urlGenerator,
  85. $this->jobList,
  86. $this->trustedServers,
  87. $this->logger,
  88. $this->discoverService,
  89. $this->timeFactory
  90. ]
  91. )->setMethods(['parentStart'])->getMock();
  92. $this->invokePrivate($getSharedSecret, 'argument', [['url' => 'url', 'token' => 'token']]);
  93. $this->trustedServers->expects($this->once())->method('isTrustedServer')
  94. ->with('url')->willReturn($isTrustedServer);
  95. if ($isTrustedServer) {
  96. $getSharedSecret->expects($this->once())->method('parentStart');
  97. } else {
  98. $getSharedSecret->expects($this->never())->method('parentStart');
  99. }
  100. $this->invokePrivate($getSharedSecret, 'retainJob', [$retainBackgroundJob]);
  101. $this->jobList->expects($this->once())->method('remove');
  102. $this->timeFactory->method('getTime')->willReturn(42);
  103. if ($retainBackgroundJob) {
  104. $this->jobList->expects($this->once())
  105. ->method('add')
  106. ->with(
  107. GetSharedSecret::class,
  108. [
  109. 'url' => 'url',
  110. 'token' => 'token',
  111. 'created' => 42,
  112. ]
  113. );
  114. } else {
  115. $this->jobList->expects($this->never())->method('add');
  116. }
  117. $getSharedSecret->start($this->jobList);
  118. }
  119. public function dataTestExecute() {
  120. return [
  121. [true, true],
  122. [true, false],
  123. [false, false],
  124. ];
  125. }
  126. /**
  127. * @dataProvider dataTestRun
  128. *
  129. * @param int $statusCode
  130. */
  131. public function testRun($statusCode): void {
  132. $target = 'targetURL';
  133. $source = 'sourceURL';
  134. $token = 'token';
  135. $argument = ['url' => $target, 'token' => $token];
  136. $this->timeFactory->method('getTime')
  137. ->willReturn(42);
  138. $this->urlGenerator->expects($this->once())->method('getAbsoluteURL')->with('/')
  139. ->willReturn($source);
  140. $this->httpClient->expects($this->once())->method('get')
  141. ->with(
  142. $target . '/ocs/v2.php/apps/federation/api/v1/shared-secret',
  143. [
  144. 'query' =>
  145. [
  146. 'url' => $source,
  147. 'token' => $token,
  148. 'format' => 'json',
  149. ],
  150. 'timeout' => 3,
  151. 'connect_timeout' => 3,
  152. ]
  153. )->willReturn($this->response);
  154. $this->response->expects($this->once())->method('getStatusCode')
  155. ->willReturn($statusCode);
  156. if ($statusCode === Http::STATUS_OK) {
  157. $this->response->expects($this->once())->method('getBody')
  158. ->willReturn('{"ocs":{"data":{"sharedSecret":"secret"}}}');
  159. $this->trustedServers->expects($this->once())->method('addSharedSecret')
  160. ->with($target, 'secret');
  161. } else {
  162. $this->trustedServers->expects($this->never())->method('addSharedSecret');
  163. }
  164. $this->invokePrivate($this->getSharedSecret, 'run', [$argument]);
  165. if (
  166. $statusCode !== Http::STATUS_OK
  167. && $statusCode !== Http::STATUS_FORBIDDEN
  168. ) {
  169. $this->assertTrue($this->invokePrivate($this->getSharedSecret, 'retainJob'));
  170. } else {
  171. $this->assertFalse($this->invokePrivate($this->getSharedSecret, 'retainJob'));
  172. }
  173. }
  174. public function dataTestRun() {
  175. return [
  176. [Http::STATUS_OK],
  177. [Http::STATUS_FORBIDDEN],
  178. [Http::STATUS_CONFLICT],
  179. ];
  180. }
  181. public function testRunExpired(): void {
  182. $target = 'targetURL';
  183. $source = 'sourceURL';
  184. $token = 'token';
  185. $created = 42;
  186. $argument = [
  187. 'url' => $target,
  188. 'token' => $token,
  189. 'created' => $created,
  190. ];
  191. $this->urlGenerator->expects($this->once())
  192. ->method('getAbsoluteURL')
  193. ->with('/')
  194. ->willReturn($source);
  195. $this->timeFactory->method('getTime')
  196. ->willReturn($created + 2592000 + 1);
  197. $this->trustedServers->expects($this->once())
  198. ->method('setServerStatus')
  199. ->with(
  200. $target,
  201. TrustedServers::STATUS_FAILURE
  202. );
  203. $this->invokePrivate($this->getSharedSecret, 'run', [$argument]);
  204. }
  205. public function testRunConnectionError(): void {
  206. $target = 'targetURL';
  207. $source = 'sourceURL';
  208. $token = 'token';
  209. $argument = ['url' => $target, 'token' => $token];
  210. $this->timeFactory->method('getTime')
  211. ->willReturn(42);
  212. $this->urlGenerator
  213. ->expects($this->once())
  214. ->method('getAbsoluteURL')
  215. ->with('/')
  216. ->willReturn($source);
  217. $this->httpClient->expects($this->once())->method('get')
  218. ->with(
  219. $target . '/ocs/v2.php/apps/federation/api/v1/shared-secret',
  220. [
  221. 'query' =>
  222. [
  223. 'url' => $source,
  224. 'token' => $token,
  225. 'format' => 'json',
  226. ],
  227. 'timeout' => 3,
  228. 'connect_timeout' => 3,
  229. ]
  230. )->willThrowException($this->createMock(ConnectException::class));
  231. $this->trustedServers->expects($this->never())->method('addSharedSecret');
  232. $this->invokePrivate($this->getSharedSecret, 'run', [$argument]);
  233. $this->assertTrue($this->invokePrivate($this->getSharedSecret, 'retainJob'));
  234. }
  235. }