diff options
-rw-r--r-- | apps/dav/lib/Connector/Sabre/BlockLegacyClientPlugin.php | 6 | ||||
-rw-r--r-- | apps/dav/tests/unit/Connector/Sabre/AuthTest.php | 20 | ||||
-rw-r--r-- | apps/dav/tests/unit/Connector/Sabre/BlockLegacyClientPluginTest.php | 47 | ||||
-rw-r--r-- | apps/workflowengine/tests/Check/RequestUserAgentTest.php | 32 | ||||
-rw-r--r-- | lib/public/IRequest.php | 24 | ||||
-rw-r--r-- | tests/lib/AppFramework/Http/RequestTest.php | 57 |
6 files changed, 109 insertions, 77 deletions
diff --git a/apps/dav/lib/Connector/Sabre/BlockLegacyClientPlugin.php b/apps/dav/lib/Connector/Sabre/BlockLegacyClientPlugin.php index 257068b9576..5d3f7104d6a 100644 --- a/apps/dav/lib/Connector/Sabre/BlockLegacyClientPlugin.php +++ b/apps/dav/lib/Connector/Sabre/BlockLegacyClientPlugin.php @@ -26,6 +26,7 @@ namespace OCA\DAV\Connector\Sabre; use OCP\IConfig; +use OCP\IRequest; use Sabre\DAV\ServerPlugin; use Sabre\HTTP\RequestInterface; use Sabre\DAV\Server; @@ -65,10 +66,7 @@ class BlockLegacyClientPlugin extends ServerPlugin { } $minimumSupportedDesktopVersion = $this->config->getSystemValue('minimum.supported.desktop.version', '2.3.0'); - - // Match on the mirall version which is in scheme "Mozilla/5.0 (%1) mirall/%2" or - // "mirall/%1" for older releases - preg_match("/(?:mirall\\/)([\d.]+)/i", $userAgent, $versionMatches); + preg_match(IRequest::USER_AGENT_CLIENT_DESKTOP, $userAgent, $versionMatches); if (isset($versionMatches[1]) && version_compare($versionMatches[1], $minimumSupportedDesktopVersion) === -1) { throw new \Sabre\DAV\Exception\Forbidden('Unsupported client version.'); diff --git a/apps/dav/tests/unit/Connector/Sabre/AuthTest.php b/apps/dav/tests/unit/Connector/Sabre/AuthTest.php index be841295f0b..b3b3341240a 100644 --- a/apps/dav/tests/unit/Connector/Sabre/AuthTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/AuthTest.php @@ -301,11 +301,6 @@ class AuthTest extends TestCase { $this->request ->expects($this->any()) ->method('isUserAgent') - ->with([ - '/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/', - '/^Mozilla\/5\.0 \(Android\) (ownCloud|Nextcloud)\-android.*$/', - '/^Mozilla\/5\.0 \(iOS\) (ownCloud|Nextcloud)\-iOS.*$/', - ]) ->willReturn(false); $this->session ->expects($this->any()) @@ -351,11 +346,6 @@ class AuthTest extends TestCase { $this->request ->expects($this->any()) ->method('isUserAgent') - ->with([ - '/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/', - '/^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/', - '/^Mozilla\/5\.0 \(iOS\) (ownCloud|Nextcloud)\-iOS.*$/', - ]) ->willReturn(false); $this->session ->expects($this->any()) @@ -405,11 +395,6 @@ class AuthTest extends TestCase { $this->request ->expects($this->any()) ->method('isUserAgent') - ->with([ - '/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/', - '/^Mozilla\/5\.0 \(Android\) (ownCloud|Nextcloud)\-android.*$/', - '/^Mozilla\/5\.0 \(iOS\) (ownCloud|Nextcloud)\-iOS.*$/', - ]) ->willReturn(false); $this->session ->expects($this->any()) @@ -451,11 +436,6 @@ class AuthTest extends TestCase { $this->request ->expects($this->any()) ->method('isUserAgent') - ->with([ - '/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/', - '/^Mozilla\/5\.0 \(Android\) (ownCloud|Nextcloud)\-android.*$/', - '/^Mozilla\/5\.0 \(iOS\) (ownCloud|Nextcloud)\-iOS.*$/', - ]) ->willReturn(true); $this->session ->expects($this->any()) diff --git a/apps/dav/tests/unit/Connector/Sabre/BlockLegacyClientPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/BlockLegacyClientPluginTest.php index e0a274321f0..616e9796ab4 100644 --- a/apps/dav/tests/unit/Connector/Sabre/BlockLegacyClientPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/BlockLegacyClientPluginTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -28,7 +30,9 @@ namespace OCA\DAV\Tests\unit\Connector\Sabre; use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin; use OCP\IConfig; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; +use Sabre\HTTP\RequestInterface; /** * Class BlockLegacyClientPluginTest @@ -36,7 +40,7 @@ use Test\TestCase; * @package OCA\DAV\Tests\unit\Connector\Sabre */ class BlockLegacyClientPluginTest extends TestCase { - /** @var IConfig | \PHPUnit\Framework\MockObject\MockObject */ + /** @var IConfig|MockObject */ private $config; /** @var BlockLegacyClientPlugin */ private $blockLegacyClientVersionPlugin; @@ -44,34 +48,25 @@ class BlockLegacyClientPluginTest extends TestCase { protected function setUp(): void { parent::setUp(); - $this->config = $this->getMockBuilder(IConfig::class) - ->disableOriginalConstructor() - ->getMock(); + $this->config = $this->createMock(IConfig::class); $this->blockLegacyClientVersionPlugin = new BlockLegacyClientPlugin($this->config); } - /** - * @return array - */ - public function oldDesktopClientProvider() { + public function oldDesktopClientProvider(): array { return [ - ['Mozilla/5.0 (1.5.0) mirall/1.5.0'], - ['mirall/1.5.0'], - ['mirall/1.5.4'], - ['mirall/1.6.0'], + ['Mozilla/5.0 (Windows) mirall/1.5.0'], ['Mozilla/5.0 (Bogus Text) mirall/1.6.9'], ]; } /** * @dataProvider oldDesktopClientProvider - * @param string $userAgent */ - public function testBeforeHandlerException($userAgent): void { + public function testBeforeHandlerException(string $userAgent): void { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); $this->expectExceptionMessage('Unsupported client version.'); - /** @var \Sabre\HTTP\RequestInterface | \PHPUnit\Framework\MockObject\MockObject $request */ + /** @var RequestInterface|MockObject $request */ $request = $this->createMock('\Sabre\HTTP\RequestInterface'); $request ->expects($this->once()) @@ -88,26 +83,20 @@ class BlockLegacyClientPluginTest extends TestCase { $this->blockLegacyClientVersionPlugin->beforeHandler($request); } - /** - * @return array - */ - public function newAndAlternateDesktopClientProvider() { + public function newAndAlternateDesktopClientProvider(): array { return [ - ['Mozilla/5.0 (1.7.0) mirall/1.7.0'], - ['mirall/1.8.3'], - ['mirall/1.7.2'], - ['mirall/1.7.0'], + ['Mozilla/5.0 (Windows) mirall/1.7.0'], ['Mozilla/5.0 (Bogus Text) mirall/1.9.3'], + ['Mozilla/5.0 (Not Our Client But Old Version) LegacySync/1.1.0'], ]; } /** * @dataProvider newAndAlternateDesktopClientProvider - * @param string $userAgent */ - public function testBeforeHandlerSuccess($userAgent): void { - /** @var \Sabre\HTTP\RequestInterface | \PHPUnit\Framework\MockObject\MockObject $request */ - $request = $this->createMock('\Sabre\HTTP\RequestInterface'); + public function testBeforeHandlerSuccess(string $userAgent): void { + /** @var RequestInterface|MockObject $request */ + $request = $this->createMock(RequestInterface::class); $request ->expects($this->once()) ->method('getHeader') @@ -124,8 +113,8 @@ class BlockLegacyClientPluginTest extends TestCase { } public function testBeforeHandlerNoUserAgent(): void { - /** @var \Sabre\HTTP\RequestInterface | \PHPUnit\Framework\MockObject\MockObject $request */ - $request = $this->createMock('\Sabre\HTTP\RequestInterface'); + /** @var RequestInterface|MockObject $request */ + $request = $this->createMock(RequestInterface::class); $request ->expects($this->once()) ->method('getHeader') diff --git a/apps/workflowengine/tests/Check/RequestUserAgentTest.php b/apps/workflowengine/tests/Check/RequestUserAgentTest.php index 3111b4ffc8e..dbf52a112cb 100644 --- a/apps/workflowengine/tests/Check/RequestUserAgentTest.php +++ b/apps/workflowengine/tests/Check/RequestUserAgentTest.php @@ -57,46 +57,46 @@ class RequestUserAgentTest extends TestCase { public function dataExecuteCheck() { return [ - ['is', 'android', 'Mozilla/5.0 (Android) Nextcloud-android v2.2.0', true], - ['is', 'android', 'Mozilla/5.0 (iOS) Nextcloud-iOS v2.2.0', false], + ['is', 'android', 'Mozilla/5.0 (Android) Nextcloud-android/2.2.0', true], + ['is', 'android', 'Mozilla/5.0 (iOS) Nextcloud-iOS/2.2.0', false], ['is', 'android', 'Mozilla/5.0 (Linux) mirall/2.2.0', false], ['is', 'android', 'Mozilla/5.0 (Windows) Nextcloud-Outlook v2.2.0', false], ['is', 'android', 'Mozilla/5.0 (Linux) Nextcloud-Thunderbird v2.2.0', false], - ['!is', 'android', 'Mozilla/5.0 (Android) Nextcloud-android v2.2.0', false], - ['!is', 'android', 'Mozilla/5.0 (iOS) Nextcloud-iOS v2.2.0', true], + ['!is', 'android', 'Mozilla/5.0 (Android) Nextcloud-android/2.2.0', false], + ['!is', 'android', 'Mozilla/5.0 (iOS) Nextcloud-iOS/2.2.0', true], ['!is', 'android', 'Mozilla/5.0 (Linux) mirall/2.2.0', true], ['!is', 'android', 'Mozilla/5.0 (Windows) Nextcloud-Outlook v2.2.0', true], ['!is', 'android', 'Mozilla/5.0 (Linux) Nextcloud-Thunderbird v2.2.0', true], - ['is', 'ios', 'Mozilla/5.0 (Android) Nextcloud-android v2.2.0', false], - ['is', 'ios', 'Mozilla/5.0 (iOS) Nextcloud-iOS v2.2.0', true], + ['is', 'ios', 'Mozilla/5.0 (Android) Nextcloud-android/2.2.0', false], + ['is', 'ios', 'Mozilla/5.0 (iOS) Nextcloud-iOS/2.2.0', true], ['is', 'ios', 'Mozilla/5.0 (Linux) mirall/2.2.0', false], ['is', 'ios', 'Mozilla/5.0 (Windows) Nextcloud-Outlook v2.2.0', false], ['is', 'ios', 'Mozilla/5.0 (Linux) Nextcloud-Thunderbird v2.2.0', false], - ['!is', 'ios', 'Mozilla/5.0 (Android) Nextcloud-android v2.2.0', true], - ['!is', 'ios', 'Mozilla/5.0 (iOS) Nextcloud-iOS v2.2.0', false], + ['!is', 'ios', 'Mozilla/5.0 (Android) Nextcloud-android/2.2.0', true], + ['!is', 'ios', 'Mozilla/5.0 (iOS) Nextcloud-iOS/2.2.0', false], ['!is', 'ios', 'Mozilla/5.0 (Linux) mirall/2.2.0', true], ['!is', 'ios', 'Mozilla/5.0 (Windows) Nextcloud-Outlook v2.2.0', true], ['!is', 'ios', 'Mozilla/5.0 (Linux) Nextcloud-Thunderbird v2.2.0', true], - ['is', 'desktop', 'Mozilla/5.0 (Android) Nextcloud-android v2.2.0', false], - ['is', 'desktop', 'Mozilla/5.0 (iOS) Nextcloud-iOS v2.2.0', false], + ['is', 'desktop', 'Mozilla/5.0 (Android) Nextcloud-android/2.2.0', false], + ['is', 'desktop', 'Mozilla/5.0 (iOS) Nextcloud-iOS/2.2.0', false], ['is', 'desktop', 'Mozilla/5.0 (Linux) mirall/2.2.0', true], ['is', 'desktop', 'Mozilla/5.0 (Windows) Nextcloud-Outlook v2.2.0', false], ['is', 'desktop', 'Mozilla/5.0 (Linux) Nextcloud-Thunderbird v2.2.0', false], - ['!is', 'desktop', 'Mozilla/5.0 (Android) Nextcloud-android v2.2.0', true], - ['!is', 'desktop', 'Mozilla/5.0 (iOS) Nextcloud-iOS v2.2.0', true], + ['!is', 'desktop', 'Mozilla/5.0 (Android) Nextcloud-android/2.2.0', true], + ['!is', 'desktop', 'Mozilla/5.0 (iOS) Nextcloud-iOS/2.2.0', true], ['!is', 'desktop', 'Mozilla/5.0 (Linux) mirall/2.2.0', false], ['!is', 'desktop', 'Mozilla/5.0 (Windows) Nextcloud-Outlook v2.2.0', true], ['!is', 'desktop', 'Mozilla/5.0 (Linux) Nextcloud-Thunderbird v2.2.0', true], - ['is', 'mail', 'Mozilla/5.0 (Android) Nextcloud-android v2.2.0', false], - ['is', 'mail', 'Mozilla/5.0 (iOS) Nextcloud-iOS v2.2.0', false], + ['is', 'mail', 'Mozilla/5.0 (Android) Nextcloud-android/2.2.0', false], + ['is', 'mail', 'Mozilla/5.0 (iOS) Nextcloud-iOS/2.2.0', false], ['is', 'mail', 'Mozilla/5.0 (Linux) mirall/2.2.0', false], ['is', 'mail', 'Mozilla/5.0 (Windows) Nextcloud-Outlook v2.2.0', true], ['is', 'mail', 'Mozilla/5.0 (Linux) Nextcloud-Thunderbird v2.2.0', true], - ['!is', 'mail', 'Mozilla/5.0 (Android) Nextcloud-android v2.2.0', true], - ['!is', 'mail', 'Mozilla/5.0 (iOS) Nextcloud-iOS v2.2.0', true], + ['!is', 'mail', 'Mozilla/5.0 (Android) Nextcloud-android/2.2.0', true], + ['!is', 'mail', 'Mozilla/5.0 (iOS) Nextcloud-iOS/2.2.0', true], ['!is', 'mail', 'Mozilla/5.0 (Linux) mirall/2.2.0', true], ['!is', 'mail', 'Mozilla/5.0 (Windows) Nextcloud-Outlook v2.2.0', false], ['!is', 'mail', 'Mozilla/5.0 (Linux) Nextcloud-Thunderbird v2.2.0', false], diff --git a/lib/public/IRequest.php b/lib/public/IRequest.php index 93f065500cb..bc1f88504a8 100644 --- a/lib/public/IRequest.php +++ b/lib/public/IRequest.php @@ -64,43 +64,51 @@ namespace OCP; interface IRequest { /** * @since 9.1.0 + * @since 28.0.0 The regex has a group matching the version number */ - public const USER_AGENT_CLIENT_ANDROID = '/^Mozilla\/5\.0 \(Android\) (ownCloud|Nextcloud)\-android.*$/'; + public const USER_AGENT_CLIENT_ANDROID = '/^Mozilla\/5\.0 \(Android\) (?:ownCloud|Nextcloud)\-android\/([^ ]*).*$/'; /** * @since 13.0.0 + * @since 28.0.0 The regex has a group matching the version number */ - public const USER_AGENT_TALK_ANDROID = '/^Mozilla\/5\.0 \(Android\) Nextcloud\-Talk v.*$/'; + public const USER_AGENT_TALK_ANDROID = '/^Mozilla\/5\.0 \(Android\) Nextcloud\-Talk v([^ ]*).*$/'; /** * @since 9.1.0 + * @since 28.0.0 The regex has a group matching the version number */ - public const USER_AGENT_CLIENT_DESKTOP = '/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/'; + public const USER_AGENT_CLIENT_DESKTOP = '/^Mozilla\/5\.0 \([A-Za-z ]+\) (?:mirall|csyncoC)\/([^ ]*).*$/'; /** * @since 26.0.0 + * @since 28.0.0 The regex has a group matching the version number */ - public const USER_AGENT_TALK_DESKTOP = '/^Mozilla\/5\.0 \((?!Android|iOS)[A-Za-z ]+\) Nextcloud\-Talk v.*$/'; + public const USER_AGENT_TALK_DESKTOP = '/^Mozilla\/5\.0 \((?!Android|iOS)[A-Za-z ]+\) Nextcloud\-Talk v([^ ]*).*$/'; /** * @since 9.1.0 + * @since 28.0.0 The regex has a group matching the version number */ - public const USER_AGENT_CLIENT_IOS = '/^Mozilla\/5\.0 \(iOS\) (ownCloud|Nextcloud)\-iOS.*$/'; + public const USER_AGENT_CLIENT_IOS = '/^Mozilla\/5\.0 \(iOS\) (?:ownCloud|Nextcloud)\-iOS\/([^ ]*).*$/'; /** * @since 13.0.0 + * @since 28.0.0 The regex has a group matching the version number */ - public const USER_AGENT_TALK_IOS = '/^Mozilla\/5\.0 \(iOS\) Nextcloud\-Talk v.*$/'; + public const USER_AGENT_TALK_IOS = '/^Mozilla\/5\.0 \(iOS\) Nextcloud\-Talk v([^ ]*).*$/'; /** * @since 13.0.1 + * @since 28.0.0 The regex has a group matching the version number */ - public const USER_AGENT_OUTLOOK_ADDON = '/^Mozilla\/5\.0 \([A-Za-z ]+\) Nextcloud\-Outlook v.*$/'; + public const USER_AGENT_OUTLOOK_ADDON = '/^Mozilla\/5\.0 \([A-Za-z ]+\) Nextcloud\-Outlook v([^ ]*).*$/'; /** * @since 13.0.1 + * @since 28.0.0 The regex has a group matching the version number */ - public const USER_AGENT_THUNDERBIRD_ADDON = '/^Mozilla\/5\.0 \([A-Za-z ]+\) Nextcloud\-Thunderbird v.*$/'; + public const USER_AGENT_THUNDERBIRD_ADDON = '/^Mozilla\/5\.0 \([A-Za-z ]+\) Nextcloud\-Thunderbird v([^ ]*).*$/'; /** * @since 26.0.0 diff --git a/tests/lib/AppFramework/Http/RequestTest.php b/tests/lib/AppFramework/Http/RequestTest.php index 839c7ad4338..0ce2e283bb5 100644 --- a/tests/lib/AppFramework/Http/RequestTest.php +++ b/tests/lib/AppFramework/Http/RequestTest.php @@ -1265,6 +1265,63 @@ class RequestTest extends \Test\TestCase { ]; } + public function dataMatchClientVersion(): array { + return [ + [ + 'Mozilla/5.0 (Android) Nextcloud-android/3.24.1', + Request::USER_AGENT_CLIENT_ANDROID, + '3.24.1', + ], + [ + 'Mozilla/5.0 (iOS) Nextcloud-iOS/4.8.2', + Request::USER_AGENT_CLIENT_IOS, + '4.8.2', + ], + [ + 'Mozilla/5.0 (Windows) mirall/3.8.1', + Request::USER_AGENT_CLIENT_DESKTOP, + '3.8.1', + ], + [ + 'Mozilla/5.0 (Android) Nextcloud-Talk v17.10.0', + Request::USER_AGENT_TALK_ANDROID, + '17.10.0', + ], + [ + 'Mozilla/5.0 (iOS) Nextcloud-Talk v17.0.1', + Request::USER_AGENT_TALK_IOS, + '17.0.1', + ], + [ + 'Mozilla/5.0 (Windows) Nextcloud-Talk v0.6.0', + Request::USER_AGENT_TALK_DESKTOP, + '0.6.0', + ], + [ + 'Mozilla/5.0 (Windows) Nextcloud-Outlook v1.0.0', + Request::USER_AGENT_OUTLOOK_ADDON, + '1.0.0', + ], + [ + 'Mozilla/5.0 (Linux) Nextcloud-Thunderbird v1.0.0', + Request::USER_AGENT_THUNDERBIRD_ADDON, + '1.0.0', + ], + ]; + } + + /** + * @dataProvider dataMatchClientVersion + * @param string $testAgent + * @param string $userAgent + * @param string $version + */ + public function testMatchClientVersion(string $testAgent, string $userAgent, string $version): void { + preg_match($userAgent, $testAgent, $matches); + + $this->assertSame($version, $matches[1]); + } + public function testInsecureServerHostServerNameHeader() { $request = new Request( [ |