CSPMiddlewareTest.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test\AppFramework\Middleware\Security;
  8. use OC\AppFramework\Middleware\Security\CSPMiddleware;
  9. use OC\Security\CSP\ContentSecurityPolicy;
  10. use OC\Security\CSP\ContentSecurityPolicyManager;
  11. use OC\Security\CSP\ContentSecurityPolicyNonceManager;
  12. use OCP\AppFramework\Controller;
  13. use OCP\AppFramework\Http\EmptyContentSecurityPolicy;
  14. use OCP\AppFramework\Http\Response;
  15. use PHPUnit\Framework\MockObject\MockObject;
  16. class CSPMiddlewareTest extends \Test\TestCase {
  17. /** @var CSPMiddleware&MockObject */
  18. private $middleware;
  19. /** @var Controller&MockObject */
  20. private $controller;
  21. /** @var ContentSecurityPolicyManager&MockObject */
  22. private $contentSecurityPolicyManager;
  23. /** @var ContentSecurityPolicyNonceManager&MockObject */
  24. private $cspNonceManager;
  25. protected function setUp(): void {
  26. parent::setUp();
  27. $this->controller = $this->createMock(Controller::class);
  28. $this->contentSecurityPolicyManager = $this->createMock(ContentSecurityPolicyManager::class);
  29. $this->cspNonceManager = $this->createMock(ContentSecurityPolicyNonceManager::class);
  30. $this->middleware = new CSPMiddleware(
  31. $this->contentSecurityPolicyManager,
  32. $this->cspNonceManager,
  33. );
  34. }
  35. public function testAfterController(): void {
  36. $this->cspNonceManager
  37. ->expects($this->once())
  38. ->method('browserSupportsCspV3')
  39. ->willReturn(false);
  40. $response = $this->createMock(Response::class);
  41. $defaultPolicy = new ContentSecurityPolicy();
  42. $defaultPolicy->addAllowedImageDomain('defaultpolicy');
  43. $currentPolicy = new ContentSecurityPolicy();
  44. $currentPolicy->addAllowedConnectDomain('currentPolicy');
  45. $mergedPolicy = new ContentSecurityPolicy();
  46. $mergedPolicy->addAllowedMediaDomain('mergedPolicy');
  47. $response
  48. ->expects($this->exactly(2))
  49. ->method('getContentSecurityPolicy')
  50. ->willReturn($currentPolicy);
  51. $this->contentSecurityPolicyManager
  52. ->expects($this->once())
  53. ->method('getDefaultPolicy')
  54. ->willReturn($defaultPolicy);
  55. $this->contentSecurityPolicyManager
  56. ->expects($this->once())
  57. ->method('mergePolicies')
  58. ->with($defaultPolicy, $currentPolicy)
  59. ->willReturn($mergedPolicy);
  60. $response->expects($this->once())
  61. ->method('setContentSecurityPolicy')
  62. ->with($mergedPolicy);
  63. $this->middleware->afterController($this->controller, 'test', $response);
  64. }
  65. public function testAfterControllerEmptyCSP(): void {
  66. $response = $this->createMock(Response::class);
  67. $emptyPolicy = new EmptyContentSecurityPolicy();
  68. $response->expects($this->any())
  69. ->method('getContentSecurityPolicy')
  70. ->willReturn($emptyPolicy);
  71. $response->expects($this->never())
  72. ->method('setContentSecurityPolicy');
  73. $this->middleware->afterController($this->controller, 'test', $response);
  74. }
  75. public function testAfterControllerWithContentSecurityPolicy3Support(): void {
  76. $this->cspNonceManager
  77. ->expects($this->once())
  78. ->method('browserSupportsCspV3')
  79. ->willReturn(true);
  80. $token = base64_encode('the-nonce');
  81. $this->cspNonceManager
  82. ->expects($this->once())
  83. ->method('getNonce')
  84. ->willReturn($token);
  85. $response = $this->createMock(Response::class);
  86. $defaultPolicy = new ContentSecurityPolicy();
  87. $defaultPolicy->addAllowedImageDomain('defaultpolicy');
  88. $currentPolicy = new ContentSecurityPolicy();
  89. $currentPolicy->addAllowedConnectDomain('currentPolicy');
  90. $mergedPolicy = new ContentSecurityPolicy();
  91. $mergedPolicy->addAllowedMediaDomain('mergedPolicy');
  92. $response
  93. ->expects($this->exactly(2))
  94. ->method('getContentSecurityPolicy')
  95. ->willReturn($currentPolicy);
  96. $this->contentSecurityPolicyManager
  97. ->expects($this->once())
  98. ->method('getDefaultPolicy')
  99. ->willReturn($defaultPolicy);
  100. $this->contentSecurityPolicyManager
  101. ->expects($this->once())
  102. ->method('mergePolicies')
  103. ->with($defaultPolicy, $currentPolicy)
  104. ->willReturn($mergedPolicy);
  105. $response->expects($this->once())
  106. ->method('setContentSecurityPolicy')
  107. ->with($mergedPolicy);
  108. $this->assertEquals($response, $this->middleware->afterController($this->controller, 'test', $response));
  109. }
  110. }