aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/Security
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/Security')
-rw-r--r--tests/lib/Security/Bruteforce/Backend/MemoryCacheBackendTest.php137
-rw-r--r--tests/lib/Security/Bruteforce/CapabilitiesTest.php40
-rw-r--r--tests/lib/Security/Bruteforce/ThrottlerTest.php242
-rw-r--r--tests/lib/Security/CSP/AddContentSecurityPolicyEventTest.php23
-rw-r--r--tests/lib/Security/CSP/ContentSecurityPolicyManagerTest.php62
-rw-r--r--tests/lib/Security/CSP/ContentSecurityPolicyNonceManagerTest.php46
-rw-r--r--tests/lib/Security/CSRF/CsrfTokenGeneratorTest.php31
-rw-r--r--tests/lib/Security/CSRF/CsrfTokenManagerTest.php67
-rw-r--r--tests/lib/Security/CSRF/CsrfTokenTest.php34
-rw-r--r--tests/lib/Security/CSRF/TokenStorage/SessionStorageTest.php43
-rw-r--r--tests/lib/Security/CertificateManagerTest.php76
-rw-r--r--tests/lib/Security/CertificateTest.php51
-rw-r--r--tests/lib/Security/CredentialsManagerTest.php47
-rw-r--r--tests/lib/Security/CryptoTest.php46
-rw-r--r--tests/lib/Security/Events/GenerateSecurePasswordEventTest.php33
-rw-r--r--tests/lib/Security/Events/ValidatePasswordPolicyEventTest.php28
-rw-r--r--tests/lib/Security/FeaturePolicy/AddFeaturePolicyEventTest.php23
-rw-r--r--tests/lib/Security/FeaturePolicy/FeaturePolicyManagerTest.php37
-rw-r--r--tests/lib/Security/HasherTest.php83
-rw-r--r--tests/lib/Security/IdentityProof/KeyTest.php25
-rw-r--r--tests/lib/Security/IdentityProof/ManagerTest.php118
-rw-r--r--tests/lib/Security/IdentityProof/SignerTest.php29
-rw-r--r--tests/lib/Security/Ip/BruteforceAllowListTest.php161
-rw-r--r--tests/lib/Security/Ip/RemoteAddressTest.php79
-rw-r--r--tests/lib/Security/Normalizer/IpAddressTest.php37
-rw-r--r--tests/lib/Security/RateLimiting/Backend/MemoryCacheBackendTest.php36
-rw-r--r--tests/lib/Security/RateLimiting/LimiterTest.php55
-rw-r--r--tests/lib/Security/RemoteHostValidatorIntegrationTest.php38
-rw-r--r--tests/lib/Security/RemoteHostValidatorTest.php35
-rw-r--r--tests/lib/Security/SecureRandomTest.php47
-rw-r--r--tests/lib/Security/TrustedDomainHelperTest.php19
-rw-r--r--tests/lib/Security/VerificationToken/VerificationTokenTest.php55
32 files changed, 929 insertions, 954 deletions
diff --git a/tests/lib/Security/Bruteforce/Backend/MemoryCacheBackendTest.php b/tests/lib/Security/Bruteforce/Backend/MemoryCacheBackendTest.php
new file mode 100644
index 00000000000..e0289fa7ca9
--- /dev/null
+++ b/tests/lib/Security/Bruteforce/Backend/MemoryCacheBackendTest.php
@@ -0,0 +1,137 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Security\Bruteforce\Backend;
+
+use OC\Security\Bruteforce\Backend\IBackend;
+use OC\Security\Bruteforce\Backend\MemoryCacheBackend;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\ICache;
+use OCP\ICacheFactory;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class MemoryCacheBackendTest extends TestCase {
+ /** @var ICacheFactory|MockObject */
+ private $cacheFactory;
+ /** @var ITimeFactory|MockObject */
+ private $timeFactory;
+ /** @var ICache|MockObject */
+ private $cache;
+ private IBackend $backend;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->cacheFactory = $this->createMock(ICacheFactory::class);
+ $this->timeFactory = $this->createMock(ITimeFactory::class);
+ $this->cache = $this->createMock(ICache::class);
+
+ $this->cacheFactory
+ ->expects($this->once())
+ ->method('createDistributed')
+ ->with(MemoryCacheBackend::class)
+ ->willReturn($this->cache);
+
+ $this->backend = new MemoryCacheBackend(
+ $this->cacheFactory,
+ $this->timeFactory
+ );
+ }
+
+ public function testGetAttemptsWithNoAttemptsBefore(): void {
+ $this->cache
+ ->expects($this->once())
+ ->method('get')
+ ->with('8b9da631d1f7b022bb2c3c489e16092f82b42fd4')
+ ->willReturn(null);
+
+ $this->assertSame(0, $this->backend->getAttempts('10.10.10.10/32', 0));
+ }
+
+ public static function dataGetAttempts(): array {
+ return [
+ [0, null, null, 4],
+ [100, null, null, 2],
+ [0, 'action1', null, 2],
+ [100, 'action1', null, 1],
+ [0, 'action1', ['metadata2'], 1],
+ [100, 'action1', ['metadata2'], 1],
+ [100, 'action1', ['metadata1'], 0],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataGetAttempts')]
+ public function testGetAttempts(int $maxAge, ?string $action, ?array $metadata, int $expected): void {
+ $this->cache
+ ->expects($this->once())
+ ->method('get')
+ ->with('8b9da631d1f7b022bb2c3c489e16092f82b42fd4')
+ ->willReturn(json_encode([
+ '1' . '#' . hash('sha1', 'action1') . '#' . hash('sha1', json_encode(['metadata1'])),
+ '300' . '#' . hash('sha1', 'action1') . '#' . hash('sha1', json_encode(['metadata2'])),
+ '1' . '#' . hash('sha1', 'action2') . '#' . hash('sha1', json_encode(['metadata1'])),
+ '300' . '#' . hash('sha1', 'action2') . '#' . hash('sha1', json_encode(['metadata2'])),
+ ]));
+
+ $this->assertSame($expected, $this->backend->getAttempts('10.10.10.10/32', $maxAge, $action, $metadata));
+ }
+
+ public function testRegisterAttemptWithNoAttemptsBefore(): void {
+ $this->cache
+ ->expects($this->once())
+ ->method('get')
+ ->with('8b9da631d1f7b022bb2c3c489e16092f82b42fd4')
+ ->willReturn(null);
+ $this->cache
+ ->expects($this->once())
+ ->method('set')
+ ->with(
+ '8b9da631d1f7b022bb2c3c489e16092f82b42fd4',
+ json_encode(['223#' . hash('sha1', 'action1') . '#' . hash('sha1', json_encode(['metadata1']))])
+ );
+
+ $this->backend->registerAttempt('10.10.10.10', '10.10.10.10/32', 223, 'action1', ['metadata1']);
+ }
+
+ public function testRegisterAttempt(): void {
+ $this->timeFactory
+ ->expects($this->once())
+ ->method('getTime')
+ ->willReturn(12 * 3600 + 86);
+
+ $this->cache
+ ->expects($this->once())
+ ->method('get')
+ ->with('8b9da631d1f7b022bb2c3c489e16092f82b42fd4')
+ ->willReturn(json_encode([
+ '1#' . hash('sha1', 'action1') . '#' . hash('sha1', json_encode(['metadata1'])),
+ '2#' . hash('sha1', 'action2') . '#' . hash('sha1', json_encode(['metadata1'])),
+ '87#' . hash('sha1', 'action3') . '#' . hash('sha1', json_encode(['metadata1'])),
+ '123#' . hash('sha1', 'action4') . '#' . hash('sha1', json_encode(['metadata1'])),
+ '123#' . hash('sha1', 'action5') . '#' . hash('sha1', json_encode(['metadata1'])),
+ '124#' . hash('sha1', 'action6') . '#' . hash('sha1', json_encode(['metadata1'])),
+ ]));
+ $this->cache
+ ->expects($this->once())
+ ->method('set')
+ ->with(
+ '8b9da631d1f7b022bb2c3c489e16092f82b42fd4',
+ json_encode([
+ '87#' . hash('sha1', 'action3') . '#' . hash('sha1', json_encode(['metadata1'])),
+ '123#' . hash('sha1', 'action4') . '#' . hash('sha1', json_encode(['metadata1'])),
+ '123#' . hash('sha1', 'action5') . '#' . hash('sha1', json_encode(['metadata1'])),
+ '124#' . hash('sha1', 'action6') . '#' . hash('sha1', json_encode(['metadata1'])),
+ '186#' . hash('sha1', 'action7') . '#' . hash('sha1', json_encode(['metadata2'])),
+ ])
+ );
+
+ $this->backend->registerAttempt('10.10.10.10', '10.10.10.10/32', 186, 'action7', ['metadata2']);
+ }
+}
diff --git a/tests/lib/Security/Bruteforce/CapabilitiesTest.php b/tests/lib/Security/Bruteforce/CapabilitiesTest.php
index 1c2bbb6bc53..438a24f2240 100644
--- a/tests/lib/Security/Bruteforce/CapabilitiesTest.php
+++ b/tests/lib/Security/Bruteforce/CapabilitiesTest.php
@@ -3,30 +3,15 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2017 Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\Bruteforce;
use OC\Security\Bruteforce\Capabilities;
-use OC\Security\Bruteforce\Throttler;
use OCP\IRequest;
+use OCP\Security\Bruteforce\IThrottler;
use Test\TestCase;
class CapabilitiesTest extends TestCase {
@@ -36,7 +21,7 @@ class CapabilitiesTest extends TestCase {
/** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */
private $request;
- /** @var Throttler|\PHPUnit\Framework\MockObject\MockObject */
+ /** @var IThrottler|\PHPUnit\Framework\MockObject\MockObject */
private $throttler;
protected function setUp(): void {
@@ -44,7 +29,7 @@ class CapabilitiesTest extends TestCase {
$this->request = $this->createMock(IRequest::class);
- $this->throttler = $this->createMock(Throttler::class);
+ $this->throttler = $this->createMock(IThrottler::class);
$this->capabilities = new Capabilities(
$this->request,
@@ -52,18 +37,24 @@ class CapabilitiesTest extends TestCase {
);
}
- public function testGetCapabilities() {
+ public function testGetCapabilities(): void {
$this->throttler->expects($this->atLeastOnce())
->method('getDelay')
->with('10.10.10.10')
->willReturn(42);
+ $this->throttler->expects($this->atLeastOnce())
+ ->method('isBypassListed')
+ ->with('10.10.10.10')
+ ->willReturn(true);
+
$this->request->method('getRemoteAddress')
->willReturn('10.10.10.10');
$expected = [
'bruteforce' => [
- 'delay' => 42
+ 'delay' => 42,
+ 'allow-listed' => true,
]
];
$result = $this->capabilities->getCapabilities();
@@ -71,7 +62,7 @@ class CapabilitiesTest extends TestCase {
$this->assertEquals($expected, $result);
}
- public function testGetCapabilitiesOnCli() {
+ public function testGetCapabilitiesOnCli(): void {
$this->throttler->expects($this->atLeastOnce())
->method('getDelay')
->with('')
@@ -82,7 +73,8 @@ class CapabilitiesTest extends TestCase {
$expected = [
'bruteforce' => [
- 'delay' => 0
+ 'delay' => 0,
+ 'allow-listed' => false,
]
];
$result = $this->capabilities->getCapabilities();
diff --git a/tests/lib/Security/Bruteforce/ThrottlerTest.php b/tests/lib/Security/Bruteforce/ThrottlerTest.php
deleted file mode 100644
index 6639f884ae1..00000000000
--- a/tests/lib/Security/Bruteforce/ThrottlerTest.php
+++ /dev/null
@@ -1,242 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-/**
- * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-namespace Test\Security\Bruteforce;
-
-use OC\AppFramework\Utility\TimeFactory;
-use OC\Security\Bruteforce\Throttler;
-use OCP\IConfig;
-use OCP\IDBConnection;
-use Psr\Log\LoggerInterface;
-use Test\TestCase;
-
-/**
- * Based on the unit tests from Paragonie's Airship CMS
- * Ref: https://github.com/paragonie/airship/blob/7e5bad7e3c0fbbf324c11f963fd1f80e59762606/test/unit/Engine/Security/AirBrakeTest.php
- *
- * @package Test\Security\Bruteforce
- */
-class ThrottlerTest extends TestCase {
- /** @var Throttler */
- private $throttler;
- /** @var IDBConnection */
- private $dbConnection;
- /** @var LoggerInterface */
- private $logger;
- /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
- private $config;
-
- protected function setUp(): void {
- $this->dbConnection = $this->createMock(IDBConnection::class);
- $this->logger = $this->createMock(LoggerInterface::class);
- $this->config = $this->createMock(IConfig::class);
-
- $this->throttler = new Throttler(
- $this->dbConnection,
- new TimeFactory(),
- $this->logger,
- $this->config
- );
- parent::setUp();
- }
-
- public function testCutoff() {
- // precisely 31 second shy of 12 hours
- $cutoff = self::invokePrivate($this->throttler, 'getCutoff', [43169]);
- $this->assertSame(0, $cutoff->y);
- $this->assertSame(0, $cutoff->m);
- $this->assertSame(0, $cutoff->d);
- $this->assertSame(11, $cutoff->h);
- $this->assertSame(59, $cutoff->i);
- $this->assertSame(29, $cutoff->s);
- $cutoff = self::invokePrivate($this->throttler, 'getCutoff', [86401]);
- $this->assertSame(0, $cutoff->y);
- $this->assertSame(0, $cutoff->m);
- $this->assertSame(1, $cutoff->d);
- $this->assertSame(0, $cutoff->h);
- $this->assertSame(0, $cutoff->i);
- // Leap second tolerance:
- $this->assertLessThan(2, $cutoff->s);
- }
-
- public function dataIsIPWhitelisted() {
- return [
- [
- '10.10.10.10',
- [
- 'whitelist_0' => '10.10.10.0/24',
- ],
- true,
- ],
- [
- '10.10.10.10',
- [
- 'whitelist_0' => '192.168.0.0/16',
- ],
- false,
- ],
- [
- '10.10.10.10',
- [
- 'whitelist_0' => '192.168.0.0/16',
- 'whitelist_1' => '10.10.10.0/24',
- ],
- true,
- ],
- [
- '10.10.10.10',
- [
- 'whitelist_0' => '10.10.10.11/31',
- ],
- true,
- ],
- [
- '10.10.10.10',
- [
- 'whitelist_0' => '10.10.10.9/31',
- ],
- false,
- ],
- [
- '10.10.10.10',
- [
- 'whitelist_0' => '10.10.10.15/29',
- ],
- true,
- ],
- [
- 'dead:beef:cafe::1',
- [
- 'whitelist_0' => '192.168.0.0/16',
- 'whitelist_1' => '10.10.10.0/24',
- 'whitelist_2' => 'deaf:beef:cafe:1234::/64'
- ],
- false,
- ],
- [
- 'dead:beef:cafe::1',
- [
- 'whitelist_0' => '192.168.0.0/16',
- 'whitelist_1' => '10.10.10.0/24',
- 'whitelist_2' => 'deaf:beef::/64'
- ],
- false,
- ],
- [
- 'dead:beef:cafe::1',
- [
- 'whitelist_0' => '192.168.0.0/16',
- 'whitelist_1' => '10.10.10.0/24',
- 'whitelist_2' => 'deaf:cafe::/8'
- ],
- true,
- ],
- [
- 'dead:beef:cafe::1111',
- [
- 'whitelist_0' => 'dead:beef:cafe::1100/123',
-
- ],
- true,
- ],
- [
- 'invalid',
- [],
- false,
- ],
- ];
- }
-
- /**
- * @param string $ip
- * @param string[] $whitelists
- * @param bool $isWhiteListed
- * @param bool $enabled
- */
- private function isIpWhiteListedHelper($ip,
- $whitelists,
- $isWhiteListed,
- $enabled) {
- $this->config->method('getAppKeys')
- ->with($this->equalTo('bruteForce'))
- ->willReturn(array_keys($whitelists));
- $this->config
- ->expects($this->once())
- ->method('getSystemValue')
- ->with('auth.bruteforce.protection.enabled', true)
- ->willReturn($enabled);
-
- $this->config->method('getAppValue')
- ->willReturnCallback(function ($app, $key, $default) use ($whitelists) {
- if ($app !== 'bruteForce') {
- return $default;
- }
- if (isset($whitelists[$key])) {
- return $whitelists[$key];
- }
- return $default;
- });
-
- $this->assertSame(
- ($enabled === false) ? true : $isWhiteListed,
- self::invokePrivate($this->throttler, 'isIPWhitelisted', [$ip])
- );
- }
-
- /**
- * @dataProvider dataIsIPWhitelisted
- *
- * @param string $ip
- * @param string[] $whitelists
- * @param bool $isWhiteListed
- */
- public function testIsIpWhiteListedWithEnabledProtection($ip,
- $whitelists,
- $isWhiteListed) {
- $this->isIpWhiteListedHelper(
- $ip,
- $whitelists,
- $isWhiteListed,
- true
- );
- }
-
- /**
- * @dataProvider dataIsIPWhitelisted
- *
- * @param string $ip
- * @param string[] $whitelists
- * @param bool $isWhiteListed
- */
- public function testIsIpWhiteListedWithDisabledProtection($ip,
- $whitelists,
- $isWhiteListed) {
- $this->isIpWhiteListedHelper(
- $ip,
- $whitelists,
- $isWhiteListed,
- false
- );
- }
-}
diff --git a/tests/lib/Security/CSP/AddContentSecurityPolicyEventTest.php b/tests/lib/Security/CSP/AddContentSecurityPolicyEventTest.php
index 7de4665ec58..39dd7a95890 100644
--- a/tests/lib/Security/CSP/AddContentSecurityPolicyEventTest.php
+++ b/tests/lib/Security/CSP/AddContentSecurityPolicyEventTest.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\CSP;
@@ -32,7 +15,7 @@ use OCP\Security\CSP\AddContentSecurityPolicyEvent;
use Test\TestCase;
class AddContentSecurityPolicyEventTest extends TestCase {
- public function testAddEvent() {
+ public function testAddEvent(): void {
$cspManager = $this->createMock(ContentSecurityPolicyManager::class);
$policy = $this->createMock(ContentSecurityPolicy::class);
$event = new AddContentSecurityPolicyEvent($cspManager);
diff --git a/tests/lib/Security/CSP/ContentSecurityPolicyManagerTest.php b/tests/lib/Security/CSP/ContentSecurityPolicyManagerTest.php
index 082ef46330d..a32a4132287 100644
--- a/tests/lib/Security/CSP/ContentSecurityPolicyManagerTest.php
+++ b/tests/lib/Security/CSP/ContentSecurityPolicyManagerTest.php
@@ -3,35 +3,23 @@
declare(strict_types=1);
/**
- * @author Lukas Reschke <lukas@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Test\Security\CSP;
use OC\Security\CSP\ContentSecurityPolicyManager;
+use OCP\AppFramework\Http\ContentSecurityPolicy;
+use OCP\AppFramework\Http\EmptyContentSecurityPolicy;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Security\CSP\AddContentSecurityPolicyEvent;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use OCP\Server;
use Test\TestCase;
class ContentSecurityPolicyManagerTest extends TestCase {
- /** @var EventDispatcherInterface */
+ /** @var IEventDispatcher */
private $dispatcher;
/** @var ContentSecurityPolicyManager */
@@ -39,34 +27,32 @@ class ContentSecurityPolicyManagerTest extends TestCase {
protected function setUp(): void {
parent::setUp();
- $this->dispatcher = \OC::$server->query(IEventDispatcher::class);
+ $this->dispatcher = Server::get(IEventDispatcher::class);
$this->contentSecurityPolicyManager = new ContentSecurityPolicyManager($this->dispatcher);
}
- public function testAddDefaultPolicy() {
- $this->contentSecurityPolicyManager->addDefaultPolicy(new \OCP\AppFramework\Http\ContentSecurityPolicy());
+ public function testAddDefaultPolicy(): void {
+ $this->contentSecurityPolicyManager->addDefaultPolicy(new ContentSecurityPolicy());
$this->addToAssertionCount(1);
}
- public function testGetDefaultPolicyWithPolicies() {
- $policy = new \OCP\AppFramework\Http\ContentSecurityPolicy();
+ public function testGetDefaultPolicyWithPolicies(): void {
+ $policy = new ContentSecurityPolicy();
$policy->addAllowedFontDomain('mydomain.com');
$policy->addAllowedImageDomain('anotherdomain.de');
$this->contentSecurityPolicyManager->addDefaultPolicy($policy);
- $policy = new \OCP\AppFramework\Http\ContentSecurityPolicy();
+ $policy = new ContentSecurityPolicy();
$policy->addAllowedFontDomain('example.com');
$policy->addAllowedImageDomain('example.org');
- $policy->allowInlineScript(true);
$policy->allowEvalScript(true);
$this->contentSecurityPolicyManager->addDefaultPolicy($policy);
- $policy = new \OCP\AppFramework\Http\EmptyContentSecurityPolicy();
+ $policy = new EmptyContentSecurityPolicy();
$policy->addAllowedChildSrcDomain('childdomain');
$policy->addAllowedFontDomain('anotherFontDomain');
$policy->addAllowedFormActionDomain('thirdDomain');
$this->contentSecurityPolicyManager->addDefaultPolicy($policy);
$expected = new \OC\Security\CSP\ContentSecurityPolicy();
- $expected->allowInlineScript(true);
$expected->allowEvalScript(true);
$expected->addAllowedFontDomain('mydomain.com');
$expected->addAllowedFontDomain('example.com');
@@ -75,15 +61,15 @@ class ContentSecurityPolicyManagerTest extends TestCase {
$expected->addAllowedImageDomain('anotherdomain.de');
$expected->addAllowedImageDomain('example.org');
$expected->addAllowedChildSrcDomain('childdomain');
- $expectedStringPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: anotherdomain.de example.org;font-src 'self' data: mydomain.com example.com anotherFontDomain;connect-src 'self';media-src 'self';child-src childdomain;frame-ancestors 'self';form-action 'self' thirdDomain";
+ $expectedStringPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: anotherdomain.de example.org;font-src 'self' data: mydomain.com example.com anotherFontDomain;connect-src 'self';media-src 'self';child-src childdomain;frame-ancestors 'self';form-action 'self' thirdDomain";
$this->assertEquals($expected, $this->contentSecurityPolicyManager->getDefaultPolicy());
$this->assertSame($expectedStringPolicy, $this->contentSecurityPolicyManager->getDefaultPolicy()->buildPolicy());
}
- public function testGetDefaultPolicyWithPoliciesViaEvent() {
- $this->dispatcher->addListener(AddContentSecurityPolicyEvent::class, function (AddContentSecurityPolicyEvent $e) {
- $policy = new \OCP\AppFramework\Http\ContentSecurityPolicy();
+ public function testGetDefaultPolicyWithPoliciesViaEvent(): void {
+ $this->dispatcher->addListener(AddContentSecurityPolicyEvent::class, function (AddContentSecurityPolicyEvent $e): void {
+ $policy = new ContentSecurityPolicy();
$policy->addAllowedFontDomain('mydomain.com');
$policy->addAllowedImageDomain('anotherdomain.de');
$policy->useStrictDynamic(true);
@@ -92,17 +78,16 @@ class ContentSecurityPolicyManagerTest extends TestCase {
$e->addPolicy($policy);
});
- $this->dispatcher->addListener(AddContentSecurityPolicyEvent::class, function (AddContentSecurityPolicyEvent $e) {
- $policy = new \OCP\AppFramework\Http\ContentSecurityPolicy();
+ $this->dispatcher->addListener(AddContentSecurityPolicyEvent::class, function (AddContentSecurityPolicyEvent $e): void {
+ $policy = new ContentSecurityPolicy();
$policy->addAllowedFontDomain('example.com');
$policy->addAllowedImageDomain('example.org');
- $policy->allowInlineScript(true);
$policy->allowEvalScript(false);
$e->addPolicy($policy);
});
- $this->dispatcher->addListener(AddContentSecurityPolicyEvent::class, function (AddContentSecurityPolicyEvent $e) {
- $policy = new \OCP\AppFramework\Http\EmptyContentSecurityPolicy();
+ $this->dispatcher->addListener(AddContentSecurityPolicyEvent::class, function (AddContentSecurityPolicyEvent $e): void {
+ $policy = new EmptyContentSecurityPolicy();
$policy->addAllowedChildSrcDomain('childdomain');
$policy->addAllowedFontDomain('anotherFontDomain');
$policy->addAllowedFormActionDomain('thirdDomain');
@@ -110,7 +95,6 @@ class ContentSecurityPolicyManagerTest extends TestCase {
});
$expected = new \OC\Security\CSP\ContentSecurityPolicy();
- $expected->allowInlineScript(true);
$expected->allowEvalScript(true);
$expected->addAllowedFontDomain('mydomain.com');
$expected->addAllowedFontDomain('example.com');
@@ -120,7 +104,7 @@ class ContentSecurityPolicyManagerTest extends TestCase {
$expected->addAllowedChildSrcDomain('childdomain');
$expected->addAllowedFormActionDomain('thirdDomain');
$expected->useStrictDynamic(true);
- $expectedStringPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: anotherdomain.de example.org;font-src 'self' data: mydomain.com example.com anotherFontDomain;connect-src 'self';media-src 'self';child-src childdomain;frame-ancestors 'self';form-action 'self' thirdDomain";
+ $expectedStringPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: anotherdomain.de example.org;font-src 'self' data: mydomain.com example.com anotherFontDomain;connect-src 'self';media-src 'self';child-src childdomain;frame-ancestors 'self';form-action 'self' thirdDomain";
$this->assertEquals($expected, $this->contentSecurityPolicyManager->getDefaultPolicy());
$this->assertSame($expectedStringPolicy, $this->contentSecurityPolicyManager->getDefaultPolicy()->buildPolicy());
diff --git a/tests/lib/Security/CSP/ContentSecurityPolicyNonceManagerTest.php b/tests/lib/Security/CSP/ContentSecurityPolicyNonceManagerTest.php
index 0e21f13e6f7..3765311155a 100644
--- a/tests/lib/Security/CSP/ContentSecurityPolicyNonceManagerTest.php
+++ b/tests/lib/Security/CSP/ContentSecurityPolicyNonceManagerTest.php
@@ -3,23 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\CSP;
@@ -28,42 +13,46 @@ use OC\AppFramework\Http\Request;
use OC\Security\CSP\ContentSecurityPolicyNonceManager;
use OC\Security\CSRF\CsrfToken;
use OC\Security\CSRF\CsrfTokenManager;
+use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
class ContentSecurityPolicyNonceManagerTest extends TestCase {
- /** @var CsrfTokenManager */
- private $csrfTokenManager;
- /** @var Request */
+ /** @var CsrfTokenManager&MockObject */
+ private $CSRFTokenManager;
+ /** @var Request&MockObject */
private $request;
/** @var ContentSecurityPolicyNonceManager */
private $nonceManager;
protected function setUp(): void {
- $this->csrfTokenManager = $this->createMock(CsrfTokenManager::class);
+ $this->CSRFTokenManager = $this->createMock(CsrfTokenManager::class);
$this->request = $this->createMock(Request::class);
$this->nonceManager = new ContentSecurityPolicyNonceManager(
- $this->csrfTokenManager,
+ $this->CSRFTokenManager,
$this->request
);
}
- public function testGetNonce() {
+ public function testGetNonce(): void {
+ $secret = base64_encode('secret');
+ $tokenValue = base64_encode('secret' ^ 'value_') . ':' . $secret;
$token = $this->createMock(CsrfToken::class);
$token
->expects($this->once())
->method('getEncryptedValue')
- ->willReturn('MyToken');
+ ->willReturn($tokenValue);
- $this->csrfTokenManager
+ $this->CSRFTokenManager
->expects($this->once())
->method('getToken')
->willReturn($token);
- $this->assertSame('TXlUb2tlbg==', $this->nonceManager->getNonce());
- $this->assertSame('TXlUb2tlbg==', $this->nonceManager->getNonce());
+ $this->assertSame($secret, $this->nonceManager->getNonce());
+ // call it twice but `getEncryptedValue` is expected to be called only once
+ $this->assertSame($secret, $this->nonceManager->getNonce());
}
- public function testGetNonceServerVar() {
+ public function testGetNonceServerVar(): void {
$token = 'SERVERNONCE';
$this->request
->method('__isset')
@@ -76,6 +65,7 @@ class ContentSecurityPolicyNonceManagerTest extends TestCase {
->willReturn(['CSP_NONCE' => $token]);
$this->assertSame($token, $this->nonceManager->getNonce());
+ // call it twice but `CSP_NONCE` variable is expected to be loaded only once
$this->assertSame($token, $this->nonceManager->getNonce());
}
}
diff --git a/tests/lib/Security/CSRF/CsrfTokenGeneratorTest.php b/tests/lib/Security/CSRF/CsrfTokenGeneratorTest.php
index 256199eff15..86f458d8ea8 100644
--- a/tests/lib/Security/CSRF/CsrfTokenGeneratorTest.php
+++ b/tests/lib/Security/CSRF/CsrfTokenGeneratorTest.php
@@ -3,29 +3,18 @@
declare(strict_types=1);
/**
- * @author Lukas Reschke <lukas@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Test\Security\CSRF;
+use OC\Security\CSRF\CsrfTokenGenerator;
+use OCP\Security\ISecureRandom;
+
class CsrfTokenGeneratorTest extends \Test\TestCase {
- /** @var \OCP\Security\ISecureRandom */
+ /** @var ISecureRandom */
private $random;
/** @var \OC\Security\CSRF\CsrfTokenGenerator */
private $csrfTokenGenerator;
@@ -34,10 +23,10 @@ class CsrfTokenGeneratorTest extends \Test\TestCase {
parent::setUp();
$this->random = $this->getMockBuilder('\OCP\Security\ISecureRandom')
->disableOriginalConstructor()->getMock();
- $this->csrfTokenGenerator = new \OC\Security\CSRF\CsrfTokenGenerator($this->random);
+ $this->csrfTokenGenerator = new CsrfTokenGenerator($this->random);
}
- public function testGenerateTokenWithCustomNumber() {
+ public function testGenerateTokenWithCustomNumber(): void {
$this->random
->expects($this->once())
->method('generate')
@@ -46,7 +35,7 @@ class CsrfTokenGeneratorTest extends \Test\TestCase {
$this->assertSame('abc', $this->csrfTokenGenerator->generateToken(3));
}
- public function testGenerateTokenWithDefault() {
+ public function testGenerateTokenWithDefault(): void {
$this->random
->expects($this->once())
->method('generate')
diff --git a/tests/lib/Security/CSRF/CsrfTokenManagerTest.php b/tests/lib/Security/CSRF/CsrfTokenManagerTest.php
index 44a9a7a929d..66ee18475a4 100644
--- a/tests/lib/Security/CSRF/CsrfTokenManagerTest.php
+++ b/tests/lib/Security/CSRF/CsrfTokenManagerTest.php
@@ -3,27 +3,16 @@
declare(strict_types=1);
/**
- * @author Lukas Reschke <lukas@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Test\Security\CSRF;
+use OC\Security\CSRF\CsrfToken;
+use OC\Security\CSRF\CsrfTokenManager;
+
class CsrfTokenManagerTest extends \Test\TestCase {
/** @var \OC\Security\CSRF\CsrfTokenManager */
private $csrfTokenManager;
@@ -39,13 +28,13 @@ class CsrfTokenManagerTest extends \Test\TestCase {
$this->storageInterface = $this->getMockBuilder('\OC\Security\CSRF\TokenStorage\SessionStorage')
->disableOriginalConstructor()->getMock();
- $this->csrfTokenManager = new \OC\Security\CSRF\CsrfTokenManager(
+ $this->csrfTokenManager = new CsrfTokenManager(
$this->tokenGenerator,
$this->storageInterface
);
}
- public function testGetTokenWithExistingToken() {
+ public function testGetTokenWithExistingToken(): void {
$this->storageInterface
->expects($this->once())
->method('hasToken')
@@ -55,11 +44,11 @@ class CsrfTokenManagerTest extends \Test\TestCase {
->method('getToken')
->willReturn('MyExistingToken');
- $expected = new \OC\Security\CSRF\CsrfToken('MyExistingToken');
+ $expected = new CsrfToken('MyExistingToken');
$this->assertEquals($expected, $this->csrfTokenManager->getToken());
}
- public function testGetTokenWithExistingTokenKeepsOnSecondRequest() {
+ public function testGetTokenWithExistingTokenKeepsOnSecondRequest(): void {
$this->storageInterface
->expects($this->once())
->method('hasToken')
@@ -69,13 +58,13 @@ class CsrfTokenManagerTest extends \Test\TestCase {
->method('getToken')
->willReturn('MyExistingToken');
- $expected = new \OC\Security\CSRF\CsrfToken('MyExistingToken');
+ $expected = new CsrfToken('MyExistingToken');
$token = $this->csrfTokenManager->getToken();
$this->assertSame($token, $this->csrfTokenManager->getToken());
$this->assertSame($token, $this->csrfTokenManager->getToken());
}
- public function testGetTokenWithoutExistingToken() {
+ public function testGetTokenWithoutExistingToken(): void {
$this->storageInterface
->expects($this->once())
->method('hasToken')
@@ -89,11 +78,11 @@ class CsrfTokenManagerTest extends \Test\TestCase {
->method('setToken')
->with('MyNewToken');
- $expected = new \OC\Security\CSRF\CsrfToken('MyNewToken');
+ $expected = new CsrfToken('MyNewToken');
$this->assertEquals($expected, $this->csrfTokenManager->getToken());
}
- public function testRefreshToken() {
+ public function testRefreshToken(): void {
$this->tokenGenerator
->expects($this->once())
->method('generateToken')
@@ -103,11 +92,11 @@ class CsrfTokenManagerTest extends \Test\TestCase {
->method('setToken')
->with('MyNewToken');
- $expected = new \OC\Security\CSRF\CsrfToken('MyNewToken');
+ $expected = new CsrfToken('MyNewToken');
$this->assertEquals($expected, $this->csrfTokenManager->refreshToken());
}
- public function testRemoveToken() {
+ public function testRemoveToken(): void {
$this->storageInterface
->expects($this->once())
->method('removeToken');
@@ -115,22 +104,22 @@ class CsrfTokenManagerTest extends \Test\TestCase {
$this->csrfTokenManager->removeToken();
}
- public function testIsTokenValidWithoutToken() {
+ public function testIsTokenValidWithoutToken(): void {
$this->storageInterface
->expects($this->once())
->method('hasToken')
->willReturn(false);
- $token = new \OC\Security\CSRF\CsrfToken('Token');
+ $token = new CsrfToken('Token');
$this->assertSame(false, $this->csrfTokenManager->isTokenValid($token));
}
- public function testIsTokenValidWithWrongToken() {
+ public function testIsTokenValidWithWrongToken(): void {
$this->storageInterface
->expects($this->once())
->method('hasToken')
->willReturn(true);
- $token = new \OC\Security\CSRF\CsrfToken('Token');
+ $token = new CsrfToken('Token');
$this->storageInterface
->expects($this->once())
->method('getToken')
@@ -139,20 +128,20 @@ class CsrfTokenManagerTest extends \Test\TestCase {
$this->assertSame(false, $this->csrfTokenManager->isTokenValid($token));
}
- public function testIsTokenValidWithValidToken() {
+ public function testIsTokenValidWithValidToken(): void {
$a = 'abc';
$b = 'def';
$xorB64 = 'BQcF';
$tokenVal = sprintf('%s:%s', $xorB64, base64_encode($a));
$this->storageInterface
- ->expects($this->once())
- ->method('hasToken')
- ->willReturn(true);
- $token = new \OC\Security\CSRF\CsrfToken($tokenVal);
+ ->expects($this->once())
+ ->method('hasToken')
+ ->willReturn(true);
+ $token = new CsrfToken($tokenVal);
$this->storageInterface
- ->expects($this->once())
- ->method('getToken')
- ->willReturn($b);
+ ->expects($this->once())
+ ->method('getToken')
+ ->willReturn($b);
$this->assertSame(true, $this->csrfTokenManager->isTokenValid($token));
}
diff --git a/tests/lib/Security/CSRF/CsrfTokenTest.php b/tests/lib/Security/CSRF/CsrfTokenTest.php
index b694e797232..5b5ba5ae54f 100644
--- a/tests/lib/Security/CSRF/CsrfTokenTest.php
+++ b/tests/lib/Security/CSRF/CsrfTokenTest.php
@@ -3,47 +3,35 @@
declare(strict_types=1);
/**
- * @author Lukas Reschke <lukas@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Test\Security\CSRF;
+use OC\Security\CSRF\CsrfToken;
+
class CsrfTokenTest extends \Test\TestCase {
- public function testGetEncryptedValue() {
- $csrfToken = new \OC\Security\CSRF\CsrfToken('MyCsrfToken');
+ public function testGetEncryptedValue(): void {
+ $csrfToken = new CsrfToken('MyCsrfToken');
$this->assertSame(33, strlen($csrfToken->getEncryptedValue()));
$this->assertSame(':', $csrfToken->getEncryptedValue()[16]);
}
- public function testGetEncryptedValueStaysSameOnSecondRequest() {
- $csrfToken = new \OC\Security\CSRF\CsrfToken('MyCsrfToken');
+ public function testGetEncryptedValueStaysSameOnSecondRequest(): void {
+ $csrfToken = new CsrfToken('MyCsrfToken');
$tokenValue = $csrfToken->getEncryptedValue();
$this->assertSame($tokenValue, $csrfToken->getEncryptedValue());
$this->assertSame($tokenValue, $csrfToken->getEncryptedValue());
}
- public function testGetDecryptedValue() {
+ public function testGetDecryptedValue(): void {
$a = 'abc';
$b = 'def';
$xorB64 = 'BQcF';
$tokenVal = sprintf('%s:%s', $xorB64, base64_encode($a));
- $csrfToken = new \OC\Security\CSRF\CsrfToken($tokenVal);
+ $csrfToken = new CsrfToken($tokenVal);
$this->assertSame($b, $csrfToken->getDecryptedValue());
}
}
diff --git a/tests/lib/Security/CSRF/TokenStorage/SessionStorageTest.php b/tests/lib/Security/CSRF/TokenStorage/SessionStorageTest.php
index f55cf49f142..2b2c4af0444 100644
--- a/tests/lib/Security/CSRF/TokenStorage/SessionStorageTest.php
+++ b/tests/lib/Security/CSRF/TokenStorage/SessionStorageTest.php
@@ -3,31 +3,18 @@
declare(strict_types=1);
/**
- * @author Lukas Reschke <lukas@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Test\Security\CSRF\TokenStorage;
+use OC\Security\CSRF\TokenStorage\SessionStorage;
use OCP\ISession;
class SessionStorageTest extends \Test\TestCase {
- /** @var \OCP\ISession */
+ /** @var ISession */
private $session;
/** @var \OC\Security\CSRF\TokenStorage\SessionStorage */
private $sessionStorage;
@@ -36,13 +23,13 @@ class SessionStorageTest extends \Test\TestCase {
parent::setUp();
$this->session = $this->getMockBuilder(ISession::class)
->disableOriginalConstructor()->getMock();
- $this->sessionStorage = new \OC\Security\CSRF\TokenStorage\SessionStorage($this->session);
+ $this->sessionStorage = new SessionStorage($this->session);
}
/**
* @return array
*/
- public function getTokenDataProvider() {
+ public static function getTokenDataProvider(): array {
return [
[
'',
@@ -55,10 +42,10 @@ class SessionStorageTest extends \Test\TestCase {
/**
* @param string $token
- * @dataProvider getTokenDataProvider
*
*/
- public function testGetTokenWithEmptyToken($token) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('getTokenDataProvider')]
+ public function testGetTokenWithEmptyToken($token): void {
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Session does not contain a requesttoken');
@@ -70,7 +57,7 @@ class SessionStorageTest extends \Test\TestCase {
$this->sessionStorage->getToken();
}
- public function testGetTokenWithValidToken() {
+ public function testGetTokenWithValidToken(): void {
$this->session
->expects($this->once())
->method('get')
@@ -79,7 +66,7 @@ class SessionStorageTest extends \Test\TestCase {
$this->assertSame('MyFancyCsrfToken', $this->sessionStorage->getToken());
}
- public function testSetToken() {
+ public function testSetToken(): void {
$this->session
->expects($this->once())
->method('set')
@@ -87,7 +74,7 @@ class SessionStorageTest extends \Test\TestCase {
$this->sessionStorage->setToken('TokenToSet');
}
- public function testRemoveToken() {
+ public function testRemoveToken(): void {
$this->session
->expects($this->once())
->method('remove')
@@ -95,7 +82,7 @@ class SessionStorageTest extends \Test\TestCase {
$this->sessionStorage->removeToken();
}
- public function testHasTokenWithExistingToken() {
+ public function testHasTokenWithExistingToken(): void {
$this->session
->expects($this->once())
->method('exists')
@@ -104,7 +91,7 @@ class SessionStorageTest extends \Test\TestCase {
$this->assertSame(true, $this->sessionStorage->hasToken());
}
- public function testHasTokenWithoutExistingToken() {
+ public function testHasTokenWithoutExistingToken(): void {
$this->session
->expects($this->once())
->method('exists')
@@ -113,7 +100,7 @@ class SessionStorageTest extends \Test\TestCase {
$this->assertSame(false, $this->sessionStorage->hasToken());
}
- public function testSetSession() {
+ public function testSetSession(): void {
$session = $this->createMock(ISession::class);
$session
->expects($this->once())
diff --git a/tests/lib/Security/CertificateManagerTest.php b/tests/lib/Security/CertificateManagerTest.php
index fdc6b40533e..4dadc824ef6 100644
--- a/tests/lib/Security/CertificateManagerTest.php
+++ b/tests/lib/Security/CertificateManagerTest.php
@@ -3,18 +3,24 @@
declare(strict_types=1);
/**
- * Copyright (c) 2014 Lukas Reschke <lukas@owncloud.com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security;
+use OC\Files\Filesystem;
+use OC\Files\Storage\Temporary;
use OC\Files\View;
+use OC\Security\Certificate;
use OC\Security\CertificateManager;
+use OCP\Files\InvalidPathException;
use OCP\IConfig;
+use OCP\IUserManager;
use OCP\Security\ISecureRandom;
+use OCP\Server;
+use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
/**
@@ -26,12 +32,9 @@ class CertificateManagerTest extends \Test\TestCase {
use \Test\Traits\UserTrait;
use \Test\Traits\MountProviderTrait;
- /** @var CertificateManager */
- private $certificateManager;
- /** @var String */
- private $username;
- /** @var ISecureRandom */
- private $random;
+ private CertificateManager $certificateManager;
+ private string $username;
+ private ISecureRandom&MockObject $random;
protected function setUp(): void {
parent::setUp();
@@ -39,16 +42,16 @@ class CertificateManagerTest extends \Test\TestCase {
$this->username = $this->getUniqueID('', 20);
$this->createUser($this->username, '');
- $storage = new \OC\Files\Storage\Temporary();
+ $storage = new Temporary();
$this->registerMount($this->username, $storage, '/' . $this->username . '/');
\OC_Util::tearDownFS();
- \OC_User::setUserId('');
- \OC\Files\Filesystem::tearDown();
+ \OC_User::setUserId($this->username);
+ Filesystem::tearDown();
\OC_Util::setupFS($this->username);
$config = $this->createMock(IConfig::class);
- $config->expects($this->any())->method('getSystemValue')
+ $config->expects($this->any())->method('getSystemValueBool')
->with('installed', false)->willReturn(true);
$this->random = $this->createMock(ISecureRandom::class);
@@ -56,7 +59,7 @@ class CertificateManagerTest extends \Test\TestCase {
->willReturn('random');
$this->certificateManager = new CertificateManager(
- new \OC\Files\View(),
+ new View(),
$config,
$this->createMock(LoggerInterface::class),
$this->random
@@ -64,7 +67,7 @@ class CertificateManagerTest extends \Test\TestCase {
}
protected function tearDown(): void {
- $user = \OC::$server->getUserManager()->get($this->username);
+ $user = Server::get(IUserManager::class)->get($this->username);
if ($user !== null) {
$user->delete();
}
@@ -78,34 +81,31 @@ class CertificateManagerTest extends \Test\TestCase {
$this->assertEquals($expected, $actual);
}
- public function testListCertificates() {
+ public function testListCertificates(): void {
// Test empty certificate bundle
$this->assertSame([], $this->certificateManager->listCertificates());
// Add some certificates
$this->certificateManager->addCertificate(file_get_contents(__DIR__ . '/../../data/certificates/goodCertificate.crt'), 'GoodCertificate');
$certificateStore = [];
- $certificateStore[] = new \OC\Security\Certificate(file_get_contents(__DIR__ . '/../../data/certificates/goodCertificate.crt'), 'GoodCertificate');
+ $certificateStore[] = new Certificate(file_get_contents(__DIR__ . '/../../data/certificates/goodCertificate.crt'), 'GoodCertificate');
$this->assertEqualsArrays($certificateStore, $this->certificateManager->listCertificates());
// Add another certificates
$this->certificateManager->addCertificate(file_get_contents(__DIR__ . '/../../data/certificates/expiredCertificate.crt'), 'ExpiredCertificate');
- $certificateStore[] = new \OC\Security\Certificate(file_get_contents(__DIR__ . '/../../data/certificates/expiredCertificate.crt'), 'ExpiredCertificate');
+ $certificateStore[] = new Certificate(file_get_contents(__DIR__ . '/../../data/certificates/expiredCertificate.crt'), 'ExpiredCertificate');
$this->assertEqualsArrays($certificateStore, $this->certificateManager->listCertificates());
}
- public function testAddInvalidCertificate() {
+ public function testAddInvalidCertificate(): void {
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Certificate could not get parsed.');
$this->certificateManager->addCertificate('InvalidCertificate', 'invalidCertificate');
}
- /**
- * @return array
- */
- public function dangerousFileProvider() {
+ public static function dangerousFileProvider(): array {
return [
['.htaccess'],
['../../foo.txt'],
@@ -114,42 +114,40 @@ class CertificateManagerTest extends \Test\TestCase {
}
/**
- * @dataProvider dangerousFileProvider
* @param string $filename
*/
- public function testAddDangerousFile($filename) {
- $this->expectException(\Exception::class);
- $this->expectExceptionMessage('Filename is not valid');
-
+ #[\PHPUnit\Framework\Attributes\DataProvider('dangerousFileProvider')]
+ public function testAddDangerousFile($filename): void {
+ $this->expectException(InvalidPathException::class);
$this->certificateManager->addCertificate(file_get_contents(__DIR__ . '/../../data/certificates/expiredCertificate.crt'), $filename);
}
- public function testRemoveDangerousFile() {
+ public function testRemoveDangerousFile(): void {
$this->assertFalse($this->certificateManager->removeCertificate('../../foo.txt'));
}
- public function testRemoveExistingFile() {
+ public function testRemoveExistingFile(): void {
$this->certificateManager->addCertificate(file_get_contents(__DIR__ . '/../../data/certificates/goodCertificate.crt'), 'GoodCertificate');
$this->assertTrue($this->certificateManager->removeCertificate('GoodCertificate'));
}
- public function testGetCertificateBundle() {
+ public function testGetCertificateBundle(): void {
$this->assertSame('/files_external/rootcerts.crt', $this->certificateManager->getCertificateBundle());
}
/**
- * @dataProvider dataTestNeedRebundling
*
* @param int $CaBundleMtime
* @param int $targetBundleMtime
* @param int $targetBundleExists
* @param bool $expected
*/
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataTestNeedRebundling')]
public function testNeedRebundling($CaBundleMtime,
- $targetBundleMtime,
- $targetBundleExists,
- $expected
- ) {
+ $targetBundleMtime,
+ $targetBundleExists,
+ $expected,
+ ): void {
$view = $this->getMockBuilder(View::class)
->disableOriginalConstructor()->getMock();
$config = $this->createMock(IConfig::class);
@@ -157,7 +155,7 @@ class CertificateManagerTest extends \Test\TestCase {
/** @var CertificateManager | \PHPUnit\Framework\MockObject\MockObject $certificateManager */
$certificateManager = $this->getMockBuilder('OC\Security\CertificateManager')
->setConstructorArgs([$view, $config, $this->createMock(LoggerInterface::class), $this->random])
- ->setMethods(['getFilemtimeOfCaBundle', 'getCertificateBundle'])
+ ->onlyMethods(['getFilemtimeOfCaBundle', 'getCertificateBundle'])
->getMock();
$certificateManager->expects($this->any())->method('getFilemtimeOfCaBundle')
@@ -185,7 +183,7 @@ class CertificateManagerTest extends \Test\TestCase {
);
}
- public function dataTestNeedRebundling() {
+ public static function dataTestNeedRebundling(): array {
return [
//values: CaBundleMtime, targetBundleMtime, targetBundleExists, expected
diff --git a/tests/lib/Security/CertificateTest.php b/tests/lib/Security/CertificateTest.php
index 2c430fc1273..732b431d73e 100644
--- a/tests/lib/Security/CertificateTest.php
+++ b/tests/lib/Security/CertificateTest.php
@@ -3,23 +3,9 @@
declare(strict_types=1);
/**
- * @author Lukas Reschke <lukas@owncloud.com>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Test\Security;
@@ -45,8 +31,8 @@ class CertificateTest extends \Test\TestCase {
$this->expiredCertificate = new Certificate($expiredCertificate, 'ExpiredCertificate');
}
-
- public function testBogusData() {
+
+ public function testBogusData(): void {
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Certificate could not get parsed.');
@@ -54,37 +40,42 @@ class CertificateTest extends \Test\TestCase {
$certificate->getIssueDate();
}
-
- public function testCertificateStartingWithFileReference() {
+ public function testOpenSslTrustedCertificateFormat(): void {
+ $trustedCertificate = file_get_contents(__DIR__ . '/../../data/certificates/openSslTrustedCertificate.crt');
+ $certificate = new Certificate($trustedCertificate, 'TrustedCertificate');
+ $this->assertSame('thawte, Inc.', $certificate->getOrganization());
+ }
+
+ public function testCertificateStartingWithFileReference(): void {
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Certificate could not get parsed.');
- new Certificate('file://'.__DIR__ . '/../../data/certificates/goodCertificate.crt', 'bar');
+ new Certificate('file://' . __DIR__ . '/../../data/certificates/goodCertificate.crt', 'bar');
}
- public function testGetName() {
+ public function testGetName(): void {
$this->assertSame('GoodCertificate', $this->goodCertificate->getName());
$this->assertSame('BadCertificate', $this->invalidCertificate->getName());
}
- public function testGetCommonName() {
+ public function testGetCommonName(): void {
$this->assertSame('security.owncloud.com', $this->goodCertificate->getCommonName());
$this->assertSame(null, $this->invalidCertificate->getCommonName());
}
- public function testGetOrganization() {
+ public function testGetOrganization(): void {
$this->assertSame('ownCloud Security', $this->goodCertificate->getOrganization());
$this->assertSame('Internet Widgits Pty Ltd', $this->invalidCertificate->getOrganization());
}
- public function testGetIssueDate() {
+ public function testGetIssueDate(): void {
$expected = new \DateTime('2015-08-27 20:03:42 GMT');
$this->assertEquals($expected->getTimestamp(), $this->goodCertificate->getIssueDate()->getTimestamp());
$expected = new \DateTime('2015-08-27 20:19:13 GMT');
$this->assertEquals($expected->getTimestamp(), $this->invalidCertificate->getIssueDate()->getTimestamp());
}
- public function testGetExpireDate() {
+ public function testGetExpireDate(): void {
$expected = new \DateTime('2025-08-24 20:03:42 GMT');
$this->assertEquals($expected->getTimestamp(), $this->goodCertificate->getExpireDate()->getTimestamp());
$expected = new \DateTime('2025-08-24 20:19:13 GMT');
@@ -93,19 +84,19 @@ class CertificateTest extends \Test\TestCase {
$this->assertEquals($expected->getTimestamp(), $this->expiredCertificate->getExpireDate()->getTimestamp());
}
- public function testIsExpired() {
+ public function testIsExpired(): void {
$this->assertSame(false, $this->goodCertificate->isExpired());
$this->assertSame(false, $this->invalidCertificate->isExpired());
$this->assertSame(true, $this->expiredCertificate->isExpired());
}
- public function testGetIssuerName() {
+ public function testGetIssuerName(): void {
$this->assertSame('security.owncloud.com', $this->goodCertificate->getIssuerName());
$this->assertSame(null, $this->invalidCertificate->getIssuerName());
$this->assertSame(null, $this->expiredCertificate->getIssuerName());
}
- public function testGetIssuerOrganization() {
+ public function testGetIssuerOrganization(): void {
$this->assertSame('ownCloud Security', $this->goodCertificate->getIssuerOrganization());
$this->assertSame('Internet Widgits Pty Ltd', $this->invalidCertificate->getIssuerOrganization());
$this->assertSame('Internet Widgits Pty Ltd', $this->expiredCertificate->getIssuerOrganization());
diff --git a/tests/lib/Security/CredentialsManagerTest.php b/tests/lib/Security/CredentialsManagerTest.php
index 6f535c84275..4dfe8c5681d 100644
--- a/tests/lib/Security/CredentialsManagerTest.php
+++ b/tests/lib/Security/CredentialsManagerTest.php
@@ -3,36 +3,23 @@
declare(strict_types=1);
/**
- * @author Robin McCorkell <rmccorkell@owncloud.com>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Test\Security;
+use OCP\Security\ICredentialsManager;
+use OCP\Server;
+
/**
* @group DB
*/
class CredentialsManagerTest extends \Test\TestCase {
- /**
- * @dataProvider credentialsProvider
- */
- public function testWithDB($userId, $identifier) {
- $credentialsManager = \OC::$server->getCredentialsManager();
+ #[\PHPUnit\Framework\Attributes\DataProvider('credentialsProvider')]
+ public function testWithDB($userId, $identifier): void {
+ $credentialsManager = Server::get(ICredentialsManager::class);
$secrets = 'Open Sesame';
@@ -45,7 +32,21 @@ class CredentialsManagerTest extends \Test\TestCase {
$this->assertSame(1, $removedRows);
}
- public function credentialsProvider() {
+ #[\PHPUnit\Framework\Attributes\DataProvider('credentialsProvider')]
+ public function testUpdate($userId, $identifier): void {
+ $credentialsManager = Server::get(ICredentialsManager::class);
+
+ $secrets = 'Open Sesame';
+ $secretsRev = strrev($secrets);
+
+ $credentialsManager->store($userId, $identifier, $secrets);
+ $credentialsManager->store($userId, $identifier, $secretsRev);
+ $received = $credentialsManager->retrieve($userId, $identifier);
+
+ $this->assertSame($secretsRev, $received);
+ }
+
+ public static function credentialsProvider(): array {
return [
[
'alice',
diff --git a/tests/lib/Security/CryptoTest.php b/tests/lib/Security/CryptoTest.php
index bdbad8b2610..0f8575ab0b5 100644
--- a/tests/lib/Security/CryptoTest.php
+++ b/tests/lib/Security/CryptoTest.php
@@ -3,18 +3,19 @@
declare(strict_types=1);
/**
- * Copyright (c) 2014 Lukas Reschke <lukas@owncloud.com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security;
use OC\Security\Crypto;
+use OCP\IConfig;
+use OCP\Server;
class CryptoTest extends \Test\TestCase {
- public function defaultEncryptionProvider() {
+ public static function defaultEncryptionProvider(): array {
return [
['Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt.'],
[''],
@@ -27,19 +28,17 @@ class CryptoTest extends \Test\TestCase {
protected function setUp(): void {
parent::setUp();
- $this->crypto = new Crypto(\OC::$server->getConfig());
+ $this->crypto = new Crypto(Server::get(IConfig::class));
}
- /**
- * @dataProvider defaultEncryptionProvider
- */
- public function testDefaultEncrypt($stringToEncrypt) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('defaultEncryptionProvider')]
+ public function testDefaultEncrypt($stringToEncrypt): void {
$ciphertext = $this->crypto->encrypt($stringToEncrypt);
$this->assertEquals($stringToEncrypt, $this->crypto->decrypt($ciphertext));
}
- public function testWrongPassword() {
+ public function testWrongPassword(): void {
$this->expectException(\Exception::class);
$this->expectExceptionMessage('HMAC does not match.');
@@ -48,14 +47,14 @@ class CryptoTest extends \Test\TestCase {
$this->crypto->decrypt($ciphertext, 'A wrong password!');
}
- public function testLaterDecryption() {
+ public function testLaterDecryption(): void {
$stringToEncrypt = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt.';
$encryptedString = '44a35023cca2e7a6125e06c29fc4b2ad9d8a33d0873a8b45b0de4ef9284f260c6c46bf25dc62120644c59b8bafe4281ddc47a70c35ae6c29ef7a63d79eefacc297e60b13042ac582733598d0a6b4de37311556bb5c480fd2633de4e6ebafa868c2d1e2d80a5d24f9660360dba4d6e0c8|lhrFgK0zd9U160Wo|a75e57ab701f9124e1113543fd1dc596f21e20d456a0d1e813d5a8aaec9adcb11213788e96598b67fe9486a9f0b99642c18296d0175db44b1ae426e4e91080ee';
$this->assertEquals($stringToEncrypt, $this->crypto->decrypt($encryptedString, 'ThisIsAVeryS3cur3P4ssw0rd'));
}
- public function testWrongIV() {
+ public function testWrongIV(): void {
$this->expectException(\Exception::class);
$this->expectExceptionMessage('HMAC does not match.');
@@ -64,7 +63,7 @@ class CryptoTest extends \Test\TestCase {
}
- public function testWrongParameters() {
+ public function testWrongParameters(): void {
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Authenticated ciphertext could not be decoded.');
@@ -72,14 +71,14 @@ class CryptoTest extends \Test\TestCase {
$this->crypto->decrypt($encryptedString, 'ThisIsAVeryS3cur3P4ssw0rd');
}
- public function testLegacy() {
+ public function testLegacy(): void {
$cipherText = 'e16599188e3d212f5c7f17fdc2abca46|M1WfLAxbcAmITeD6|509457885d6ca5e6c3bfd3741852687a7f2bffce197f8d5ae97b65818b15a1b7f616b68326ff312371540f4ca8ac55f8e2de4aa13aab3474bd3431e51214e3ee';
$password = 'mypass';
$this->assertSame('legacy test', $this->crypto->decrypt($cipherText, $password));
}
- public function testVersion2CiphertextDecryptsToCorrectPlaintext() {
+ public function testVersion2CiphertextDecryptsToCorrectPlaintext(): void {
$this->assertSame(
'This is a plaintext value that will be encrypted with version 2. Which addresses the reduced permutations on the IV.',
$this->crypto->decrypt(
@@ -89,7 +88,20 @@ class CryptoTest extends \Test\TestCase {
);
}
- public function testVersion3CiphertextDecryptsToCorrectPlaintext() {
+ /**
+ * Test data taken from https://github.com/owncloud/core/blob/9deb8196b20354c8de0cd720ad4d18d52ccc96d8/tests/lib/Security/CryptoTest.php#L56-L60
+ */
+ public function testOcVersion2CiphertextDecryptsToCorrectPlaintext(): void {
+ $this->assertSame(
+ 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt.',
+ $this->crypto->decrypt(
+ 'v2|d57dbe4d1317cdf19d4ddc2df807f6b5d63ab1e119c46590ce54bae56a9cd3969168c4ec1600ac9758dd7e7afb9c4c962dd23072c1463add1d9c77c467723b37bb768ef00e3c50898e59247cbb59ce56b74ce5990648ffe9e40d0e95076c27a785bdcf32c219ea4ad5c316b1f12f48c1|6bd21db258a5e406a2c288a444de195f|a19111a4cf1a11ee95fc1734699c20964eaa05bb007e1cecc4cc6872f827a4b7deedc977c13b138d728d68116aa3d82f9673e20c7e447a9788aa3be994b67cd6',
+ 'ThisIsAVeryS3cur3P4ssw0rd'
+ )
+ );
+ }
+
+ public function testVersion3CiphertextDecryptsToCorrectPlaintext(): void {
$this->assertSame(
'Another plaintext value that will be encrypted with version 3. It addresses the related key issue. Old ciphertexts should be decrypted properly, but only use the better version for encryption.',
$this->crypto->decrypt(
diff --git a/tests/lib/Security/Events/GenerateSecurePasswordEventTest.php b/tests/lib/Security/Events/GenerateSecurePasswordEventTest.php
new file mode 100644
index 00000000000..e589f20f62c
--- /dev/null
+++ b/tests/lib/Security/Events/GenerateSecurePasswordEventTest.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Security\Events;
+
+use OCP\Security\Events\GenerateSecurePasswordEvent;
+use OCP\Security\PasswordContext;
+
+class GenerateSecurePasswordEventTest extends \Test\TestCase {
+
+ public function testDefaultProperties(): void {
+ $event = new GenerateSecurePasswordEvent();
+ $this->assertNull($event->getPassword());
+ $this->assertEquals(PasswordContext::ACCOUNT, $event->getContext());
+ }
+
+ public function testSettingPassword(): void {
+ $event = new GenerateSecurePasswordEvent();
+ $event->setPassword('example');
+ $this->assertEquals('example', $event->getPassword());
+ }
+
+ public function testSettingContext(): void {
+ $event = new GenerateSecurePasswordEvent(PasswordContext::SHARING);
+ $this->assertEquals(PasswordContext::SHARING, $event->getContext());
+ }
+}
diff --git a/tests/lib/Security/Events/ValidatePasswordPolicyEventTest.php b/tests/lib/Security/Events/ValidatePasswordPolicyEventTest.php
new file mode 100644
index 00000000000..272f34e31aa
--- /dev/null
+++ b/tests/lib/Security/Events/ValidatePasswordPolicyEventTest.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Security\Events;
+
+use OCP\Security\Events\ValidatePasswordPolicyEvent;
+use OCP\Security\PasswordContext;
+
+class ValidatePasswordPolicyEventTest extends \Test\TestCase {
+
+ public function testDefaultProperties(): void {
+ $password = 'example';
+ $event = new ValidatePasswordPolicyEvent($password);
+ $this->assertEquals($password, $event->getPassword());
+ $this->assertEquals(PasswordContext::ACCOUNT, $event->getContext());
+ }
+
+ public function testSettingContext(): void {
+ $event = new ValidatePasswordPolicyEvent('example', PasswordContext::SHARING);
+ $this->assertEquals(PasswordContext::SHARING, $event->getContext());
+ }
+}
diff --git a/tests/lib/Security/FeaturePolicy/AddFeaturePolicyEventTest.php b/tests/lib/Security/FeaturePolicy/AddFeaturePolicyEventTest.php
index 6e6433adbeb..1fe01e26280 100644
--- a/tests/lib/Security/FeaturePolicy/AddFeaturePolicyEventTest.php
+++ b/tests/lib/Security/FeaturePolicy/AddFeaturePolicyEventTest.php
@@ -2,25 +2,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\CSP;
@@ -31,7 +14,7 @@ use OCP\Security\FeaturePolicy\AddFeaturePolicyEvent;
use Test\TestCase;
class AddFeaturePolicyEventTest extends TestCase {
- public function testAddEvent() {
+ public function testAddEvent(): void {
$manager = $this->createMock(FeaturePolicyManager::class);
$policy = $this->createMock(FeaturePolicy::class);
$event = new AddFeaturePolicyEvent($manager);
diff --git a/tests/lib/Security/FeaturePolicy/FeaturePolicyManagerTest.php b/tests/lib/Security/FeaturePolicy/FeaturePolicyManagerTest.php
index b8f558719dc..01624cb92d3 100644
--- a/tests/lib/Security/FeaturePolicy/FeaturePolicyManagerTest.php
+++ b/tests/lib/Security/FeaturePolicy/FeaturePolicyManagerTest.php
@@ -2,25 +2,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\CSP;
@@ -29,11 +12,11 @@ use OC\Security\FeaturePolicy\FeaturePolicyManager;
use OCP\AppFramework\Http\FeaturePolicy;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Security\FeaturePolicy\AddFeaturePolicyEvent;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use OCP\Server;
use Test\TestCase;
class FeaturePolicyManagerTest extends TestCase {
- /** @var EventDispatcherInterface */
+ /** @var IEventDispatcher */
private $dispatcher;
/** @var FeaturePolicyManager */
@@ -41,17 +24,17 @@ class FeaturePolicyManagerTest extends TestCase {
protected function setUp(): void {
parent::setUp();
- $this->dispatcher = \OC::$server->query(IEventDispatcher::class);
+ $this->dispatcher = Server::get(IEventDispatcher::class);
$this->manager = new FeaturePolicyManager($this->dispatcher);
}
- public function testAddDefaultPolicy() {
+ public function testAddDefaultPolicy(): void {
$this->manager->addDefaultPolicy(new FeaturePolicy());
$this->addToAssertionCount(1);
}
- public function testGetDefaultPolicyWithPoliciesViaEvent() {
- $this->dispatcher->addListener(AddFeaturePolicyEvent::class, function (AddFeaturePolicyEvent $e) {
+ public function testGetDefaultPolicyWithPoliciesViaEvent(): void {
+ $this->dispatcher->addListener(AddFeaturePolicyEvent::class, function (AddFeaturePolicyEvent $e): void {
$policy = new FeaturePolicy();
$policy->addAllowedMicrophoneDomain('mydomain.com');
$policy->addAllowedPaymentDomain('mypaymentdomain.com');
@@ -59,7 +42,7 @@ class FeaturePolicyManagerTest extends TestCase {
$e->addPolicy($policy);
});
- $this->dispatcher->addListener(AddFeaturePolicyEvent::class, function (AddFeaturePolicyEvent $e) {
+ $this->dispatcher->addListener(AddFeaturePolicyEvent::class, function (AddFeaturePolicyEvent $e): void {
$policy = new FeaturePolicy();
$policy->addAllowedPaymentDomain('mydomainother.com');
$policy->addAllowedGeoLocationDomain('mylocation.here');
@@ -67,7 +50,7 @@ class FeaturePolicyManagerTest extends TestCase {
$e->addPolicy($policy);
});
- $this->dispatcher->addListener(AddFeaturePolicyEvent::class, function (AddFeaturePolicyEvent $e) {
+ $this->dispatcher->addListener(AddFeaturePolicyEvent::class, function (AddFeaturePolicyEvent $e): void {
$policy = new FeaturePolicy();
$policy->addAllowedAutoplayDomain('youtube.com');
diff --git a/tests/lib/Security/HasherTest.php b/tests/lib/Security/HasherTest.php
index 37e2adcc13c..33130f86a73 100644
--- a/tests/lib/Security/HasherTest.php
+++ b/tests/lib/Security/HasherTest.php
@@ -3,10 +3,9 @@
declare(strict_types=1);
/**
- * Copyright (c) 2014 Lukas Reschke <lukas@owncloud.com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security;
@@ -18,10 +17,7 @@ use OCP\IConfig;
* Class HasherTest
*/
class HasherTest extends \Test\TestCase {
- /**
- * @return array
- */
- public function versionHashProvider() {
+ public static function versionHashProvider(): array {
return [
['asf32äà$$a.|3', null],
['asf32äà$$a.|3|5', null],
@@ -31,7 +27,7 @@ class HasherTest extends \Test\TestCase {
];
}
- public function hashProviders70_71(): array {
+ public static function hashProviders70_71(): array {
return [
// Valid SHA1 strings
['password', '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', true],
@@ -67,7 +63,7 @@ class HasherTest extends \Test\TestCase {
];
}
- public function hashProviders72(): array {
+ public static function hashProviders72(): array {
return [
// Valid ARGON2 hashes
['password', '2|$argon2i$v=19$m=1024,t=2,p=2$T3JGcEkxVFNOVktNSjZUcg$4/hyLtSejxNgAuzSFFV/HLM3qRQKBwEtKw61qPN4zWA', true],
@@ -84,7 +80,7 @@ class HasherTest extends \Test\TestCase {
];
}
- public function hashProviders73(): array {
+ public static function hashProviders73(): array {
return [
// Valid ARGON2ID hashes
['password', '2|$argon2id$v=19$m=65536,t=4,p=1$TEtIMnhUczliQzI0Y01WeA$BpMUDrApy25iagIogUAnlc0rNTPJmGs8lOEeVHujJ9Q', true],
@@ -123,24 +119,20 @@ class HasherTest extends \Test\TestCase {
$this->hasher = new Hasher($this->config);
}
- public function testHash() {
+ public function testHash(): void {
$hash = $this->hasher->hash('String To Hash');
$this->assertNotNull($hash);
}
- /**
- * @dataProvider versionHashProvider
- */
- public function testSplitHash($hash, $expected) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('versionHashProvider')]
+ public function testSplitHash($hash, $expected): void {
$relativePath = self::invokePrivate($this->hasher, 'splitHash', [$hash]);
$this->assertSame($expected, $relativePath);
}
- /**
- * @dataProvider hashProviders70_71
- */
- public function testVerify($password, $hash, $expected) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('hashProviders70_71')]
+ public function testVerify($password, $hash, $expected): void {
$this->config
->expects($this->any())
->method('getSystemValue')
@@ -155,10 +147,8 @@ class HasherTest extends \Test\TestCase {
$this->assertSame($expected, $result);
}
- /**
- * @dataProvider hashProviders72
- */
- public function testVerifyArgon2i($password, $hash, $expected) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('hashProviders72')]
+ public function testVerifyArgon2i($password, $hash, $expected): void {
if (!\defined('PASSWORD_ARGON2I')) {
$this->markTestSkipped('Need ARGON2 support to test ARGON2 hashes');
}
@@ -167,10 +157,8 @@ class HasherTest extends \Test\TestCase {
$this->assertSame($expected, $result);
}
- /**
- * @dataProvider hashProviders73
- */
- public function testVerifyArgon2id(string $password, string $hash, bool $expected) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('hashProviders73')]
+ public function testVerifyArgon2id(string $password, string $hash, bool $expected): void {
if (!\defined('PASSWORD_ARGON2ID')) {
$this->markTestSkipped('Need ARGON2ID support to test ARGON2ID hashes');
}
@@ -179,7 +167,7 @@ class HasherTest extends \Test\TestCase {
$this->assertSame($expected, $result);
}
- public function testUpgradeHashBlowFishToArgon2() {
+ public function testUpgradeHashBlowFishToArgon2(): void {
if (!\defined('PASSWORD_ARGON2I')) {
$this->markTestSkipped('Need ARGON2 support to test ARGON2 hashes');
}
@@ -204,12 +192,12 @@ class HasherTest extends \Test\TestCase {
$this->assertFalse(password_needs_rehash($relativePath['hash'], $newAlg, []));
}
- public function testUsePasswordDefaultArgon2iVerify() {
+ public function testUsePasswordDefaultArgon2iVerify(): void {
if (!\defined('PASSWORD_ARGON2I')) {
$this->markTestSkipped('Need ARGON2 support to test ARGON2 hashes');
}
- $this->config->method('getSystemValue')
+ $this->config->method('getSystemValueBool')
->with('hashing_default_password')
->willReturn(true);
@@ -228,12 +216,12 @@ class HasherTest extends \Test\TestCase {
$this->assertTrue(password_verify($message, $relativePath['hash']));
}
- public function testDoNotUsePasswordDefaultArgon2idVerify() {
+ public function testDoNotUsePasswordDefaultArgon2idVerify(): void {
if (!\defined('PASSWORD_ARGON2ID')) {
$this->markTestSkipped('Need ARGON2ID support to test ARGON2ID hashes');
}
- $this->config->method('getSystemValue')
+ $this->config->method('getSystemValueBool')
->with('hashing_default_password')
->willReturn(false);
@@ -246,12 +234,12 @@ class HasherTest extends \Test\TestCase {
$this->assertNull($newHash);
}
- public function testHashUsePasswordDefault() {
+ public function testHashUsePasswordDefault(): void {
if (!\defined('PASSWORD_ARGON2I')) {
$this->markTestSkipped('Need ARGON2 support to test ARGON2 hashes');
}
- $this->config->method('getSystemValue')
+ $this->config->method('getSystemValueBool')
->with('hashing_default_password')
->willReturn(true);
@@ -265,4 +253,29 @@ class HasherTest extends \Test\TestCase {
$info = password_get_info($relativePath['hash']);
$this->assertEquals(PASSWORD_BCRYPT, $info['algo']);
}
+
+ public function testValidHash(): void {
+ $hash = '3|$argon2id$v=19$m=65536,t=4,p=1$czFCSjk3LklVdXppZ2VCWA$li0NgdXe2/jwSRxgteGQPWlzJU0E0xdtfHbCbrpych0';
+
+ $isValid = $this->hasher->validate($hash);
+
+ $this->assertTrue($isValid);
+ }
+
+ public function testValidGeneratedHash(): void {
+ $message = 'secret';
+ $hash = $this->hasher->hash($message);
+
+ $isValid = $this->hasher->validate($hash);
+
+ $this->assertTrue($isValid);
+ }
+
+ public function testInvalidHash(): void {
+ $invalidHash = 'someInvalidHash';
+
+ $isValid = $this->hasher->validate($invalidHash);
+
+ $this->assertFalse($isValid);
+ }
}
diff --git a/tests/lib/Security/IdentityProof/KeyTest.php b/tests/lib/Security/IdentityProof/KeyTest.php
index 4c852ff7020..572bfbea619 100644
--- a/tests/lib/Security/IdentityProof/KeyTest.php
+++ b/tests/lib/Security/IdentityProof/KeyTest.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\IdentityProof;
@@ -39,11 +22,11 @@ class KeyTest extends TestCase {
$this->key = new Key('public', 'private');
}
- public function testGetPrivate() {
+ public function testGetPrivate(): void {
$this->assertSame('private', $this->key->getPrivate());
}
- public function testGetPublic() {
+ public function testGetPublic(): void {
$this->assertSame('public', $this->key->getPublic());
}
}
diff --git a/tests/lib/Security/IdentityProof/ManagerTest.php b/tests/lib/Security/IdentityProof/ManagerTest.php
index 8733d5de8be..921d72388a1 100644
--- a/tests/lib/Security/IdentityProof/ManagerTest.php
+++ b/tests/lib/Security/IdentityProof/ManagerTest.php
@@ -3,23 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\IdentityProof;
@@ -31,6 +16,8 @@ use OC\Security\IdentityProof\Manager;
use OCP\Files\IAppData;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\Files\SimpleFS\ISimpleFolder;
+use OCP\ICache;
+use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\IUser;
use OCP\Security\ICrypto;
@@ -39,18 +26,14 @@ use Psr\Log\LoggerInterface;
use Test\TestCase;
class ManagerTest extends TestCase {
- /** @var Factory|MockObject */
- private $factory;
- /** @var IAppData|MockObject */
- private $appData;
- /** @var ICrypto|MockObject */
- private $crypto;
- /** @var Manager|MockObject */
- private $manager;
- /** @var IConfig|MockObject */
- private $config;
- /** @var LoggerInterface|MockObject */
- private $logger;
+ private Factory&MockObject $factory;
+ private IAppData&MockObject $appData;
+ private ICrypto&MockObject $crypto;
+ private Manager&MockObject $manager;
+ private IConfig&MockObject $config;
+ private LoggerInterface&MockObject $logger;
+ private ICacheFactory&MockObject $cacheFactory;
+ private ICache&MockObject $cache;
protected function setUp(): void {
parent::setUp();
@@ -64,6 +47,12 @@ class ManagerTest extends TestCase {
->with('identityproof')
->willReturn($this->appData);
$this->logger = $this->createMock(LoggerInterface::class);
+ $this->cacheFactory = $this->createMock(ICacheFactory::class);
+ $this->cache = $this->createMock(ICache::class);
+
+ $this->cacheFactory->expects($this->any())
+ ->method('createDistributed')
+ ->willReturn($this->cache);
$this->crypto = $this->createMock(ICrypto::class);
$this->manager = $this->getManager(['generateKeyPair']);
@@ -81,7 +70,8 @@ class ManagerTest extends TestCase {
$this->factory,
$this->crypto,
$this->config,
- $this->logger
+ $this->logger,
+ $this->cacheFactory,
);
} else {
return $this->getMockBuilder(Manager::class)
@@ -89,12 +79,15 @@ class ManagerTest extends TestCase {
$this->factory,
$this->crypto,
$this->config,
- $this->logger
- ])->setMethods($setMethods)->getMock();
+ $this->logger,
+ $this->cacheFactory,
+ ])
+ ->onlyMethods($setMethods)
+ ->getMock();
}
}
- public function testGetKeyWithExistingKey() {
+ public function testGetKeyWithExistingKey(): void {
$user = $this->createMock(IUser::class);
$user
->expects($this->once())
@@ -119,25 +112,48 @@ class ManagerTest extends TestCase {
$folder
->expects($this->exactly(2))
->method('getFile')
- ->withConsecutive(
- ['private'],
- ['public']
- )
- ->willReturnOnConsecutiveCalls(
- $privateFile,
- $publicFile
- );
+ ->willReturnMap([
+ ['private', $privateFile],
+ ['public', $publicFile],
+ ]);
$this->appData
->expects($this->once())
->method('getFolder')
->with('user-MyUid')
->willReturn($folder);
+ $this->cache
+ ->expects($this->exactly(2))
+ ->method('get')
+ ->willReturn(null);
+
+ $expected = new Key('MyPublicKey', 'MyPrivateKey');
+ $this->assertEquals($expected, $this->manager->getKey($user));
+ }
+
+ public function testGetKeyWithExistingKeyCached(): void {
+ $user = $this->createMock(IUser::class);
+ $user
+ ->expects($this->once())
+ ->method('getUID')
+ ->willReturn('MyUid');
+ $this->crypto
+ ->expects($this->once())
+ ->method('decrypt')
+ ->with('EncryptedPrivateKey')
+ ->willReturn('MyPrivateKey');
+ $this->cache
+ ->expects($this->exactly(2))
+ ->method('get')
+ ->willReturnMap([
+ ['user-MyUid-public', 'MyPublicKey'],
+ ['user-MyUid-private', 'EncryptedPrivateKey'],
+ ]);
$expected = new Key('MyPublicKey', 'MyPrivateKey');
$this->assertEquals($expected, $this->manager->getKey($user));
}
- public function testGetKeyWithNotExistingKey() {
+ public function testGetKeyWithNotExistingKey(): void {
$user = $this->createMock(IUser::class);
$user
->expects($this->once())
@@ -170,14 +186,10 @@ class ManagerTest extends TestCase {
$folder
->expects($this->exactly(2))
->method('newFile')
- ->withConsecutive(
- ['private'],
- ['public']
- )
- ->willReturnOnConsecutiveCalls(
- $privateFile,
- $publicFile
- );
+ ->willReturnMap([
+ ['private', null, $privateFile],
+ ['public', null, $publicFile],
+ ]);
$this->appData
->expects($this->exactly(2))
->method('getFolder')
@@ -192,7 +204,7 @@ class ManagerTest extends TestCase {
$this->assertEquals($expected, $this->manager->getKey($user));
}
- public function testGenerateKeyPair() {
+ public function testGenerateKeyPair(): void {
$manager = $this->getManager();
$data = 'MyTestData';
@@ -204,7 +216,7 @@ class ManagerTest extends TestCase {
$this->assertSame(2048, $details['bits']);
}
- public function testGetSystemKey() {
+ public function testGetSystemKey(): void {
$manager = $this->getManager(['retrieveKey']);
/** @var Key|\PHPUnit\Framework\MockObject\MockObject $key */
@@ -221,7 +233,7 @@ class ManagerTest extends TestCase {
- public function testGetSystemKeyFailure() {
+ public function testGetSystemKeyFailure(): void {
$this->expectException(\RuntimeException::class);
$manager = $this->getManager(['retrieveKey']);
diff --git a/tests/lib/Security/IdentityProof/SignerTest.php b/tests/lib/Security/IdentityProof/SignerTest.php
index 36b7ef97bb6..6dc73c072e4 100644
--- a/tests/lib/Security/IdentityProof/SignerTest.php
+++ b/tests/lib/Security/IdentityProof/SignerTest.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\IdentityProof;
@@ -107,7 +90,7 @@ gQIDAQAB
);
}
- public function testSign() {
+ public function testSign(): void {
$user = $this->createMock(IUser::class);
$user->method('getCloudId')
->willReturn('foo@example.com');
@@ -140,7 +123,7 @@ gQIDAQAB
$this->assertEquals($expects, $result);
}
- public function testVerifyValid() {
+ public function testVerifyValid(): void {
$data = [
'message' => [
'data' => [
@@ -168,7 +151,7 @@ gQIDAQAB
$this->assertTrue($this->signer->verify($data));
}
- public function testVerifyInvalid() {
+ public function testVerifyInvalid(): void {
$data = [
'message' => [
'data' => [
@@ -196,7 +179,7 @@ gQIDAQAB
$this->assertFalse($this->signer->verify($data));
}
- public function testVerifyInvalidData() {
+ public function testVerifyInvalidData(): void {
$data = [
];
diff --git a/tests/lib/Security/Ip/BruteforceAllowListTest.php b/tests/lib/Security/Ip/BruteforceAllowListTest.php
new file mode 100644
index 00000000000..1454b779c1b
--- /dev/null
+++ b/tests/lib/Security/Ip/BruteforceAllowListTest.php
@@ -0,0 +1,161 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Security\Ip;
+
+use OC\Security\Ip\BruteforceAllowList;
+use OC\Security\Ip\Factory;
+use OCP\IAppConfig;
+use OCP\Security\Ip\IFactory;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+/**
+ * Based on the unit tests from Paragonie's Airship CMS
+ * Ref: https://github.com/paragonie/airship/blob/7e5bad7e3c0fbbf324c11f963fd1f80e59762606/test/unit/Engine/Security/AirBrakeTest.php
+ *
+ * @package Test\Security\Bruteforce
+ */
+class BruteforceAllowListTest extends TestCase {
+ /** @var IAppConfig|MockObject */
+ private $appConfig;
+ /** @var IFactory|MockObject */
+ private $factory;
+ /** @var BruteforceAllowList */
+ private $allowList;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->appConfig = $this->createMock(IAppConfig::class);
+ $this->factory = new Factory();
+
+ $this->allowList = new BruteforceAllowList(
+ $this->appConfig,
+ $this->factory,
+ );
+ }
+
+ public static function dataIsBypassListed(): array {
+ return [
+ [
+ '10.10.10.10',
+ [
+ 'whitelist_0' => '10.10.10.0/24',
+ ],
+ true,
+ ],
+ [
+ '10.10.10.10',
+ [
+ 'whitelist_0' => '192.168.0.0/16',
+ ],
+ false,
+ ],
+ [
+ '10.10.10.10',
+ [
+ 'whitelist_0' => '192.168.0.0/16',
+ 'whitelist_1' => '10.10.10.0/24',
+ ],
+ true,
+ ],
+ [
+ '10.10.10.10',
+ [
+ 'whitelist_0' => '10.10.10.11/31',
+ ],
+ true,
+ ],
+ [
+ '10.10.10.10',
+ [
+ 'whitelist_0' => '10.10.10.9/31',
+ ],
+ false,
+ ],
+ [
+ '10.10.10.10',
+ [
+ 'whitelist_0' => '10.10.10.15/29',
+ ],
+ true,
+ ],
+ [
+ 'dead:beef:cafe::1',
+ [
+ 'whitelist_0' => '192.168.0.0/16',
+ 'whitelist_1' => '10.10.10.0/24',
+ 'whitelist_2' => 'deaf:beef:cafe:1234::/64'
+ ],
+ false,
+ ],
+ [
+ 'dead:beef:cafe::1',
+ [
+ 'whitelist_0' => '192.168.0.0/16',
+ 'whitelist_1' => '10.10.10.0/24',
+ 'whitelist_2' => 'deaf:beef::/64'
+ ],
+ false,
+ ],
+ [
+ 'dead:beef:cafe::1',
+ [
+ 'whitelist_0' => '192.168.0.0/16',
+ 'whitelist_1' => '10.10.10.0/24',
+ 'whitelist_2' => 'deaf:cafe::/8'
+ ],
+ true,
+ ],
+ [
+ 'dead:beef:cafe::1111',
+ [
+ 'whitelist_0' => 'dead:beef:cafe::1100/123',
+ ],
+ true,
+ ],
+ [
+ 'invalid',
+ [],
+ false,
+ ],
+ ];
+ }
+
+ /**
+ * @param string[] $allowList
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataIsBypassListed')]
+ public function testIsBypassListed(
+ string $ip,
+ array $allowList,
+ bool $isAllowListed,
+ ): void {
+ $this->appConfig->method('searchKeys')
+ ->with($this->equalTo('bruteForce'), $this->equalTo('whitelist_'))
+ ->willReturn(array_keys($allowList));
+
+ $this->appConfig->method('getValueString')
+ ->willReturnCallback(function ($app, $key, $default) use ($allowList) {
+ if ($app !== 'bruteForce') {
+ return $default;
+ }
+ if (isset($allowList[$key])) {
+ return $allowList[$key];
+ }
+ return $default;
+ });
+
+ $this->assertSame(
+ $isAllowListed,
+ $this->allowList->isBypassListed($ip)
+ );
+ }
+}
diff --git a/tests/lib/Security/Ip/RemoteAddressTest.php b/tests/lib/Security/Ip/RemoteAddressTest.php
new file mode 100644
index 00000000000..a6619cffe8e
--- /dev/null
+++ b/tests/lib/Security/Ip/RemoteAddressTest.php
@@ -0,0 +1,79 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Security\Ip;
+
+use OC\Security\Ip\RemoteAddress;
+use OCP\IConfig;
+use OCP\IRequest;
+
+class RemoteAddressTest extends \Test\TestCase {
+ private IConfig $config;
+ private IRequest $request;
+
+ protected function setUp(): void {
+ parent::setUp();
+ $this->config = $this->createMock(IConfig::class);
+ $this->request = $this->createMock(IRequest::class);
+ }
+
+ /**
+ * @param mixed $allowedRanges
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataProvider')]
+ public function testAllowedIps(string $remoteIp, $allowedRanges, bool $expected): void {
+ $this->request
+ ->method('getRemoteAddress')
+ ->willReturn($remoteIp);
+ $this->config
+ ->method('getSystemValue')
+ ->with('allowed_admin_ranges', false)
+ ->willReturn($allowedRanges);
+
+ $remoteAddress = new RemoteAddress($this->config, $this->request);
+
+ $this->assertEquals($expected, $remoteAddress->allowsAdminActions());
+ }
+
+ /**
+ * @return array<string, mixed, bool>
+ */
+ public static function dataProvider(): array {
+ return [
+ // No IP (ie. CLI)
+ ['', ['192.168.1.2/24'], true],
+ ['', ['fe80/8'], true],
+ // No configuration
+ ['1.2.3.4', false, true],
+ ['1234:4567:8910::', false, true],
+ // v6 Zone ID
+ ['fe80::1fc4:15d8:78db:2319%enp4s0', false, true],
+ // Empty configuration
+ ['1.2.3.4', [], true],
+ ['1234:4567:8910::', [], true],
+ // Invalid configuration
+ ['1.2.3.4', 'hello', true],
+ ['1234:4567:8910::', 'world', true],
+ // Mixed configuration
+ ['192.168.1.5', ['1.2.3.*', '1234::/8'], false],
+ ['::1', ['127.0.0.1', '1234::/8'], false],
+ ['192.168.1.5', ['192.168.1.0/24', '1234::/8'], true],
+ // Allowed IP
+ ['1.2.3.4', ['1.2.3.*'], true],
+ ['fc00:1:2:3::1', ['fc00::/7'], true],
+ ['1.2.3.4', ['192.168.1.2/24', '1.2.3.0/24'], true],
+ ['1234:4567:8910::1', ['fe80::/8','1234:4567::/16'], true],
+ // Blocked IP
+ ['192.168.1.5', ['1.2.3.*'], false],
+ ['9234:4567:8910::', ['1234:4567::1'], false],
+ ['192.168.2.1', ['192.168.1.2/24', '1.2.3.0/24'], false],
+ ['9234:4567:8910::', ['fe80::/8','1234:4567::/16'], false],
+ ];
+ }
+}
diff --git a/tests/lib/Security/Normalizer/IpAddressTest.php b/tests/lib/Security/Normalizer/IpAddressTest.php
index bb487659ced..f7adfb4a0dd 100644
--- a/tests/lib/Security/Normalizer/IpAddressTest.php
+++ b/tests/lib/Security/Normalizer/IpAddressTest.php
@@ -3,23 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\Normalizer;
@@ -28,7 +13,7 @@ use OC\Security\Normalizer\IpAddress;
use Test\TestCase;
class IpAddressTest extends TestCase {
- public function subnetDataProvider() {
+ public static function subnetDataProvider(): array {
return [
[
'64.233.191.254',
@@ -51,35 +36,35 @@ class IpAddressTest extends TestCase {
'192.168.0.123/32',
],
[
- '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
- '2001:db8:85a3::/64',
+ '2001:0db8:0000:0000:0000:8a2e:0370:7334',
+ '2001:db8::/56',
],
[
'2001:db8:3333:4444:5555:6666:7777:8888',
- '2001:db8:3333:4444::/64',
+ '2001:db8:3333:4400::/56',
],
[
'::1234:5678',
- '::/64',
+ '::/56',
],
[
'[::1]',
- '::/64',
+ '::/56',
],
];
}
/**
- * @dataProvider subnetDataProvider
*
* @param string $input
* @param string $expected
*/
- public function testGetSubnet($input, $expected) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('subnetDataProvider')]
+ public function testGetSubnet($input, $expected): void {
$this->assertSame($expected, (new IpAddress($input))->getSubnet());
}
- public function testToString() {
+ public function testToString(): void {
$this->assertSame('127.0.0.1', (string)(new IpAddress('127.0.0.1')));
}
}
diff --git a/tests/lib/Security/RateLimiting/Backend/MemoryCacheBackendTest.php b/tests/lib/Security/RateLimiting/Backend/MemoryCacheBackendTest.php
index e7cb4a93a29..24e3ab1a209 100644
--- a/tests/lib/Security/RateLimiting/Backend/MemoryCacheBackendTest.php
+++ b/tests/lib/Security/RateLimiting/Backend/MemoryCacheBackendTest.php
@@ -3,23 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\RateLimiting\Backend;
@@ -28,9 +13,12 @@ use OC\Security\RateLimiting\Backend\MemoryCacheBackend;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\ICache;
use OCP\ICacheFactory;
+use OCP\IConfig;
use Test\TestCase;
class MemoryCacheBackendTest extends TestCase {
+ /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
+ private $config;
/** @var ICacheFactory|\PHPUnit\Framework\MockObject\MockObject */
private $cacheFactory;
/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
@@ -43,6 +31,7 @@ class MemoryCacheBackendTest extends TestCase {
protected function setUp(): void {
parent::setUp();
+ $this->config = $this->createMock(IConfig::class);
$this->cacheFactory = $this->createMock(ICacheFactory::class);
$this->timeFactory = $this->createMock(ITimeFactory::class);
$this->cache = $this->createMock(ICache::class);
@@ -53,13 +42,18 @@ class MemoryCacheBackendTest extends TestCase {
->with('OC\Security\RateLimiting\Backend\MemoryCacheBackend')
->willReturn($this->cache);
+ $this->config->method('getSystemValueBool')
+ ->with('ratelimit.protection.enabled')
+ ->willReturn(true);
+
$this->memoryCache = new MemoryCacheBackend(
+ $this->config,
$this->cacheFactory,
$this->timeFactory
);
}
- public function testGetAttemptsWithNoAttemptsBefore() {
+ public function testGetAttemptsWithNoAttemptsBefore(): void {
$this->cache
->expects($this->once())
->method('get')
@@ -69,7 +63,7 @@ class MemoryCacheBackendTest extends TestCase {
$this->assertSame(0, $this->memoryCache->getAttempts('Method', 'User'));
}
- public function testGetAttempts() {
+ public function testGetAttempts(): void {
$this->timeFactory
->expects($this->once())
->method('getTime')
@@ -90,7 +84,7 @@ class MemoryCacheBackendTest extends TestCase {
$this->assertSame(3, $this->memoryCache->getAttempts('Method', 'User'));
}
- public function testRegisterAttemptWithNoAttemptsBefore() {
+ public function testRegisterAttemptWithNoAttemptsBefore(): void {
$this->timeFactory
->expects($this->once())
->method('getTime')
@@ -112,7 +106,7 @@ class MemoryCacheBackendTest extends TestCase {
$this->memoryCache->registerAttempt('Method', 'User', 100);
}
- public function testRegisterAttempt() {
+ public function testRegisterAttempt(): void {
$this->timeFactory
->expects($this->once())
->method('getTime')
diff --git a/tests/lib/Security/RateLimiting/LimiterTest.php b/tests/lib/Security/RateLimiting/LimiterTest.php
index a5b187fb546..b19d5c6feba 100644
--- a/tests/lib/Security/RateLimiting/LimiterTest.php
+++ b/tests/lib/Security/RateLimiting/LimiterTest.php
@@ -3,51 +3,42 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\RateLimiting;
use OC\Security\RateLimiting\Backend\IBackend;
+use OC\Security\RateLimiting\Exception\RateLimitExceededException;
use OC\Security\RateLimiting\Limiter;
use OCP\IUser;
+use OCP\Security\RateLimiting\ILimiter;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Log\LoggerInterface;
use Test\TestCase;
class LimiterTest extends TestCase {
- /** @var IBackend|\PHPUnit\Framework\MockObject\MockObject */
- private $backend;
- /** @var Limiter */
- private $limiter;
+
+ private IBackend&MockObject $backend;
+ private ILimiter $limiter;
+ private LoggerInterface $logger;
protected function setUp(): void {
parent::setUp();
$this->backend = $this->createMock(IBackend::class);
+ $this->logger = $this->createMock(LoggerInterface::class);
$this->limiter = new Limiter(
- $this->backend
+ $this->backend,
+ $this->logger,
);
}
- public function testRegisterAnonRequestExceeded() {
- $this->expectException(\OC\Security\RateLimiting\Exception\RateLimitExceededException::class);
+ public function testRegisterAnonRequestExceeded(): void {
+ $this->expectException(RateLimitExceededException::class);
$this->expectExceptionMessage('Rate limit exceeded');
$this->backend
@@ -58,11 +49,13 @@ class LimiterTest extends TestCase {
'4664f0d9c88dcb7552be47b37bb52ce35977b2e60e1ac13757cf625f31f87050a41f3da064887fa87d49fd042e4c8eb20de8f10464877d3959677ab011b73a47'
)
->willReturn(101);
+ $this->logger->expects($this->once())
+ ->method('info');
$this->limiter->registerAnonRequest('MyIdentifier', 100, 100, '127.0.0.1');
}
- public function testRegisterAnonRequestSuccess() {
+ public function testRegisterAnonRequestSuccess(): void {
$this->backend
->expects($this->once())
->method('getAttempts')
@@ -79,13 +72,15 @@ class LimiterTest extends TestCase {
'4664f0d9c88dcb7552be47b37bb52ce35977b2e60e1ac13757cf625f31f87050a41f3da064887fa87d49fd042e4c8eb20de8f10464877d3959677ab011b73a47',
100
);
+ $this->logger->expects($this->never())
+ ->method('info');
$this->limiter->registerAnonRequest('MyIdentifier', 100, 100, '127.0.0.1');
}
- public function testRegisterUserRequestExceeded() {
- $this->expectException(\OC\Security\RateLimiting\Exception\RateLimitExceededException::class);
+ public function testRegisterUserRequestExceeded(): void {
+ $this->expectException(RateLimitExceededException::class);
$this->expectExceptionMessage('Rate limit exceeded');
/** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
@@ -102,11 +97,13 @@ class LimiterTest extends TestCase {
'ddb2ec50fa973fd49ecf3d816f677c8095143e944ad10485f30fb3dac85c13a346dace4dae2d0a15af91867320957bfd38a43d9eefbb74fe6919e15119b6d805'
)
->willReturn(101);
+ $this->logger->expects($this->once())
+ ->method('info');
$this->limiter->registerUserRequest('MyIdentifier', 100, 100, $user);
}
- public function testRegisterUserRequestSuccess() {
+ public function testRegisterUserRequestSuccess(): void {
/** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
$user = $this->createMock(IUser::class);
$user
@@ -130,6 +127,8 @@ class LimiterTest extends TestCase {
'ddb2ec50fa973fd49ecf3d816f677c8095143e944ad10485f30fb3dac85c13a346dace4dae2d0a15af91867320957bfd38a43d9eefbb74fe6919e15119b6d805',
100
);
+ $this->logger->expects($this->never())
+ ->method('info');
$this->limiter->registerUserRequest('MyIdentifier', 100, 100, $user);
}
diff --git a/tests/lib/Security/RemoteHostValidatorIntegrationTest.php b/tests/lib/Security/RemoteHostValidatorIntegrationTest.php
index 3cf99161b77..913acfa054d 100644
--- a/tests/lib/Security/RemoteHostValidatorIntegrationTest.php
+++ b/tests/lib/Security/RemoteHostValidatorIntegrationTest.php
@@ -2,25 +2,9 @@
declare(strict_types=1);
-/*
- * @copyright 2022 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @author 2022 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+/**
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace lib\Security;
@@ -53,7 +37,7 @@ class RemoteHostValidatorIntegrationTest extends TestCase {
);
}
- public function localHostsData(): array {
+ public static function localHostsData(): array {
return [
['[::1]'],
['[::]'],
@@ -89,9 +73,7 @@ class RemoteHostValidatorIntegrationTest extends TestCase {
];
}
- /**
- * @dataProvider localHostsData
- */
+ #[\PHPUnit\Framework\Attributes\DataProvider('localHostsData')]
public function testLocalHostsWhenNotAllowed(string $host): void {
$this->config
->method('getSystemValueBool')
@@ -103,9 +85,7 @@ class RemoteHostValidatorIntegrationTest extends TestCase {
self::assertFalse($isValid);
}
- /**
- * @dataProvider localHostsData
- */
+ #[\PHPUnit\Framework\Attributes\DataProvider('localHostsData')]
public function testLocalHostsWhenAllowed(string $host): void {
$this->config
->method('getSystemValueBool')
@@ -117,7 +97,7 @@ class RemoteHostValidatorIntegrationTest extends TestCase {
self::assertTrue($isValid);
}
- public function externalAddressesData():array {
+ public static function externalAddressesData():array {
return [
['8.8.8.8'],
['8.8.4.4'],
@@ -127,9 +107,7 @@ class RemoteHostValidatorIntegrationTest extends TestCase {
];
}
- /**
- * @dataProvider externalAddressesData
- */
+ #[\PHPUnit\Framework\Attributes\DataProvider('externalAddressesData')]
public function testExternalHost(string $host): void {
$this->config
->method('getSystemValueBool')
diff --git a/tests/lib/Security/RemoteHostValidatorTest.php b/tests/lib/Security/RemoteHostValidatorTest.php
index 030a75b1e79..b048b9dafd1 100644
--- a/tests/lib/Security/RemoteHostValidatorTest.php
+++ b/tests/lib/Security/RemoteHostValidatorTest.php
@@ -2,25 +2,9 @@
declare(strict_types=1);
-/*
- * @copyright 2022 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @author 2022 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+/**
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace lib\Security;
@@ -60,8 +44,15 @@ class RemoteHostValidatorTest extends TestCase {
);
}
- public function testValid(): void {
- $host = 'nextcloud.com';
+ public static function dataValid(): array {
+ return [
+ ['nextcloud.com', true],
+ ['com.one-.nextcloud-one.com', false],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataValid')]
+ public function testValid(string $host, bool $expected): void {
$this->hostnameClassifier
->method('isLocalHostname')
->with($host)
@@ -73,7 +64,7 @@ class RemoteHostValidatorTest extends TestCase {
$valid = $this->validator->isValid($host);
- self::assertTrue($valid);
+ self::assertSame($expected, $valid);
}
public function testLocalHostname(): void {
diff --git a/tests/lib/Security/SecureRandomTest.php b/tests/lib/Security/SecureRandomTest.php
index c7ee76a96bb..954fd85eaf1 100644
--- a/tests/lib/Security/SecureRandomTest.php
+++ b/tests/lib/Security/SecureRandomTest.php
@@ -3,10 +3,9 @@
declare(strict_types=1);
/**
- * Copyright (c) 2014 Lukas Reschke <lukas@owncloud.com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security;
@@ -14,7 +13,7 @@ namespace Test\Security;
use OC\Security\SecureRandom;
class SecureRandomTest extends \Test\TestCase {
- public function stringGenerationProvider() {
+ public static function stringGenerationProvider(): array {
return [
[1, 1],
[128, 128],
@@ -25,7 +24,7 @@ class SecureRandomTest extends \Test\TestCase {
];
}
- public static function charCombinations() {
+ public static function charCombinations(): array {
return [
['CHAR_LOWER', '[a-z]'],
['CHAR_UPPER', '[A-Z]'],
@@ -38,56 +37,46 @@ class SecureRandomTest extends \Test\TestCase {
protected function setUp(): void {
parent::setUp();
- $this->rng = new \OC\Security\SecureRandom();
+ $this->rng = new SecureRandom();
}
- /**
- * @dataProvider stringGenerationProvider
- */
- public function testGetLowStrengthGeneratorLength($length, $expectedLength) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('stringGenerationProvider')]
+ public function testGetLowStrengthGeneratorLength($length, $expectedLength): void {
$generator = $this->rng;
$this->assertEquals($expectedLength, strlen($generator->generate($length)));
}
- /**
- * @dataProvider stringGenerationProvider
- */
- public function testMediumLowStrengthGeneratorLength($length, $expectedLength) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('stringGenerationProvider')]
+ public function testMediumLowStrengthGeneratorLength($length, $expectedLength): void {
$generator = $this->rng;
$this->assertEquals($expectedLength, strlen($generator->generate($length)));
}
- /**
- * @dataProvider stringGenerationProvider
- */
- public function testUninitializedGenerate($length, $expectedLength) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('stringGenerationProvider')]
+ public function testUninitializedGenerate($length, $expectedLength): void {
$this->assertEquals($expectedLength, strlen($this->rng->generate($length)));
}
- /**
- * @dataProvider charCombinations
- */
- public function testScheme($charName, $chars) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('charCombinations')]
+ public function testScheme($charName, $chars): void {
$generator = $this->rng;
$scheme = constant('OCP\Security\ISecureRandom::' . $charName);
$randomString = $generator->generate(100, $scheme);
- $matchesRegex = preg_match('/^'.$chars.'+$/', $randomString);
+ $matchesRegex = preg_match('/^' . $chars . '+$/', $randomString);
$this->assertSame(1, $matchesRegex);
}
- public static function invalidLengths() {
+ public static function invalidLengths(): array {
return [
[0],
[-1],
];
}
- /**
- * @dataProvider invalidLengths
- */
- public function testInvalidLengths($length) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('invalidLengths')]
+ public function testInvalidLengths($length): void {
$this->expectException(\LengthException::class);
$generator = $this->rng;
$generator->generate($length);
diff --git a/tests/lib/Security/TrustedDomainHelperTest.php b/tests/lib/Security/TrustedDomainHelperTest.php
index 3fedf8964c5..8b671a93d06 100644
--- a/tests/lib/Security/TrustedDomainHelperTest.php
+++ b/tests/lib/Security/TrustedDomainHelperTest.php
@@ -3,10 +3,9 @@
declare(strict_types=1);
/**
- * Copyright (c) 2015 Lukas Reschke <lukas@owncloud.com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security;
@@ -28,12 +27,12 @@ class TrustedDomainHelperTest extends \Test\TestCase {
}
/**
- * @dataProvider trustedDomainDataProvider
* @param string $trustedDomains
* @param string $testDomain
* @param bool $result
*/
- public function testIsTrustedUrl($trustedDomains, $testDomain, $result) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('trustedDomainDataProvider')]
+ public function testIsTrustedUrl($trustedDomains, $testDomain, $result): void {
$this->config->method('getSystemValue')
->willReturnMap([
['overwritehost', '', ''],
@@ -45,12 +44,12 @@ class TrustedDomainHelperTest extends \Test\TestCase {
}
/**
- * @dataProvider trustedDomainDataProvider
* @param string $trustedDomains
* @param string $testDomain
* @param bool $result
*/
- public function testIsTrustedDomain($trustedDomains, $testDomain, $result) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('trustedDomainDataProvider')]
+ public function testIsTrustedDomain($trustedDomains, $testDomain, $result): void {
$this->config->method('getSystemValue')
->willReturnMap([
['overwritehost', '', ''],
@@ -64,7 +63,7 @@ class TrustedDomainHelperTest extends \Test\TestCase {
/**
* @return array
*/
- public function trustedDomainDataProvider() {
+ public static function trustedDomainDataProvider(): array {
$trustedHostTestList = [
'host.one.test',
'host.two.test',
@@ -135,7 +134,7 @@ class TrustedDomainHelperTest extends \Test\TestCase {
];
}
- public function testIsTrustedDomainOverwriteHost() {
+ public function testIsTrustedDomainOverwriteHost(): void {
$this->config->method('getSystemValue')
->with('overwritehost')
->willReturn('myproxyhost');
diff --git a/tests/lib/Security/VerificationToken/VerificationTokenTest.php b/tests/lib/Security/VerificationToken/VerificationTokenTest.php
index 481646f26ab..7123cc8b013 100644
--- a/tests/lib/Security/VerificationToken/VerificationTokenTest.php
+++ b/tests/lib/Security/VerificationToken/VerificationTokenTest.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2021 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace Test\Security\VerificationToken;
@@ -34,8 +17,8 @@ use OCP\IUser;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
use OCP\Security\VerificationToken\InvalidTokenException;
-use Test\TestCase;
use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
class VerificationTokenTest extends TestCase {
/** @var VerificationToken */
@@ -69,13 +52,13 @@ class VerificationTokenTest extends TestCase {
);
}
- public function testTokenUserUnknown() {
+ public function testTokenUserUnknown(): void {
$this->expectException(InvalidTokenException::class);
$this->expectExceptionCode(InvalidTokenException::USER_UNKNOWN);
$this->token->check('encryptedToken', null, 'fingerprintToken', 'foobar');
}
- public function testTokenUserUnknown2() {
+ public function testTokenUserUnknown2(): void {
$user = $this->createMock(IUser::class);
$user->expects($this->atLeastOnce())
->method('isEnabled')
@@ -86,7 +69,7 @@ class VerificationTokenTest extends TestCase {
$this->token->check('encryptedToken', $user, 'fingerprintToken', 'foobar');
}
- public function testTokenNotFound() {
+ public function testTokenNotFound(): void {
$user = $this->createMock(IUser::class);
$user->expects($this->atLeastOnce())
->method('isEnabled')
@@ -102,7 +85,7 @@ class VerificationTokenTest extends TestCase {
$this->token->check('encryptedToken', $user, 'fingerprintToken', 'foobar');
}
- public function testTokenDecryptionError() {
+ public function testTokenDecryptionError(): void {
$user = $this->createMock(IUser::class);
$user->expects($this->atLeastOnce())
->method('isEnabled')
@@ -116,7 +99,7 @@ class VerificationTokenTest extends TestCase {
->with('alice', 'core', 'fingerprintToken', null)
->willReturn('encryptedToken');
$this->config->expects($this->any())
- ->method('getSystemValue')
+ ->method('getSystemValueString')
->with('secret')
->willReturn('357111317');
@@ -129,7 +112,7 @@ class VerificationTokenTest extends TestCase {
$this->token->check('encryptedToken', $user, 'fingerprintToken', 'foobar');
}
- public function testTokenInvalidFormat() {
+ public function testTokenInvalidFormat(): void {
$user = $this->createMock(IUser::class);
$user->expects($this->atLeastOnce())
->method('isEnabled')
@@ -143,7 +126,7 @@ class VerificationTokenTest extends TestCase {
->with('alice', 'core', 'fingerprintToken', null)
->willReturn('encryptedToken');
$this->config->expects($this->any())
- ->method('getSystemValue')
+ ->method('getSystemValueString')
->with('secret')
->willReturn('357111317');
@@ -156,7 +139,7 @@ class VerificationTokenTest extends TestCase {
$this->token->check('encryptedToken', $user, 'fingerprintToken', 'foobar');
}
- public function testTokenExpired() {
+ public function testTokenExpired(): void {
$user = $this->createMock(IUser::class);
$user->expects($this->atLeastOnce())
->method('isEnabled')
@@ -173,7 +156,7 @@ class VerificationTokenTest extends TestCase {
->with('alice', 'core', 'fingerprintToken', null)
->willReturn('encryptedToken');
$this->config->expects($this->any())
- ->method('getSystemValue')
+ ->method('getSystemValueString')
->with('secret')
->willReturn('357111317');
@@ -190,7 +173,7 @@ class VerificationTokenTest extends TestCase {
$this->token->check('encryptedToken', $user, 'fingerprintToken', 'foobar');
}
- public function testTokenExpiredByLogin() {
+ public function testTokenExpiredByLogin(): void {
$user = $this->createMock(IUser::class);
$user->expects($this->atLeastOnce())
->method('isEnabled')
@@ -207,7 +190,7 @@ class VerificationTokenTest extends TestCase {
->with('alice', 'core', 'fingerprintToken', null)
->willReturn('encryptedToken');
$this->config->expects($this->any())
- ->method('getSystemValue')
+ ->method('getSystemValueString')
->with('secret')
->willReturn('357111317');
@@ -224,7 +207,7 @@ class VerificationTokenTest extends TestCase {
$this->token->check('encryptedToken', $user, 'fingerprintToken', 'foobar', true);
}
- public function testTokenMismatch() {
+ public function testTokenMismatch(): void {
$user = $this->createMock(IUser::class);
$user->expects($this->atLeastOnce())
->method('isEnabled')
@@ -241,7 +224,7 @@ class VerificationTokenTest extends TestCase {
->with('alice', 'core', 'fingerprintToken', null)
->willReturn('encryptedToken');
$this->config->expects($this->any())
- ->method('getSystemValue')
+ ->method('getSystemValueString')
->with('secret')
->willReturn('357111317');
@@ -258,7 +241,7 @@ class VerificationTokenTest extends TestCase {
$this->token->check('encryptedToken', $user, 'fingerprintToken', 'foobar');
}
- public function testTokenSuccess() {
+ public function testTokenSuccess(): void {
$user = $this->createMock(IUser::class);
$user->expects($this->atLeastOnce())
->method('isEnabled')
@@ -275,7 +258,7 @@ class VerificationTokenTest extends TestCase {
->with('alice', 'core', 'fingerprintToken', null)
->willReturn('encryptedToken');
$this->config->expects($this->any())
- ->method('getSystemValue')
+ ->method('getSystemValueString')
->with('secret')
->willReturn('357111317');
@@ -290,7 +273,7 @@ class VerificationTokenTest extends TestCase {
$this->token->check('barfoo', $user, 'fingerprintToken', 'foobar');
}
- public function testCreate() {
+ public function testCreate(): void {
$user = $this->createMock(IUser::class);
$user->expects($this->any())
->method('getUID')