2015-04-16 16:39:44 -04:00
< ? php
2023-06-23 03:50:46 -04:00
declare ( strict_types = 1 );
2024-05-28 06:34:11 -04:00
2015-04-16 16:39:44 -04:00
/**
2024-05-28 06:34:11 -04:00
* SPDX - FileCopyrightText : 2016 - 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX - FileCopyrightText : 2016 ownCloud , Inc .
* SPDX - License - Identifier : AGPL - 3.0 - only
2015-04-16 16:39:44 -04:00
*/
2016-05-25 10:04:15 -04:00
namespace OCA\DAV\Tests\unit\Connector\Sabre ;
2015-04-16 16:39:44 -04:00
2015-08-30 13:13:01 -04:00
use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin ;
2024-09-06 08:39:32 -04:00
use OCA\Theming\ThemingDefaults ;
2019-11-22 14:52:10 -05:00
use OCP\IConfig ;
2023-06-23 03:50:46 -04:00
use PHPUnit\Framework\MockObject\MockObject ;
use Sabre\HTTP\RequestInterface ;
2015-04-16 16:39:44 -04:00
use Test\TestCase ;
2024-11-27 04:06:14 -05:00
enum ERROR_TYPE {
case MIN_ERROR ;
case MAX_ERROR ;
case NONE ;
}
2015-04-16 16:39:44 -04:00
/**
* Class BlockLegacyClientPluginTest
*
2016-05-25 10:04:15 -04:00
* @ package OCA\DAV\Tests\unit\Connector\Sabre
2015-04-16 16:39:44 -04:00
*/
class BlockLegacyClientPluginTest extends TestCase {
2024-09-06 08:39:32 -04:00
private IConfig & MockObject $config ;
private ThemingDefaults & MockObject $themingDefaults ;
private BlockLegacyClientPlugin $blockLegacyClientVersionPlugin ;
2015-04-16 16:39:44 -04:00
2019-11-27 09:27:18 -05:00
protected function setUp () : void {
2015-04-16 16:39:44 -04:00
parent :: setUp ();
2023-06-23 03:50:46 -04:00
$this -> config = $this -> createMock ( IConfig :: class );
2024-09-06 08:39:32 -04:00
$this -> themingDefaults = $this -> createMock ( ThemingDefaults :: class );
$this -> blockLegacyClientVersionPlugin = new BlockLegacyClientPlugin (
$this -> config ,
$this -> themingDefaults ,
);
2015-04-16 16:39:44 -04:00
}
2024-09-06 08:39:32 -04:00
public static function oldDesktopClientProvider () : array {
2015-04-16 16:39:44 -04:00
return [
2024-11-27 04:06:14 -05:00
[ 'Mozilla/5.0 (Windows) mirall/1.5.0' , ERROR_TYPE :: MIN_ERROR ],
[ 'Mozilla/5.0 (Bogus Text) mirall/1.6.9' , ERROR_TYPE :: MIN_ERROR ],
[ 'Mozilla/5.0 (Windows) mirall/2.5.0' , ERROR_TYPE :: MAX_ERROR ],
[ 'Mozilla/5.0 (Bogus Text) mirall/2.0.1' , ERROR_TYPE :: MAX_ERROR ],
[ 'Mozilla/5.0 (Windows) mirall/2.0.0' , ERROR_TYPE :: NONE ],
[ 'Mozilla/5.0 (Bogus Text) mirall/2.0.0' , ERROR_TYPE :: NONE ],
2015-04-16 16:39:44 -04:00
];
}
2026-01-07 08:21:48 -05:00
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'oldDesktopClientProvider')]
2024-11-27 04:06:14 -05:00
public function testBeforeHandlerException ( string $userAgent , ERROR_TYPE $errorType ) : void {
2024-09-06 08:39:32 -04:00
$this -> themingDefaults
2024-11-27 04:06:14 -05:00
-> expects ( $this -> atMost ( 1 ))
2024-09-06 08:39:32 -04:00
-> method ( 'getSyncClientUrl' )
2024-02-02 04:41:43 -05:00
-> willReturn ( 'https://nextcloud.com/install/#install-clients' );
$this -> config
2024-11-27 04:06:14 -05:00
-> expects ( $this -> exactly ( 2 ))
-> method ( 'getSystemValueString' )
-> willReturnCallback ( function ( string $key ) {
if ( $key === 'minimum.supported.desktop.version' ) {
return '1.7.0' ;
}
return '2.0.0' ;
});
if ( $errorType !== ERROR_TYPE :: NONE ) {
$errorString = $errorType === ERROR_TYPE :: MIN_ERROR
? 'This version of the client is unsupported. Upgrade to <a href="https://nextcloud.com/install/#install-clients">version 1.7.0 or later</a>.'
: 'This version of the client is unsupported. Downgrade to <a href="https://nextcloud.com/install/#install-clients">version 2.0.0 or earlier</a>.' ;
$this -> expectException ( \Sabre\DAV\Exception\Forbidden :: class );
$this -> expectExceptionMessage ( $errorString );
}
2019-11-27 09:27:18 -05:00
2023-06-23 03:50:46 -04:00
/** @var RequestInterface|MockObject $request */
2025-05-27 17:36:08 -04:00
$request = $this -> createMock ( RequestInterface :: class );
2015-04-16 16:39:44 -04:00
$request
-> expects ( $this -> once ())
-> method ( 'getHeader' )
-> with ( 'User-Agent' )
2020-03-25 17:21:27 -04:00
-> willReturn ( $userAgent );
2015-04-16 16:39:44 -04:00
$this -> blockLegacyClientVersionPlugin -> beforeHandler ( $request );
}
2024-09-06 08:39:32 -04:00
/**
* Ensure that there is no room for XSS attack through configured URL / version
*/
2026-01-07 08:21:48 -05:00
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'oldDesktopClientProvider')]
2024-11-27 04:06:14 -05:00
public function testBeforeHandlerExceptionPreventXSSAttack ( string $userAgent , ERROR_TYPE $errorType ) : void {
2024-09-06 08:39:32 -04:00
$this -> expectException ( \Sabre\DAV\Exception\Forbidden :: class );
$this -> themingDefaults
2024-11-27 04:06:14 -05:00
-> expects ( $this -> atMost ( 1 ))
2024-09-06 08:39:32 -04:00
-> method ( 'getSyncClientUrl' )
-> willReturn ( 'https://example.com"><script>alter("hacked");</script>' );
$this -> config
2024-11-27 04:06:14 -05:00
-> expects ( $this -> exactly ( 2 ))
-> method ( 'getSystemValueString' )
-> willReturnCallback ( function ( string $key ) {
if ( $key === 'minimum.supported.desktop.version' ) {
return '1.7.0 <script>alert("unsafe")</script>' ;
}
return '2.0.0 <script>alert("unsafe")</script>' ;
});
$errorString = $errorType === ERROR_TYPE :: MIN_ERROR
? 'This version of the client is unsupported. Upgrade to <a href="https://example.com"><script>alter("hacked");</script>">version 1.7.0 <script>alert("unsafe")</script> or later</a>.'
: 'This version of the client is unsupported. Downgrade to <a href="https://example.com"><script>alter("hacked");</script>">version 2.0.0 <script>alert("unsafe")</script> or earlier</a>.' ;
$this -> expectExceptionMessage ( $errorString );
2024-09-06 08:39:32 -04:00
/** @var RequestInterface|MockObject $request */
$request = $this -> createMock ( '\Sabre\HTTP\RequestInterface' );
$request
-> expects ( $this -> once ())
-> method ( 'getHeader' )
-> with ( 'User-Agent' )
-> willReturn ( $userAgent );
$this -> blockLegacyClientVersionPlugin -> beforeHandler ( $request );
}
2024-11-27 04:06:14 -05:00
public static function newAndAlternateDesktopClientProvider () : array {
2015-04-16 16:39:44 -04:00
return [
2023-06-23 03:50:46 -04:00
[ 'Mozilla/5.0 (Windows) mirall/1.7.0' ],
2015-04-16 16:39:44 -04:00
[ 'Mozilla/5.0 (Bogus Text) mirall/1.9.3' ],
2023-06-23 03:50:46 -04:00
[ 'Mozilla/5.0 (Not Our Client But Old Version) LegacySync/1.1.0' ],
2024-11-27 04:06:14 -05:00
[ 'Mozilla/5.0 (Windows) mirall/4.7.0' ],
[ 'Mozilla/5.0 (Bogus Text) mirall/3.9.3' ],
[ 'Mozilla/5.0 (Not Our Client But Old Version) LegacySync/45.0.0' ],
2015-04-16 16:39:44 -04:00
];
}
2026-01-07 08:21:48 -05:00
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'newAndAlternateDesktopClientProvider')]
2023-06-23 03:50:46 -04:00
public function testBeforeHandlerSuccess ( string $userAgent ) : void {
/** @var RequestInterface|MockObject $request */
$request = $this -> createMock ( RequestInterface :: class );
2015-04-16 16:39:44 -04:00
$request
-> expects ( $this -> once ())
-> method ( 'getHeader' )
-> with ( 'User-Agent' )
2020-03-25 17:21:27 -04:00
-> willReturn ( $userAgent );
2015-04-16 16:39:44 -04:00
$this -> config
2024-11-27 04:06:14 -05:00
-> expects ( $this -> exactly ( 2 ))
-> method ( 'getSystemValueString' )
-> willReturnCallback ( function ( string $key ) {
if ( $key === 'minimum.supported.desktop.version' ) {
return '1.7.0' ;
}
return '10.0.0' ;
});
2015-04-16 16:39:44 -04:00
$this -> blockLegacyClientVersionPlugin -> beforeHandler ( $request );
}
2023-01-20 02:38:43 -05:00
public function testBeforeHandlerNoUserAgent () : void {
2023-06-23 03:50:46 -04:00
/** @var RequestInterface|MockObject $request */
$request = $this -> createMock ( RequestInterface :: class );
2015-04-23 10:33:51 -04:00
$request
-> expects ( $this -> once ())
-> method ( 'getHeader' )
-> with ( 'User-Agent' )
2020-03-25 17:21:27 -04:00
-> willReturn ( null );
2024-11-27 04:06:14 -05:00
2015-04-23 10:33:51 -04:00
$this -> blockLegacyClientVersionPlugin -> beforeHandler ( $request );
}
2015-04-16 16:39:44 -04:00
}