@@ -23,107 +23,107 @@ discard block |
||
| 23 | 23 | use Test\TestCase; |
| 24 | 24 | |
| 25 | 25 | class CheckerTest extends TestCase { |
| 26 | - /** @var ServerVersion|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 27 | - private $serverVersion; |
|
| 28 | - /** @var EnvironmentHelper|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 29 | - private $environmentHelper; |
|
| 30 | - /** @var AppLocator|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 31 | - private $appLocator; |
|
| 32 | - /** @var Checker */ |
|
| 33 | - private $checker; |
|
| 34 | - /** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 35 | - private $fileAccessHelper; |
|
| 36 | - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 37 | - private $config; |
|
| 38 | - /** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 39 | - private $appConfig; |
|
| 40 | - /** @var ICacheFactory|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 41 | - private $cacheFactory; |
|
| 42 | - /** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 43 | - private $appManager; |
|
| 44 | - /** @var \OC\Files\Type\Detection|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 45 | - private $mimeTypeDetector; |
|
| 46 | - |
|
| 47 | - protected function setUp(): void { |
|
| 48 | - parent::setUp(); |
|
| 49 | - $this->serverVersion = $this->createMock(ServerVersion::class); |
|
| 50 | - $this->environmentHelper = $this->createMock(EnvironmentHelper::class); |
|
| 51 | - $this->fileAccessHelper = $this->createMock(FileAccessHelper::class); |
|
| 52 | - $this->appLocator = $this->createMock(AppLocator::class); |
|
| 53 | - $this->config = $this->createMock(IConfig::class); |
|
| 54 | - $this->appConfig = $this->createMock(IAppConfig::class); |
|
| 55 | - $this->cacheFactory = $this->createMock(ICacheFactory::class); |
|
| 56 | - $this->appManager = $this->createMock(IAppManager::class); |
|
| 57 | - $this->mimeTypeDetector = $this->createMock(\OC\Files\Type\Detection::class); |
|
| 58 | - |
|
| 59 | - $this->config->method('getAppValue') |
|
| 60 | - ->willReturnArgument(2); |
|
| 61 | - |
|
| 62 | - $this->cacheFactory |
|
| 63 | - ->expects($this->any()) |
|
| 64 | - ->method('createDistributed') |
|
| 65 | - ->with('oc.integritycheck.checker') |
|
| 66 | - ->willReturn(new NullCache()); |
|
| 67 | - |
|
| 68 | - $this->checker = new Checker( |
|
| 69 | - $this->serverVersion, |
|
| 70 | - $this->environmentHelper, |
|
| 71 | - $this->fileAccessHelper, |
|
| 72 | - $this->appLocator, |
|
| 73 | - $this->config, |
|
| 74 | - $this->appConfig, |
|
| 75 | - $this->cacheFactory, |
|
| 76 | - $this->appManager, |
|
| 77 | - $this->mimeTypeDetector |
|
| 78 | - ); |
|
| 79 | - } |
|
| 80 | - |
|
| 81 | - |
|
| 82 | - public function testWriteAppSignatureOfNotExistingApp(): void { |
|
| 83 | - $this->expectException(\Exception::class); |
|
| 84 | - $this->expectExceptionMessage('Exception message'); |
|
| 85 | - |
|
| 86 | - $this->fileAccessHelper |
|
| 87 | - ->expects($this->once()) |
|
| 88 | - ->method('assertDirectoryExists') |
|
| 89 | - ->with('NotExistingApp/appinfo') |
|
| 90 | - ->willThrowException(new \Exception('Exception message')); |
|
| 91 | - $this->fileAccessHelper |
|
| 92 | - ->expects($this->once()) |
|
| 93 | - ->method('is_writable') |
|
| 94 | - ->with('NotExistingApp/appinfo') |
|
| 95 | - ->willReturn(true); |
|
| 96 | - |
|
| 97 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 98 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 99 | - $rsa = new RSA(); |
|
| 100 | - $rsa->loadKey($rsaPrivateKey); |
|
| 101 | - $x509 = new X509(); |
|
| 102 | - $x509->loadX509($keyBundle); |
|
| 103 | - $this->checker->writeAppSignature('NotExistingApp', $x509, $rsa); |
|
| 104 | - } |
|
| 105 | - |
|
| 106 | - |
|
| 107 | - public function testWriteAppSignatureWrongPermissions(): void { |
|
| 108 | - $this->expectException(\Exception::class); |
|
| 109 | - $this->expectExceptionMessageMatches('/[a-zA-Z\\/_-]+ is not writable/'); |
|
| 110 | - |
|
| 111 | - $this->fileAccessHelper |
|
| 112 | - ->expects($this->once()) |
|
| 113 | - ->method('file_put_contents') |
|
| 114 | - ->will($this->throwException(new \Exception('Exception message'))); |
|
| 115 | - |
|
| 116 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 117 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 118 | - $rsa = new RSA(); |
|
| 119 | - $rsa->loadKey($rsaPrivateKey); |
|
| 120 | - $x509 = new X509(); |
|
| 121 | - $x509->loadX509($keyBundle); |
|
| 122 | - $this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa); |
|
| 123 | - } |
|
| 124 | - |
|
| 125 | - public function testWriteAppSignature(): void { |
|
| 126 | - $expectedSignatureFileData = '{ |
|
| 26 | + /** @var ServerVersion|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 27 | + private $serverVersion; |
|
| 28 | + /** @var EnvironmentHelper|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 29 | + private $environmentHelper; |
|
| 30 | + /** @var AppLocator|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 31 | + private $appLocator; |
|
| 32 | + /** @var Checker */ |
|
| 33 | + private $checker; |
|
| 34 | + /** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 35 | + private $fileAccessHelper; |
|
| 36 | + /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 37 | + private $config; |
|
| 38 | + /** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 39 | + private $appConfig; |
|
| 40 | + /** @var ICacheFactory|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 41 | + private $cacheFactory; |
|
| 42 | + /** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 43 | + private $appManager; |
|
| 44 | + /** @var \OC\Files\Type\Detection|\PHPUnit\Framework\MockObject\MockObject */ |
|
| 45 | + private $mimeTypeDetector; |
|
| 46 | + |
|
| 47 | + protected function setUp(): void { |
|
| 48 | + parent::setUp(); |
|
| 49 | + $this->serverVersion = $this->createMock(ServerVersion::class); |
|
| 50 | + $this->environmentHelper = $this->createMock(EnvironmentHelper::class); |
|
| 51 | + $this->fileAccessHelper = $this->createMock(FileAccessHelper::class); |
|
| 52 | + $this->appLocator = $this->createMock(AppLocator::class); |
|
| 53 | + $this->config = $this->createMock(IConfig::class); |
|
| 54 | + $this->appConfig = $this->createMock(IAppConfig::class); |
|
| 55 | + $this->cacheFactory = $this->createMock(ICacheFactory::class); |
|
| 56 | + $this->appManager = $this->createMock(IAppManager::class); |
|
| 57 | + $this->mimeTypeDetector = $this->createMock(\OC\Files\Type\Detection::class); |
|
| 58 | + |
|
| 59 | + $this->config->method('getAppValue') |
|
| 60 | + ->willReturnArgument(2); |
|
| 61 | + |
|
| 62 | + $this->cacheFactory |
|
| 63 | + ->expects($this->any()) |
|
| 64 | + ->method('createDistributed') |
|
| 65 | + ->with('oc.integritycheck.checker') |
|
| 66 | + ->willReturn(new NullCache()); |
|
| 67 | + |
|
| 68 | + $this->checker = new Checker( |
|
| 69 | + $this->serverVersion, |
|
| 70 | + $this->environmentHelper, |
|
| 71 | + $this->fileAccessHelper, |
|
| 72 | + $this->appLocator, |
|
| 73 | + $this->config, |
|
| 74 | + $this->appConfig, |
|
| 75 | + $this->cacheFactory, |
|
| 76 | + $this->appManager, |
|
| 77 | + $this->mimeTypeDetector |
|
| 78 | + ); |
|
| 79 | + } |
|
| 80 | + |
|
| 81 | + |
|
| 82 | + public function testWriteAppSignatureOfNotExistingApp(): void { |
|
| 83 | + $this->expectException(\Exception::class); |
|
| 84 | + $this->expectExceptionMessage('Exception message'); |
|
| 85 | + |
|
| 86 | + $this->fileAccessHelper |
|
| 87 | + ->expects($this->once()) |
|
| 88 | + ->method('assertDirectoryExists') |
|
| 89 | + ->with('NotExistingApp/appinfo') |
|
| 90 | + ->willThrowException(new \Exception('Exception message')); |
|
| 91 | + $this->fileAccessHelper |
|
| 92 | + ->expects($this->once()) |
|
| 93 | + ->method('is_writable') |
|
| 94 | + ->with('NotExistingApp/appinfo') |
|
| 95 | + ->willReturn(true); |
|
| 96 | + |
|
| 97 | + $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 98 | + $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 99 | + $rsa = new RSA(); |
|
| 100 | + $rsa->loadKey($rsaPrivateKey); |
|
| 101 | + $x509 = new X509(); |
|
| 102 | + $x509->loadX509($keyBundle); |
|
| 103 | + $this->checker->writeAppSignature('NotExistingApp', $x509, $rsa); |
|
| 104 | + } |
|
| 105 | + |
|
| 106 | + |
|
| 107 | + public function testWriteAppSignatureWrongPermissions(): void { |
|
| 108 | + $this->expectException(\Exception::class); |
|
| 109 | + $this->expectExceptionMessageMatches('/[a-zA-Z\\/_-]+ is not writable/'); |
|
| 110 | + |
|
| 111 | + $this->fileAccessHelper |
|
| 112 | + ->expects($this->once()) |
|
| 113 | + ->method('file_put_contents') |
|
| 114 | + ->will($this->throwException(new \Exception('Exception message'))); |
|
| 115 | + |
|
| 116 | + $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 117 | + $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 118 | + $rsa = new RSA(); |
|
| 119 | + $rsa->loadKey($rsaPrivateKey); |
|
| 120 | + $x509 = new X509(); |
|
| 121 | + $x509->loadX509($keyBundle); |
|
| 122 | + $this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa); |
|
| 123 | + } |
|
| 124 | + |
|
| 125 | + public function testWriteAppSignature(): void { |
|
| 126 | + $expectedSignatureFileData = '{ |
|
| 127 | 127 | "hashes": { |
| 128 | 128 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 129 | 129 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -131,65 +131,65 @@ discard block |
||
| 131 | 131 | "signature": "Y5yvXvcGHVPuRRatKVDUONWq1FpLXugZd6Km\/+aEHsQj7coVl9FeMj9OsWamBf7yRIw3dtNLguTLlAA9QAv\/b0uHN3JnbNZN+dwFOve4NMtqXfSDlWftqKN00VS+RJXpG1S2IIx9Poyp2NoghL\/5AuTv4GHiNb7zU\/DT\/kt71pUGPgPR6IIFaE+zHOD96vjYkrH+GfWZzKR0FCdLib9yyNvk+EGrcjKM6qjs2GKfS\/XFjj\/\/neDnh\/0kcPuKE3ZbofnI4TIDTv0CGqvOp7PtqVNc3Vy\/UKa7uF1PT0MAUKMww6EiMUSFZdUVP4WWF0Y72W53Qdtf1hrAZa2kfKyoK5kd7sQmCSKUPSU8978AUVZlBtTRlyT803IKwMV0iHMkw+xYB1sN2FlHup\/DESADqxhdgYuK35bCPvgkb4SBe4B8Voz\/izTvcP7VT5UvkYdAO+05\/jzdaHEmzmsD92CFfvX0q8O\/Y\/29ubftUJsqcHeMDKgcR4eZOE8+\/QVc\/89QO6WnKNuNuV+5bybO6g6PAdC9ZPsCvnihS61O2mwRXHLR3jv2UleFWm+lZEquPKtkhi6SLtDiijA4GV6dmS+dzujSLb7hGeD5o1plZcZ94uhWljl+QIp82+zU\/lYB1Zfr4Mb4e+V7r2gv7Fbv7y6YtjE2GIQwRhC5jq56bD0ZB+I=", |
| 132 | 132 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEwTCCAqmgAwIBAgIUWv0iujufs5lUr0svCf\/qTQvoyKAwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIyNDk1M1oXDTE2MTEwMzIyNDk1M1owEjEQMA4GA1UEAwwHU29tZUFwcDCCAiIw\r\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK8q0x62agGSRBqeWsaeEwFfepMk\r\nF8cAobMMi50qHCv9IrOn\/ZH9l52xBrbIkErVmRjmly0d4JhD8Ymhidsh9ONKYl\/j\r\n+ishsZDM8eNNdp3Ew+fEYVvY1W7mR1qU24NWj0bzVsClI7hvPVIuw7AjfBDq1C5+\r\nA+ZSLSXYvOK2cEWjdxQfuNZwEZSjmA63DUllBIrm35IaTvfuyhU6BW9yHZxmb8+M\r\nw0xDv30D5UkE\/2N7Pa\/HQJLxCR+3zKibRK3nUyRDLSXxMkU9PnFNaPNX59VPgyj4\r\nGB1CFSToldJVPF4pzh7p36uGXZVxs8m3LFD4Ol8mhi7jkxDZjqFN46gzR0r23Py6\r\ndol9vfawGIoUwp9LvL0S7MvdRY0oazLXwClLP4OQ17zpSMAiCj7fgNT661JamPGj\r\nt5O7Zn2wA7I4ddDS\/HDTWCu98Zwc9fHIpsJPgCZ9awoqxi4Mnf7Pk9g5nnXhszGC\r\ncxxIASQKM+GhdzoRxKknax2RzUCwCzcPRtCj8AQT\/x\/mqN3PfRmlnFBNACUw9bpZ\r\nSOoNq2pCF9igftDWpSIXQ38pVpKLWowjjg3DVRmVKBgivHnUnVLyzYBahHPj0vaz\r\ntFtUFRaqXDnt+4qyUGyrT5h5pjZaTcHIcSB4PiarYwdVvgslgwnQzOUcGAzRWBD4\r\n6jV2brP5vFY3g6iPAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBACTY3CCHC+Z28gCf\r\nFWGKQ3wAKs+k4+0yoti0qm2EKX7rSGQ0PHSas6uW79WstC4Rj+DYkDtIhGMSg8FS\r\nHVGZHGBCc0HwdX+BOAt3zi4p7Sf3oQef70\/4imPoKxbAVCpd\/cveVcFyDC19j1yB\r\nBapwu87oh+muoeaZxOlqQI4UxjBlR\/uRSMhOn2UGauIr3dWJgAF4pGt7TtIzt+1v\r\n0uA6FtN1Y4R5O8AaJPh1bIG0CVvFBE58esGzjEYLhOydgKFnEP94kVPgJD5ds9C3\r\npPhEpo1dRpiXaF7WGIV1X6DI\/ipWvfrF7CEy6I\/kP1InY\/vMDjQjeDnJ\/VrXIWXO\r\nyZvHXVaN\/m+1RlETsH7YO\/QmxRue9ZHN3gvvWtmpCeA95sfpepOk7UcHxHZYyQbF\r\n49\/au8j+5tsr4A83xzsT1JbcKRxkAaQ7WDJpOnE5O1+H0fB+BaLakTg6XX9d4Fo7\r\n7Gin7hVWX7pL+JIyxMzME3LhfI61+CRcqZQIrpyaafUziPQbWIPfEs7h8tCOWyvW\r\nUO8ZLervYCB3j44ivkrxPlcBklDCqqKKBzDP9dYOtS\/P4RB1NkHA9+NTvmBpTonS\r\nSFXdg9fFMD7VfjDE3Vnk+8DWkVH5wBYowTAD7w9Wuzr7DumiAULexnP\/Y7xwxLv7\r\n4B+pXTAcRK0zECDEaX3npS8xWzrB\r\n-----END CERTIFICATE-----" |
| 133 | 133 | }'; |
| 134 | - $this->fileAccessHelper |
|
| 135 | - ->expects($this->once()) |
|
| 136 | - ->method('file_put_contents') |
|
| 137 | - ->with( |
|
| 138 | - $this->equalTo(\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json'), |
|
| 139 | - $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 140 | - $expectedArray = json_decode($expectedSignatureFileData, true); |
|
| 141 | - $actualArray = json_decode($signature, true); |
|
| 142 | - $this->assertEquals($expectedArray, $actualArray); |
|
| 143 | - return true; |
|
| 144 | - }) |
|
| 145 | - ); |
|
| 146 | - |
|
| 147 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 148 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 149 | - $rsa = new RSA(); |
|
| 150 | - $rsa->loadKey($rsaPrivateKey); |
|
| 151 | - $x509 = new X509(); |
|
| 152 | - $x509->loadX509($keyBundle); |
|
| 153 | - $this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa); |
|
| 154 | - } |
|
| 155 | - |
|
| 156 | - public function testVerifyAppSignatureWithoutSignatureData(): void { |
|
| 157 | - $this->serverVersion |
|
| 158 | - ->expects($this->once()) |
|
| 159 | - ->method('getChannel') |
|
| 160 | - ->willReturn('stable'); |
|
| 161 | - $this->config |
|
| 162 | - ->expects($this->any()) |
|
| 163 | - ->method('getSystemValueBool') |
|
| 164 | - ->with('integrity.check.disabled', false) |
|
| 165 | - ->willReturn(false); |
|
| 166 | - |
|
| 167 | - $expected = [ |
|
| 168 | - 'EXCEPTION' => [ |
|
| 169 | - 'class' => 'OC\IntegrityCheck\Exceptions\InvalidSignatureException', |
|
| 170 | - 'message' => 'Signature data not found.', |
|
| 171 | - ], |
|
| 172 | - ]; |
|
| 173 | - $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp')); |
|
| 174 | - } |
|
| 175 | - |
|
| 176 | - public function testVerifyAppSignatureWithValidSignatureData(): void { |
|
| 177 | - $this->serverVersion |
|
| 178 | - ->expects($this->once()) |
|
| 179 | - ->method('getChannel') |
|
| 180 | - ->willReturn('stable'); |
|
| 181 | - $this->config |
|
| 182 | - ->expects($this->any()) |
|
| 183 | - ->method('getSystemValueBool') |
|
| 184 | - ->with('integrity.check.disabled', false) |
|
| 185 | - ->willReturn(false); |
|
| 186 | - |
|
| 187 | - $this->appLocator |
|
| 188 | - ->expects($this->once()) |
|
| 189 | - ->method('getAppPath') |
|
| 190 | - ->with('SomeApp') |
|
| 191 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 192 | - $signatureDataFile = '{ |
|
| 134 | + $this->fileAccessHelper |
|
| 135 | + ->expects($this->once()) |
|
| 136 | + ->method('file_put_contents') |
|
| 137 | + ->with( |
|
| 138 | + $this->equalTo(\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json'), |
|
| 139 | + $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 140 | + $expectedArray = json_decode($expectedSignatureFileData, true); |
|
| 141 | + $actualArray = json_decode($signature, true); |
|
| 142 | + $this->assertEquals($expectedArray, $actualArray); |
|
| 143 | + return true; |
|
| 144 | + }) |
|
| 145 | + ); |
|
| 146 | + |
|
| 147 | + $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 148 | + $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 149 | + $rsa = new RSA(); |
|
| 150 | + $rsa->loadKey($rsaPrivateKey); |
|
| 151 | + $x509 = new X509(); |
|
| 152 | + $x509->loadX509($keyBundle); |
|
| 153 | + $this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa); |
|
| 154 | + } |
|
| 155 | + |
|
| 156 | + public function testVerifyAppSignatureWithoutSignatureData(): void { |
|
| 157 | + $this->serverVersion |
|
| 158 | + ->expects($this->once()) |
|
| 159 | + ->method('getChannel') |
|
| 160 | + ->willReturn('stable'); |
|
| 161 | + $this->config |
|
| 162 | + ->expects($this->any()) |
|
| 163 | + ->method('getSystemValueBool') |
|
| 164 | + ->with('integrity.check.disabled', false) |
|
| 165 | + ->willReturn(false); |
|
| 166 | + |
|
| 167 | + $expected = [ |
|
| 168 | + 'EXCEPTION' => [ |
|
| 169 | + 'class' => 'OC\IntegrityCheck\Exceptions\InvalidSignatureException', |
|
| 170 | + 'message' => 'Signature data not found.', |
|
| 171 | + ], |
|
| 172 | + ]; |
|
| 173 | + $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp')); |
|
| 174 | + } |
|
| 175 | + |
|
| 176 | + public function testVerifyAppSignatureWithValidSignatureData(): void { |
|
| 177 | + $this->serverVersion |
|
| 178 | + ->expects($this->once()) |
|
| 179 | + ->method('getChannel') |
|
| 180 | + ->willReturn('stable'); |
|
| 181 | + $this->config |
|
| 182 | + ->expects($this->any()) |
|
| 183 | + ->method('getSystemValueBool') |
|
| 184 | + ->with('integrity.check.disabled', false) |
|
| 185 | + ->willReturn(false); |
|
| 186 | + |
|
| 187 | + $this->appLocator |
|
| 188 | + ->expects($this->once()) |
|
| 189 | + ->method('getAppPath') |
|
| 190 | + ->with('SomeApp') |
|
| 191 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 192 | + $signatureDataFile = '{ |
|
| 193 | 193 | "hashes": { |
| 194 | 194 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 195 | 195 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -197,34 +197,34 @@ discard block |
||
| 197 | 197 | "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=", |
| 198 | 198 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 199 | 199 | }'; |
| 200 | - $this->fileAccessHelper |
|
| 201 | - ->expects($this->exactly(2)) |
|
| 202 | - ->method('file_get_contents') |
|
| 203 | - ->willReturnMap([ |
|
| 204 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 205 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 206 | - ]); |
|
| 207 | - |
|
| 208 | - $this->assertSame([], $this->checker->verifyAppSignature('SomeApp')); |
|
| 209 | - } |
|
| 210 | - |
|
| 211 | - public function testVerifyAppSignatureWithTamperedSignatureData(): void { |
|
| 212 | - $this->serverVersion |
|
| 213 | - ->expects($this->once()) |
|
| 214 | - ->method('getChannel') |
|
| 215 | - ->willReturn('stable'); |
|
| 216 | - $this->config |
|
| 217 | - ->expects($this->any()) |
|
| 218 | - ->method('getSystemValueBool') |
|
| 219 | - ->with('integrity.check.disabled', false) |
|
| 220 | - ->willReturn(false); |
|
| 221 | - |
|
| 222 | - $this->appLocator |
|
| 223 | - ->expects($this->once()) |
|
| 224 | - ->method('getAppPath') |
|
| 225 | - ->with('SomeApp') |
|
| 226 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 227 | - $signatureDataFile = '{ |
|
| 200 | + $this->fileAccessHelper |
|
| 201 | + ->expects($this->exactly(2)) |
|
| 202 | + ->method('file_get_contents') |
|
| 203 | + ->willReturnMap([ |
|
| 204 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 205 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 206 | + ]); |
|
| 207 | + |
|
| 208 | + $this->assertSame([], $this->checker->verifyAppSignature('SomeApp')); |
|
| 209 | + } |
|
| 210 | + |
|
| 211 | + public function testVerifyAppSignatureWithTamperedSignatureData(): void { |
|
| 212 | + $this->serverVersion |
|
| 213 | + ->expects($this->once()) |
|
| 214 | + ->method('getChannel') |
|
| 215 | + ->willReturn('stable'); |
|
| 216 | + $this->config |
|
| 217 | + ->expects($this->any()) |
|
| 218 | + ->method('getSystemValueBool') |
|
| 219 | + ->with('integrity.check.disabled', false) |
|
| 220 | + ->willReturn(false); |
|
| 221 | + |
|
| 222 | + $this->appLocator |
|
| 223 | + ->expects($this->once()) |
|
| 224 | + ->method('getAppPath') |
|
| 225 | + ->with('SomeApp') |
|
| 226 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 227 | + $signatureDataFile = '{ |
|
| 228 | 228 | "hashes": { |
| 229 | 229 | "AnotherFile.txt": "tampered", |
| 230 | 230 | "subfolder\/file.txt": "tampered" |
@@ -232,40 +232,40 @@ discard block |
||
| 232 | 232 | "signature": "EL49UaSeyMAqyMtqId+tgOhhwgOevPZsRLX4j2blnybAB6fN07z0936JqZV7+eMPiE30Idx+UCY6rCFN531Kqe9vAOCdgtHUSOjjKyKc+lvULESlMb6YQcrZrvDlEMMjzjH49ewG7Ai8sNN6HrRUd9U8ws+ewSkW2DOOBItj\/21RBnkrSt+2AtGXGigEvuTm57HrCYDj8\/lSkumC2GVkjLUHeLOKYo4PRNOr6yP5mED5v7zo66AWvXl2fKv54InZcdxsAk35lyK9DGZbk\/027ZRd0AOHT3LImRLvQ+8EAg3XLlRUy0hOFGgPC+jYonMzgYvsAXAXi2j8LnLJlsLwpFwu1k1B+kZVPMumKZvP9OvJb70EirecXmz62V+Jiyuaq7ne4y7Kp5gKZT\/T8SeZ0lFtCmPfYyzBB0y8s5ldmTTmdVYHs54t\/OCCW82HzQZxnFNPzDTRa8HglsaMKrqPtW59+R4UvRKSWhB8M\/Ah57qgzycvPV4KMz\/FbD4l\/\/9chRKSlCfc2k3b8ZSHNmi+EzCKgJjWIoKdgN1yax94puU8jfn8UW+G7H9Y1Jsf\/jox6QLyYEgtV1vOHY2xLT7fVs2vhyvkN2MNjJnmQ70gFG5Qz2lBz5wi6ZpB+tOfCcpbLxWAkoWoIrmC\/Ilqh7mfmRZ43g5upjkepHNd93ONuY8=", |
| 233 | 233 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEwTCCAqmgAwIBAgIUWv0iujufs5lUr0svCf\/qTQvoyKAwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIyNDk1M1oXDTE2MTEwMzIyNDk1M1owEjEQMA4GA1UEAwwHU29tZUFwcDCCAiIw\r\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK8q0x62agGSRBqeWsaeEwFfepMk\r\nF8cAobMMi50qHCv9IrOn\/ZH9l52xBrbIkErVmRjmly0d4JhD8Ymhidsh9ONKYl\/j\r\n+ishsZDM8eNNdp3Ew+fEYVvY1W7mR1qU24NWj0bzVsClI7hvPVIuw7AjfBDq1C5+\r\nA+ZSLSXYvOK2cEWjdxQfuNZwEZSjmA63DUllBIrm35IaTvfuyhU6BW9yHZxmb8+M\r\nw0xDv30D5UkE\/2N7Pa\/HQJLxCR+3zKibRK3nUyRDLSXxMkU9PnFNaPNX59VPgyj4\r\nGB1CFSToldJVPF4pzh7p36uGXZVxs8m3LFD4Ol8mhi7jkxDZjqFN46gzR0r23Py6\r\ndol9vfawGIoUwp9LvL0S7MvdRY0oazLXwClLP4OQ17zpSMAiCj7fgNT661JamPGj\r\nt5O7Zn2wA7I4ddDS\/HDTWCu98Zwc9fHIpsJPgCZ9awoqxi4Mnf7Pk9g5nnXhszGC\r\ncxxIASQKM+GhdzoRxKknax2RzUCwCzcPRtCj8AQT\/x\/mqN3PfRmlnFBNACUw9bpZ\r\nSOoNq2pCF9igftDWpSIXQ38pVpKLWowjjg3DVRmVKBgivHnUnVLyzYBahHPj0vaz\r\ntFtUFRaqXDnt+4qyUGyrT5h5pjZaTcHIcSB4PiarYwdVvgslgwnQzOUcGAzRWBD4\r\n6jV2brP5vFY3g6iPAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBACTY3CCHC+Z28gCf\r\nFWGKQ3wAKs+k4+0yoti0qm2EKX7rSGQ0PHSas6uW79WstC4Rj+DYkDtIhGMSg8FS\r\nHVGZHGBCc0HwdX+BOAt3zi4p7Sf3oQef70\/4imPoKxbAVCpd\/cveVcFyDC19j1yB\r\nBapwu87oh+muoeaZxOlqQI4UxjBlR\/uRSMhOn2UGauIr3dWJgAF4pGt7TtIzt+1v\r\n0uA6FtN1Y4R5O8AaJPh1bIG0CVvFBE58esGzjEYLhOydgKFnEP94kVPgJD5ds9C3\r\npPhEpo1dRpiXaF7WGIV1X6DI\/ipWvfrF7CEy6I\/kP1InY\/vMDjQjeDnJ\/VrXIWXO\r\nyZvHXVaN\/m+1RlETsH7YO\/QmxRue9ZHN3gvvWtmpCeA95sfpepOk7UcHxHZYyQbF\r\n49\/au8j+5tsr4A83xzsT1JbcKRxkAaQ7WDJpOnE5O1+H0fB+BaLakTg6XX9d4Fo7\r\n7Gin7hVWX7pL+JIyxMzME3LhfI61+CRcqZQIrpyaafUziPQbWIPfEs7h8tCOWyvW\r\nUO8ZLervYCB3j44ivkrxPlcBklDCqqKKBzDP9dYOtS\/P4RB1NkHA9+NTvmBpTonS\r\nSFXdg9fFMD7VfjDE3Vnk+8DWkVH5wBYowTAD7w9Wuzr7DumiAULexnP\/Y7xwxLv7\r\n4B+pXTAcRK0zECDEaX3npS8xWzrB\r\n-----END CERTIFICATE-----" |
| 234 | 234 | }'; |
| 235 | - $this->fileAccessHelper |
|
| 236 | - ->expects($this->exactly(2)) |
|
| 237 | - ->method('file_get_contents') |
|
| 238 | - ->willReturnMap([ |
|
| 239 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 240 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 241 | - ]); |
|
| 242 | - |
|
| 243 | - $expected = [ |
|
| 244 | - 'EXCEPTION' => [ |
|
| 245 | - 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 246 | - 'message' => 'Signature could not get verified.', |
|
| 247 | - ], |
|
| 248 | - ]; |
|
| 249 | - $this->assertEquals($expected, $this->checker->verifyAppSignature('SomeApp')); |
|
| 250 | - } |
|
| 251 | - |
|
| 252 | - public function testVerifyAppSignatureWithTamperedFiles(): void { |
|
| 253 | - $this->serverVersion |
|
| 254 | - ->expects($this->once()) |
|
| 255 | - ->method('getChannel') |
|
| 256 | - ->willReturn('stable'); |
|
| 257 | - $this->config |
|
| 258 | - ->expects($this->any()) |
|
| 259 | - ->method('getSystemValueBool') |
|
| 260 | - ->with('integrity.check.disabled', false) |
|
| 261 | - ->willReturn(false); |
|
| 262 | - |
|
| 263 | - $this->appLocator |
|
| 264 | - ->expects($this->once()) |
|
| 265 | - ->method('getAppPath') |
|
| 266 | - ->with('SomeApp') |
|
| 267 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 268 | - $signatureDataFile = '{ |
|
| 235 | + $this->fileAccessHelper |
|
| 236 | + ->expects($this->exactly(2)) |
|
| 237 | + ->method('file_get_contents') |
|
| 238 | + ->willReturnMap([ |
|
| 239 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 240 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 241 | + ]); |
|
| 242 | + |
|
| 243 | + $expected = [ |
|
| 244 | + 'EXCEPTION' => [ |
|
| 245 | + 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 246 | + 'message' => 'Signature could not get verified.', |
|
| 247 | + ], |
|
| 248 | + ]; |
|
| 249 | + $this->assertEquals($expected, $this->checker->verifyAppSignature('SomeApp')); |
|
| 250 | + } |
|
| 251 | + |
|
| 252 | + public function testVerifyAppSignatureWithTamperedFiles(): void { |
|
| 253 | + $this->serverVersion |
|
| 254 | + ->expects($this->once()) |
|
| 255 | + ->method('getChannel') |
|
| 256 | + ->willReturn('stable'); |
|
| 257 | + $this->config |
|
| 258 | + ->expects($this->any()) |
|
| 259 | + ->method('getSystemValueBool') |
|
| 260 | + ->with('integrity.check.disabled', false) |
|
| 261 | + ->willReturn(false); |
|
| 262 | + |
|
| 263 | + $this->appLocator |
|
| 264 | + ->expects($this->once()) |
|
| 265 | + ->method('getAppPath') |
|
| 266 | + ->with('SomeApp') |
|
| 267 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 268 | + $signatureDataFile = '{ |
|
| 269 | 269 | "hashes": { |
| 270 | 270 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 271 | 271 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -273,55 +273,55 @@ discard block |
||
| 273 | 273 | "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=", |
| 274 | 274 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 275 | 275 | }'; |
| 276 | - $this->fileAccessHelper |
|
| 277 | - ->expects($this->exactly(2)) |
|
| 278 | - ->method('file_get_contents') |
|
| 279 | - ->willReturnMap([ |
|
| 280 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 281 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 282 | - ]); |
|
| 283 | - |
|
| 284 | - |
|
| 285 | - $expected = [ |
|
| 286 | - 'INVALID_HASH' => [ |
|
| 287 | - 'AnotherFile.txt' => [ |
|
| 288 | - 'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112', |
|
| 289 | - 'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c', |
|
| 290 | - ], |
|
| 291 | - ], |
|
| 292 | - 'FILE_MISSING' => [ |
|
| 293 | - 'subfolder/file.txt' => [ |
|
| 294 | - 'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b', |
|
| 295 | - 'current' => '', |
|
| 296 | - ], |
|
| 297 | - ], |
|
| 298 | - 'EXTRA_FILE' => [ |
|
| 299 | - 'UnecessaryFile' => [ |
|
| 300 | - 'expected' => '', |
|
| 301 | - 'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', |
|
| 302 | - ], |
|
| 303 | - ], |
|
| 304 | - |
|
| 305 | - ]; |
|
| 306 | - $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp')); |
|
| 307 | - } |
|
| 308 | - |
|
| 309 | - public function testVerifyAppSignatureWithTamperedFilesAndAlternatePath(): void { |
|
| 310 | - $this->serverVersion |
|
| 311 | - ->expects($this->once()) |
|
| 312 | - ->method('getChannel') |
|
| 313 | - ->willReturn('stable'); |
|
| 314 | - $this->config |
|
| 315 | - ->expects($this->any()) |
|
| 316 | - ->method('getSystemValueBool') |
|
| 317 | - ->with('integrity.check.disabled', false) |
|
| 318 | - ->willReturn(false); |
|
| 319 | - |
|
| 320 | - $this->appLocator |
|
| 321 | - ->expects($this->never()) |
|
| 322 | - ->method('getAppPath') |
|
| 323 | - ->with('SomeApp'); |
|
| 324 | - $signatureDataFile = '{ |
|
| 276 | + $this->fileAccessHelper |
|
| 277 | + ->expects($this->exactly(2)) |
|
| 278 | + ->method('file_get_contents') |
|
| 279 | + ->willReturnMap([ |
|
| 280 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 281 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 282 | + ]); |
|
| 283 | + |
|
| 284 | + |
|
| 285 | + $expected = [ |
|
| 286 | + 'INVALID_HASH' => [ |
|
| 287 | + 'AnotherFile.txt' => [ |
|
| 288 | + 'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112', |
|
| 289 | + 'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c', |
|
| 290 | + ], |
|
| 291 | + ], |
|
| 292 | + 'FILE_MISSING' => [ |
|
| 293 | + 'subfolder/file.txt' => [ |
|
| 294 | + 'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b', |
|
| 295 | + 'current' => '', |
|
| 296 | + ], |
|
| 297 | + ], |
|
| 298 | + 'EXTRA_FILE' => [ |
|
| 299 | + 'UnecessaryFile' => [ |
|
| 300 | + 'expected' => '', |
|
| 301 | + 'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', |
|
| 302 | + ], |
|
| 303 | + ], |
|
| 304 | + |
|
| 305 | + ]; |
|
| 306 | + $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp')); |
|
| 307 | + } |
|
| 308 | + |
|
| 309 | + public function testVerifyAppSignatureWithTamperedFilesAndAlternatePath(): void { |
|
| 310 | + $this->serverVersion |
|
| 311 | + ->expects($this->once()) |
|
| 312 | + ->method('getChannel') |
|
| 313 | + ->willReturn('stable'); |
|
| 314 | + $this->config |
|
| 315 | + ->expects($this->any()) |
|
| 316 | + ->method('getSystemValueBool') |
|
| 317 | + ->with('integrity.check.disabled', false) |
|
| 318 | + ->willReturn(false); |
|
| 319 | + |
|
| 320 | + $this->appLocator |
|
| 321 | + ->expects($this->never()) |
|
| 322 | + ->method('getAppPath') |
|
| 323 | + ->with('SomeApp'); |
|
| 324 | + $signatureDataFile = '{ |
|
| 325 | 325 | "hashes": { |
| 326 | 326 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 327 | 327 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -329,55 +329,55 @@ discard block |
||
| 329 | 329 | "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=", |
| 330 | 330 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 331 | 331 | }'; |
| 332 | - $this->fileAccessHelper |
|
| 333 | - ->expects($this->exactly(2)) |
|
| 334 | - ->method('file_get_contents') |
|
| 335 | - ->willReturnMap([ |
|
| 336 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 337 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 338 | - ]); |
|
| 339 | - |
|
| 340 | - $expected = [ |
|
| 341 | - 'INVALID_HASH' => [ |
|
| 342 | - 'AnotherFile.txt' => [ |
|
| 343 | - 'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112', |
|
| 344 | - 'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c', |
|
| 345 | - ], |
|
| 346 | - ], |
|
| 347 | - 'FILE_MISSING' => [ |
|
| 348 | - 'subfolder/file.txt' => [ |
|
| 349 | - 'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b', |
|
| 350 | - 'current' => '', |
|
| 351 | - ], |
|
| 352 | - ], |
|
| 353 | - 'EXTRA_FILE' => [ |
|
| 354 | - 'UnecessaryFile' => [ |
|
| 355 | - 'expected' => '', |
|
| 356 | - 'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', |
|
| 357 | - ], |
|
| 358 | - ], |
|
| 359 | - |
|
| 360 | - ]; |
|
| 361 | - $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp', \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/')); |
|
| 362 | - } |
|
| 363 | - |
|
| 364 | - public function testVerifyAppWithDifferentScope(): void { |
|
| 365 | - $this->serverVersion |
|
| 366 | - ->expects($this->once()) |
|
| 367 | - ->method('getChannel') |
|
| 368 | - ->willReturn('stable'); |
|
| 369 | - $this->config |
|
| 370 | - ->expects($this->any()) |
|
| 371 | - ->method('getSystemValueBool') |
|
| 372 | - ->with('integrity.check.disabled', false) |
|
| 373 | - ->willReturn(false); |
|
| 374 | - |
|
| 375 | - $this->appLocator |
|
| 376 | - ->expects($this->once()) |
|
| 377 | - ->method('getAppPath') |
|
| 378 | - ->with('SomeApp') |
|
| 379 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 380 | - $signatureDataFile = '{ |
|
| 332 | + $this->fileAccessHelper |
|
| 333 | + ->expects($this->exactly(2)) |
|
| 334 | + ->method('file_get_contents') |
|
| 335 | + ->willReturnMap([ |
|
| 336 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 337 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 338 | + ]); |
|
| 339 | + |
|
| 340 | + $expected = [ |
|
| 341 | + 'INVALID_HASH' => [ |
|
| 342 | + 'AnotherFile.txt' => [ |
|
| 343 | + 'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112', |
|
| 344 | + 'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c', |
|
| 345 | + ], |
|
| 346 | + ], |
|
| 347 | + 'FILE_MISSING' => [ |
|
| 348 | + 'subfolder/file.txt' => [ |
|
| 349 | + 'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b', |
|
| 350 | + 'current' => '', |
|
| 351 | + ], |
|
| 352 | + ], |
|
| 353 | + 'EXTRA_FILE' => [ |
|
| 354 | + 'UnecessaryFile' => [ |
|
| 355 | + 'expected' => '', |
|
| 356 | + 'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', |
|
| 357 | + ], |
|
| 358 | + ], |
|
| 359 | + |
|
| 360 | + ]; |
|
| 361 | + $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp', \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/')); |
|
| 362 | + } |
|
| 363 | + |
|
| 364 | + public function testVerifyAppWithDifferentScope(): void { |
|
| 365 | + $this->serverVersion |
|
| 366 | + ->expects($this->once()) |
|
| 367 | + ->method('getChannel') |
|
| 368 | + ->willReturn('stable'); |
|
| 369 | + $this->config |
|
| 370 | + ->expects($this->any()) |
|
| 371 | + ->method('getSystemValueBool') |
|
| 372 | + ->with('integrity.check.disabled', false) |
|
| 373 | + ->willReturn(false); |
|
| 374 | + |
|
| 375 | + $this->appLocator |
|
| 376 | + ->expects($this->once()) |
|
| 377 | + ->method('getAppPath') |
|
| 378 | + ->with('SomeApp') |
|
| 379 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 380 | + $signatureDataFile = '{ |
|
| 381 | 381 | "hashes": { |
| 382 | 382 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 383 | 383 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -385,40 +385,40 @@ discard block |
||
| 385 | 385 | "signature": "eXesvDm3pkek12xSwMG10y9suRES79Nye3jYNe5KYq1tTUPqRRNgxmMGAfcUro0zpLeAr2YgHeSMWtglblGOW7pmwGVPZ0O1Y4r1fE6jnep0kW+35PLIaqCorIOnCAtSzDNKBhwd1ow3zW2wC0DFouuEkIO8u5Fw28g8E8dp8zEk1xMblNPy+xtWkmYHrVJ\/dQgun1bYOF2ZFtAzatwndTI\/bGsy1i3Wsl+x6HyWKQdq8y8VObtOqKDH7uERBEpB9DHVyKflj1v1gQuEH6BhaRdATc7ee0MiQdGblraIySwYRdfo2d8i82OVKrenMB3SLwyCvDPyQ9iKpTOnSF52ZBqaqSXKM2N\/RAkweeBFQQCwcHhqxvB0cfbyHcbkOLeCZe\/tsh68IxwTiYgzvLfl7sOZ5arnZbzrPpZmB+hfV2omkoJ1tDwOWz9hEmLLNtfo2OxyUH1m0+XFaC+Gbn4WkVDgf7YZkwUcG+Qoa3oKDNMss8MEyZxewl2iDGZcf402dlidHRprlfmXbAYuVQ08\/a0HxIKYPGh\/nsMGmwnO15CWtFpAbhUA\/D5oRjsIxnvXaMDg0iAFpdu\/5Ffsj7g3EPdBkiQHNYK7YU1RRx609eH0bZyiIYHdUPw7ikLupvrebZmELqi3mqDFO99u4eISlxFJlUbUND3L4BtmWTWrKwI=", |
| 386 | 386 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIExjCCAq6gAwIBAgIUHSJjhJqMwr+3TkoiQFg4SVVYQ1gwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIzMjc1NVoXDTE2MTEwMzIzMjc1NVowFzEVMBMGA1UEAwwMQW5vdGhlclNjb3Bl\r\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA33npb5RmUkXrDT+TbwMf\r\n0zQ33SlzsjoGxCrbSwJOn6leGGInJ6ZrdzLL0WTi\/dTpg+Y\/JS+72XWm5NSjaTxo\r\n7OHc3cQBwXQj4tN6j\/y5qqY0GDLYufEkx2rpazqt9lBSJ72u1bGl2yoOXzYCz5i0\r\n60KsJXC9K44LKzGsarzbwAgskSVNkjAsPgjnCWZmcl6icpLi5Fz9rs2UMOWbdvdI\r\nAROsn0eC9E\/akmXTy5YMu6bAIGpvjZFHzyA83FQRbvv5o1V5Gsye\/VQLEgh7rqfz\r\nT\/jgWifP+JgoeB6otzuRZ3fFsmbBiyCIRtIOzQQflozhUlWtmiEGwg4GySuMUjEH\r\nA1LF86LO+ZzDQgd2oYNKmrQ8O+EcLqx9BpV4AFhEvqdk7uycJYPHs6yl+yfbzTeJ\r\n2Xd0yVAfd9r\/iDr36clLj2bzEObdl9xzKjcCIXE4Q0G4Pur41\/BJUDK9PI390ccQ\r\nnFjjVYBMsC859OwW64tMP0zkM9Vv72LCaEzaR8jqH0j11catqxunr+StfMcmxLTN\r\nbqBJbSEq4ER3mJxCTI2UrIVmdQ7+wRxgv3QTDNOZyqrz2L8A1Rpb3h0APxtQv+oA\r\n8KIZYID5\/qsS2V2jITkMQ8Nd1W3b0cZhZ600z+znh3jLJ0TYLvwN6\/qBQTUDaM2o\r\ng1+icMqXIXIeKuoPCVVsG7cCAwEAATANBgkqhkiG9w0BAQUFAAOCAgEAHc4F\/kOV\r\nHc8In5MmGg2YtjwZzjdeoC5TIPZczRqz0B+wRbJzN6aYryKZKLmP+wKpgRnJWDzp\r\nrgKGyyEQIAfK63DEv4B9p4N1B+B3aeMKsSpVcw7wbFTD57V5A7pURGoo31d0mw5L\r\nUIXZ2u+TUfGbzucMxLdFhTwjGpz9M6Kkm\/POxmV0tvLija5LdbdKnYR9BFmyu4IX\r\nqyoIAtComATNLl+3URu3SZxhE3NxhzMz+eAeNfh1KuIf2gWIIeDCXalVSJLym+OQ\r\nHFDpqRhJqfTMprrRlmmU7Zntgbj8\/RRZuXnBvH9cQ2KykLOb4UoCPlGUqOqKyP9m\r\nDJSFRiMJfpgMQUaJk1TLhKF+IR6FnmwURLEtkONJumtDQju9KaWPlhueONdyGi0p\r\nqxLVUo1Vb52XnPhk2GEEduxpDc9V5ePJ+pdcEdMifY\/uPNBRuBj2c87yq1DLH+U4\r\n3XzP1MlwjnBWZYuoFo0j6Jq0r\/MG6HjGdmkGIsRoheRi8Z8Scz5AW5QRkNz8pKop\r\nTELFqQy9g6TyQzzC8t6HZcpNe842ZUk4raEAbCZe\/XqxWMw5svPgNceBqM3fh7sZ\r\nBSykOHLaL8kiRO\/IS3y1yZEAuiWBvtxcTNLzBb+hdRpm2y8\/qH\/pKo+CMj1VzjNT\r\nD8YRQg0cjmDytJzHDrtV\/aTc9W1aPHun0vw=\r\n-----END CERTIFICATE-----" |
| 387 | 387 | }'; |
| 388 | - $this->fileAccessHelper |
|
| 389 | - ->expects($this->exactly(2)) |
|
| 390 | - ->method('file_get_contents') |
|
| 391 | - ->willReturnMap([ |
|
| 392 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 393 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 394 | - ]); |
|
| 395 | - |
|
| 396 | - $expected = [ |
|
| 397 | - 'EXCEPTION' => [ |
|
| 398 | - 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 399 | - 'message' => 'Certificate is not valid for required scope. (Requested: SomeApp, current: CN=AnotherScope)', |
|
| 400 | - ], |
|
| 401 | - ]; |
|
| 402 | - $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp')); |
|
| 403 | - } |
|
| 404 | - |
|
| 405 | - public function testVerifyAppWithDifferentScopeAndAlwaysTrustedCore(): void { |
|
| 406 | - $this->serverVersion |
|
| 407 | - ->expects($this->once()) |
|
| 408 | - ->method('getChannel') |
|
| 409 | - ->willReturn('stable'); |
|
| 410 | - $this->config |
|
| 411 | - ->expects($this->any()) |
|
| 412 | - ->method('getSystemValueBool') |
|
| 413 | - ->with('integrity.check.disabled', false) |
|
| 414 | - ->willReturn(false); |
|
| 415 | - |
|
| 416 | - $this->appLocator |
|
| 417 | - ->expects($this->once()) |
|
| 418 | - ->method('getAppPath') |
|
| 419 | - ->with('SomeApp') |
|
| 420 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 421 | - $signatureDataFile = '{ |
|
| 388 | + $this->fileAccessHelper |
|
| 389 | + ->expects($this->exactly(2)) |
|
| 390 | + ->method('file_get_contents') |
|
| 391 | + ->willReturnMap([ |
|
| 392 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 393 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 394 | + ]); |
|
| 395 | + |
|
| 396 | + $expected = [ |
|
| 397 | + 'EXCEPTION' => [ |
|
| 398 | + 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 399 | + 'message' => 'Certificate is not valid for required scope. (Requested: SomeApp, current: CN=AnotherScope)', |
|
| 400 | + ], |
|
| 401 | + ]; |
|
| 402 | + $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp')); |
|
| 403 | + } |
|
| 404 | + |
|
| 405 | + public function testVerifyAppWithDifferentScopeAndAlwaysTrustedCore(): void { |
|
| 406 | + $this->serverVersion |
|
| 407 | + ->expects($this->once()) |
|
| 408 | + ->method('getChannel') |
|
| 409 | + ->willReturn('stable'); |
|
| 410 | + $this->config |
|
| 411 | + ->expects($this->any()) |
|
| 412 | + ->method('getSystemValueBool') |
|
| 413 | + ->with('integrity.check.disabled', false) |
|
| 414 | + ->willReturn(false); |
|
| 415 | + |
|
| 416 | + $this->appLocator |
|
| 417 | + ->expects($this->once()) |
|
| 418 | + ->method('getAppPath') |
|
| 419 | + ->with('SomeApp') |
|
| 420 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 421 | + $signatureDataFile = '{ |
|
| 422 | 422 | "hashes": { |
| 423 | 423 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 424 | 424 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -426,67 +426,67 @@ discard block |
||
| 426 | 426 | "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=", |
| 427 | 427 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 428 | 428 | }'; |
| 429 | - $this->fileAccessHelper |
|
| 430 | - ->expects($this->exactly(2)) |
|
| 431 | - ->method('file_get_contents') |
|
| 432 | - ->willReturnMap([ |
|
| 433 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 434 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 435 | - ]); |
|
| 436 | - |
|
| 437 | - $this->assertSame([], $this->checker->verifyAppSignature('SomeApp')); |
|
| 438 | - } |
|
| 439 | - |
|
| 440 | - |
|
| 441 | - public function testWriteCoreSignatureWithException(): void { |
|
| 442 | - $this->expectException(\Exception::class); |
|
| 443 | - $this->expectExceptionMessage('Exception message'); |
|
| 444 | - |
|
| 445 | - $this->fileAccessHelper |
|
| 446 | - ->expects($this->once()) |
|
| 447 | - ->method('assertDirectoryExists') |
|
| 448 | - ->will($this->throwException(new \Exception('Exception message'))); |
|
| 449 | - $this->fileAccessHelper |
|
| 450 | - ->expects($this->once()) |
|
| 451 | - ->method('is_writable') |
|
| 452 | - ->with(__DIR__ . '/core') |
|
| 453 | - ->willReturn(true); |
|
| 454 | - |
|
| 455 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 456 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 457 | - $rsa = new RSA(); |
|
| 458 | - $rsa->loadKey($rsaPrivateKey); |
|
| 459 | - $x509 = new X509(); |
|
| 460 | - $x509->loadX509($keyBundle); |
|
| 461 | - $this->checker->writeCoreSignature($x509, $rsa, __DIR__); |
|
| 462 | - } |
|
| 463 | - |
|
| 464 | - |
|
| 465 | - public function testWriteCoreSignatureWrongPermissions(): void { |
|
| 466 | - $this->expectException(\Exception::class); |
|
| 467 | - $this->expectExceptionMessageMatches('/[a-zA-Z\\/_-]+ is not writable/'); |
|
| 468 | - |
|
| 469 | - $this->fileAccessHelper |
|
| 470 | - ->expects($this->once()) |
|
| 471 | - ->method('assertDirectoryExists') |
|
| 472 | - ->will($this->throwException(new \Exception('Exception message'))); |
|
| 473 | - $this->fileAccessHelper |
|
| 474 | - ->expects($this->once()) |
|
| 475 | - ->method('is_writable') |
|
| 476 | - ->with(__DIR__ . '/core') |
|
| 477 | - ->willReturn(false); |
|
| 478 | - |
|
| 479 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 480 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 481 | - $rsa = new RSA(); |
|
| 482 | - $rsa->loadKey($rsaPrivateKey); |
|
| 483 | - $x509 = new X509(); |
|
| 484 | - $x509->loadX509($keyBundle); |
|
| 485 | - $this->checker->writeCoreSignature($x509, $rsa, __DIR__); |
|
| 486 | - } |
|
| 487 | - |
|
| 488 | - public function testWriteCoreSignature(): void { |
|
| 489 | - $expectedSignatureFileData = '{ |
|
| 429 | + $this->fileAccessHelper |
|
| 430 | + ->expects($this->exactly(2)) |
|
| 431 | + ->method('file_get_contents') |
|
| 432 | + ->willReturnMap([ |
|
| 433 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 434 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 435 | + ]); |
|
| 436 | + |
|
| 437 | + $this->assertSame([], $this->checker->verifyAppSignature('SomeApp')); |
|
| 438 | + } |
|
| 439 | + |
|
| 440 | + |
|
| 441 | + public function testWriteCoreSignatureWithException(): void { |
|
| 442 | + $this->expectException(\Exception::class); |
|
| 443 | + $this->expectExceptionMessage('Exception message'); |
|
| 444 | + |
|
| 445 | + $this->fileAccessHelper |
|
| 446 | + ->expects($this->once()) |
|
| 447 | + ->method('assertDirectoryExists') |
|
| 448 | + ->will($this->throwException(new \Exception('Exception message'))); |
|
| 449 | + $this->fileAccessHelper |
|
| 450 | + ->expects($this->once()) |
|
| 451 | + ->method('is_writable') |
|
| 452 | + ->with(__DIR__ . '/core') |
|
| 453 | + ->willReturn(true); |
|
| 454 | + |
|
| 455 | + $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 456 | + $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 457 | + $rsa = new RSA(); |
|
| 458 | + $rsa->loadKey($rsaPrivateKey); |
|
| 459 | + $x509 = new X509(); |
|
| 460 | + $x509->loadX509($keyBundle); |
|
| 461 | + $this->checker->writeCoreSignature($x509, $rsa, __DIR__); |
|
| 462 | + } |
|
| 463 | + |
|
| 464 | + |
|
| 465 | + public function testWriteCoreSignatureWrongPermissions(): void { |
|
| 466 | + $this->expectException(\Exception::class); |
|
| 467 | + $this->expectExceptionMessageMatches('/[a-zA-Z\\/_-]+ is not writable/'); |
|
| 468 | + |
|
| 469 | + $this->fileAccessHelper |
|
| 470 | + ->expects($this->once()) |
|
| 471 | + ->method('assertDirectoryExists') |
|
| 472 | + ->will($this->throwException(new \Exception('Exception message'))); |
|
| 473 | + $this->fileAccessHelper |
|
| 474 | + ->expects($this->once()) |
|
| 475 | + ->method('is_writable') |
|
| 476 | + ->with(__DIR__ . '/core') |
|
| 477 | + ->willReturn(false); |
|
| 478 | + |
|
| 479 | + $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 480 | + $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 481 | + $rsa = new RSA(); |
|
| 482 | + $rsa->loadKey($rsaPrivateKey); |
|
| 483 | + $x509 = new X509(); |
|
| 484 | + $x509->loadX509($keyBundle); |
|
| 485 | + $this->checker->writeCoreSignature($x509, $rsa, __DIR__); |
|
| 486 | + } |
|
| 487 | + |
|
| 488 | + public function testWriteCoreSignature(): void { |
|
| 489 | + $expectedSignatureFileData = '{ |
|
| 490 | 490 | "hashes": { |
| 491 | 491 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 492 | 492 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -494,34 +494,34 @@ discard block |
||
| 494 | 494 | "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=", |
| 495 | 495 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 496 | 496 | }'; |
| 497 | - $this->environmentHelper |
|
| 498 | - ->expects($this->any()) |
|
| 499 | - ->method('getServerRoot') |
|
| 500 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 501 | - $this->fileAccessHelper |
|
| 502 | - ->expects($this->once()) |
|
| 503 | - ->method('file_put_contents') |
|
| 504 | - ->with( |
|
| 505 | - \OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', |
|
| 506 | - $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 507 | - $expectedArray = json_decode($expectedSignatureFileData, true); |
|
| 508 | - $actualArray = json_decode($signature, true); |
|
| 509 | - $this->assertEquals($expectedArray, $actualArray); |
|
| 510 | - return true; |
|
| 511 | - }) |
|
| 512 | - ); |
|
| 513 | - |
|
| 514 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 515 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 516 | - $rsa = new RSA(); |
|
| 517 | - $rsa->loadKey($rsaPrivateKey); |
|
| 518 | - $x509 = new X509(); |
|
| 519 | - $x509->loadX509($keyBundle); |
|
| 520 | - $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 521 | - } |
|
| 522 | - |
|
| 523 | - public function testWriteCoreSignatureWithUnmodifiedHtaccess(): void { |
|
| 524 | - $expectedSignatureFileData = '{ |
|
| 497 | + $this->environmentHelper |
|
| 498 | + ->expects($this->any()) |
|
| 499 | + ->method('getServerRoot') |
|
| 500 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 501 | + $this->fileAccessHelper |
|
| 502 | + ->expects($this->once()) |
|
| 503 | + ->method('file_put_contents') |
|
| 504 | + ->with( |
|
| 505 | + \OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', |
|
| 506 | + $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 507 | + $expectedArray = json_decode($expectedSignatureFileData, true); |
|
| 508 | + $actualArray = json_decode($signature, true); |
|
| 509 | + $this->assertEquals($expectedArray, $actualArray); |
|
| 510 | + return true; |
|
| 511 | + }) |
|
| 512 | + ); |
|
| 513 | + |
|
| 514 | + $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 515 | + $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 516 | + $rsa = new RSA(); |
|
| 517 | + $rsa->loadKey($rsaPrivateKey); |
|
| 518 | + $x509 = new X509(); |
|
| 519 | + $x509->loadX509($keyBundle); |
|
| 520 | + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 521 | + } |
|
| 522 | + |
|
| 523 | + public function testWriteCoreSignatureWithUnmodifiedHtaccess(): void { |
|
| 524 | + $expectedSignatureFileData = '{ |
|
| 525 | 525 | "hashes": { |
| 526 | 526 | ".htaccess": "dc479770a6232061e04a768ee1f9133fdb3aea7b3a99f7105b0e0b6197474733e8d14b5b2bbad054e6b62a410fe5d0b3d790242dee1e0f11274af2100f5289e2", |
| 527 | 527 | "subfolder\/.htaccess": "2c57b1e25050e11dc3ae975832f378c452159f7b69f818e47eeeafadd6ba568517461dcb4d843b90b906cd7c89d161bc1b89dff8e3ae0eb6f5088508c47befd1" |
@@ -529,64 +529,64 @@ discard block |
||
| 529 | 529 | "signature": "nRtR377DB\/I\/4hmh9q3elMQYfSHnQFlNtjchNgrdfmUQqVmgkU\/4qgGyxDqYkV8mSMbH2gYysfP42nx\/3zSo7n0dBYDfU87Q6f96Cv597vEV27do8CaBkEk8Xjn2SxhHw8hVxracvE2OBAPxk0H3sRp\/cQBgjoXpju4kQin0N5E+DEJMh7Sp+u8aKoFpb+2FaAZJFn\/hnqxLTlVi2nyDxGL3U0eobWY+jWH9XPt52v3Hyh8TDhcAnQ1cN30B8Jn2+jkrm8ib+buchaCXHk0cPX72xuPECdwOEKLCBNrJa3FGSvO1zWiecnCgxCXgt+R8hUgsVPTsbrdFY2YRJGIhHndYZL98XzgG7cw85SnnMMe2SulzeL7xANGF8qiEVyiC7x83bbj5xOkeM\/CUTajrLBO3vyZ23KKOxvskjgI0t+Zw1zFsl+sYW0\/O\/V5WzPOwMwV8+iApQ8k9gEMiYQg98QLEMYnSohncmp0Z9qx2qFcQuHLcKJVa1J6wGtE\/EHR\/4d0aYPd6IRjg+qshCJmdzud\/12xjpGTl+BT0Hi0VsU5o7ZMi7WhmukZmmv8u0uZsvKREQNATm4cO4WCkYySt5O9gZEJOF+jjgeynDoAh09lyrNXIgMpM9ufm\/XEG\/I\/f2zIwbAUc6J6qks5OuYlJzW5vscTiOKhwcGZU9WBLgh0=", |
| 530 | 530 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 531 | 531 | }'; |
| 532 | - $this->environmentHelper |
|
| 533 | - ->expects($this->any()) |
|
| 534 | - ->method('getServerRoot') |
|
| 535 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/'); |
|
| 536 | - $this->fileAccessHelper |
|
| 537 | - ->expects($this->once()) |
|
| 538 | - ->method('file_put_contents') |
|
| 539 | - ->with( |
|
| 540 | - \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified//core/signature.json', |
|
| 541 | - $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 542 | - $expectedArray = json_decode($expectedSignatureFileData, true); |
|
| 543 | - $actualArray = json_decode($signature, true); |
|
| 544 | - $this->assertEquals($expectedArray, $actualArray); |
|
| 545 | - return true; |
|
| 546 | - }) |
|
| 547 | - ); |
|
| 548 | - |
|
| 549 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 550 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 551 | - $rsa = new RSA(); |
|
| 552 | - $rsa->loadKey($rsaPrivateKey); |
|
| 553 | - $x509 = new X509(); |
|
| 554 | - $x509->loadX509($keyBundle); |
|
| 555 | - $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/'); |
|
| 556 | - } |
|
| 557 | - |
|
| 558 | - public function testWriteCoreSignatureWithInvalidModifiedHtaccess(): void { |
|
| 559 | - $expectedSignatureFileData = '{ |
|
| 532 | + $this->environmentHelper |
|
| 533 | + ->expects($this->any()) |
|
| 534 | + ->method('getServerRoot') |
|
| 535 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/'); |
|
| 536 | + $this->fileAccessHelper |
|
| 537 | + ->expects($this->once()) |
|
| 538 | + ->method('file_put_contents') |
|
| 539 | + ->with( |
|
| 540 | + \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified//core/signature.json', |
|
| 541 | + $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 542 | + $expectedArray = json_decode($expectedSignatureFileData, true); |
|
| 543 | + $actualArray = json_decode($signature, true); |
|
| 544 | + $this->assertEquals($expectedArray, $actualArray); |
|
| 545 | + return true; |
|
| 546 | + }) |
|
| 547 | + ); |
|
| 548 | + |
|
| 549 | + $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 550 | + $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 551 | + $rsa = new RSA(); |
|
| 552 | + $rsa->loadKey($rsaPrivateKey); |
|
| 553 | + $x509 = new X509(); |
|
| 554 | + $x509->loadX509($keyBundle); |
|
| 555 | + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/'); |
|
| 556 | + } |
|
| 557 | + |
|
| 558 | + public function testWriteCoreSignatureWithInvalidModifiedHtaccess(): void { |
|
| 559 | + $expectedSignatureFileData = '{ |
|
| 560 | 560 | "hashes": { |
| 561 | 561 | ".htaccess": "4a54273dc8d697b2ca615acf2ae2c1ee3c1c643492cb04f42b10984fa9aacff1420dc829fd82f93ad3476fbd0cdab0251142c887dc8f872d03e39a3a3eb6d381" |
| 562 | 562 | }, |
| 563 | 563 | "signature": "qpDddYGgAKNR3TszOgjPXRphUl2P9Ym5OQaetltocgZASGDkOun5D64+1D0QJRKb4SG2+48muxGOHyL2Ngos4NUrrSR+SIkywZacay82YQBCEdr7\/4MjW1WHRPjvboLwEJwViw0EdAjsWRpD68aPnzUGrGsy2BsCo06P5iwjk9cXcHxdjC9R39npvoC3QNvQ2jmNIbh1Lc4U97dbb+CsXEQCLU1OSa9p3q6cEFV98Easwt7uF\/DzHK+CbeZlxVZ0DwLh2\/ylT1PyGou8QC1b3vKAnPjLWMO+UsCPpCKhk3C5pV+5etQ8puGd+0x2t5tEU+qXxLzek91zWNC+rqgC\/WlqLKbwPb\/BCHs4zLGV55Q2fEQmT21x0KCUELdPs4dBnYP4Ox5tEDugtJujWFzOHzoY6gGa\/BY\/78pSZXmq9o8dWkBEtioWWvaNZ1rM0ddE83GBlBTgjigi9Ay1D++bUW\/FCBB7CMk6qyNlV81H+cBuIEODw2aymmkM9LLDD2Qbmvo8gHEPRjiQxPC5OpDlcdSNiL+zcxVxeuX4FpT+9xzz\/\/DRONhufxRpsbuCOMxd96RW7y9U2N2Uxb3Bzn\/BIqEayUUsdgZjfaGcXXYKR+chu\/LOwNYN6RlnLsgqL\/dhGKwlRVKXw1RA2\/af\/CpqyR7uVP6al1YJo\/YJ+5XJ6zE=", |
| 564 | 564 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 565 | 565 | }'; |
| 566 | - $this->fileAccessHelper |
|
| 567 | - ->expects($this->once()) |
|
| 568 | - ->method('file_put_contents') |
|
| 569 | - ->with( |
|
| 570 | - \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent//core/signature.json', |
|
| 571 | - $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 572 | - $expectedArray = json_decode($expectedSignatureFileData, true); |
|
| 573 | - $actualArray = json_decode($signature, true); |
|
| 574 | - $this->assertEquals($expectedArray, $actualArray); |
|
| 575 | - return true; |
|
| 576 | - }) |
|
| 577 | - ); |
|
| 578 | - |
|
| 579 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 580 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 581 | - $rsa = new RSA(); |
|
| 582 | - $rsa->loadKey($rsaPrivateKey); |
|
| 583 | - $x509 = new X509(); |
|
| 584 | - $x509->loadX509($keyBundle); |
|
| 585 | - $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent/'); |
|
| 586 | - } |
|
| 587 | - |
|
| 588 | - public function testWriteCoreSignatureWithValidModifiedHtaccess(): void { |
|
| 589 | - $expectedSignatureFileData = '{ |
|
| 566 | + $this->fileAccessHelper |
|
| 567 | + ->expects($this->once()) |
|
| 568 | + ->method('file_put_contents') |
|
| 569 | + ->with( |
|
| 570 | + \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent//core/signature.json', |
|
| 571 | + $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 572 | + $expectedArray = json_decode($expectedSignatureFileData, true); |
|
| 573 | + $actualArray = json_decode($signature, true); |
|
| 574 | + $this->assertEquals($expectedArray, $actualArray); |
|
| 575 | + return true; |
|
| 576 | + }) |
|
| 577 | + ); |
|
| 578 | + |
|
| 579 | + $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 580 | + $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 581 | + $rsa = new RSA(); |
|
| 582 | + $rsa->loadKey($rsaPrivateKey); |
|
| 583 | + $x509 = new X509(); |
|
| 584 | + $x509->loadX509($keyBundle); |
|
| 585 | + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent/'); |
|
| 586 | + } |
|
| 587 | + |
|
| 588 | + public function testWriteCoreSignatureWithValidModifiedHtaccess(): void { |
|
| 589 | + $expectedSignatureFileData = '{ |
|
| 590 | 590 | "hashes": { |
| 591 | 591 | ".htaccess": "7e6a7a4d8ee4f3fbc45dd579407c643471575a9d127d1c75f6d0a49e80766c3c587104b2139ef76d2a4bffce3f45777900605aaa49519c9532909b71e5030227", |
| 592 | 592 | "subfolder\/.htaccess": "2c57b1e25050e11dc3ae975832f378c452159f7b69f818e47eeeafadd6ba568517461dcb4d843b90b906cd7c89d161bc1b89dff8e3ae0eb6f5088508c47befd1" |
@@ -594,68 +594,68 @@ discard block |
||
| 594 | 594 | "signature": "YVwQvl9Dh8UebCumfgzFxfz3NiZJLmYG8oJVTfEBhulI4KXBnTG1jZTprf4XxG2XIriEYAZXsoXpu9xWsUFe9QfdncwoEpqJtGq7l6aVDTofX5Be5b03MQFJr4cflgllqW77QZ84D9O9qWF\/vNDAofXcwrzT04CxLDhyQgTCgYUnRjG9pnuP\/gtbDKbTjRvxhTyfg3T0Phv1+XAvpTPnH2q5A+1+LmiqziUJ1sMipsKo+jQP614eCi9qjmqhHIgLRgcuOBvsi4g5WUcdcAIZ6qLt5gm2Y3r6rKNVchosU9ZydMUTfjuejDbVwE2fNH5UUnV57fQBxwg9CfX7iFHqKv1bfv5Zviu12paShgWCB12uR3iH\/3lmTJn8K5Xqit3G4eymFaJ5IChdUThBp\/jhQSI2r8sPcZDYSJ\/UZKuFnezFdKhEBd5hMXe8aKAd6ijGDjLARksFuqpi1sS8llC5K1Q+DzktSL\/o64TY4Vuvykiwe\/BAk2SkL9voOtrvU7vfDBcuCPbDJnSBBC0ESpcXeClTBIn6xZ9WaxqoS7sinE\/kUwtWsRd04I7d79\/ouotyNb+mBhTuRsZT12p\/gn4JHXXNUAIpTwchYzGxbfNJ4kxnYBFZWVmvsSqOLFZu1yi5BP3ktA9yhFyWIa5659azRFEKRdXpVHtQVa4IgdhxEqA=", |
| 595 | 595 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 596 | 596 | }'; |
| 597 | - $this->environmentHelper |
|
| 598 | - ->expects($this->any()) |
|
| 599 | - ->method('getServerRoot') |
|
| 600 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 601 | - $this->fileAccessHelper |
|
| 602 | - ->expects($this->once()) |
|
| 603 | - ->method('file_put_contents') |
|
| 604 | - ->with( |
|
| 605 | - \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', |
|
| 606 | - $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 607 | - $expectedArray = json_decode($expectedSignatureFileData, true); |
|
| 608 | - $actualArray = json_decode($signature, true); |
|
| 609 | - $this->assertEquals($expectedArray, $actualArray); |
|
| 610 | - return true; |
|
| 611 | - }) |
|
| 612 | - ); |
|
| 613 | - |
|
| 614 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 615 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 616 | - $rsa = new RSA(); |
|
| 617 | - $rsa->loadKey($rsaPrivateKey); |
|
| 618 | - $x509 = new X509(); |
|
| 619 | - $x509->loadX509($keyBundle); |
|
| 620 | - $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 621 | - } |
|
| 622 | - |
|
| 623 | - public function testVerifyCoreSignatureWithoutSignatureData(): void { |
|
| 624 | - $this->serverVersion |
|
| 625 | - ->expects($this->once()) |
|
| 626 | - ->method('getChannel') |
|
| 627 | - ->willReturn('stable'); |
|
| 628 | - $this->config |
|
| 629 | - ->expects($this->any()) |
|
| 630 | - ->method('getSystemValueBool') |
|
| 631 | - ->with('integrity.check.disabled', false) |
|
| 632 | - ->willReturn(false); |
|
| 633 | - |
|
| 634 | - $expected = [ |
|
| 635 | - 'EXCEPTION' => [ |
|
| 636 | - 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 637 | - 'message' => 'Signature data not found.', |
|
| 638 | - ], |
|
| 639 | - ]; |
|
| 640 | - $this->assertSame($expected, $this->checker->verifyCoreSignature()); |
|
| 641 | - } |
|
| 642 | - |
|
| 643 | - public function testVerifyCoreSignatureWithValidSignatureData(): void { |
|
| 644 | - $this->serverVersion |
|
| 645 | - ->expects($this->once()) |
|
| 646 | - ->method('getChannel') |
|
| 647 | - ->willReturn('stable'); |
|
| 648 | - $this->config |
|
| 649 | - ->expects($this->any()) |
|
| 650 | - ->method('getSystemValueBool') |
|
| 651 | - ->with('integrity.check.disabled', false) |
|
| 652 | - ->willReturn(false); |
|
| 653 | - |
|
| 654 | - $this->environmentHelper |
|
| 655 | - ->expects($this->any()) |
|
| 656 | - ->method('getServerRoot') |
|
| 657 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 658 | - $signatureDataFile = '{ |
|
| 597 | + $this->environmentHelper |
|
| 598 | + ->expects($this->any()) |
|
| 599 | + ->method('getServerRoot') |
|
| 600 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 601 | + $this->fileAccessHelper |
|
| 602 | + ->expects($this->once()) |
|
| 603 | + ->method('file_put_contents') |
|
| 604 | + ->with( |
|
| 605 | + \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', |
|
| 606 | + $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 607 | + $expectedArray = json_decode($expectedSignatureFileData, true); |
|
| 608 | + $actualArray = json_decode($signature, true); |
|
| 609 | + $this->assertEquals($expectedArray, $actualArray); |
|
| 610 | + return true; |
|
| 611 | + }) |
|
| 612 | + ); |
|
| 613 | + |
|
| 614 | + $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 615 | + $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 616 | + $rsa = new RSA(); |
|
| 617 | + $rsa->loadKey($rsaPrivateKey); |
|
| 618 | + $x509 = new X509(); |
|
| 619 | + $x509->loadX509($keyBundle); |
|
| 620 | + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 621 | + } |
|
| 622 | + |
|
| 623 | + public function testVerifyCoreSignatureWithoutSignatureData(): void { |
|
| 624 | + $this->serverVersion |
|
| 625 | + ->expects($this->once()) |
|
| 626 | + ->method('getChannel') |
|
| 627 | + ->willReturn('stable'); |
|
| 628 | + $this->config |
|
| 629 | + ->expects($this->any()) |
|
| 630 | + ->method('getSystemValueBool') |
|
| 631 | + ->with('integrity.check.disabled', false) |
|
| 632 | + ->willReturn(false); |
|
| 633 | + |
|
| 634 | + $expected = [ |
|
| 635 | + 'EXCEPTION' => [ |
|
| 636 | + 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 637 | + 'message' => 'Signature data not found.', |
|
| 638 | + ], |
|
| 639 | + ]; |
|
| 640 | + $this->assertSame($expected, $this->checker->verifyCoreSignature()); |
|
| 641 | + } |
|
| 642 | + |
|
| 643 | + public function testVerifyCoreSignatureWithValidSignatureData(): void { |
|
| 644 | + $this->serverVersion |
|
| 645 | + ->expects($this->once()) |
|
| 646 | + ->method('getChannel') |
|
| 647 | + ->willReturn('stable'); |
|
| 648 | + $this->config |
|
| 649 | + ->expects($this->any()) |
|
| 650 | + ->method('getSystemValueBool') |
|
| 651 | + ->with('integrity.check.disabled', false) |
|
| 652 | + ->willReturn(false); |
|
| 653 | + |
|
| 654 | + $this->environmentHelper |
|
| 655 | + ->expects($this->any()) |
|
| 656 | + ->method('getServerRoot') |
|
| 657 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 658 | + $signatureDataFile = '{ |
|
| 659 | 659 | "hashes": { |
| 660 | 660 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 661 | 661 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -663,33 +663,33 @@ discard block |
||
| 663 | 663 | "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=", |
| 664 | 664 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 665 | 665 | }'; |
| 666 | - $this->fileAccessHelper |
|
| 667 | - ->expects($this->exactly(2)) |
|
| 668 | - ->method('file_get_contents') |
|
| 669 | - ->willReturnMap([ |
|
| 670 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 671 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 672 | - ]); |
|
| 673 | - |
|
| 674 | - $this->assertSame([], $this->checker->verifyCoreSignature()); |
|
| 675 | - } |
|
| 676 | - |
|
| 677 | - public function testVerifyCoreSignatureWithValidModifiedHtaccessSignatureData(): void { |
|
| 678 | - $this->serverVersion |
|
| 679 | - ->expects($this->once()) |
|
| 680 | - ->method('getChannel') |
|
| 681 | - ->willReturn('stable'); |
|
| 682 | - $this->config |
|
| 683 | - ->expects($this->any()) |
|
| 684 | - ->method('getSystemValueBool') |
|
| 685 | - ->with('integrity.check.disabled', false) |
|
| 686 | - ->willReturn(false); |
|
| 687 | - |
|
| 688 | - $this->environmentHelper |
|
| 689 | - ->expects($this->any()) |
|
| 690 | - ->method('getServerRoot') |
|
| 691 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 692 | - $signatureDataFile = '{ |
|
| 666 | + $this->fileAccessHelper |
|
| 667 | + ->expects($this->exactly(2)) |
|
| 668 | + ->method('file_get_contents') |
|
| 669 | + ->willReturnMap([ |
|
| 670 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 671 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 672 | + ]); |
|
| 673 | + |
|
| 674 | + $this->assertSame([], $this->checker->verifyCoreSignature()); |
|
| 675 | + } |
|
| 676 | + |
|
| 677 | + public function testVerifyCoreSignatureWithValidModifiedHtaccessSignatureData(): void { |
|
| 678 | + $this->serverVersion |
|
| 679 | + ->expects($this->once()) |
|
| 680 | + ->method('getChannel') |
|
| 681 | + ->willReturn('stable'); |
|
| 682 | + $this->config |
|
| 683 | + ->expects($this->any()) |
|
| 684 | + ->method('getSystemValueBool') |
|
| 685 | + ->with('integrity.check.disabled', false) |
|
| 686 | + ->willReturn(false); |
|
| 687 | + |
|
| 688 | + $this->environmentHelper |
|
| 689 | + ->expects($this->any()) |
|
| 690 | + ->method('getServerRoot') |
|
| 691 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 692 | + $signatureDataFile = '{ |
|
| 693 | 693 | "hashes": { |
| 694 | 694 | ".htaccess": "7e6a7a4d8ee4f3fbc45dd579407c643471575a9d127d1c75f6d0a49e80766c3c587104b2139ef76d2a4bffce3f45777900605aaa49519c9532909b71e5030227", |
| 695 | 695 | "subfolder\/.htaccess": "2c57b1e25050e11dc3ae975832f378c452159f7b69f818e47eeeafadd6ba568517461dcb4d843b90b906cd7c89d161bc1b89dff8e3ae0eb6f5088508c47befd1" |
@@ -697,85 +697,85 @@ discard block |
||
| 697 | 697 | "signature": "YVwQvl9Dh8UebCumfgzFxfz3NiZJLmYG8oJVTfEBhulI4KXBnTG1jZTprf4XxG2XIriEYAZXsoXpu9xWsUFe9QfdncwoEpqJtGq7l6aVDTofX5Be5b03MQFJr4cflgllqW77QZ84D9O9qWF\/vNDAofXcwrzT04CxLDhyQgTCgYUnRjG9pnuP\/gtbDKbTjRvxhTyfg3T0Phv1+XAvpTPnH2q5A+1+LmiqziUJ1sMipsKo+jQP614eCi9qjmqhHIgLRgcuOBvsi4g5WUcdcAIZ6qLt5gm2Y3r6rKNVchosU9ZydMUTfjuejDbVwE2fNH5UUnV57fQBxwg9CfX7iFHqKv1bfv5Zviu12paShgWCB12uR3iH\/3lmTJn8K5Xqit3G4eymFaJ5IChdUThBp\/jhQSI2r8sPcZDYSJ\/UZKuFnezFdKhEBd5hMXe8aKAd6ijGDjLARksFuqpi1sS8llC5K1Q+DzktSL\/o64TY4Vuvykiwe\/BAk2SkL9voOtrvU7vfDBcuCPbDJnSBBC0ESpcXeClTBIn6xZ9WaxqoS7sinE\/kUwtWsRd04I7d79\/ouotyNb+mBhTuRsZT12p\/gn4JHXXNUAIpTwchYzGxbfNJ4kxnYBFZWVmvsSqOLFZu1yi5BP3ktA9yhFyWIa5659azRFEKRdXpVHtQVa4IgdhxEqA=", |
| 698 | 698 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 699 | 699 | }'; |
| 700 | - $this->fileAccessHelper |
|
| 701 | - ->expects($this->exactly(2)) |
|
| 702 | - ->method('file_get_contents') |
|
| 703 | - ->willReturnMap([ |
|
| 704 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', $signatureDataFile], |
|
| 705 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 706 | - ]); |
|
| 707 | - |
|
| 708 | - $this->assertSame([], $this->checker->verifyCoreSignature()); |
|
| 709 | - } |
|
| 710 | - |
|
| 711 | - /** |
|
| 712 | - * See inline instruction on how to update the test assets when changing mimetypealiases.dist.json |
|
| 713 | - */ |
|
| 714 | - public function testVerifyCoreSignatureWithModifiedMimetypelistSignatureData(): void { |
|
| 715 | - $shippedMimetypeAliases = (array)json_decode(file_get_contents(\OC::$SERVERROOT . '/resources/config/mimetypealiases.dist.json')); |
|
| 716 | - $allAliases = array_merge($shippedMimetypeAliases, ['my-custom/mimetype' => 'custom']); |
|
| 717 | - |
|
| 718 | - $this->mimeTypeDetector |
|
| 719 | - ->method('getOnlyDefaultAliases') |
|
| 720 | - ->willReturn($shippedMimetypeAliases); |
|
| 721 | - |
|
| 722 | - $this->mimeTypeDetector |
|
| 723 | - ->method('getAllAliases') |
|
| 724 | - ->willReturn($allAliases); |
|
| 725 | - |
|
| 726 | - $oldMimetypeList = new GenerateMimetypeFileBuilder(); |
|
| 727 | - $all = $this->mimeTypeDetector->getAllAliases(); |
|
| 728 | - $newFile = $oldMimetypeList->generateFile($all); |
|
| 729 | - |
|
| 730 | - // When updating the mimetype list the test assets need to be updated as well |
|
| 731 | - // 1. Update core/js/mimetypelist.js with the new generated js by running the test with the next line uncommented: |
|
| 732 | - // file_put_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js', $newFile); |
|
| 733 | - // 2. Update signature.json using the following occ command: |
|
| 734 | - // occ integrity:sign-core --privateKey=./tests/data/integritycheck/core.key --certificate=./tests/data/integritycheck/core.crt --path=./tests/data/integritycheck/mimetypeListModified |
|
| 735 | - self::assertEquals($newFile, file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js')); |
|
| 736 | - |
|
| 737 | - $this->serverVersion |
|
| 738 | - ->expects($this->once()) |
|
| 739 | - ->method('getChannel') |
|
| 740 | - ->willReturn('stable'); |
|
| 741 | - $this->config |
|
| 742 | - ->expects($this->any()) |
|
| 743 | - ->method('getSystemValueBool') |
|
| 744 | - ->with('integrity.check.disabled', false) |
|
| 745 | - ->willReturn(false); |
|
| 746 | - |
|
| 747 | - $this->environmentHelper |
|
| 748 | - ->expects($this->any()) |
|
| 749 | - ->method('getServerRoot') |
|
| 750 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified'); |
|
| 751 | - |
|
| 752 | - $signatureDataFile = file_get_contents(__DIR__ . '/../../data/integritycheck/mimetypeListModified/core/signature.json'); |
|
| 753 | - $this->fileAccessHelper |
|
| 754 | - ->method('file_get_contents') |
|
| 755 | - ->willReturnMap([ |
|
| 756 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/signature.json', $signatureDataFile], |
|
| 757 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 758 | - ]); |
|
| 759 | - |
|
| 760 | - $this->assertSame([], $this->checker->verifyCoreSignature()); |
|
| 761 | - } |
|
| 762 | - |
|
| 763 | - public function testVerifyCoreSignatureWithValidSignatureDataAndNotAlphabeticOrder(): void { |
|
| 764 | - $this->serverVersion |
|
| 765 | - ->expects($this->once()) |
|
| 766 | - ->method('getChannel') |
|
| 767 | - ->willReturn('stable'); |
|
| 768 | - $this->config |
|
| 769 | - ->expects($this->any()) |
|
| 770 | - ->method('getSystemValueBool') |
|
| 771 | - ->with('integrity.check.disabled', false) |
|
| 772 | - ->willReturn(false); |
|
| 773 | - |
|
| 774 | - $this->environmentHelper |
|
| 775 | - ->expects($this->any()) |
|
| 776 | - ->method('getServerRoot') |
|
| 777 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 778 | - $signatureDataFile = '{ |
|
| 700 | + $this->fileAccessHelper |
|
| 701 | + ->expects($this->exactly(2)) |
|
| 702 | + ->method('file_get_contents') |
|
| 703 | + ->willReturnMap([ |
|
| 704 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', $signatureDataFile], |
|
| 705 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 706 | + ]); |
|
| 707 | + |
|
| 708 | + $this->assertSame([], $this->checker->verifyCoreSignature()); |
|
| 709 | + } |
|
| 710 | + |
|
| 711 | + /** |
|
| 712 | + * See inline instruction on how to update the test assets when changing mimetypealiases.dist.json |
|
| 713 | + */ |
|
| 714 | + public function testVerifyCoreSignatureWithModifiedMimetypelistSignatureData(): void { |
|
| 715 | + $shippedMimetypeAliases = (array)json_decode(file_get_contents(\OC::$SERVERROOT . '/resources/config/mimetypealiases.dist.json')); |
|
| 716 | + $allAliases = array_merge($shippedMimetypeAliases, ['my-custom/mimetype' => 'custom']); |
|
| 717 | + |
|
| 718 | + $this->mimeTypeDetector |
|
| 719 | + ->method('getOnlyDefaultAliases') |
|
| 720 | + ->willReturn($shippedMimetypeAliases); |
|
| 721 | + |
|
| 722 | + $this->mimeTypeDetector |
|
| 723 | + ->method('getAllAliases') |
|
| 724 | + ->willReturn($allAliases); |
|
| 725 | + |
|
| 726 | + $oldMimetypeList = new GenerateMimetypeFileBuilder(); |
|
| 727 | + $all = $this->mimeTypeDetector->getAllAliases(); |
|
| 728 | + $newFile = $oldMimetypeList->generateFile($all); |
|
| 729 | + |
|
| 730 | + // When updating the mimetype list the test assets need to be updated as well |
|
| 731 | + // 1. Update core/js/mimetypelist.js with the new generated js by running the test with the next line uncommented: |
|
| 732 | + // file_put_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js', $newFile); |
|
| 733 | + // 2. Update signature.json using the following occ command: |
|
| 734 | + // occ integrity:sign-core --privateKey=./tests/data/integritycheck/core.key --certificate=./tests/data/integritycheck/core.crt --path=./tests/data/integritycheck/mimetypeListModified |
|
| 735 | + self::assertEquals($newFile, file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js')); |
|
| 736 | + |
|
| 737 | + $this->serverVersion |
|
| 738 | + ->expects($this->once()) |
|
| 739 | + ->method('getChannel') |
|
| 740 | + ->willReturn('stable'); |
|
| 741 | + $this->config |
|
| 742 | + ->expects($this->any()) |
|
| 743 | + ->method('getSystemValueBool') |
|
| 744 | + ->with('integrity.check.disabled', false) |
|
| 745 | + ->willReturn(false); |
|
| 746 | + |
|
| 747 | + $this->environmentHelper |
|
| 748 | + ->expects($this->any()) |
|
| 749 | + ->method('getServerRoot') |
|
| 750 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified'); |
|
| 751 | + |
|
| 752 | + $signatureDataFile = file_get_contents(__DIR__ . '/../../data/integritycheck/mimetypeListModified/core/signature.json'); |
|
| 753 | + $this->fileAccessHelper |
|
| 754 | + ->method('file_get_contents') |
|
| 755 | + ->willReturnMap([ |
|
| 756 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/signature.json', $signatureDataFile], |
|
| 757 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 758 | + ]); |
|
| 759 | + |
|
| 760 | + $this->assertSame([], $this->checker->verifyCoreSignature()); |
|
| 761 | + } |
|
| 762 | + |
|
| 763 | + public function testVerifyCoreSignatureWithValidSignatureDataAndNotAlphabeticOrder(): void { |
|
| 764 | + $this->serverVersion |
|
| 765 | + ->expects($this->once()) |
|
| 766 | + ->method('getChannel') |
|
| 767 | + ->willReturn('stable'); |
|
| 768 | + $this->config |
|
| 769 | + ->expects($this->any()) |
|
| 770 | + ->method('getSystemValueBool') |
|
| 771 | + ->with('integrity.check.disabled', false) |
|
| 772 | + ->willReturn(false); |
|
| 773 | + |
|
| 774 | + $this->environmentHelper |
|
| 775 | + ->expects($this->any()) |
|
| 776 | + ->method('getServerRoot') |
|
| 777 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 778 | + $signatureDataFile = '{ |
|
| 779 | 779 | "hashes": { |
| 780 | 780 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 781 | 781 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -783,33 +783,33 @@ discard block |
||
| 783 | 783 | "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=", |
| 784 | 784 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 785 | 785 | }'; |
| 786 | - $this->fileAccessHelper |
|
| 787 | - ->expects($this->exactly(2)) |
|
| 788 | - ->method('file_get_contents') |
|
| 789 | - ->willReturnMap([ |
|
| 790 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 791 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 792 | - ]); |
|
| 793 | - |
|
| 794 | - $this->assertSame([], $this->checker->verifyCoreSignature()); |
|
| 795 | - } |
|
| 796 | - |
|
| 797 | - public function testVerifyCoreSignatureWithTamperedSignatureData(): void { |
|
| 798 | - $this->serverVersion |
|
| 799 | - ->expects($this->once()) |
|
| 800 | - ->method('getChannel') |
|
| 801 | - ->willReturn('stable'); |
|
| 802 | - $this->config |
|
| 803 | - ->expects($this->any()) |
|
| 804 | - ->method('getSystemValueBool') |
|
| 805 | - ->with('integrity.check.disabled', false) |
|
| 806 | - ->willReturn(false); |
|
| 807 | - |
|
| 808 | - $this->environmentHelper |
|
| 809 | - ->expects($this->any()) |
|
| 810 | - ->method('getServerRoot') |
|
| 811 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 812 | - $signatureDataFile = '{ |
|
| 786 | + $this->fileAccessHelper |
|
| 787 | + ->expects($this->exactly(2)) |
|
| 788 | + ->method('file_get_contents') |
|
| 789 | + ->willReturnMap([ |
|
| 790 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 791 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 792 | + ]); |
|
| 793 | + |
|
| 794 | + $this->assertSame([], $this->checker->verifyCoreSignature()); |
|
| 795 | + } |
|
| 796 | + |
|
| 797 | + public function testVerifyCoreSignatureWithTamperedSignatureData(): void { |
|
| 798 | + $this->serverVersion |
|
| 799 | + ->expects($this->once()) |
|
| 800 | + ->method('getChannel') |
|
| 801 | + ->willReturn('stable'); |
|
| 802 | + $this->config |
|
| 803 | + ->expects($this->any()) |
|
| 804 | + ->method('getSystemValueBool') |
|
| 805 | + ->with('integrity.check.disabled', false) |
|
| 806 | + ->willReturn(false); |
|
| 807 | + |
|
| 808 | + $this->environmentHelper |
|
| 809 | + ->expects($this->any()) |
|
| 810 | + ->method('getServerRoot') |
|
| 811 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 812 | + $signatureDataFile = '{ |
|
| 813 | 813 | "hashes": { |
| 814 | 814 | "AnotherFile.txt": "tampered", |
| 815 | 815 | "subfolder\/file.txt": "tampered" |
@@ -817,39 +817,39 @@ discard block |
||
| 817 | 817 | "signature": "eXesvDm3pkek12xSwMG10y9suRES79Nye3jYNe5KYq1tTUPqRRNgxmMGAfcUro0zpLeAr2YgHeSMWtglblGOW7pmwGVPZ0O1Y4r1fE6jnep0kW+35PLIaqCorIOnCAtSzDNKBhwd1ow3zW2wC0DFouuEkIO8u5Fw28g8E8dp8zEk1xMblNPy+xtWkmYHrVJ\/dQgun1bYOF2ZFtAzatwndTI\/bGsy1i3Wsl+x6HyWKQdq8y8VObtOqKDH7uERBEpB9DHVyKflj1v1gQuEH6BhaRdATc7ee0MiQdGblraIySwYRdfo2d8i82OVKrenMB3SLwyCvDPyQ9iKpTOnSF52ZBqaqSXKM2N\/RAkweeBFQQCwcHhqxvB0cfbyHcbkOLeCZe\/tsh68IxwTiYgzvLfl7sOZ5arnZbzrPpZmB+hfV2omkoJ1tDwOWz9hEmLLNtfo2OxyUH1m0+XFaC+Gbn4WkVDgf7YZkwUcG+Qoa3oKDNMss8MEyZxewl2iDGZcf402dlidHRprlfmXbAYuVQ08\/a0HxIKYPGh\/nsMGmwnO15CWtFpAbhUA\/D5oRjsIxnvXaMDg0iAFpdu\/5Ffsj7g3EPdBkiQHNYK7YU1RRx609eH0bZyiIYHdUPw7ikLupvrebZmELqi3mqDFO99u4eISlxFJlUbUND3L4BtmWTWrKwI=", |
| 818 | 818 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 819 | 819 | }'; |
| 820 | - $this->fileAccessHelper |
|
| 821 | - ->expects($this->exactly(2)) |
|
| 822 | - ->method('file_get_contents') |
|
| 823 | - ->willReturnMap([ |
|
| 824 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile], |
|
| 825 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 826 | - ]); |
|
| 827 | - |
|
| 828 | - $expected = [ |
|
| 829 | - 'EXCEPTION' => [ |
|
| 830 | - 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 831 | - 'message' => 'Signature could not get verified.', |
|
| 832 | - ] |
|
| 833 | - ]; |
|
| 834 | - $this->assertSame($expected, $this->checker->verifyCoreSignature()); |
|
| 835 | - } |
|
| 836 | - |
|
| 837 | - public function testVerifyCoreSignatureWithTamperedFiles(): void { |
|
| 838 | - $this->serverVersion |
|
| 839 | - ->expects($this->once()) |
|
| 840 | - ->method('getChannel') |
|
| 841 | - ->willReturn('stable'); |
|
| 842 | - $this->config |
|
| 843 | - ->expects($this->any()) |
|
| 844 | - ->method('getSystemValueBool') |
|
| 845 | - ->with('integrity.check.disabled', false) |
|
| 846 | - ->willReturn(false); |
|
| 847 | - |
|
| 848 | - $this->environmentHelper |
|
| 849 | - ->expects($this->any()) |
|
| 850 | - ->method('getServerRoot') |
|
| 851 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 852 | - $signatureDataFile = '{ |
|
| 820 | + $this->fileAccessHelper |
|
| 821 | + ->expects($this->exactly(2)) |
|
| 822 | + ->method('file_get_contents') |
|
| 823 | + ->willReturnMap([ |
|
| 824 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile], |
|
| 825 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 826 | + ]); |
|
| 827 | + |
|
| 828 | + $expected = [ |
|
| 829 | + 'EXCEPTION' => [ |
|
| 830 | + 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 831 | + 'message' => 'Signature could not get verified.', |
|
| 832 | + ] |
|
| 833 | + ]; |
|
| 834 | + $this->assertSame($expected, $this->checker->verifyCoreSignature()); |
|
| 835 | + } |
|
| 836 | + |
|
| 837 | + public function testVerifyCoreSignatureWithTamperedFiles(): void { |
|
| 838 | + $this->serverVersion |
|
| 839 | + ->expects($this->once()) |
|
| 840 | + ->method('getChannel') |
|
| 841 | + ->willReturn('stable'); |
|
| 842 | + $this->config |
|
| 843 | + ->expects($this->any()) |
|
| 844 | + ->method('getSystemValueBool') |
|
| 845 | + ->with('integrity.check.disabled', false) |
|
| 846 | + ->willReturn(false); |
|
| 847 | + |
|
| 848 | + $this->environmentHelper |
|
| 849 | + ->expects($this->any()) |
|
| 850 | + ->method('getServerRoot') |
|
| 851 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 852 | + $signatureDataFile = '{ |
|
| 853 | 853 | "hashes": { |
| 854 | 854 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 855 | 855 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -857,54 +857,54 @@ discard block |
||
| 857 | 857 | "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=", |
| 858 | 858 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" |
| 859 | 859 | }'; |
| 860 | - $this->fileAccessHelper |
|
| 861 | - ->expects($this->exactly(2)) |
|
| 862 | - ->method('file_get_contents') |
|
| 863 | - ->willReturnMap([ |
|
| 864 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile], |
|
| 865 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 866 | - ]); |
|
| 867 | - |
|
| 868 | - $expected = [ |
|
| 869 | - 'INVALID_HASH' => [ |
|
| 870 | - 'AnotherFile.txt' => [ |
|
| 871 | - 'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112', |
|
| 872 | - 'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c', |
|
| 873 | - ], |
|
| 874 | - ], |
|
| 875 | - 'FILE_MISSING' => [ |
|
| 876 | - 'subfolder/file.txt' => [ |
|
| 877 | - 'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b', |
|
| 878 | - 'current' => '', |
|
| 879 | - ], |
|
| 880 | - ], |
|
| 881 | - 'EXTRA_FILE' => [ |
|
| 882 | - 'UnecessaryFile' => [ |
|
| 883 | - 'expected' => '', |
|
| 884 | - 'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', |
|
| 885 | - ], |
|
| 886 | - ], |
|
| 887 | - |
|
| 888 | - ]; |
|
| 889 | - $this->assertSame($expected, $this->checker->verifyCoreSignature()); |
|
| 890 | - } |
|
| 891 | - |
|
| 892 | - public function testVerifyCoreWithInvalidCertificate(): void { |
|
| 893 | - $this->serverVersion |
|
| 894 | - ->expects($this->once()) |
|
| 895 | - ->method('getChannel') |
|
| 896 | - ->willReturn('stable'); |
|
| 897 | - $this->config |
|
| 898 | - ->expects($this->any()) |
|
| 899 | - ->method('getSystemValueBool') |
|
| 900 | - ->with('integrity.check.disabled', false) |
|
| 901 | - ->willReturn(false); |
|
| 902 | - |
|
| 903 | - $this->environmentHelper |
|
| 904 | - ->expects($this->any()) |
|
| 905 | - ->method('getServerRoot') |
|
| 906 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 907 | - $signatureDataFile = '{ |
|
| 860 | + $this->fileAccessHelper |
|
| 861 | + ->expects($this->exactly(2)) |
|
| 862 | + ->method('file_get_contents') |
|
| 863 | + ->willReturnMap([ |
|
| 864 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile], |
|
| 865 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 866 | + ]); |
|
| 867 | + |
|
| 868 | + $expected = [ |
|
| 869 | + 'INVALID_HASH' => [ |
|
| 870 | + 'AnotherFile.txt' => [ |
|
| 871 | + 'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112', |
|
| 872 | + 'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c', |
|
| 873 | + ], |
|
| 874 | + ], |
|
| 875 | + 'FILE_MISSING' => [ |
|
| 876 | + 'subfolder/file.txt' => [ |
|
| 877 | + 'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b', |
|
| 878 | + 'current' => '', |
|
| 879 | + ], |
|
| 880 | + ], |
|
| 881 | + 'EXTRA_FILE' => [ |
|
| 882 | + 'UnecessaryFile' => [ |
|
| 883 | + 'expected' => '', |
|
| 884 | + 'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', |
|
| 885 | + ], |
|
| 886 | + ], |
|
| 887 | + |
|
| 888 | + ]; |
|
| 889 | + $this->assertSame($expected, $this->checker->verifyCoreSignature()); |
|
| 890 | + } |
|
| 891 | + |
|
| 892 | + public function testVerifyCoreWithInvalidCertificate(): void { |
|
| 893 | + $this->serverVersion |
|
| 894 | + ->expects($this->once()) |
|
| 895 | + ->method('getChannel') |
|
| 896 | + ->willReturn('stable'); |
|
| 897 | + $this->config |
|
| 898 | + ->expects($this->any()) |
|
| 899 | + ->method('getSystemValueBool') |
|
| 900 | + ->with('integrity.check.disabled', false) |
|
| 901 | + ->willReturn(false); |
|
| 902 | + |
|
| 903 | + $this->environmentHelper |
|
| 904 | + ->expects($this->any()) |
|
| 905 | + ->method('getServerRoot') |
|
| 906 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 907 | + $signatureDataFile = '{ |
|
| 908 | 908 | "hashes": { |
| 909 | 909 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 910 | 910 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -912,39 +912,39 @@ discard block |
||
| 912 | 912 | "signature": "eXesvDm3pkek12xSwMG10y9suRES79Nye3jYNe5KYq1tTUPqRRNgxmMGAfcUro0zpLeAr2YgHeSMWtglblGOW7pmwGVPZ0O1Y4r1fE6jnep0kW+35PLIaqCorIOnCAtSzDNKBhwd1ow3zW2wC0DFouuEkIO8u5Fw28g8E8dp8zEk1xMblNPy+xtWkmYHrVJ\/dQgun1bYOF2ZFtAzatwndTI\/bGsy1i3Wsl+x6HyWKQdq8y8VObtOqKDH7uERBEpB9DHVyKflj1v1gQuEH6BhaRdATc7ee0MiQdGblraIySwYRdfo2d8i82OVKrenMB3SLwyCvDPyQ9iKpTOnSF52ZBqaqSXKM2N\/RAkweeBFQQCwcHhqxvB0cfbyHcbkOLeCZe\/tsh68IxwTiYgzvLfl7sOZ5arnZbzrPpZmB+hfV2omkoJ1tDwOWz9hEmLLNtfo2OxyUH1m0+XFaC+Gbn4WkVDgf7YZkwUcG+Qoa3oKDNMss8MEyZxewl2iDGZcf402dlidHRprlfmXbAYuVQ08\/a0HxIKYPGh\/nsMGmwnO15CWtFpAbhUA\/D5oRjsIxnvXaMDg0iAFpdu\/5Ffsj7g3EPdBkiQHNYK7YU1RRx609eH0bZyiIYHdUPw7ikLupvrebZmELqi3mqDFO99u4eISlxFJlUbUND3L4BtmWTWrKwI=", |
| 913 | 913 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUPYoweUxCPqbDW4ntuh7QvgyqSrgwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIyNDIwNloXDTE2MTEwMzIyNDIwNlowDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJui3nDbjOIjxNnthdBZplphujsN6u8K\r\nQ\/62zAuSwzXVp0+3IMgM\/2sepklVE8YfCyVJ5+SUJqnqHoUWVRVfs8jL0wW6nrHM\r\n\/lsscAguWCee4iAdNOqI9kq4+DUau8J45e62XA9mrAo\/8\/NKzFE2y2WduDoQZcm+\r\n8+dwcUUHXw2jl8dfrmvEMYSqTNDdb4rGmQpeV+dr9BLqr+x03U1Q08qCG9j7mSOz\r\ncvJENjOvC5uzAh5LCuCgxqG4o+mPzB0FtNnwoRRu6IsF3Y3KacRqPc30fB\/iXDn5\r\nBPr14uNxTTYWoZJ1F0tZrLzRbXdjJJOC+dnQurTtXWZ8WjPB1BWQYK7fW6t82mkN\r\n2Qe2xen99gs9nX5yY\/sHM3TKSJdM7AVCEv\/emW3gNjkvWTtRlN\/Nc7X2ckNwXcvo\r\n0yi3fSPjzXpDgLbhp1FzrMlHDn1VzmRT3r8wLByWa\/hsxrJDsBzwunMJYhXhmeKb\r\n3wX0tN\/EUJTWBntpwVOIGnRPD51oBoQUOMaEAq\/kz8PgN181bWZkJbRuf+FWkijQ\r\no+HR2lVF1jWXXst5Uc+s9HN81Uly7X4O9MMg0QxT4+wymtGDs6AOkwMi9rgBTrRB\r\n3tLU3XL2UIwRXgmd8cPtTu\/I6Bm7LdyaYtZ3yJTxRewq3nZdWypqBhD8uhpIYVkf\r\no4bxmGkVAQVTAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAKKAX5EHgU1grODnJ0of\r\nspFpgB1K67YvclNUyuU6NQ6zBJx1\/w1RnM7uxLcxiiWj1BbUhwZQ0ojmEHeUyi6O\r\nGrDVajwhTccDMmja3u5adhEncx65\/H+lD85IPRRkS2qBDssMDdJHhZ0uI+40nI7M\r\nMq1kFjl+6wiuqZXqps66DuLbk45g\/ZlrFIrIo3Ix5vj0OVqwT+gO4LYirJK6KgVS\r\nUttbcEsc\/yKU9ThnM8\/n4m2jstZXfzKPgOsJrQcZrFOtpj+CWmBzVElBSPlDT3Nh\r\nHSgOeTFJ8bQBxj2iG5dLA+JZJQKxyJ1gy2ZtxIJ2GyvLtSe8NUSqvfPWOaAKEUV2\r\ngniytnEFLr+PcD+9EGux6jZNuj6HmtWVThTfD5VGFmtlVU2z71ZRYY0kn6J3mmFc\r\nS2ecEcCUwqG5YNLncEUCyZhC2klWql2SHyGctCEyWWY7ikIDjVzYt2EbcFvLNBnP\r\ntybN1TYHRRZxlug00CCoOE9EZfk46FkZpDvU6KmqJRofkNZ5sj+SffyGcwYwNrDH\r\nKqe8m+9lHf3CRTIDeMu8r2xl1I6M6ZZfjabbmVP9Jd6WN4s6f1FlXDWzhlT1N0Qw\r\nGzJj6xB+SPtS3UV05tBlvbfA4e06D5G9uD7Q8ONcINtMS0xsSJ2oo82AqlpvlF\/q\r\noj7YKHsaTVGA+FxBktZHfoxD\r\n-----END CERTIFICATE-----" |
| 914 | 914 | }'; |
| 915 | - $this->fileAccessHelper |
|
| 916 | - ->expects($this->exactly(2)) |
|
| 917 | - ->method('file_get_contents') |
|
| 918 | - ->willReturnMap([ |
|
| 919 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 920 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 921 | - ]); |
|
| 922 | - |
|
| 923 | - $expected = [ |
|
| 924 | - 'EXCEPTION' => [ |
|
| 925 | - 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 926 | - 'message' => 'Certificate is not valid.', |
|
| 927 | - ] |
|
| 928 | - ]; |
|
| 929 | - $this->assertSame($expected, $this->checker->verifyCoreSignature()); |
|
| 930 | - } |
|
| 931 | - |
|
| 932 | - public function testVerifyCoreWithDifferentScope(): void { |
|
| 933 | - $this->serverVersion |
|
| 934 | - ->expects($this->once()) |
|
| 935 | - ->method('getChannel') |
|
| 936 | - ->willReturn('stable'); |
|
| 937 | - $this->config |
|
| 938 | - ->expects($this->any()) |
|
| 939 | - ->method('getSystemValueBool') |
|
| 940 | - ->with('integrity.check.disabled', false) |
|
| 941 | - ->willReturn(false); |
|
| 942 | - |
|
| 943 | - $this->environmentHelper |
|
| 944 | - ->expects($this->any()) |
|
| 945 | - ->method('getServerRoot') |
|
| 946 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 947 | - $signatureDataFile = '{ |
|
| 915 | + $this->fileAccessHelper |
|
| 916 | + ->expects($this->exactly(2)) |
|
| 917 | + ->method('file_get_contents') |
|
| 918 | + ->willReturnMap([ |
|
| 919 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 920 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 921 | + ]); |
|
| 922 | + |
|
| 923 | + $expected = [ |
|
| 924 | + 'EXCEPTION' => [ |
|
| 925 | + 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 926 | + 'message' => 'Certificate is not valid.', |
|
| 927 | + ] |
|
| 928 | + ]; |
|
| 929 | + $this->assertSame($expected, $this->checker->verifyCoreSignature()); |
|
| 930 | + } |
|
| 931 | + |
|
| 932 | + public function testVerifyCoreWithDifferentScope(): void { |
|
| 933 | + $this->serverVersion |
|
| 934 | + ->expects($this->once()) |
|
| 935 | + ->method('getChannel') |
|
| 936 | + ->willReturn('stable'); |
|
| 937 | + $this->config |
|
| 938 | + ->expects($this->any()) |
|
| 939 | + ->method('getSystemValueBool') |
|
| 940 | + ->with('integrity.check.disabled', false) |
|
| 941 | + ->willReturn(false); |
|
| 942 | + |
|
| 943 | + $this->environmentHelper |
|
| 944 | + ->expects($this->any()) |
|
| 945 | + ->method('getServerRoot') |
|
| 946 | + ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 947 | + $signatureDataFile = '{ |
|
| 948 | 948 | "hashes": { |
| 949 | 949 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
| 950 | 950 | "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b" |
@@ -952,155 +952,155 @@ discard block |
||
| 952 | 952 | "signature": "EL49UaSeyMAqyMtqId+tgOhhwgOevPZsRLX4j2blnybAB6fN07z0936JqZV7+eMPiE30Idx+UCY6rCFN531Kqe9vAOCdgtHUSOjjKyKc+lvULESlMb6YQcrZrvDlEMMjzjH49ewG7Ai8sNN6HrRUd9U8ws+ewSkW2DOOBItj\/21RBnkrSt+2AtGXGigEvuTm57HrCYDj8\/lSkumC2GVkjLUHeLOKYo4PRNOr6yP5mED5v7zo66AWvXl2fKv54InZcdxsAk35lyK9DGZbk\/027ZRd0AOHT3LImRLvQ+8EAg3XLlRUy0hOFGgPC+jYonMzgYvsAXAXi2j8LnLJlsLwpFwu1k1B+kZVPMumKZvP9OvJb70EirecXmz62V+Jiyuaq7ne4y7Kp5gKZT\/T8SeZ0lFtCmPfYyzBB0y8s5ldmTTmdVYHs54t\/OCCW82HzQZxnFNPzDTRa8HglsaMKrqPtW59+R4UvRKSWhB8M\/Ah57qgzycvPV4KMz\/FbD4l\/\/9chRKSlCfc2k3b8ZSHNmi+EzCKgJjWIoKdgN1yax94puU8jfn8UW+G7H9Y1Jsf\/jox6QLyYEgtV1vOHY2xLT7fVs2vhyvkN2MNjJnmQ70gFG5Qz2lBz5wi6ZpB+tOfCcpbLxWAkoWoIrmC\/Ilqh7mfmRZ43g5upjkepHNd93ONuY8=", |
| 953 | 953 | "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEwTCCAqmgAwIBAgIUWv0iujufs5lUr0svCf\/qTQvoyKAwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIyNDk1M1oXDTE2MTEwMzIyNDk1M1owEjEQMA4GA1UEAwwHU29tZUFwcDCCAiIw\r\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK8q0x62agGSRBqeWsaeEwFfepMk\r\nF8cAobMMi50qHCv9IrOn\/ZH9l52xBrbIkErVmRjmly0d4JhD8Ymhidsh9ONKYl\/j\r\n+ishsZDM8eNNdp3Ew+fEYVvY1W7mR1qU24NWj0bzVsClI7hvPVIuw7AjfBDq1C5+\r\nA+ZSLSXYvOK2cEWjdxQfuNZwEZSjmA63DUllBIrm35IaTvfuyhU6BW9yHZxmb8+M\r\nw0xDv30D5UkE\/2N7Pa\/HQJLxCR+3zKibRK3nUyRDLSXxMkU9PnFNaPNX59VPgyj4\r\nGB1CFSToldJVPF4pzh7p36uGXZVxs8m3LFD4Ol8mhi7jkxDZjqFN46gzR0r23Py6\r\ndol9vfawGIoUwp9LvL0S7MvdRY0oazLXwClLP4OQ17zpSMAiCj7fgNT661JamPGj\r\nt5O7Zn2wA7I4ddDS\/HDTWCu98Zwc9fHIpsJPgCZ9awoqxi4Mnf7Pk9g5nnXhszGC\r\ncxxIASQKM+GhdzoRxKknax2RzUCwCzcPRtCj8AQT\/x\/mqN3PfRmlnFBNACUw9bpZ\r\nSOoNq2pCF9igftDWpSIXQ38pVpKLWowjjg3DVRmVKBgivHnUnVLyzYBahHPj0vaz\r\ntFtUFRaqXDnt+4qyUGyrT5h5pjZaTcHIcSB4PiarYwdVvgslgwnQzOUcGAzRWBD4\r\n6jV2brP5vFY3g6iPAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBACTY3CCHC+Z28gCf\r\nFWGKQ3wAKs+k4+0yoti0qm2EKX7rSGQ0PHSas6uW79WstC4Rj+DYkDtIhGMSg8FS\r\nHVGZHGBCc0HwdX+BOAt3zi4p7Sf3oQef70\/4imPoKxbAVCpd\/cveVcFyDC19j1yB\r\nBapwu87oh+muoeaZxOlqQI4UxjBlR\/uRSMhOn2UGauIr3dWJgAF4pGt7TtIzt+1v\r\n0uA6FtN1Y4R5O8AaJPh1bIG0CVvFBE58esGzjEYLhOydgKFnEP94kVPgJD5ds9C3\r\npPhEpo1dRpiXaF7WGIV1X6DI\/ipWvfrF7CEy6I\/kP1InY\/vMDjQjeDnJ\/VrXIWXO\r\nyZvHXVaN\/m+1RlETsH7YO\/QmxRue9ZHN3gvvWtmpCeA95sfpepOk7UcHxHZYyQbF\r\n49\/au8j+5tsr4A83xzsT1JbcKRxkAaQ7WDJpOnE5O1+H0fB+BaLakTg6XX9d4Fo7\r\n7Gin7hVWX7pL+JIyxMzME3LhfI61+CRcqZQIrpyaafUziPQbWIPfEs7h8tCOWyvW\r\nUO8ZLervYCB3j44ivkrxPlcBklDCqqKKBzDP9dYOtS\/P4RB1NkHA9+NTvmBpTonS\r\nSFXdg9fFMD7VfjDE3Vnk+8DWkVH5wBYowTAD7w9Wuzr7DumiAULexnP\/Y7xwxLv7\r\n4B+pXTAcRK0zECDEaX3npS8xWzrB\r\n-----END CERTIFICATE-----" |
| 954 | 954 | }'; |
| 955 | - $this->fileAccessHelper |
|
| 956 | - ->expects($this->exactly(2)) |
|
| 957 | - ->method('file_get_contents') |
|
| 958 | - ->willReturnMap([ |
|
| 959 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 960 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 961 | - ]); |
|
| 962 | - |
|
| 963 | - $expected = [ |
|
| 964 | - 'EXCEPTION' => [ |
|
| 965 | - 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 966 | - 'message' => 'Certificate is not valid for required scope. (Requested: core, current: CN=SomeApp)', |
|
| 967 | - ] |
|
| 968 | - ]; |
|
| 969 | - $this->assertSame($expected, $this->checker->verifyCoreSignature()); |
|
| 970 | - } |
|
| 971 | - |
|
| 972 | - public function testRunInstanceVerification(): void { |
|
| 973 | - $this->checker = $this->getMockBuilder('\OC\IntegrityCheck\Checker') |
|
| 974 | - ->setConstructorArgs([ |
|
| 975 | - $this->serverVersion, |
|
| 976 | - $this->environmentHelper, |
|
| 977 | - $this->fileAccessHelper, |
|
| 978 | - $this->appLocator, |
|
| 979 | - $this->config, |
|
| 980 | - $this->appConfig, |
|
| 981 | - $this->cacheFactory, |
|
| 982 | - $this->appManager, |
|
| 983 | - $this->mimeTypeDetector, |
|
| 984 | - ]) |
|
| 985 | - ->onlyMethods([ |
|
| 986 | - 'verifyCoreSignature', |
|
| 987 | - 'verifyAppSignature', |
|
| 988 | - ]) |
|
| 989 | - ->getMock(); |
|
| 990 | - |
|
| 991 | - $this->checker |
|
| 992 | - ->expects($this->once()) |
|
| 993 | - ->method('verifyCoreSignature'); |
|
| 994 | - $this->appManager |
|
| 995 | - ->expects($this->once()) |
|
| 996 | - ->method('getAllAppsInAppsFolders') |
|
| 997 | - ->willReturn([ |
|
| 998 | - 'files', |
|
| 999 | - 'calendar', |
|
| 1000 | - 'contacts', |
|
| 1001 | - 'dav', |
|
| 1002 | - ]); |
|
| 1003 | - $this->appManager |
|
| 1004 | - ->expects($this->exactly(4)) |
|
| 1005 | - ->method('isShipped') |
|
| 1006 | - ->willReturnMap([ |
|
| 1007 | - ['files', true], |
|
| 1008 | - ['calendar', false], |
|
| 1009 | - ['contacts', false], |
|
| 1010 | - ['dav', true], |
|
| 1011 | - ]); |
|
| 1012 | - |
|
| 1013 | - $calls = [ |
|
| 1014 | - 'files', |
|
| 1015 | - 'calendar', |
|
| 1016 | - 'dav', |
|
| 1017 | - ]; |
|
| 1018 | - $this->checker |
|
| 1019 | - ->expects($this->exactly(3)) |
|
| 1020 | - ->method('verifyAppSignature') |
|
| 1021 | - ->willReturnCallback(function ($app) use (&$calls) { |
|
| 1022 | - $expected = array_shift($calls); |
|
| 1023 | - $this->assertSame($expected, $app); |
|
| 1024 | - return []; |
|
| 1025 | - }); |
|
| 1026 | - $this->appLocator |
|
| 1027 | - ->expects($this->exactly(2)) |
|
| 1028 | - ->method('getAppPath') |
|
| 1029 | - ->willReturnMap([ |
|
| 1030 | - ['calendar', '/apps/calendar'], |
|
| 1031 | - ['contacts', '/apps/contacts'], |
|
| 1032 | - ]); |
|
| 1033 | - $this->fileAccessHelper |
|
| 1034 | - ->expects($this->exactly(2)) |
|
| 1035 | - ->method('file_exists') |
|
| 1036 | - ->willReturnMap([ |
|
| 1037 | - ['/apps/calendar/appinfo/signature.json', true], |
|
| 1038 | - ['/apps/contacts/appinfo/signature.json', false], |
|
| 1039 | - ]); |
|
| 1040 | - $this->appConfig |
|
| 1041 | - ->expects($this->once()) |
|
| 1042 | - ->method('deleteKey') |
|
| 1043 | - ->with('core', 'oc.integritycheck.checker'); |
|
| 1044 | - |
|
| 1045 | - $this->checker->runInstanceVerification(); |
|
| 1046 | - } |
|
| 1047 | - |
|
| 1048 | - public function testVerifyAppSignatureWithoutSignatureDataAndCodeCheckerDisabled(): void { |
|
| 1049 | - $this->serverVersion |
|
| 1050 | - ->expects($this->once()) |
|
| 1051 | - ->method('getChannel') |
|
| 1052 | - ->willReturn('stable'); |
|
| 1053 | - $this->config |
|
| 1054 | - ->expects($this->any()) |
|
| 1055 | - ->method('getSystemValueBool') |
|
| 1056 | - ->with('integrity.check.disabled', false) |
|
| 1057 | - ->willReturn(true); |
|
| 1058 | - |
|
| 1059 | - $expected = []; |
|
| 1060 | - $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp')); |
|
| 1061 | - } |
|
| 1062 | - |
|
| 1063 | - public static function channelDataProvider(): array { |
|
| 1064 | - return [ |
|
| 1065 | - ['stable', true], |
|
| 1066 | - ['git', false], |
|
| 1067 | - ]; |
|
| 1068 | - } |
|
| 1069 | - |
|
| 1070 | - /** |
|
| 1071 | - * @param string $channel |
|
| 1072 | - * @param bool $isCodeSigningEnforced |
|
| 1073 | - * @dataProvider channelDataProvider |
|
| 1074 | - */ |
|
| 1075 | - public function testIsCodeCheckEnforced($channel, $isCodeSigningEnforced): void { |
|
| 1076 | - $this->serverVersion |
|
| 1077 | - ->expects($this->once()) |
|
| 1078 | - ->method('getChannel') |
|
| 1079 | - ->willReturn($channel); |
|
| 1080 | - $this->config |
|
| 1081 | - ->expects($this->any()) |
|
| 1082 | - ->method('getSystemValueBool') |
|
| 1083 | - ->with('integrity.check.disabled', false) |
|
| 1084 | - ->willReturn(false); |
|
| 1085 | - |
|
| 1086 | - $this->assertSame($isCodeSigningEnforced, $this->checker->isCodeCheckEnforced()); |
|
| 1087 | - } |
|
| 1088 | - |
|
| 1089 | - /** |
|
| 1090 | - * @param string $channel |
|
| 1091 | - * @dataProvider channelDataProvider |
|
| 1092 | - */ |
|
| 1093 | - public function testIsCodeCheckEnforcedWithDisabledConfigSwitch($channel): void { |
|
| 1094 | - $this->serverVersion |
|
| 1095 | - ->expects($this->once()) |
|
| 1096 | - ->method('getChannel') |
|
| 1097 | - ->willReturn($channel); |
|
| 1098 | - $this->config |
|
| 1099 | - ->expects($this->any()) |
|
| 1100 | - ->method('getSystemValueBool') |
|
| 1101 | - ->with('integrity.check.disabled', false) |
|
| 1102 | - ->willReturn(true); |
|
| 1103 | - |
|
| 1104 | - $this->assertFalse(self::invokePrivate($this->checker, 'isCodeCheckEnforced')); |
|
| 1105 | - } |
|
| 955 | + $this->fileAccessHelper |
|
| 956 | + ->expects($this->exactly(2)) |
|
| 957 | + ->method('file_get_contents') |
|
| 958 | + ->willReturnMap([ |
|
| 959 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 960 | + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 961 | + ]); |
|
| 962 | + |
|
| 963 | + $expected = [ |
|
| 964 | + 'EXCEPTION' => [ |
|
| 965 | + 'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException', |
|
| 966 | + 'message' => 'Certificate is not valid for required scope. (Requested: core, current: CN=SomeApp)', |
|
| 967 | + ] |
|
| 968 | + ]; |
|
| 969 | + $this->assertSame($expected, $this->checker->verifyCoreSignature()); |
|
| 970 | + } |
|
| 971 | + |
|
| 972 | + public function testRunInstanceVerification(): void { |
|
| 973 | + $this->checker = $this->getMockBuilder('\OC\IntegrityCheck\Checker') |
|
| 974 | + ->setConstructorArgs([ |
|
| 975 | + $this->serverVersion, |
|
| 976 | + $this->environmentHelper, |
|
| 977 | + $this->fileAccessHelper, |
|
| 978 | + $this->appLocator, |
|
| 979 | + $this->config, |
|
| 980 | + $this->appConfig, |
|
| 981 | + $this->cacheFactory, |
|
| 982 | + $this->appManager, |
|
| 983 | + $this->mimeTypeDetector, |
|
| 984 | + ]) |
|
| 985 | + ->onlyMethods([ |
|
| 986 | + 'verifyCoreSignature', |
|
| 987 | + 'verifyAppSignature', |
|
| 988 | + ]) |
|
| 989 | + ->getMock(); |
|
| 990 | + |
|
| 991 | + $this->checker |
|
| 992 | + ->expects($this->once()) |
|
| 993 | + ->method('verifyCoreSignature'); |
|
| 994 | + $this->appManager |
|
| 995 | + ->expects($this->once()) |
|
| 996 | + ->method('getAllAppsInAppsFolders') |
|
| 997 | + ->willReturn([ |
|
| 998 | + 'files', |
|
| 999 | + 'calendar', |
|
| 1000 | + 'contacts', |
|
| 1001 | + 'dav', |
|
| 1002 | + ]); |
|
| 1003 | + $this->appManager |
|
| 1004 | + ->expects($this->exactly(4)) |
|
| 1005 | + ->method('isShipped') |
|
| 1006 | + ->willReturnMap([ |
|
| 1007 | + ['files', true], |
|
| 1008 | + ['calendar', false], |
|
| 1009 | + ['contacts', false], |
|
| 1010 | + ['dav', true], |
|
| 1011 | + ]); |
|
| 1012 | + |
|
| 1013 | + $calls = [ |
|
| 1014 | + 'files', |
|
| 1015 | + 'calendar', |
|
| 1016 | + 'dav', |
|
| 1017 | + ]; |
|
| 1018 | + $this->checker |
|
| 1019 | + ->expects($this->exactly(3)) |
|
| 1020 | + ->method('verifyAppSignature') |
|
| 1021 | + ->willReturnCallback(function ($app) use (&$calls) { |
|
| 1022 | + $expected = array_shift($calls); |
|
| 1023 | + $this->assertSame($expected, $app); |
|
| 1024 | + return []; |
|
| 1025 | + }); |
|
| 1026 | + $this->appLocator |
|
| 1027 | + ->expects($this->exactly(2)) |
|
| 1028 | + ->method('getAppPath') |
|
| 1029 | + ->willReturnMap([ |
|
| 1030 | + ['calendar', '/apps/calendar'], |
|
| 1031 | + ['contacts', '/apps/contacts'], |
|
| 1032 | + ]); |
|
| 1033 | + $this->fileAccessHelper |
|
| 1034 | + ->expects($this->exactly(2)) |
|
| 1035 | + ->method('file_exists') |
|
| 1036 | + ->willReturnMap([ |
|
| 1037 | + ['/apps/calendar/appinfo/signature.json', true], |
|
| 1038 | + ['/apps/contacts/appinfo/signature.json', false], |
|
| 1039 | + ]); |
|
| 1040 | + $this->appConfig |
|
| 1041 | + ->expects($this->once()) |
|
| 1042 | + ->method('deleteKey') |
|
| 1043 | + ->with('core', 'oc.integritycheck.checker'); |
|
| 1044 | + |
|
| 1045 | + $this->checker->runInstanceVerification(); |
|
| 1046 | + } |
|
| 1047 | + |
|
| 1048 | + public function testVerifyAppSignatureWithoutSignatureDataAndCodeCheckerDisabled(): void { |
|
| 1049 | + $this->serverVersion |
|
| 1050 | + ->expects($this->once()) |
|
| 1051 | + ->method('getChannel') |
|
| 1052 | + ->willReturn('stable'); |
|
| 1053 | + $this->config |
|
| 1054 | + ->expects($this->any()) |
|
| 1055 | + ->method('getSystemValueBool') |
|
| 1056 | + ->with('integrity.check.disabled', false) |
|
| 1057 | + ->willReturn(true); |
|
| 1058 | + |
|
| 1059 | + $expected = []; |
|
| 1060 | + $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp')); |
|
| 1061 | + } |
|
| 1062 | + |
|
| 1063 | + public static function channelDataProvider(): array { |
|
| 1064 | + return [ |
|
| 1065 | + ['stable', true], |
|
| 1066 | + ['git', false], |
|
| 1067 | + ]; |
|
| 1068 | + } |
|
| 1069 | + |
|
| 1070 | + /** |
|
| 1071 | + * @param string $channel |
|
| 1072 | + * @param bool $isCodeSigningEnforced |
|
| 1073 | + * @dataProvider channelDataProvider |
|
| 1074 | + */ |
|
| 1075 | + public function testIsCodeCheckEnforced($channel, $isCodeSigningEnforced): void { |
|
| 1076 | + $this->serverVersion |
|
| 1077 | + ->expects($this->once()) |
|
| 1078 | + ->method('getChannel') |
|
| 1079 | + ->willReturn($channel); |
|
| 1080 | + $this->config |
|
| 1081 | + ->expects($this->any()) |
|
| 1082 | + ->method('getSystemValueBool') |
|
| 1083 | + ->with('integrity.check.disabled', false) |
|
| 1084 | + ->willReturn(false); |
|
| 1085 | + |
|
| 1086 | + $this->assertSame($isCodeSigningEnforced, $this->checker->isCodeCheckEnforced()); |
|
| 1087 | + } |
|
| 1088 | + |
|
| 1089 | + /** |
|
| 1090 | + * @param string $channel |
|
| 1091 | + * @dataProvider channelDataProvider |
|
| 1092 | + */ |
|
| 1093 | + public function testIsCodeCheckEnforcedWithDisabledConfigSwitch($channel): void { |
|
| 1094 | + $this->serverVersion |
|
| 1095 | + ->expects($this->once()) |
|
| 1096 | + ->method('getChannel') |
|
| 1097 | + ->willReturn($channel); |
|
| 1098 | + $this->config |
|
| 1099 | + ->expects($this->any()) |
|
| 1100 | + ->method('getSystemValueBool') |
|
| 1101 | + ->with('integrity.check.disabled', false) |
|
| 1102 | + ->willReturn(true); |
|
| 1103 | + |
|
| 1104 | + $this->assertFalse(self::invokePrivate($this->checker, 'isCodeCheckEnforced')); |
|
| 1105 | + } |
|
| 1106 | 1106 | } |
@@ -94,8 +94,8 @@ discard block |
||
| 94 | 94 | ->with('NotExistingApp/appinfo') |
| 95 | 95 | ->willReturn(true); |
| 96 | 96 | |
| 97 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 98 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 97 | + $keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.crt'); |
|
| 98 | + $rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.key'); |
|
| 99 | 99 | $rsa = new RSA(); |
| 100 | 100 | $rsa->loadKey($rsaPrivateKey); |
| 101 | 101 | $x509 = new X509(); |
@@ -113,13 +113,13 @@ discard block |
||
| 113 | 113 | ->method('file_put_contents') |
| 114 | 114 | ->will($this->throwException(new \Exception('Exception message'))); |
| 115 | 115 | |
| 116 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 117 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 116 | + $keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.crt'); |
|
| 117 | + $rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.key'); |
|
| 118 | 118 | $rsa = new RSA(); |
| 119 | 119 | $rsa->loadKey($rsaPrivateKey); |
| 120 | 120 | $x509 = new X509(); |
| 121 | 121 | $x509->loadX509($keyBundle); |
| 122 | - $this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa); |
|
| 122 | + $this->checker->writeAppSignature(\OC::$SERVERROOT.'/tests/data/integritycheck/app/', $x509, $rsa); |
|
| 123 | 123 | } |
| 124 | 124 | |
| 125 | 125 | public function testWriteAppSignature(): void { |
@@ -135,8 +135,8 @@ discard block |
||
| 135 | 135 | ->expects($this->once()) |
| 136 | 136 | ->method('file_put_contents') |
| 137 | 137 | ->with( |
| 138 | - $this->equalTo(\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json'), |
|
| 139 | - $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 138 | + $this->equalTo(\OC::$SERVERROOT.'/tests/data/integritycheck/app//appinfo/signature.json'), |
|
| 139 | + $this->callback(function($signature) use ($expectedSignatureFileData) { |
|
| 140 | 140 | $expectedArray = json_decode($expectedSignatureFileData, true); |
| 141 | 141 | $actualArray = json_decode($signature, true); |
| 142 | 142 | $this->assertEquals($expectedArray, $actualArray); |
@@ -144,13 +144,13 @@ discard block |
||
| 144 | 144 | }) |
| 145 | 145 | ); |
| 146 | 146 | |
| 147 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 148 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 147 | + $keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.crt'); |
|
| 148 | + $rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.key'); |
|
| 149 | 149 | $rsa = new RSA(); |
| 150 | 150 | $rsa->loadKey($rsaPrivateKey); |
| 151 | 151 | $x509 = new X509(); |
| 152 | 152 | $x509->loadX509($keyBundle); |
| 153 | - $this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa); |
|
| 153 | + $this->checker->writeAppSignature(\OC::$SERVERROOT.'/tests/data/integritycheck/app/', $x509, $rsa); |
|
| 154 | 154 | } |
| 155 | 155 | |
| 156 | 156 | public function testVerifyAppSignatureWithoutSignatureData(): void { |
@@ -188,7 +188,7 @@ discard block |
||
| 188 | 188 | ->expects($this->once()) |
| 189 | 189 | ->method('getAppPath') |
| 190 | 190 | ->with('SomeApp') |
| 191 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 191 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/'); |
|
| 192 | 192 | $signatureDataFile = '{ |
| 193 | 193 | "hashes": { |
| 194 | 194 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
@@ -201,8 +201,8 @@ discard block |
||
| 201 | 201 | ->expects($this->exactly(2)) |
| 202 | 202 | ->method('file_get_contents') |
| 203 | 203 | ->willReturnMap([ |
| 204 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 205 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 204 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 205 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 206 | 206 | ]); |
| 207 | 207 | |
| 208 | 208 | $this->assertSame([], $this->checker->verifyAppSignature('SomeApp')); |
@@ -223,7 +223,7 @@ discard block |
||
| 223 | 223 | ->expects($this->once()) |
| 224 | 224 | ->method('getAppPath') |
| 225 | 225 | ->with('SomeApp') |
| 226 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 226 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/'); |
|
| 227 | 227 | $signatureDataFile = '{ |
| 228 | 228 | "hashes": { |
| 229 | 229 | "AnotherFile.txt": "tampered", |
@@ -236,8 +236,8 @@ discard block |
||
| 236 | 236 | ->expects($this->exactly(2)) |
| 237 | 237 | ->method('file_get_contents') |
| 238 | 238 | ->willReturnMap([ |
| 239 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 240 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 239 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 240 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 241 | 241 | ]); |
| 242 | 242 | |
| 243 | 243 | $expected = [ |
@@ -264,7 +264,7 @@ discard block |
||
| 264 | 264 | ->expects($this->once()) |
| 265 | 265 | ->method('getAppPath') |
| 266 | 266 | ->with('SomeApp') |
| 267 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 267 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData/'); |
|
| 268 | 268 | $signatureDataFile = '{ |
| 269 | 269 | "hashes": { |
| 270 | 270 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
@@ -277,8 +277,8 @@ discard block |
||
| 277 | 277 | ->expects($this->exactly(2)) |
| 278 | 278 | ->method('file_get_contents') |
| 279 | 279 | ->willReturnMap([ |
| 280 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 281 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 280 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 281 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 282 | 282 | ]); |
| 283 | 283 | |
| 284 | 284 | |
@@ -333,8 +333,8 @@ discard block |
||
| 333 | 333 | ->expects($this->exactly(2)) |
| 334 | 334 | ->method('file_get_contents') |
| 335 | 335 | ->willReturnMap([ |
| 336 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 337 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 336 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 337 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 338 | 338 | ]); |
| 339 | 339 | |
| 340 | 340 | $expected = [ |
@@ -358,7 +358,7 @@ discard block |
||
| 358 | 358 | ], |
| 359 | 359 | |
| 360 | 360 | ]; |
| 361 | - $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp', \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/')); |
|
| 361 | + $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp', \OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData/')); |
|
| 362 | 362 | } |
| 363 | 363 | |
| 364 | 364 | public function testVerifyAppWithDifferentScope(): void { |
@@ -376,7 +376,7 @@ discard block |
||
| 376 | 376 | ->expects($this->once()) |
| 377 | 377 | ->method('getAppPath') |
| 378 | 378 | ->with('SomeApp') |
| 379 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 379 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData/'); |
|
| 380 | 380 | $signatureDataFile = '{ |
| 381 | 381 | "hashes": { |
| 382 | 382 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
@@ -389,8 +389,8 @@ discard block |
||
| 389 | 389 | ->expects($this->exactly(2)) |
| 390 | 390 | ->method('file_get_contents') |
| 391 | 391 | ->willReturnMap([ |
| 392 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 393 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 392 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile], |
|
| 393 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 394 | 394 | ]); |
| 395 | 395 | |
| 396 | 396 | $expected = [ |
@@ -417,7 +417,7 @@ discard block |
||
| 417 | 417 | ->expects($this->once()) |
| 418 | 418 | ->method('getAppPath') |
| 419 | 419 | ->with('SomeApp') |
| 420 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 420 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/'); |
|
| 421 | 421 | $signatureDataFile = '{ |
| 422 | 422 | "hashes": { |
| 423 | 423 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
@@ -430,8 +430,8 @@ discard block |
||
| 430 | 430 | ->expects($this->exactly(2)) |
| 431 | 431 | ->method('file_get_contents') |
| 432 | 432 | ->willReturnMap([ |
| 433 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 434 | - ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 433 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile], |
|
| 434 | + ['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 435 | 435 | ]); |
| 436 | 436 | |
| 437 | 437 | $this->assertSame([], $this->checker->verifyAppSignature('SomeApp')); |
@@ -449,11 +449,11 @@ discard block |
||
| 449 | 449 | $this->fileAccessHelper |
| 450 | 450 | ->expects($this->once()) |
| 451 | 451 | ->method('is_writable') |
| 452 | - ->with(__DIR__ . '/core') |
|
| 452 | + ->with(__DIR__.'/core') |
|
| 453 | 453 | ->willReturn(true); |
| 454 | 454 | |
| 455 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 456 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 455 | + $keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.crt'); |
|
| 456 | + $rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.key'); |
|
| 457 | 457 | $rsa = new RSA(); |
| 458 | 458 | $rsa->loadKey($rsaPrivateKey); |
| 459 | 459 | $x509 = new X509(); |
@@ -473,11 +473,11 @@ discard block |
||
| 473 | 473 | $this->fileAccessHelper |
| 474 | 474 | ->expects($this->once()) |
| 475 | 475 | ->method('is_writable') |
| 476 | - ->with(__DIR__ . '/core') |
|
| 476 | + ->with(__DIR__.'/core') |
|
| 477 | 477 | ->willReturn(false); |
| 478 | 478 | |
| 479 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt'); |
|
| 480 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key'); |
|
| 479 | + $keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.crt'); |
|
| 480 | + $rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.key'); |
|
| 481 | 481 | $rsa = new RSA(); |
| 482 | 482 | $rsa->loadKey($rsaPrivateKey); |
| 483 | 483 | $x509 = new X509(); |
@@ -497,13 +497,13 @@ discard block |
||
| 497 | 497 | $this->environmentHelper |
| 498 | 498 | ->expects($this->any()) |
| 499 | 499 | ->method('getServerRoot') |
| 500 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 500 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/'); |
|
| 501 | 501 | $this->fileAccessHelper |
| 502 | 502 | ->expects($this->once()) |
| 503 | 503 | ->method('file_put_contents') |
| 504 | 504 | ->with( |
| 505 | - \OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', |
|
| 506 | - $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 505 | + \OC::$SERVERROOT.'/tests/data/integritycheck/app//core/signature.json', |
|
| 506 | + $this->callback(function($signature) use ($expectedSignatureFileData) { |
|
| 507 | 507 | $expectedArray = json_decode($expectedSignatureFileData, true); |
| 508 | 508 | $actualArray = json_decode($signature, true); |
| 509 | 509 | $this->assertEquals($expectedArray, $actualArray); |
@@ -511,13 +511,13 @@ discard block |
||
| 511 | 511 | }) |
| 512 | 512 | ); |
| 513 | 513 | |
| 514 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 515 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 514 | + $keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/core.crt'); |
|
| 515 | + $rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/core.key'); |
|
| 516 | 516 | $rsa = new RSA(); |
| 517 | 517 | $rsa->loadKey($rsaPrivateKey); |
| 518 | 518 | $x509 = new X509(); |
| 519 | 519 | $x509->loadX509($keyBundle); |
| 520 | - $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 520 | + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT.'/tests/data/integritycheck/app/'); |
|
| 521 | 521 | } |
| 522 | 522 | |
| 523 | 523 | public function testWriteCoreSignatureWithUnmodifiedHtaccess(): void { |
@@ -532,13 +532,13 @@ discard block |
||
| 532 | 532 | $this->environmentHelper |
| 533 | 533 | ->expects($this->any()) |
| 534 | 534 | ->method('getServerRoot') |
| 535 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/'); |
|
| 535 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessUnmodified/'); |
|
| 536 | 536 | $this->fileAccessHelper |
| 537 | 537 | ->expects($this->once()) |
| 538 | 538 | ->method('file_put_contents') |
| 539 | 539 | ->with( |
| 540 | - \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified//core/signature.json', |
|
| 541 | - $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 540 | + \OC::$SERVERROOT.'/tests/data/integritycheck/htaccessUnmodified//core/signature.json', |
|
| 541 | + $this->callback(function($signature) use ($expectedSignatureFileData) { |
|
| 542 | 542 | $expectedArray = json_decode($expectedSignatureFileData, true); |
| 543 | 543 | $actualArray = json_decode($signature, true); |
| 544 | 544 | $this->assertEquals($expectedArray, $actualArray); |
@@ -546,13 +546,13 @@ discard block |
||
| 546 | 546 | }) |
| 547 | 547 | ); |
| 548 | 548 | |
| 549 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 550 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 549 | + $keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/core.crt'); |
|
| 550 | + $rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/core.key'); |
|
| 551 | 551 | $rsa = new RSA(); |
| 552 | 552 | $rsa->loadKey($rsaPrivateKey); |
| 553 | 553 | $x509 = new X509(); |
| 554 | 554 | $x509->loadX509($keyBundle); |
| 555 | - $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/'); |
|
| 555 | + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT.'/tests/data/integritycheck/htaccessUnmodified/'); |
|
| 556 | 556 | } |
| 557 | 557 | |
| 558 | 558 | public function testWriteCoreSignatureWithInvalidModifiedHtaccess(): void { |
@@ -567,8 +567,8 @@ discard block |
||
| 567 | 567 | ->expects($this->once()) |
| 568 | 568 | ->method('file_put_contents') |
| 569 | 569 | ->with( |
| 570 | - \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent//core/signature.json', |
|
| 571 | - $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 570 | + \OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithInvalidModifiedContent//core/signature.json', |
|
| 571 | + $this->callback(function($signature) use ($expectedSignatureFileData) { |
|
| 572 | 572 | $expectedArray = json_decode($expectedSignatureFileData, true); |
| 573 | 573 | $actualArray = json_decode($signature, true); |
| 574 | 574 | $this->assertEquals($expectedArray, $actualArray); |
@@ -576,13 +576,13 @@ discard block |
||
| 576 | 576 | }) |
| 577 | 577 | ); |
| 578 | 578 | |
| 579 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 580 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 579 | + $keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/core.crt'); |
|
| 580 | + $rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/core.key'); |
|
| 581 | 581 | $rsa = new RSA(); |
| 582 | 582 | $rsa->loadKey($rsaPrivateKey); |
| 583 | 583 | $x509 = new X509(); |
| 584 | 584 | $x509->loadX509($keyBundle); |
| 585 | - $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent/'); |
|
| 585 | + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithInvalidModifiedContent/'); |
|
| 586 | 586 | } |
| 587 | 587 | |
| 588 | 588 | public function testWriteCoreSignatureWithValidModifiedHtaccess(): void { |
@@ -597,13 +597,13 @@ discard block |
||
| 597 | 597 | $this->environmentHelper |
| 598 | 598 | ->expects($this->any()) |
| 599 | 599 | ->method('getServerRoot') |
| 600 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 600 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 601 | 601 | $this->fileAccessHelper |
| 602 | 602 | ->expects($this->once()) |
| 603 | 603 | ->method('file_put_contents') |
| 604 | 604 | ->with( |
| 605 | - \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', |
|
| 606 | - $this->callback(function ($signature) use ($expectedSignatureFileData) { |
|
| 605 | + \OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', |
|
| 606 | + $this->callback(function($signature) use ($expectedSignatureFileData) { |
|
| 607 | 607 | $expectedArray = json_decode($expectedSignatureFileData, true); |
| 608 | 608 | $actualArray = json_decode($signature, true); |
| 609 | 609 | $this->assertEquals($expectedArray, $actualArray); |
@@ -611,13 +611,13 @@ discard block |
||
| 611 | 611 | }) |
| 612 | 612 | ); |
| 613 | 613 | |
| 614 | - $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt'); |
|
| 615 | - $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key'); |
|
| 614 | + $keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/core.crt'); |
|
| 615 | + $rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/core.key'); |
|
| 616 | 616 | $rsa = new RSA(); |
| 617 | 617 | $rsa->loadKey($rsaPrivateKey); |
| 618 | 618 | $x509 = new X509(); |
| 619 | 619 | $x509->loadX509($keyBundle); |
| 620 | - $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 620 | + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 621 | 621 | } |
| 622 | 622 | |
| 623 | 623 | public function testVerifyCoreSignatureWithoutSignatureData(): void { |
@@ -654,7 +654,7 @@ discard block |
||
| 654 | 654 | $this->environmentHelper |
| 655 | 655 | ->expects($this->any()) |
| 656 | 656 | ->method('getServerRoot') |
| 657 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 657 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/'); |
|
| 658 | 658 | $signatureDataFile = '{ |
| 659 | 659 | "hashes": { |
| 660 | 660 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
@@ -667,8 +667,8 @@ discard block |
||
| 667 | 667 | ->expects($this->exactly(2)) |
| 668 | 668 | ->method('file_get_contents') |
| 669 | 669 | ->willReturnMap([ |
| 670 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 671 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 670 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 671 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 672 | 672 | ]); |
| 673 | 673 | |
| 674 | 674 | $this->assertSame([], $this->checker->verifyCoreSignature()); |
@@ -688,7 +688,7 @@ discard block |
||
| 688 | 688 | $this->environmentHelper |
| 689 | 689 | ->expects($this->any()) |
| 690 | 690 | ->method('getServerRoot') |
| 691 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 691 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent'); |
|
| 692 | 692 | $signatureDataFile = '{ |
| 693 | 693 | "hashes": { |
| 694 | 694 | ".htaccess": "7e6a7a4d8ee4f3fbc45dd579407c643471575a9d127d1c75f6d0a49e80766c3c587104b2139ef76d2a4bffce3f45777900605aaa49519c9532909b71e5030227", |
@@ -701,8 +701,8 @@ discard block |
||
| 701 | 701 | ->expects($this->exactly(2)) |
| 702 | 702 | ->method('file_get_contents') |
| 703 | 703 | ->willReturnMap([ |
| 704 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', $signatureDataFile], |
|
| 705 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 704 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', $signatureDataFile], |
|
| 705 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 706 | 706 | ]); |
| 707 | 707 | |
| 708 | 708 | $this->assertSame([], $this->checker->verifyCoreSignature()); |
@@ -712,7 +712,7 @@ discard block |
||
| 712 | 712 | * See inline instruction on how to update the test assets when changing mimetypealiases.dist.json |
| 713 | 713 | */ |
| 714 | 714 | public function testVerifyCoreSignatureWithModifiedMimetypelistSignatureData(): void { |
| 715 | - $shippedMimetypeAliases = (array)json_decode(file_get_contents(\OC::$SERVERROOT . '/resources/config/mimetypealiases.dist.json')); |
|
| 715 | + $shippedMimetypeAliases = (array) json_decode(file_get_contents(\OC::$SERVERROOT.'/resources/config/mimetypealiases.dist.json')); |
|
| 716 | 716 | $allAliases = array_merge($shippedMimetypeAliases, ['my-custom/mimetype' => 'custom']); |
| 717 | 717 | |
| 718 | 718 | $this->mimeTypeDetector |
@@ -732,7 +732,7 @@ discard block |
||
| 732 | 732 | // file_put_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js', $newFile); |
| 733 | 733 | // 2. Update signature.json using the following occ command: |
| 734 | 734 | // occ integrity:sign-core --privateKey=./tests/data/integritycheck/core.key --certificate=./tests/data/integritycheck/core.crt --path=./tests/data/integritycheck/mimetypeListModified |
| 735 | - self::assertEquals($newFile, file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js')); |
|
| 735 | + self::assertEquals($newFile, file_get_contents(\OC::$SERVERROOT.'/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js')); |
|
| 736 | 736 | |
| 737 | 737 | $this->serverVersion |
| 738 | 738 | ->expects($this->once()) |
@@ -747,14 +747,14 @@ discard block |
||
| 747 | 747 | $this->environmentHelper |
| 748 | 748 | ->expects($this->any()) |
| 749 | 749 | ->method('getServerRoot') |
| 750 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified'); |
|
| 750 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/mimetypeListModified'); |
|
| 751 | 751 | |
| 752 | - $signatureDataFile = file_get_contents(__DIR__ . '/../../data/integritycheck/mimetypeListModified/core/signature.json'); |
|
| 752 | + $signatureDataFile = file_get_contents(__DIR__.'/../../data/integritycheck/mimetypeListModified/core/signature.json'); |
|
| 753 | 753 | $this->fileAccessHelper |
| 754 | 754 | ->method('file_get_contents') |
| 755 | 755 | ->willReturnMap([ |
| 756 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/signature.json', $signatureDataFile], |
|
| 757 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 756 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/mimetypeListModified/core/signature.json', $signatureDataFile], |
|
| 757 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/mimetypeListModified/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 758 | 758 | ]); |
| 759 | 759 | |
| 760 | 760 | $this->assertSame([], $this->checker->verifyCoreSignature()); |
@@ -774,7 +774,7 @@ discard block |
||
| 774 | 774 | $this->environmentHelper |
| 775 | 775 | ->expects($this->any()) |
| 776 | 776 | ->method('getServerRoot') |
| 777 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 777 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/'); |
|
| 778 | 778 | $signatureDataFile = '{ |
| 779 | 779 | "hashes": { |
| 780 | 780 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
@@ -787,8 +787,8 @@ discard block |
||
| 787 | 787 | ->expects($this->exactly(2)) |
| 788 | 788 | ->method('file_get_contents') |
| 789 | 789 | ->willReturnMap([ |
| 790 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 791 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 790 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 791 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 792 | 792 | ]); |
| 793 | 793 | |
| 794 | 794 | $this->assertSame([], $this->checker->verifyCoreSignature()); |
@@ -808,7 +808,7 @@ discard block |
||
| 808 | 808 | $this->environmentHelper |
| 809 | 809 | ->expects($this->any()) |
| 810 | 810 | ->method('getServerRoot') |
| 811 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 811 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData/'); |
|
| 812 | 812 | $signatureDataFile = '{ |
| 813 | 813 | "hashes": { |
| 814 | 814 | "AnotherFile.txt": "tampered", |
@@ -821,8 +821,8 @@ discard block |
||
| 821 | 821 | ->expects($this->exactly(2)) |
| 822 | 822 | ->method('file_get_contents') |
| 823 | 823 | ->willReturnMap([ |
| 824 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile], |
|
| 825 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 824 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile], |
|
| 825 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 826 | 826 | ]); |
| 827 | 827 | |
| 828 | 828 | $expected = [ |
@@ -848,7 +848,7 @@ discard block |
||
| 848 | 848 | $this->environmentHelper |
| 849 | 849 | ->expects($this->any()) |
| 850 | 850 | ->method('getServerRoot') |
| 851 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'); |
|
| 851 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData/'); |
|
| 852 | 852 | $signatureDataFile = '{ |
| 853 | 853 | "hashes": { |
| 854 | 854 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
@@ -861,8 +861,8 @@ discard block |
||
| 861 | 861 | ->expects($this->exactly(2)) |
| 862 | 862 | ->method('file_get_contents') |
| 863 | 863 | ->willReturnMap([ |
| 864 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile], |
|
| 865 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 864 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile], |
|
| 865 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 866 | 866 | ]); |
| 867 | 867 | |
| 868 | 868 | $expected = [ |
@@ -903,7 +903,7 @@ discard block |
||
| 903 | 903 | $this->environmentHelper |
| 904 | 904 | ->expects($this->any()) |
| 905 | 905 | ->method('getServerRoot') |
| 906 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 906 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/'); |
|
| 907 | 907 | $signatureDataFile = '{ |
| 908 | 908 | "hashes": { |
| 909 | 909 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
@@ -916,8 +916,8 @@ discard block |
||
| 916 | 916 | ->expects($this->exactly(2)) |
| 917 | 917 | ->method('file_get_contents') |
| 918 | 918 | ->willReturnMap([ |
| 919 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 920 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 919 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 920 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 921 | 921 | ]); |
| 922 | 922 | |
| 923 | 923 | $expected = [ |
@@ -943,7 +943,7 @@ discard block |
||
| 943 | 943 | $this->environmentHelper |
| 944 | 944 | ->expects($this->any()) |
| 945 | 945 | ->method('getServerRoot') |
| 946 | - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/'); |
|
| 946 | + ->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/'); |
|
| 947 | 947 | $signatureDataFile = '{ |
| 948 | 948 | "hashes": { |
| 949 | 949 | "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112", |
@@ -956,8 +956,8 @@ discard block |
||
| 956 | 956 | ->expects($this->exactly(2)) |
| 957 | 957 | ->method('file_get_contents') |
| 958 | 958 | ->willReturnMap([ |
| 959 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 960 | - [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')], |
|
| 959 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/app//core/signature.json', $signatureDataFile], |
|
| 960 | + [\OC::$SERVERROOT.'/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')], |
|
| 961 | 961 | ]); |
| 962 | 962 | |
| 963 | 963 | $expected = [ |
@@ -1018,7 +1018,7 @@ discard block |
||
| 1018 | 1018 | $this->checker |
| 1019 | 1019 | ->expects($this->exactly(3)) |
| 1020 | 1020 | ->method('verifyAppSignature') |
| 1021 | - ->willReturnCallback(function ($app) use (&$calls) { |
|
| 1021 | + ->willReturnCallback(function($app) use (&$calls) { |
|
| 1022 | 1022 | $expected = array_shift($calls); |
| 1023 | 1023 | $this->assertSame($expected, $app); |
| 1024 | 1024 | return []; |
@@ -26,55 +26,55 @@ discard block |
||
| 26 | 26 | use Test\TestCase; |
| 27 | 27 | |
| 28 | 28 | class CreateEmpty extends ACreateEmpty { |
| 29 | - public function getId(): string { |
|
| 30 | - return 'createEmpty'; |
|
| 31 | - } |
|
| 29 | + public function getId(): string { |
|
| 30 | + return 'createEmpty'; |
|
| 31 | + } |
|
| 32 | 32 | |
| 33 | - public function getName(): string { |
|
| 34 | - return 'create empty file'; |
|
| 35 | - } |
|
| 33 | + public function getName(): string { |
|
| 34 | + return 'create empty file'; |
|
| 35 | + } |
|
| 36 | 36 | |
| 37 | - public function getExtension(): string { |
|
| 38 | - return '.txt'; |
|
| 39 | - } |
|
| 37 | + public function getExtension(): string { |
|
| 38 | + return '.txt'; |
|
| 39 | + } |
|
| 40 | 40 | |
| 41 | - public function getMimetype(): string { |
|
| 42 | - return 'text/plain'; |
|
| 43 | - } |
|
| 41 | + public function getMimetype(): string { |
|
| 42 | + return 'text/plain'; |
|
| 43 | + } |
|
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | class Editor implements IEditor { |
| 47 | - public function getId(): string { |
|
| 48 | - return 'testeditor'; |
|
| 49 | - } |
|
| 47 | + public function getId(): string { |
|
| 48 | + return 'testeditor'; |
|
| 49 | + } |
|
| 50 | 50 | |
| 51 | - public function getName(): string { |
|
| 52 | - return 'Test editor'; |
|
| 53 | - } |
|
| 51 | + public function getName(): string { |
|
| 52 | + return 'Test editor'; |
|
| 53 | + } |
|
| 54 | 54 | |
| 55 | - public function getMimetypes(): array { |
|
| 56 | - return [ 'text/plain' ]; |
|
| 57 | - } |
|
| 55 | + public function getMimetypes(): array { |
|
| 56 | + return [ 'text/plain' ]; |
|
| 57 | + } |
|
| 58 | 58 | |
| 59 | 59 | |
| 60 | - public function getMimetypesOptional(): array { |
|
| 61 | - return []; |
|
| 62 | - } |
|
| 60 | + public function getMimetypesOptional(): array { |
|
| 61 | + return []; |
|
| 62 | + } |
|
| 63 | 63 | |
| 64 | - public function getCreators(): array { |
|
| 65 | - return [ |
|
| 66 | - new CreateEmpty() |
|
| 67 | - ]; |
|
| 68 | - } |
|
| 64 | + public function getCreators(): array { |
|
| 65 | + return [ |
|
| 66 | + new CreateEmpty() |
|
| 67 | + ]; |
|
| 68 | + } |
|
| 69 | 69 | |
| 70 | - public function isSecure(): bool { |
|
| 71 | - return false; |
|
| 72 | - } |
|
| 70 | + public function isSecure(): bool { |
|
| 71 | + return false; |
|
| 72 | + } |
|
| 73 | 73 | |
| 74 | 74 | |
| 75 | - public function open(IToken $token): Response { |
|
| 76 | - return new DataResponse('edit page'); |
|
| 77 | - } |
|
| 75 | + public function open(IToken $token): Response { |
|
| 76 | + return new DataResponse('edit page'); |
|
| 77 | + } |
|
| 78 | 78 | } |
| 79 | 79 | |
| 80 | 80 | /** |
@@ -84,230 +84,230 @@ discard block |
||
| 84 | 84 | * @group DB |
| 85 | 85 | */ |
| 86 | 86 | class ManagerTest extends TestCase { |
| 87 | - private $manager; |
|
| 88 | - /** |
|
| 89 | - * @var Editor |
|
| 90 | - */ |
|
| 91 | - private $editor; |
|
| 92 | - /** |
|
| 93 | - * @var MockObject|ISecureRandom |
|
| 94 | - */ |
|
| 95 | - private $random; |
|
| 96 | - /** |
|
| 97 | - * @var IDBConnection |
|
| 98 | - */ |
|
| 99 | - private $connection; |
|
| 100 | - /** |
|
| 101 | - * @var MockObject|IUserSession |
|
| 102 | - */ |
|
| 103 | - private $userSession; |
|
| 104 | - /** |
|
| 105 | - * @var MockObject|IRootFolder |
|
| 106 | - */ |
|
| 107 | - private $rootFolder; |
|
| 108 | - /** |
|
| 109 | - * @var MockObject|Folder |
|
| 110 | - */ |
|
| 111 | - private $userFolder; |
|
| 112 | - /** |
|
| 113 | - * @var MockObject|IL10N |
|
| 114 | - */ |
|
| 115 | - private $l10n; |
|
| 116 | - /** |
|
| 117 | - * @var MockObject|IManager |
|
| 118 | - */ |
|
| 119 | - private $encryptionManager; |
|
| 120 | - |
|
| 121 | - protected function setUp(): void { |
|
| 122 | - parent::setUp(); |
|
| 123 | - |
|
| 124 | - $this->editor = new Editor(); |
|
| 125 | - |
|
| 126 | - $this->random = $this->createMock(ISecureRandom::class); |
|
| 127 | - $this->connection = \OC::$server->getDatabaseConnection(); |
|
| 128 | - $this->userSession = $this->createMock(IUserSession::class); |
|
| 129 | - $this->rootFolder = $this->createMock(IRootFolder::class); |
|
| 130 | - $this->userFolder = $this->createMock(Folder::class); |
|
| 131 | - $this->l10n = $this->createMock(IL10N::class); |
|
| 132 | - $this->encryptionManager = $this->createMock(IManager::class); |
|
| 133 | - |
|
| 134 | - $l10nFactory = $this->createMock(IFactory::class); |
|
| 135 | - $l10nFactory->expects($this->once()) |
|
| 136 | - ->method('get') |
|
| 137 | - ->willReturn($this->l10n); |
|
| 138 | - |
|
| 139 | - |
|
| 140 | - $this->rootFolder->expects($this->any()) |
|
| 141 | - ->method('getUserFolder') |
|
| 142 | - ->willReturn($this->userFolder); |
|
| 143 | - |
|
| 144 | - $user = $this->createMock(IUser::class); |
|
| 145 | - $user->expects(self::any()) |
|
| 146 | - ->method('getUID') |
|
| 147 | - ->willReturn('admin'); |
|
| 148 | - $this->userSession->expects(self::any()) |
|
| 149 | - ->method('getUser') |
|
| 150 | - ->willReturn($user); |
|
| 151 | - |
|
| 152 | - $this->manager = new Manager( |
|
| 153 | - $this->random, $this->connection, $this->userSession, $this->rootFolder, $l10nFactory, $this->encryptionManager |
|
| 154 | - ); |
|
| 155 | - |
|
| 156 | - $this->manager->registerDirectEditor($this->editor); |
|
| 157 | - } |
|
| 158 | - |
|
| 159 | - public function testEditorRegistration(): void { |
|
| 160 | - $this->assertEquals($this->manager->getEditors(), ['testeditor' => $this->editor]); |
|
| 161 | - } |
|
| 162 | - |
|
| 163 | - |
|
| 164 | - public function testCreateToken(): void { |
|
| 165 | - $expectedToken = 'TOKEN' . time(); |
|
| 166 | - $file = $this->createMock(File::class); |
|
| 167 | - $file->expects($this->any()) |
|
| 168 | - ->method('getId') |
|
| 169 | - ->willReturn(123); |
|
| 170 | - $this->random->expects($this->once()) |
|
| 171 | - ->method('generate') |
|
| 172 | - ->willReturn($expectedToken); |
|
| 173 | - $folder = $this->createMock(Folder::class); |
|
| 174 | - $this->userFolder |
|
| 175 | - ->method('nodeExists') |
|
| 176 | - ->willReturnMap([ |
|
| 177 | - ['/File.txt', false], |
|
| 178 | - ['/', true], |
|
| 179 | - ]); |
|
| 180 | - $this->userFolder |
|
| 181 | - ->method('get') |
|
| 182 | - ->with('/') |
|
| 183 | - ->willReturn($folder); |
|
| 184 | - $folder->expects($this->once()) |
|
| 185 | - ->method('newFile') |
|
| 186 | - ->willReturn($file); |
|
| 187 | - $token = $this->manager->create('/File.txt', 'testeditor', 'createEmpty'); |
|
| 188 | - $this->assertEquals($token, $expectedToken); |
|
| 189 | - } |
|
| 190 | - |
|
| 191 | - public function testCreateTokenAccess(): void { |
|
| 192 | - $expectedToken = 'TOKEN' . time(); |
|
| 193 | - $file = $this->createMock(File::class); |
|
| 194 | - $file->expects($this->any()) |
|
| 195 | - ->method('getId') |
|
| 196 | - ->willReturn(123); |
|
| 197 | - $this->random->expects($this->once()) |
|
| 198 | - ->method('generate') |
|
| 199 | - ->willReturn($expectedToken); |
|
| 200 | - $folder = $this->createMock(Folder::class); |
|
| 201 | - $this->userFolder |
|
| 202 | - ->method('nodeExists') |
|
| 203 | - ->willReturnMap([ |
|
| 204 | - ['/File.txt', false], |
|
| 205 | - ['/', true], |
|
| 206 | - ]); |
|
| 207 | - $this->userFolder |
|
| 208 | - ->method('get') |
|
| 209 | - ->with('/') |
|
| 210 | - ->willReturn($folder); |
|
| 211 | - $folder->expects($this->once()) |
|
| 212 | - ->method('newFile') |
|
| 213 | - ->willReturn($file); |
|
| 214 | - $this->manager->create('/File.txt', 'testeditor', 'createEmpty'); |
|
| 215 | - $firstResult = $this->manager->edit($expectedToken); |
|
| 216 | - $secondResult = $this->manager->edit($expectedToken); |
|
| 217 | - $this->assertInstanceOf(DataResponse::class, $firstResult); |
|
| 218 | - $this->assertInstanceOf(NotFoundResponse::class, $secondResult); |
|
| 219 | - } |
|
| 220 | - |
|
| 221 | - public function testOpenByPath(): void { |
|
| 222 | - $expectedToken = 'TOKEN' . time(); |
|
| 223 | - $file = $this->createMock(File::class); |
|
| 224 | - $file->expects($this->any()) |
|
| 225 | - ->method('getId') |
|
| 226 | - ->willReturn(123); |
|
| 227 | - $file->expects($this->any()) |
|
| 228 | - ->method('getPath') |
|
| 229 | - ->willReturn('/admin/files/File.txt'); |
|
| 230 | - $this->random->expects($this->once()) |
|
| 231 | - ->method('generate') |
|
| 232 | - ->willReturn($expectedToken); |
|
| 233 | - $this->userFolder |
|
| 234 | - ->method('nodeExists') |
|
| 235 | - ->willReturnMap([ |
|
| 236 | - ['/File.txt', false], |
|
| 237 | - ['/', true], |
|
| 238 | - ]); |
|
| 239 | - $this->userFolder |
|
| 240 | - ->method('get') |
|
| 241 | - ->with('/File.txt') |
|
| 242 | - ->willReturn($file); |
|
| 243 | - $this->userFolder |
|
| 244 | - ->method('getRelativePath') |
|
| 245 | - ->willReturn('/File.txt'); |
|
| 246 | - $this->manager->open('/File.txt', 'testeditor'); |
|
| 247 | - $firstResult = $this->manager->edit($expectedToken); |
|
| 248 | - $secondResult = $this->manager->edit($expectedToken); |
|
| 249 | - $this->assertInstanceOf(DataResponse::class, $firstResult); |
|
| 250 | - $this->assertInstanceOf(NotFoundResponse::class, $secondResult); |
|
| 251 | - } |
|
| 252 | - |
|
| 253 | - public function testOpenById(): void { |
|
| 254 | - $expectedToken = 'TOKEN' . time(); |
|
| 255 | - $fileRead = $this->createMock(File::class); |
|
| 256 | - $fileRead->method('getPermissions') |
|
| 257 | - ->willReturn(1); |
|
| 258 | - $fileRead->expects($this->any()) |
|
| 259 | - ->method('getId') |
|
| 260 | - ->willReturn(123); |
|
| 261 | - $fileRead->expects($this->any()) |
|
| 262 | - ->method('getPath') |
|
| 263 | - ->willReturn('/admin/files/shared_file.txt'); |
|
| 264 | - $file = $this->createMock(File::class); |
|
| 265 | - $file->method('getPermissions') |
|
| 266 | - ->willReturn(1); |
|
| 267 | - $file->expects($this->any()) |
|
| 268 | - ->method('getId') |
|
| 269 | - ->willReturn(123); |
|
| 270 | - $file->expects($this->any()) |
|
| 271 | - ->method('getPath') |
|
| 272 | - ->willReturn('/admin/files/File.txt'); |
|
| 273 | - $this->random->expects($this->once()) |
|
| 274 | - ->method('generate') |
|
| 275 | - ->willReturn($expectedToken); |
|
| 276 | - $folder = $this->createMock(Folder::class); |
|
| 277 | - $folder->expects($this->any()) |
|
| 278 | - ->method('getById') |
|
| 279 | - ->willReturn([ |
|
| 280 | - $fileRead, |
|
| 281 | - $file |
|
| 282 | - ]); |
|
| 283 | - $this->userFolder |
|
| 284 | - ->method('nodeExists') |
|
| 285 | - ->willReturnMap([ |
|
| 286 | - ['/File.txt', false], |
|
| 287 | - ['/', true], |
|
| 288 | - ]); |
|
| 289 | - $this->userFolder |
|
| 290 | - ->method('get') |
|
| 291 | - ->with('/') |
|
| 292 | - ->willReturn($folder); |
|
| 293 | - $this->userFolder |
|
| 294 | - ->method('getRelativePath') |
|
| 295 | - ->willReturn('/File.txt'); |
|
| 296 | - |
|
| 297 | - $this->manager->open('/', 'testeditor', 123); |
|
| 298 | - $firstResult = $this->manager->edit($expectedToken); |
|
| 299 | - $secondResult = $this->manager->edit($expectedToken); |
|
| 300 | - $this->assertInstanceOf(DataResponse::class, $firstResult); |
|
| 301 | - $this->assertInstanceOf(NotFoundResponse::class, $secondResult); |
|
| 302 | - } |
|
| 303 | - |
|
| 304 | - public function testCreateFileAlreadyExists(): void { |
|
| 305 | - $this->expectException(\RuntimeException::class); |
|
| 306 | - $this->userFolder |
|
| 307 | - ->method('nodeExists') |
|
| 308 | - ->with('/File.txt') |
|
| 309 | - ->willReturn(true); |
|
| 310 | - |
|
| 311 | - $this->manager->create('/File.txt', 'testeditor', 'createEmpty'); |
|
| 312 | - } |
|
| 87 | + private $manager; |
|
| 88 | + /** |
|
| 89 | + * @var Editor |
|
| 90 | + */ |
|
| 91 | + private $editor; |
|
| 92 | + /** |
|
| 93 | + * @var MockObject|ISecureRandom |
|
| 94 | + */ |
|
| 95 | + private $random; |
|
| 96 | + /** |
|
| 97 | + * @var IDBConnection |
|
| 98 | + */ |
|
| 99 | + private $connection; |
|
| 100 | + /** |
|
| 101 | + * @var MockObject|IUserSession |
|
| 102 | + */ |
|
| 103 | + private $userSession; |
|
| 104 | + /** |
|
| 105 | + * @var MockObject|IRootFolder |
|
| 106 | + */ |
|
| 107 | + private $rootFolder; |
|
| 108 | + /** |
|
| 109 | + * @var MockObject|Folder |
|
| 110 | + */ |
|
| 111 | + private $userFolder; |
|
| 112 | + /** |
|
| 113 | + * @var MockObject|IL10N |
|
| 114 | + */ |
|
| 115 | + private $l10n; |
|
| 116 | + /** |
|
| 117 | + * @var MockObject|IManager |
|
| 118 | + */ |
|
| 119 | + private $encryptionManager; |
|
| 120 | + |
|
| 121 | + protected function setUp(): void { |
|
| 122 | + parent::setUp(); |
|
| 123 | + |
|
| 124 | + $this->editor = new Editor(); |
|
| 125 | + |
|
| 126 | + $this->random = $this->createMock(ISecureRandom::class); |
|
| 127 | + $this->connection = \OC::$server->getDatabaseConnection(); |
|
| 128 | + $this->userSession = $this->createMock(IUserSession::class); |
|
| 129 | + $this->rootFolder = $this->createMock(IRootFolder::class); |
|
| 130 | + $this->userFolder = $this->createMock(Folder::class); |
|
| 131 | + $this->l10n = $this->createMock(IL10N::class); |
|
| 132 | + $this->encryptionManager = $this->createMock(IManager::class); |
|
| 133 | + |
|
| 134 | + $l10nFactory = $this->createMock(IFactory::class); |
|
| 135 | + $l10nFactory->expects($this->once()) |
|
| 136 | + ->method('get') |
|
| 137 | + ->willReturn($this->l10n); |
|
| 138 | + |
|
| 139 | + |
|
| 140 | + $this->rootFolder->expects($this->any()) |
|
| 141 | + ->method('getUserFolder') |
|
| 142 | + ->willReturn($this->userFolder); |
|
| 143 | + |
|
| 144 | + $user = $this->createMock(IUser::class); |
|
| 145 | + $user->expects(self::any()) |
|
| 146 | + ->method('getUID') |
|
| 147 | + ->willReturn('admin'); |
|
| 148 | + $this->userSession->expects(self::any()) |
|
| 149 | + ->method('getUser') |
|
| 150 | + ->willReturn($user); |
|
| 151 | + |
|
| 152 | + $this->manager = new Manager( |
|
| 153 | + $this->random, $this->connection, $this->userSession, $this->rootFolder, $l10nFactory, $this->encryptionManager |
|
| 154 | + ); |
|
| 155 | + |
|
| 156 | + $this->manager->registerDirectEditor($this->editor); |
|
| 157 | + } |
|
| 158 | + |
|
| 159 | + public function testEditorRegistration(): void { |
|
| 160 | + $this->assertEquals($this->manager->getEditors(), ['testeditor' => $this->editor]); |
|
| 161 | + } |
|
| 162 | + |
|
| 163 | + |
|
| 164 | + public function testCreateToken(): void { |
|
| 165 | + $expectedToken = 'TOKEN' . time(); |
|
| 166 | + $file = $this->createMock(File::class); |
|
| 167 | + $file->expects($this->any()) |
|
| 168 | + ->method('getId') |
|
| 169 | + ->willReturn(123); |
|
| 170 | + $this->random->expects($this->once()) |
|
| 171 | + ->method('generate') |
|
| 172 | + ->willReturn($expectedToken); |
|
| 173 | + $folder = $this->createMock(Folder::class); |
|
| 174 | + $this->userFolder |
|
| 175 | + ->method('nodeExists') |
|
| 176 | + ->willReturnMap([ |
|
| 177 | + ['/File.txt', false], |
|
| 178 | + ['/', true], |
|
| 179 | + ]); |
|
| 180 | + $this->userFolder |
|
| 181 | + ->method('get') |
|
| 182 | + ->with('/') |
|
| 183 | + ->willReturn($folder); |
|
| 184 | + $folder->expects($this->once()) |
|
| 185 | + ->method('newFile') |
|
| 186 | + ->willReturn($file); |
|
| 187 | + $token = $this->manager->create('/File.txt', 'testeditor', 'createEmpty'); |
|
| 188 | + $this->assertEquals($token, $expectedToken); |
|
| 189 | + } |
|
| 190 | + |
|
| 191 | + public function testCreateTokenAccess(): void { |
|
| 192 | + $expectedToken = 'TOKEN' . time(); |
|
| 193 | + $file = $this->createMock(File::class); |
|
| 194 | + $file->expects($this->any()) |
|
| 195 | + ->method('getId') |
|
| 196 | + ->willReturn(123); |
|
| 197 | + $this->random->expects($this->once()) |
|
| 198 | + ->method('generate') |
|
| 199 | + ->willReturn($expectedToken); |
|
| 200 | + $folder = $this->createMock(Folder::class); |
|
| 201 | + $this->userFolder |
|
| 202 | + ->method('nodeExists') |
|
| 203 | + ->willReturnMap([ |
|
| 204 | + ['/File.txt', false], |
|
| 205 | + ['/', true], |
|
| 206 | + ]); |
|
| 207 | + $this->userFolder |
|
| 208 | + ->method('get') |
|
| 209 | + ->with('/') |
|
| 210 | + ->willReturn($folder); |
|
| 211 | + $folder->expects($this->once()) |
|
| 212 | + ->method('newFile') |
|
| 213 | + ->willReturn($file); |
|
| 214 | + $this->manager->create('/File.txt', 'testeditor', 'createEmpty'); |
|
| 215 | + $firstResult = $this->manager->edit($expectedToken); |
|
| 216 | + $secondResult = $this->manager->edit($expectedToken); |
|
| 217 | + $this->assertInstanceOf(DataResponse::class, $firstResult); |
|
| 218 | + $this->assertInstanceOf(NotFoundResponse::class, $secondResult); |
|
| 219 | + } |
|
| 220 | + |
|
| 221 | + public function testOpenByPath(): void { |
|
| 222 | + $expectedToken = 'TOKEN' . time(); |
|
| 223 | + $file = $this->createMock(File::class); |
|
| 224 | + $file->expects($this->any()) |
|
| 225 | + ->method('getId') |
|
| 226 | + ->willReturn(123); |
|
| 227 | + $file->expects($this->any()) |
|
| 228 | + ->method('getPath') |
|
| 229 | + ->willReturn('/admin/files/File.txt'); |
|
| 230 | + $this->random->expects($this->once()) |
|
| 231 | + ->method('generate') |
|
| 232 | + ->willReturn($expectedToken); |
|
| 233 | + $this->userFolder |
|
| 234 | + ->method('nodeExists') |
|
| 235 | + ->willReturnMap([ |
|
| 236 | + ['/File.txt', false], |
|
| 237 | + ['/', true], |
|
| 238 | + ]); |
|
| 239 | + $this->userFolder |
|
| 240 | + ->method('get') |
|
| 241 | + ->with('/File.txt') |
|
| 242 | + ->willReturn($file); |
|
| 243 | + $this->userFolder |
|
| 244 | + ->method('getRelativePath') |
|
| 245 | + ->willReturn('/File.txt'); |
|
| 246 | + $this->manager->open('/File.txt', 'testeditor'); |
|
| 247 | + $firstResult = $this->manager->edit($expectedToken); |
|
| 248 | + $secondResult = $this->manager->edit($expectedToken); |
|
| 249 | + $this->assertInstanceOf(DataResponse::class, $firstResult); |
|
| 250 | + $this->assertInstanceOf(NotFoundResponse::class, $secondResult); |
|
| 251 | + } |
|
| 252 | + |
|
| 253 | + public function testOpenById(): void { |
|
| 254 | + $expectedToken = 'TOKEN' . time(); |
|
| 255 | + $fileRead = $this->createMock(File::class); |
|
| 256 | + $fileRead->method('getPermissions') |
|
| 257 | + ->willReturn(1); |
|
| 258 | + $fileRead->expects($this->any()) |
|
| 259 | + ->method('getId') |
|
| 260 | + ->willReturn(123); |
|
| 261 | + $fileRead->expects($this->any()) |
|
| 262 | + ->method('getPath') |
|
| 263 | + ->willReturn('/admin/files/shared_file.txt'); |
|
| 264 | + $file = $this->createMock(File::class); |
|
| 265 | + $file->method('getPermissions') |
|
| 266 | + ->willReturn(1); |
|
| 267 | + $file->expects($this->any()) |
|
| 268 | + ->method('getId') |
|
| 269 | + ->willReturn(123); |
|
| 270 | + $file->expects($this->any()) |
|
| 271 | + ->method('getPath') |
|
| 272 | + ->willReturn('/admin/files/File.txt'); |
|
| 273 | + $this->random->expects($this->once()) |
|
| 274 | + ->method('generate') |
|
| 275 | + ->willReturn($expectedToken); |
|
| 276 | + $folder = $this->createMock(Folder::class); |
|
| 277 | + $folder->expects($this->any()) |
|
| 278 | + ->method('getById') |
|
| 279 | + ->willReturn([ |
|
| 280 | + $fileRead, |
|
| 281 | + $file |
|
| 282 | + ]); |
|
| 283 | + $this->userFolder |
|
| 284 | + ->method('nodeExists') |
|
| 285 | + ->willReturnMap([ |
|
| 286 | + ['/File.txt', false], |
|
| 287 | + ['/', true], |
|
| 288 | + ]); |
|
| 289 | + $this->userFolder |
|
| 290 | + ->method('get') |
|
| 291 | + ->with('/') |
|
| 292 | + ->willReturn($folder); |
|
| 293 | + $this->userFolder |
|
| 294 | + ->method('getRelativePath') |
|
| 295 | + ->willReturn('/File.txt'); |
|
| 296 | + |
|
| 297 | + $this->manager->open('/', 'testeditor', 123); |
|
| 298 | + $firstResult = $this->manager->edit($expectedToken); |
|
| 299 | + $secondResult = $this->manager->edit($expectedToken); |
|
| 300 | + $this->assertInstanceOf(DataResponse::class, $firstResult); |
|
| 301 | + $this->assertInstanceOf(NotFoundResponse::class, $secondResult); |
|
| 302 | + } |
|
| 303 | + |
|
| 304 | + public function testCreateFileAlreadyExists(): void { |
|
| 305 | + $this->expectException(\RuntimeException::class); |
|
| 306 | + $this->userFolder |
|
| 307 | + ->method('nodeExists') |
|
| 308 | + ->with('/File.txt') |
|
| 309 | + ->willReturn(true); |
|
| 310 | + |
|
| 311 | + $this->manager->create('/File.txt', 'testeditor', 'createEmpty'); |
|
| 312 | + } |
|
| 313 | 313 | } |
@@ -17,599 +17,599 @@ |
||
| 17 | 17 | use Test\TestCase; |
| 18 | 18 | |
| 19 | 19 | class StorageTest extends TestCase { |
| 20 | - /** @var Storage */ |
|
| 21 | - protected $storage; |
|
| 22 | - |
|
| 23 | - /** @var MockObject|\OC\Encryption\Util */ |
|
| 24 | - protected $util; |
|
| 25 | - |
|
| 26 | - /** @var MockObject|View */ |
|
| 27 | - protected $view; |
|
| 28 | - |
|
| 29 | - /** @var MockObject|IConfig */ |
|
| 30 | - protected $config; |
|
| 31 | - |
|
| 32 | - /** @var MockObject|ICrypto */ |
|
| 33 | - protected $crypto; |
|
| 34 | - |
|
| 35 | - private array $mkdirStack = []; |
|
| 36 | - |
|
| 37 | - protected function setUp(): void { |
|
| 38 | - parent::setUp(); |
|
| 39 | - |
|
| 40 | - $this->util = $this->getMockBuilder(Util::class) |
|
| 41 | - ->disableOriginalConstructor() |
|
| 42 | - ->onlyMethods(array_diff(get_class_methods(Util::class), ['getFileKeyDir'])) |
|
| 43 | - ->getMock(); |
|
| 44 | - |
|
| 45 | - $this->view = $this->getMockBuilder(View::class) |
|
| 46 | - ->disableOriginalConstructor() |
|
| 47 | - ->getMock(); |
|
| 48 | - |
|
| 49 | - $this->crypto = $this->createMock(ICrypto::class); |
|
| 50 | - $this->crypto->method('encrypt') |
|
| 51 | - ->willReturnCallback(function ($data, $pass) { |
|
| 52 | - return $data; |
|
| 53 | - }); |
|
| 54 | - $this->crypto->method('decrypt') |
|
| 55 | - ->willReturnCallback(function ($data, $pass) { |
|
| 56 | - return $data; |
|
| 57 | - }); |
|
| 58 | - |
|
| 59 | - $this->config = $this->getMockBuilder(IConfig::class) |
|
| 60 | - ->disableOriginalConstructor() |
|
| 61 | - ->getMock(); |
|
| 62 | - |
|
| 63 | - $this->storage = new Storage($this->view, $this->util, $this->crypto, $this->config); |
|
| 64 | - } |
|
| 65 | - |
|
| 66 | - public function testSetFileKey(): void { |
|
| 67 | - $this->config->method('getSystemValueString') |
|
| 68 | - ->with('version') |
|
| 69 | - ->willReturn('20.0.0.2'); |
|
| 70 | - $this->util->expects($this->any()) |
|
| 71 | - ->method('getUidAndFilename') |
|
| 72 | - ->willReturn(['user1', '/files/foo.txt']); |
|
| 73 | - $this->util->expects($this->any()) |
|
| 74 | - ->method('stripPartialFileExtension') |
|
| 75 | - ->willReturnArgument(0); |
|
| 76 | - $this->util->expects($this->any()) |
|
| 77 | - ->method('isSystemWideMountPoint') |
|
| 78 | - ->willReturn(false); |
|
| 79 | - |
|
| 80 | - $data = json_encode(['key' => base64_encode('key')]); |
|
| 81 | - $this->view->expects($this->once()) |
|
| 82 | - ->method('file_put_contents') |
|
| 83 | - ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'), |
|
| 84 | - $this->equalTo($data)) |
|
| 85 | - ->willReturn(strlen($data)); |
|
| 86 | - |
|
| 87 | - $this->assertTrue( |
|
| 88 | - $this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule') |
|
| 89 | - ); |
|
| 90 | - } |
|
| 91 | - |
|
| 92 | - public function testSetFileOld(): void { |
|
| 93 | - $this->config->method('getSystemValueString') |
|
| 94 | - ->with('version') |
|
| 95 | - ->willReturn('20.0.0.0'); |
|
| 96 | - $this->util->expects($this->any()) |
|
| 97 | - ->method('getUidAndFilename') |
|
| 98 | - ->willReturn(['user1', '/files/foo.txt']); |
|
| 99 | - $this->util->expects($this->any()) |
|
| 100 | - ->method('stripPartialFileExtension') |
|
| 101 | - ->willReturnArgument(0); |
|
| 102 | - $this->util->expects($this->any()) |
|
| 103 | - ->method('isSystemWideMountPoint') |
|
| 104 | - ->willReturn(false); |
|
| 105 | - $this->crypto->expects($this->never()) |
|
| 106 | - ->method('encrypt'); |
|
| 107 | - $this->view->expects($this->once()) |
|
| 108 | - ->method('file_put_contents') |
|
| 109 | - ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'), |
|
| 110 | - $this->equalTo('key')) |
|
| 111 | - ->willReturn(strlen('key')); |
|
| 112 | - |
|
| 113 | - $this->assertTrue( |
|
| 114 | - $this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule') |
|
| 115 | - ); |
|
| 116 | - } |
|
| 117 | - |
|
| 118 | - public static function dataTestGetFileKey() { |
|
| 119 | - return [ |
|
| 120 | - ['/files/foo.txt', '/files/foo.txt', true, 'key'], |
|
| 121 | - ['/files/foo.txt.ocTransferId2111130212.part', '/files/foo.txt', true, 'key'], |
|
| 122 | - ['/files/foo.txt.ocTransferId2111130212.part', '/files/foo.txt', false, 'key2'], |
|
| 123 | - ]; |
|
| 124 | - } |
|
| 125 | - |
|
| 126 | - /** |
|
| 127 | - * @dataProvider dataTestGetFileKey |
|
| 128 | - * |
|
| 129 | - * @param string $path |
|
| 130 | - * @param string $strippedPartialName |
|
| 131 | - * @param bool $originalKeyExists |
|
| 132 | - * @param string $expectedKeyContent |
|
| 133 | - */ |
|
| 134 | - public function testGetFileKey($path, $strippedPartialName, $originalKeyExists, $expectedKeyContent): void { |
|
| 135 | - $this->config->method('getSystemValueString') |
|
| 136 | - ->with('version') |
|
| 137 | - ->willReturn('20.0.0.2'); |
|
| 138 | - $this->util->expects($this->any()) |
|
| 139 | - ->method('getUidAndFilename') |
|
| 140 | - ->willReturnMap([ |
|
| 141 | - ['user1/files/foo.txt', ['user1', '/files/foo.txt']], |
|
| 142 | - ['user1/files/foo.txt.ocTransferId2111130212.part', ['user1', '/files/foo.txt.ocTransferId2111130212.part']], |
|
| 143 | - ]); |
|
| 144 | - // we need to strip away the part file extension in order to reuse a |
|
| 145 | - // existing key if it exists, otherwise versions will break |
|
| 146 | - $this->util->expects($this->once()) |
|
| 147 | - ->method('stripPartialFileExtension') |
|
| 148 | - ->willReturn('user1' . $strippedPartialName); |
|
| 149 | - $this->util->expects($this->any()) |
|
| 150 | - ->method('isSystemWideMountPoint') |
|
| 151 | - ->willReturn(false); |
|
| 152 | - |
|
| 153 | - $this->crypto->method('decrypt') |
|
| 154 | - ->willReturnCallback(function ($data, $pass) { |
|
| 155 | - return $data; |
|
| 156 | - }); |
|
| 157 | - |
|
| 158 | - if (!$originalKeyExists) { |
|
| 159 | - $this->view->expects($this->exactly(2)) |
|
| 160 | - ->method('file_exists') |
|
| 161 | - ->willReturnMap([ |
|
| 162 | - ['/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey', $originalKeyExists], |
|
| 163 | - ['/user1/files_encryption/keys' . $path . '/encModule/fileKey', true], |
|
| 164 | - ]); |
|
| 165 | - |
|
| 166 | - $this->view->expects($this->once()) |
|
| 167 | - ->method('file_get_contents') |
|
| 168 | - ->with($this->equalTo('/user1/files_encryption/keys' . $path . '/encModule/fileKey')) |
|
| 169 | - ->willReturn(json_encode(['key' => base64_encode('key2')])); |
|
| 170 | - } else { |
|
| 171 | - $this->view->expects($this->once()) |
|
| 172 | - ->method('file_exists') |
|
| 173 | - ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')) |
|
| 174 | - ->willReturn($originalKeyExists); |
|
| 175 | - |
|
| 176 | - $this->view->expects($this->once()) |
|
| 177 | - ->method('file_get_contents') |
|
| 178 | - ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')) |
|
| 179 | - ->willReturn(json_encode(['key' => base64_encode('key')])); |
|
| 180 | - } |
|
| 181 | - |
|
| 182 | - $this->assertSame($expectedKeyContent, |
|
| 183 | - $this->storage->getFileKey('user1' . $path, 'fileKey', 'encModule') |
|
| 184 | - ); |
|
| 185 | - } |
|
| 186 | - |
|
| 187 | - public function testSetFileKeySystemWide(): void { |
|
| 188 | - $this->config->method('getSystemValueString') |
|
| 189 | - ->with('version') |
|
| 190 | - ->willReturn('20.0.0.2'); |
|
| 191 | - |
|
| 192 | - $this->util->expects($this->any()) |
|
| 193 | - ->method('getUidAndFilename') |
|
| 194 | - ->willReturn(['user1', '/files/foo.txt']); |
|
| 195 | - $this->util->expects($this->any()) |
|
| 196 | - ->method('isSystemWideMountPoint') |
|
| 197 | - ->willReturn(true); |
|
| 198 | - $this->util->expects($this->any()) |
|
| 199 | - ->method('stripPartialFileExtension') |
|
| 200 | - ->willReturnArgument(0); |
|
| 201 | - |
|
| 202 | - $this->crypto->method('encrypt') |
|
| 203 | - ->willReturnCallback(function ($data, $pass) { |
|
| 204 | - return $data; |
|
| 205 | - }); |
|
| 206 | - |
|
| 207 | - $data = json_encode(['key' => base64_encode('key')]); |
|
| 208 | - $this->view->expects($this->once()) |
|
| 209 | - ->method('file_put_contents') |
|
| 210 | - ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'), |
|
| 211 | - $this->equalTo($data)) |
|
| 212 | - ->willReturn(strlen($data)); |
|
| 213 | - |
|
| 214 | - $this->assertTrue( |
|
| 215 | - $this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule') |
|
| 216 | - ); |
|
| 217 | - } |
|
| 218 | - |
|
| 219 | - public function testGetFileKeySystemWide(): void { |
|
| 220 | - $this->config->method('getSystemValueString') |
|
| 221 | - ->with('version') |
|
| 222 | - ->willReturn('20.0.0.2'); |
|
| 223 | - |
|
| 224 | - $this->util->expects($this->any()) |
|
| 225 | - ->method('getUidAndFilename') |
|
| 226 | - ->willReturn(['user1', '/files/foo.txt']); |
|
| 227 | - $this->util->expects($this->any()) |
|
| 228 | - ->method('stripPartialFileExtension') |
|
| 229 | - ->willReturnArgument(0); |
|
| 230 | - $this->util->expects($this->any()) |
|
| 231 | - ->method('isSystemWideMountPoint') |
|
| 232 | - ->willReturn(true); |
|
| 233 | - $this->view->expects($this->once()) |
|
| 234 | - ->method('file_get_contents') |
|
| 235 | - ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 236 | - ->willReturn(json_encode(['key' => base64_encode('key')])); |
|
| 237 | - $this->view->expects($this->once()) |
|
| 238 | - ->method('file_exists') |
|
| 239 | - ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 240 | - ->willReturn(true); |
|
| 241 | - |
|
| 242 | - $this->assertSame('key', |
|
| 243 | - $this->storage->getFileKey('user1/files/foo.txt', 'fileKey', 'encModule') |
|
| 244 | - ); |
|
| 245 | - } |
|
| 246 | - |
|
| 247 | - public function testSetSystemUserKey(): void { |
|
| 248 | - $this->config->method('getSystemValueString') |
|
| 249 | - ->with('version') |
|
| 250 | - ->willReturn('20.0.0.2'); |
|
| 251 | - |
|
| 252 | - $data = json_encode([ |
|
| 253 | - 'key' => base64_encode('key'), |
|
| 254 | - 'uid' => null] |
|
| 255 | - ); |
|
| 256 | - $this->view->expects($this->once()) |
|
| 257 | - ->method('file_put_contents') |
|
| 258 | - ->with($this->equalTo('/files_encryption/encModule/shareKey_56884'), |
|
| 259 | - $this->equalTo($data)) |
|
| 260 | - ->willReturn(strlen($data)); |
|
| 261 | - |
|
| 262 | - $this->assertTrue( |
|
| 263 | - $this->storage->setSystemUserKey('shareKey_56884', 'key', 'encModule') |
|
| 264 | - ); |
|
| 265 | - } |
|
| 266 | - |
|
| 267 | - public function testSetUserKey(): void { |
|
| 268 | - $this->config->method('getSystemValueString') |
|
| 269 | - ->with('version') |
|
| 270 | - ->willReturn('20.0.0.2'); |
|
| 271 | - |
|
| 272 | - $data = json_encode([ |
|
| 273 | - 'key' => base64_encode('key'), |
|
| 274 | - 'uid' => 'user1'] |
|
| 275 | - ); |
|
| 276 | - $this->view->expects($this->once()) |
|
| 277 | - ->method('file_put_contents') |
|
| 278 | - ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'), |
|
| 279 | - $this->equalTo($data)) |
|
| 280 | - ->willReturn(strlen($data)); |
|
| 281 | - |
|
| 282 | - $this->assertTrue( |
|
| 283 | - $this->storage->setUserKey('user1', 'publicKey', 'key', 'encModule') |
|
| 284 | - ); |
|
| 285 | - } |
|
| 286 | - |
|
| 287 | - public function testGetSystemUserKey(): void { |
|
| 288 | - $this->config->method('getSystemValueString') |
|
| 289 | - ->with('version') |
|
| 290 | - ->willReturn('20.0.0.2'); |
|
| 291 | - |
|
| 292 | - $data = json_encode([ |
|
| 293 | - 'key' => base64_encode('key'), |
|
| 294 | - 'uid' => null] |
|
| 295 | - ); |
|
| 296 | - $this->view->expects($this->once()) |
|
| 297 | - ->method('file_get_contents') |
|
| 298 | - ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) |
|
| 299 | - ->willReturn($data); |
|
| 300 | - $this->view->expects($this->once()) |
|
| 301 | - ->method('file_exists') |
|
| 302 | - ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) |
|
| 303 | - ->willReturn(true); |
|
| 304 | - |
|
| 305 | - $this->assertSame('key', |
|
| 306 | - $this->storage->getSystemUserKey('shareKey_56884', 'encModule') |
|
| 307 | - ); |
|
| 308 | - } |
|
| 309 | - |
|
| 310 | - public function testGetUserKey(): void { |
|
| 311 | - $this->config->method('getSystemValueString') |
|
| 312 | - ->with('version') |
|
| 313 | - ->willReturn('20.0.0.2'); |
|
| 314 | - |
|
| 315 | - $data = json_encode([ |
|
| 316 | - 'key' => base64_encode('key'), |
|
| 317 | - 'uid' => 'user1'] |
|
| 318 | - ); |
|
| 319 | - $this->view->expects($this->once()) |
|
| 320 | - ->method('file_get_contents') |
|
| 321 | - ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) |
|
| 322 | - ->willReturn($data); |
|
| 323 | - $this->view->expects($this->once()) |
|
| 324 | - ->method('file_exists') |
|
| 325 | - ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) |
|
| 326 | - ->willReturn(true); |
|
| 327 | - |
|
| 328 | - $this->assertSame('key', |
|
| 329 | - $this->storage->getUserKey('user1', 'publicKey', 'encModule') |
|
| 330 | - ); |
|
| 331 | - } |
|
| 332 | - |
|
| 333 | - public function testDeleteUserKey(): void { |
|
| 334 | - $this->view->expects($this->once()) |
|
| 335 | - ->method('file_exists') |
|
| 336 | - ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) |
|
| 337 | - ->willReturn(true); |
|
| 338 | - $this->view->expects($this->once()) |
|
| 339 | - ->method('unlink') |
|
| 340 | - ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) |
|
| 341 | - ->willReturn(true); |
|
| 342 | - |
|
| 343 | - $this->assertTrue( |
|
| 344 | - $this->storage->deleteUserKey('user1', 'publicKey', 'encModule') |
|
| 345 | - ); |
|
| 346 | - } |
|
| 347 | - |
|
| 348 | - public function testDeleteSystemUserKey(): void { |
|
| 349 | - $this->view->expects($this->once()) |
|
| 350 | - ->method('file_exists') |
|
| 351 | - ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) |
|
| 352 | - ->willReturn(true); |
|
| 353 | - $this->view->expects($this->once()) |
|
| 354 | - ->method('unlink') |
|
| 355 | - ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) |
|
| 356 | - ->willReturn(true); |
|
| 357 | - |
|
| 358 | - $this->assertTrue( |
|
| 359 | - $this->storage->deleteSystemUserKey('shareKey_56884', 'encModule') |
|
| 360 | - ); |
|
| 361 | - } |
|
| 362 | - |
|
| 363 | - public function testDeleteFileKeySystemWide(): void { |
|
| 364 | - $this->util->expects($this->any()) |
|
| 365 | - ->method('getUidAndFilename') |
|
| 366 | - ->willReturn(['user1', '/files/foo.txt']); |
|
| 367 | - $this->util->expects($this->any()) |
|
| 368 | - ->method('stripPartialFileExtension') |
|
| 369 | - ->willReturnArgument(0); |
|
| 370 | - $this->util->expects($this->any()) |
|
| 371 | - ->method('isSystemWideMountPoint') |
|
| 372 | - ->willReturn(true); |
|
| 373 | - $this->view->expects($this->once()) |
|
| 374 | - ->method('file_exists') |
|
| 375 | - ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 376 | - ->willReturn(true); |
|
| 377 | - $this->view->expects($this->once()) |
|
| 378 | - ->method('unlink') |
|
| 379 | - ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 380 | - ->willReturn(true); |
|
| 381 | - |
|
| 382 | - $this->assertTrue( |
|
| 383 | - $this->storage->deleteFileKey('user1/files/foo.txt', 'fileKey', 'encModule') |
|
| 384 | - ); |
|
| 385 | - } |
|
| 386 | - |
|
| 387 | - public function testDeleteFileKey(): void { |
|
| 388 | - $this->util->expects($this->any()) |
|
| 389 | - ->method('getUidAndFilename') |
|
| 390 | - ->willReturn(['user1', '/files/foo.txt']); |
|
| 391 | - $this->util->expects($this->any()) |
|
| 392 | - ->method('stripPartialFileExtension') |
|
| 393 | - ->willReturnArgument(0); |
|
| 394 | - $this->util->expects($this->any()) |
|
| 395 | - ->method('isSystemWideMountPoint') |
|
| 396 | - ->willReturn(false); |
|
| 397 | - $this->view->expects($this->once()) |
|
| 398 | - ->method('file_exists') |
|
| 399 | - ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 400 | - ->willReturn(true); |
|
| 401 | - $this->view->expects($this->once()) |
|
| 402 | - ->method('unlink') |
|
| 403 | - ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 404 | - ->willReturn(true); |
|
| 405 | - |
|
| 406 | - $this->assertTrue( |
|
| 407 | - $this->storage->deleteFileKey('user1/files/foo.txt', 'fileKey', 'encModule') |
|
| 408 | - ); |
|
| 409 | - } |
|
| 410 | - |
|
| 411 | - /** |
|
| 412 | - * @dataProvider dataProviderCopyRename |
|
| 413 | - */ |
|
| 414 | - public function testRenameKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget): void { |
|
| 415 | - $this->view->expects($this->any()) |
|
| 416 | - ->method('file_exists') |
|
| 417 | - ->willReturn(true); |
|
| 418 | - $this->view->expects($this->any()) |
|
| 419 | - ->method('is_dir') |
|
| 420 | - ->willReturn(true); |
|
| 421 | - $this->view->expects($this->once()) |
|
| 422 | - ->method('rename') |
|
| 423 | - ->with( |
|
| 424 | - $this->equalTo($expectedSource), |
|
| 425 | - $this->equalTo($expectedTarget)) |
|
| 426 | - ->willReturn(true); |
|
| 427 | - $this->util->expects($this->any()) |
|
| 428 | - ->method('getUidAndFilename') |
|
| 429 | - ->willReturnCallback([$this, 'getUidAndFilenameCallback']); |
|
| 430 | - $this->util->expects($this->any()) |
|
| 431 | - ->method('isSystemWideMountPoint') |
|
| 432 | - ->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) { |
|
| 433 | - if (strpos($path, 'source.txt') !== false) { |
|
| 434 | - return $systemWideMountSource; |
|
| 435 | - } |
|
| 436 | - return $systemWideMountTarget; |
|
| 437 | - }); |
|
| 438 | - |
|
| 439 | - $this->storage->renameKeys($source, $target); |
|
| 440 | - } |
|
| 441 | - |
|
| 442 | - /** |
|
| 443 | - * @dataProvider dataProviderCopyRename |
|
| 444 | - */ |
|
| 445 | - public function testCopyKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget): void { |
|
| 446 | - $this->view->expects($this->any()) |
|
| 447 | - ->method('file_exists') |
|
| 448 | - ->willReturn(true); |
|
| 449 | - $this->view->expects($this->any()) |
|
| 450 | - ->method('is_dir') |
|
| 451 | - ->willReturn(true); |
|
| 452 | - $this->view->expects($this->once()) |
|
| 453 | - ->method('copy') |
|
| 454 | - ->with( |
|
| 455 | - $this->equalTo($expectedSource), |
|
| 456 | - $this->equalTo($expectedTarget)) |
|
| 457 | - ->willReturn(true); |
|
| 458 | - $this->util->expects($this->any()) |
|
| 459 | - ->method('getUidAndFilename') |
|
| 460 | - ->willReturnCallback([$this, 'getUidAndFilenameCallback']); |
|
| 461 | - $this->util->expects($this->any()) |
|
| 462 | - ->method('isSystemWideMountPoint') |
|
| 463 | - ->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) { |
|
| 464 | - if (strpos($path, 'source.txt') !== false) { |
|
| 465 | - return $systemWideMountSource; |
|
| 466 | - } |
|
| 467 | - return $systemWideMountTarget; |
|
| 468 | - }); |
|
| 469 | - |
|
| 470 | - $this->storage->copyKeys($source, $target); |
|
| 471 | - } |
|
| 472 | - |
|
| 473 | - public function getUidAndFilenameCallback() { |
|
| 474 | - $args = func_get_args(); |
|
| 475 | - |
|
| 476 | - $path = $args[0]; |
|
| 477 | - $parts = explode('/', $path); |
|
| 478 | - |
|
| 479 | - return [$parts[1], '/' . implode('/', array_slice($parts, 2))]; |
|
| 480 | - } |
|
| 481 | - |
|
| 482 | - public static function dataProviderCopyRename() { |
|
| 483 | - return [ |
|
| 484 | - ['/user1/files/source.txt', '/user1/files/target.txt', false, false, |
|
| 485 | - '/user1/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 486 | - ['/user1/files/foo/source.txt', '/user1/files/target.txt', false, false, |
|
| 487 | - '/user1/files_encryption/keys/files/foo/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 488 | - ['/user1/files/source.txt', '/user1/files/foo/target.txt', false, false, |
|
| 489 | - '/user1/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/foo/target.txt/'], |
|
| 490 | - ['/user1/files/source.txt', '/user1/files/foo/target.txt', true, true, |
|
| 491 | - '/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/foo/target.txt/'], |
|
| 492 | - ['/user1/files/source.txt', '/user1/files/target.txt', false, true, |
|
| 493 | - '/user1/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/target.txt/'], |
|
| 494 | - ['/user1/files/source.txt', '/user1/files/target.txt', true, false, |
|
| 495 | - '/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 496 | - |
|
| 497 | - ['/user2/files/source.txt', '/user1/files/target.txt', false, false, |
|
| 498 | - '/user2/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 499 | - ['/user2/files/foo/source.txt', '/user1/files/target.txt', false, false, |
|
| 500 | - '/user2/files_encryption/keys/files/foo/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 501 | - ['/user2/files/source.txt', '/user1/files/foo/target.txt', false, false, |
|
| 502 | - '/user2/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/foo/target.txt/'], |
|
| 503 | - ['/user2/files/source.txt', '/user1/files/foo/target.txt', true, true, |
|
| 504 | - '/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/foo/target.txt/'], |
|
| 505 | - ['/user2/files/source.txt', '/user1/files/target.txt', false, true, |
|
| 506 | - '/user2/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/target.txt/'], |
|
| 507 | - ['/user2/files/source.txt', '/user1/files/target.txt', true, false, |
|
| 508 | - '/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 509 | - ]; |
|
| 510 | - } |
|
| 511 | - |
|
| 512 | - /** |
|
| 513 | - * @dataProvider dataTestGetPathToKeys |
|
| 514 | - * |
|
| 515 | - * @param string $path |
|
| 516 | - * @param boolean $systemWideMountPoint |
|
| 517 | - * @param string $storageRoot |
|
| 518 | - * @param string $expected |
|
| 519 | - */ |
|
| 520 | - public function testGetPathToKeys($path, $systemWideMountPoint, $storageRoot, $expected): void { |
|
| 521 | - $this->invokePrivate($this->storage, 'root_dir', [$storageRoot]); |
|
| 522 | - |
|
| 523 | - $this->util->expects($this->any()) |
|
| 524 | - ->method('getUidAndFilename') |
|
| 525 | - ->willReturnCallback([$this, 'getUidAndFilenameCallback']); |
|
| 526 | - $this->util->expects($this->any()) |
|
| 527 | - ->method('isSystemWideMountPoint') |
|
| 528 | - ->willReturn($systemWideMountPoint); |
|
| 529 | - |
|
| 530 | - $this->assertSame($expected, |
|
| 531 | - self::invokePrivate($this->storage, 'getPathToKeys', [$path]) |
|
| 532 | - ); |
|
| 533 | - } |
|
| 534 | - |
|
| 535 | - public static function dataTestGetPathToKeys() { |
|
| 536 | - return [ |
|
| 537 | - ['/user1/files/source.txt', false, '', '/user1/files_encryption/keys/files/source.txt/'], |
|
| 538 | - ['/user1/files/source.txt', true, '', '/files_encryption/keys/files/source.txt/'], |
|
| 539 | - ['/user1/files/source.txt', false, 'storageRoot', '/storageRoot/user1/files_encryption/keys/files/source.txt/'], |
|
| 540 | - ['/user1/files/source.txt', true, 'storageRoot', '/storageRoot/files_encryption/keys/files/source.txt/'], |
|
| 541 | - ]; |
|
| 542 | - } |
|
| 543 | - |
|
| 544 | - public function testKeySetPreparation(): void { |
|
| 545 | - $this->view->expects($this->any()) |
|
| 546 | - ->method('file_exists') |
|
| 547 | - ->willReturn(false); |
|
| 548 | - $this->view->expects($this->any()) |
|
| 549 | - ->method('is_dir') |
|
| 550 | - ->willReturn(false); |
|
| 551 | - $this->view->expects($this->any()) |
|
| 552 | - ->method('mkdir') |
|
| 553 | - ->willReturnCallback([$this, 'mkdirCallback']); |
|
| 554 | - |
|
| 555 | - $this->mkdirStack = [ |
|
| 556 | - '/user1/files_encryption/keys/foo', |
|
| 557 | - '/user1/files_encryption/keys', |
|
| 558 | - '/user1/files_encryption', |
|
| 559 | - '/user1']; |
|
| 560 | - |
|
| 561 | - self::invokePrivate($this->storage, 'keySetPreparation', ['/user1/files_encryption/keys/foo']); |
|
| 562 | - } |
|
| 563 | - |
|
| 564 | - public function mkdirCallback() { |
|
| 565 | - $args = func_get_args(); |
|
| 566 | - $expected = array_pop($this->mkdirStack); |
|
| 567 | - $this->assertSame($expected, $args[0]); |
|
| 568 | - } |
|
| 569 | - |
|
| 570 | - |
|
| 571 | - /** |
|
| 572 | - * @dataProvider dataTestBackupUserKeys |
|
| 573 | - * @param bool $createBackupDir |
|
| 574 | - */ |
|
| 575 | - public function testBackupUserKeys($createBackupDir): void { |
|
| 576 | - $storage = $this->getMockBuilder('OC\Encryption\Keys\Storage') |
|
| 577 | - ->setConstructorArgs([$this->view, $this->util, $this->crypto, $this->config]) |
|
| 578 | - ->onlyMethods(['getTimestamp']) |
|
| 579 | - ->getMock(); |
|
| 580 | - |
|
| 581 | - $storage->expects($this->any())->method('getTimestamp')->willReturn('1234567'); |
|
| 582 | - |
|
| 583 | - $this->view->expects($this->once())->method('file_exists') |
|
| 584 | - ->with('user1/files_encryption/backup')->willReturn(!$createBackupDir); |
|
| 585 | - |
|
| 586 | - if ($createBackupDir) { |
|
| 587 | - $calls = [ |
|
| 588 | - 'user1/files_encryption/backup', |
|
| 589 | - 'user1/files_encryption/backup/test.encryptionModule.1234567', |
|
| 590 | - ]; |
|
| 591 | - $this->view->expects($this->exactly(2))->method('mkdir') |
|
| 592 | - ->willReturnCallback(function ($path) use (&$calls) { |
|
| 593 | - $expected = array_shift($calls); |
|
| 594 | - $this->assertEquals($expected, $path); |
|
| 595 | - }); |
|
| 596 | - } else { |
|
| 597 | - $this->view->expects($this->once())->method('mkdir') |
|
| 598 | - ->with('user1/files_encryption/backup/test.encryptionModule.1234567'); |
|
| 599 | - } |
|
| 600 | - |
|
| 601 | - $this->view->expects($this->once())->method('copy') |
|
| 602 | - ->with( |
|
| 603 | - 'user1/files_encryption/encryptionModule', |
|
| 604 | - 'user1/files_encryption/backup/test.encryptionModule.1234567' |
|
| 605 | - )->willReturn(true); |
|
| 606 | - |
|
| 607 | - $this->assertTrue($storage->backupUserKeys('encryptionModule', 'test', 'user1')); |
|
| 608 | - } |
|
| 609 | - |
|
| 610 | - public static function dataTestBackupUserKeys() { |
|
| 611 | - return [ |
|
| 612 | - [true], [false] |
|
| 613 | - ]; |
|
| 614 | - } |
|
| 20 | + /** @var Storage */ |
|
| 21 | + protected $storage; |
|
| 22 | + |
|
| 23 | + /** @var MockObject|\OC\Encryption\Util */ |
|
| 24 | + protected $util; |
|
| 25 | + |
|
| 26 | + /** @var MockObject|View */ |
|
| 27 | + protected $view; |
|
| 28 | + |
|
| 29 | + /** @var MockObject|IConfig */ |
|
| 30 | + protected $config; |
|
| 31 | + |
|
| 32 | + /** @var MockObject|ICrypto */ |
|
| 33 | + protected $crypto; |
|
| 34 | + |
|
| 35 | + private array $mkdirStack = []; |
|
| 36 | + |
|
| 37 | + protected function setUp(): void { |
|
| 38 | + parent::setUp(); |
|
| 39 | + |
|
| 40 | + $this->util = $this->getMockBuilder(Util::class) |
|
| 41 | + ->disableOriginalConstructor() |
|
| 42 | + ->onlyMethods(array_diff(get_class_methods(Util::class), ['getFileKeyDir'])) |
|
| 43 | + ->getMock(); |
|
| 44 | + |
|
| 45 | + $this->view = $this->getMockBuilder(View::class) |
|
| 46 | + ->disableOriginalConstructor() |
|
| 47 | + ->getMock(); |
|
| 48 | + |
|
| 49 | + $this->crypto = $this->createMock(ICrypto::class); |
|
| 50 | + $this->crypto->method('encrypt') |
|
| 51 | + ->willReturnCallback(function ($data, $pass) { |
|
| 52 | + return $data; |
|
| 53 | + }); |
|
| 54 | + $this->crypto->method('decrypt') |
|
| 55 | + ->willReturnCallback(function ($data, $pass) { |
|
| 56 | + return $data; |
|
| 57 | + }); |
|
| 58 | + |
|
| 59 | + $this->config = $this->getMockBuilder(IConfig::class) |
|
| 60 | + ->disableOriginalConstructor() |
|
| 61 | + ->getMock(); |
|
| 62 | + |
|
| 63 | + $this->storage = new Storage($this->view, $this->util, $this->crypto, $this->config); |
|
| 64 | + } |
|
| 65 | + |
|
| 66 | + public function testSetFileKey(): void { |
|
| 67 | + $this->config->method('getSystemValueString') |
|
| 68 | + ->with('version') |
|
| 69 | + ->willReturn('20.0.0.2'); |
|
| 70 | + $this->util->expects($this->any()) |
|
| 71 | + ->method('getUidAndFilename') |
|
| 72 | + ->willReturn(['user1', '/files/foo.txt']); |
|
| 73 | + $this->util->expects($this->any()) |
|
| 74 | + ->method('stripPartialFileExtension') |
|
| 75 | + ->willReturnArgument(0); |
|
| 76 | + $this->util->expects($this->any()) |
|
| 77 | + ->method('isSystemWideMountPoint') |
|
| 78 | + ->willReturn(false); |
|
| 79 | + |
|
| 80 | + $data = json_encode(['key' => base64_encode('key')]); |
|
| 81 | + $this->view->expects($this->once()) |
|
| 82 | + ->method('file_put_contents') |
|
| 83 | + ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'), |
|
| 84 | + $this->equalTo($data)) |
|
| 85 | + ->willReturn(strlen($data)); |
|
| 86 | + |
|
| 87 | + $this->assertTrue( |
|
| 88 | + $this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule') |
|
| 89 | + ); |
|
| 90 | + } |
|
| 91 | + |
|
| 92 | + public function testSetFileOld(): void { |
|
| 93 | + $this->config->method('getSystemValueString') |
|
| 94 | + ->with('version') |
|
| 95 | + ->willReturn('20.0.0.0'); |
|
| 96 | + $this->util->expects($this->any()) |
|
| 97 | + ->method('getUidAndFilename') |
|
| 98 | + ->willReturn(['user1', '/files/foo.txt']); |
|
| 99 | + $this->util->expects($this->any()) |
|
| 100 | + ->method('stripPartialFileExtension') |
|
| 101 | + ->willReturnArgument(0); |
|
| 102 | + $this->util->expects($this->any()) |
|
| 103 | + ->method('isSystemWideMountPoint') |
|
| 104 | + ->willReturn(false); |
|
| 105 | + $this->crypto->expects($this->never()) |
|
| 106 | + ->method('encrypt'); |
|
| 107 | + $this->view->expects($this->once()) |
|
| 108 | + ->method('file_put_contents') |
|
| 109 | + ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'), |
|
| 110 | + $this->equalTo('key')) |
|
| 111 | + ->willReturn(strlen('key')); |
|
| 112 | + |
|
| 113 | + $this->assertTrue( |
|
| 114 | + $this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule') |
|
| 115 | + ); |
|
| 116 | + } |
|
| 117 | + |
|
| 118 | + public static function dataTestGetFileKey() { |
|
| 119 | + return [ |
|
| 120 | + ['/files/foo.txt', '/files/foo.txt', true, 'key'], |
|
| 121 | + ['/files/foo.txt.ocTransferId2111130212.part', '/files/foo.txt', true, 'key'], |
|
| 122 | + ['/files/foo.txt.ocTransferId2111130212.part', '/files/foo.txt', false, 'key2'], |
|
| 123 | + ]; |
|
| 124 | + } |
|
| 125 | + |
|
| 126 | + /** |
|
| 127 | + * @dataProvider dataTestGetFileKey |
|
| 128 | + * |
|
| 129 | + * @param string $path |
|
| 130 | + * @param string $strippedPartialName |
|
| 131 | + * @param bool $originalKeyExists |
|
| 132 | + * @param string $expectedKeyContent |
|
| 133 | + */ |
|
| 134 | + public function testGetFileKey($path, $strippedPartialName, $originalKeyExists, $expectedKeyContent): void { |
|
| 135 | + $this->config->method('getSystemValueString') |
|
| 136 | + ->with('version') |
|
| 137 | + ->willReturn('20.0.0.2'); |
|
| 138 | + $this->util->expects($this->any()) |
|
| 139 | + ->method('getUidAndFilename') |
|
| 140 | + ->willReturnMap([ |
|
| 141 | + ['user1/files/foo.txt', ['user1', '/files/foo.txt']], |
|
| 142 | + ['user1/files/foo.txt.ocTransferId2111130212.part', ['user1', '/files/foo.txt.ocTransferId2111130212.part']], |
|
| 143 | + ]); |
|
| 144 | + // we need to strip away the part file extension in order to reuse a |
|
| 145 | + // existing key if it exists, otherwise versions will break |
|
| 146 | + $this->util->expects($this->once()) |
|
| 147 | + ->method('stripPartialFileExtension') |
|
| 148 | + ->willReturn('user1' . $strippedPartialName); |
|
| 149 | + $this->util->expects($this->any()) |
|
| 150 | + ->method('isSystemWideMountPoint') |
|
| 151 | + ->willReturn(false); |
|
| 152 | + |
|
| 153 | + $this->crypto->method('decrypt') |
|
| 154 | + ->willReturnCallback(function ($data, $pass) { |
|
| 155 | + return $data; |
|
| 156 | + }); |
|
| 157 | + |
|
| 158 | + if (!$originalKeyExists) { |
|
| 159 | + $this->view->expects($this->exactly(2)) |
|
| 160 | + ->method('file_exists') |
|
| 161 | + ->willReturnMap([ |
|
| 162 | + ['/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey', $originalKeyExists], |
|
| 163 | + ['/user1/files_encryption/keys' . $path . '/encModule/fileKey', true], |
|
| 164 | + ]); |
|
| 165 | + |
|
| 166 | + $this->view->expects($this->once()) |
|
| 167 | + ->method('file_get_contents') |
|
| 168 | + ->with($this->equalTo('/user1/files_encryption/keys' . $path . '/encModule/fileKey')) |
|
| 169 | + ->willReturn(json_encode(['key' => base64_encode('key2')])); |
|
| 170 | + } else { |
|
| 171 | + $this->view->expects($this->once()) |
|
| 172 | + ->method('file_exists') |
|
| 173 | + ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')) |
|
| 174 | + ->willReturn($originalKeyExists); |
|
| 175 | + |
|
| 176 | + $this->view->expects($this->once()) |
|
| 177 | + ->method('file_get_contents') |
|
| 178 | + ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')) |
|
| 179 | + ->willReturn(json_encode(['key' => base64_encode('key')])); |
|
| 180 | + } |
|
| 181 | + |
|
| 182 | + $this->assertSame($expectedKeyContent, |
|
| 183 | + $this->storage->getFileKey('user1' . $path, 'fileKey', 'encModule') |
|
| 184 | + ); |
|
| 185 | + } |
|
| 186 | + |
|
| 187 | + public function testSetFileKeySystemWide(): void { |
|
| 188 | + $this->config->method('getSystemValueString') |
|
| 189 | + ->with('version') |
|
| 190 | + ->willReturn('20.0.0.2'); |
|
| 191 | + |
|
| 192 | + $this->util->expects($this->any()) |
|
| 193 | + ->method('getUidAndFilename') |
|
| 194 | + ->willReturn(['user1', '/files/foo.txt']); |
|
| 195 | + $this->util->expects($this->any()) |
|
| 196 | + ->method('isSystemWideMountPoint') |
|
| 197 | + ->willReturn(true); |
|
| 198 | + $this->util->expects($this->any()) |
|
| 199 | + ->method('stripPartialFileExtension') |
|
| 200 | + ->willReturnArgument(0); |
|
| 201 | + |
|
| 202 | + $this->crypto->method('encrypt') |
|
| 203 | + ->willReturnCallback(function ($data, $pass) { |
|
| 204 | + return $data; |
|
| 205 | + }); |
|
| 206 | + |
|
| 207 | + $data = json_encode(['key' => base64_encode('key')]); |
|
| 208 | + $this->view->expects($this->once()) |
|
| 209 | + ->method('file_put_contents') |
|
| 210 | + ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'), |
|
| 211 | + $this->equalTo($data)) |
|
| 212 | + ->willReturn(strlen($data)); |
|
| 213 | + |
|
| 214 | + $this->assertTrue( |
|
| 215 | + $this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule') |
|
| 216 | + ); |
|
| 217 | + } |
|
| 218 | + |
|
| 219 | + public function testGetFileKeySystemWide(): void { |
|
| 220 | + $this->config->method('getSystemValueString') |
|
| 221 | + ->with('version') |
|
| 222 | + ->willReturn('20.0.0.2'); |
|
| 223 | + |
|
| 224 | + $this->util->expects($this->any()) |
|
| 225 | + ->method('getUidAndFilename') |
|
| 226 | + ->willReturn(['user1', '/files/foo.txt']); |
|
| 227 | + $this->util->expects($this->any()) |
|
| 228 | + ->method('stripPartialFileExtension') |
|
| 229 | + ->willReturnArgument(0); |
|
| 230 | + $this->util->expects($this->any()) |
|
| 231 | + ->method('isSystemWideMountPoint') |
|
| 232 | + ->willReturn(true); |
|
| 233 | + $this->view->expects($this->once()) |
|
| 234 | + ->method('file_get_contents') |
|
| 235 | + ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 236 | + ->willReturn(json_encode(['key' => base64_encode('key')])); |
|
| 237 | + $this->view->expects($this->once()) |
|
| 238 | + ->method('file_exists') |
|
| 239 | + ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 240 | + ->willReturn(true); |
|
| 241 | + |
|
| 242 | + $this->assertSame('key', |
|
| 243 | + $this->storage->getFileKey('user1/files/foo.txt', 'fileKey', 'encModule') |
|
| 244 | + ); |
|
| 245 | + } |
|
| 246 | + |
|
| 247 | + public function testSetSystemUserKey(): void { |
|
| 248 | + $this->config->method('getSystemValueString') |
|
| 249 | + ->with('version') |
|
| 250 | + ->willReturn('20.0.0.2'); |
|
| 251 | + |
|
| 252 | + $data = json_encode([ |
|
| 253 | + 'key' => base64_encode('key'), |
|
| 254 | + 'uid' => null] |
|
| 255 | + ); |
|
| 256 | + $this->view->expects($this->once()) |
|
| 257 | + ->method('file_put_contents') |
|
| 258 | + ->with($this->equalTo('/files_encryption/encModule/shareKey_56884'), |
|
| 259 | + $this->equalTo($data)) |
|
| 260 | + ->willReturn(strlen($data)); |
|
| 261 | + |
|
| 262 | + $this->assertTrue( |
|
| 263 | + $this->storage->setSystemUserKey('shareKey_56884', 'key', 'encModule') |
|
| 264 | + ); |
|
| 265 | + } |
|
| 266 | + |
|
| 267 | + public function testSetUserKey(): void { |
|
| 268 | + $this->config->method('getSystemValueString') |
|
| 269 | + ->with('version') |
|
| 270 | + ->willReturn('20.0.0.2'); |
|
| 271 | + |
|
| 272 | + $data = json_encode([ |
|
| 273 | + 'key' => base64_encode('key'), |
|
| 274 | + 'uid' => 'user1'] |
|
| 275 | + ); |
|
| 276 | + $this->view->expects($this->once()) |
|
| 277 | + ->method('file_put_contents') |
|
| 278 | + ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'), |
|
| 279 | + $this->equalTo($data)) |
|
| 280 | + ->willReturn(strlen($data)); |
|
| 281 | + |
|
| 282 | + $this->assertTrue( |
|
| 283 | + $this->storage->setUserKey('user1', 'publicKey', 'key', 'encModule') |
|
| 284 | + ); |
|
| 285 | + } |
|
| 286 | + |
|
| 287 | + public function testGetSystemUserKey(): void { |
|
| 288 | + $this->config->method('getSystemValueString') |
|
| 289 | + ->with('version') |
|
| 290 | + ->willReturn('20.0.0.2'); |
|
| 291 | + |
|
| 292 | + $data = json_encode([ |
|
| 293 | + 'key' => base64_encode('key'), |
|
| 294 | + 'uid' => null] |
|
| 295 | + ); |
|
| 296 | + $this->view->expects($this->once()) |
|
| 297 | + ->method('file_get_contents') |
|
| 298 | + ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) |
|
| 299 | + ->willReturn($data); |
|
| 300 | + $this->view->expects($this->once()) |
|
| 301 | + ->method('file_exists') |
|
| 302 | + ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) |
|
| 303 | + ->willReturn(true); |
|
| 304 | + |
|
| 305 | + $this->assertSame('key', |
|
| 306 | + $this->storage->getSystemUserKey('shareKey_56884', 'encModule') |
|
| 307 | + ); |
|
| 308 | + } |
|
| 309 | + |
|
| 310 | + public function testGetUserKey(): void { |
|
| 311 | + $this->config->method('getSystemValueString') |
|
| 312 | + ->with('version') |
|
| 313 | + ->willReturn('20.0.0.2'); |
|
| 314 | + |
|
| 315 | + $data = json_encode([ |
|
| 316 | + 'key' => base64_encode('key'), |
|
| 317 | + 'uid' => 'user1'] |
|
| 318 | + ); |
|
| 319 | + $this->view->expects($this->once()) |
|
| 320 | + ->method('file_get_contents') |
|
| 321 | + ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) |
|
| 322 | + ->willReturn($data); |
|
| 323 | + $this->view->expects($this->once()) |
|
| 324 | + ->method('file_exists') |
|
| 325 | + ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) |
|
| 326 | + ->willReturn(true); |
|
| 327 | + |
|
| 328 | + $this->assertSame('key', |
|
| 329 | + $this->storage->getUserKey('user1', 'publicKey', 'encModule') |
|
| 330 | + ); |
|
| 331 | + } |
|
| 332 | + |
|
| 333 | + public function testDeleteUserKey(): void { |
|
| 334 | + $this->view->expects($this->once()) |
|
| 335 | + ->method('file_exists') |
|
| 336 | + ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) |
|
| 337 | + ->willReturn(true); |
|
| 338 | + $this->view->expects($this->once()) |
|
| 339 | + ->method('unlink') |
|
| 340 | + ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) |
|
| 341 | + ->willReturn(true); |
|
| 342 | + |
|
| 343 | + $this->assertTrue( |
|
| 344 | + $this->storage->deleteUserKey('user1', 'publicKey', 'encModule') |
|
| 345 | + ); |
|
| 346 | + } |
|
| 347 | + |
|
| 348 | + public function testDeleteSystemUserKey(): void { |
|
| 349 | + $this->view->expects($this->once()) |
|
| 350 | + ->method('file_exists') |
|
| 351 | + ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) |
|
| 352 | + ->willReturn(true); |
|
| 353 | + $this->view->expects($this->once()) |
|
| 354 | + ->method('unlink') |
|
| 355 | + ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) |
|
| 356 | + ->willReturn(true); |
|
| 357 | + |
|
| 358 | + $this->assertTrue( |
|
| 359 | + $this->storage->deleteSystemUserKey('shareKey_56884', 'encModule') |
|
| 360 | + ); |
|
| 361 | + } |
|
| 362 | + |
|
| 363 | + public function testDeleteFileKeySystemWide(): void { |
|
| 364 | + $this->util->expects($this->any()) |
|
| 365 | + ->method('getUidAndFilename') |
|
| 366 | + ->willReturn(['user1', '/files/foo.txt']); |
|
| 367 | + $this->util->expects($this->any()) |
|
| 368 | + ->method('stripPartialFileExtension') |
|
| 369 | + ->willReturnArgument(0); |
|
| 370 | + $this->util->expects($this->any()) |
|
| 371 | + ->method('isSystemWideMountPoint') |
|
| 372 | + ->willReturn(true); |
|
| 373 | + $this->view->expects($this->once()) |
|
| 374 | + ->method('file_exists') |
|
| 375 | + ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 376 | + ->willReturn(true); |
|
| 377 | + $this->view->expects($this->once()) |
|
| 378 | + ->method('unlink') |
|
| 379 | + ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 380 | + ->willReturn(true); |
|
| 381 | + |
|
| 382 | + $this->assertTrue( |
|
| 383 | + $this->storage->deleteFileKey('user1/files/foo.txt', 'fileKey', 'encModule') |
|
| 384 | + ); |
|
| 385 | + } |
|
| 386 | + |
|
| 387 | + public function testDeleteFileKey(): void { |
|
| 388 | + $this->util->expects($this->any()) |
|
| 389 | + ->method('getUidAndFilename') |
|
| 390 | + ->willReturn(['user1', '/files/foo.txt']); |
|
| 391 | + $this->util->expects($this->any()) |
|
| 392 | + ->method('stripPartialFileExtension') |
|
| 393 | + ->willReturnArgument(0); |
|
| 394 | + $this->util->expects($this->any()) |
|
| 395 | + ->method('isSystemWideMountPoint') |
|
| 396 | + ->willReturn(false); |
|
| 397 | + $this->view->expects($this->once()) |
|
| 398 | + ->method('file_exists') |
|
| 399 | + ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 400 | + ->willReturn(true); |
|
| 401 | + $this->view->expects($this->once()) |
|
| 402 | + ->method('unlink') |
|
| 403 | + ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey')) |
|
| 404 | + ->willReturn(true); |
|
| 405 | + |
|
| 406 | + $this->assertTrue( |
|
| 407 | + $this->storage->deleteFileKey('user1/files/foo.txt', 'fileKey', 'encModule') |
|
| 408 | + ); |
|
| 409 | + } |
|
| 410 | + |
|
| 411 | + /** |
|
| 412 | + * @dataProvider dataProviderCopyRename |
|
| 413 | + */ |
|
| 414 | + public function testRenameKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget): void { |
|
| 415 | + $this->view->expects($this->any()) |
|
| 416 | + ->method('file_exists') |
|
| 417 | + ->willReturn(true); |
|
| 418 | + $this->view->expects($this->any()) |
|
| 419 | + ->method('is_dir') |
|
| 420 | + ->willReturn(true); |
|
| 421 | + $this->view->expects($this->once()) |
|
| 422 | + ->method('rename') |
|
| 423 | + ->with( |
|
| 424 | + $this->equalTo($expectedSource), |
|
| 425 | + $this->equalTo($expectedTarget)) |
|
| 426 | + ->willReturn(true); |
|
| 427 | + $this->util->expects($this->any()) |
|
| 428 | + ->method('getUidAndFilename') |
|
| 429 | + ->willReturnCallback([$this, 'getUidAndFilenameCallback']); |
|
| 430 | + $this->util->expects($this->any()) |
|
| 431 | + ->method('isSystemWideMountPoint') |
|
| 432 | + ->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) { |
|
| 433 | + if (strpos($path, 'source.txt') !== false) { |
|
| 434 | + return $systemWideMountSource; |
|
| 435 | + } |
|
| 436 | + return $systemWideMountTarget; |
|
| 437 | + }); |
|
| 438 | + |
|
| 439 | + $this->storage->renameKeys($source, $target); |
|
| 440 | + } |
|
| 441 | + |
|
| 442 | + /** |
|
| 443 | + * @dataProvider dataProviderCopyRename |
|
| 444 | + */ |
|
| 445 | + public function testCopyKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget): void { |
|
| 446 | + $this->view->expects($this->any()) |
|
| 447 | + ->method('file_exists') |
|
| 448 | + ->willReturn(true); |
|
| 449 | + $this->view->expects($this->any()) |
|
| 450 | + ->method('is_dir') |
|
| 451 | + ->willReturn(true); |
|
| 452 | + $this->view->expects($this->once()) |
|
| 453 | + ->method('copy') |
|
| 454 | + ->with( |
|
| 455 | + $this->equalTo($expectedSource), |
|
| 456 | + $this->equalTo($expectedTarget)) |
|
| 457 | + ->willReturn(true); |
|
| 458 | + $this->util->expects($this->any()) |
|
| 459 | + ->method('getUidAndFilename') |
|
| 460 | + ->willReturnCallback([$this, 'getUidAndFilenameCallback']); |
|
| 461 | + $this->util->expects($this->any()) |
|
| 462 | + ->method('isSystemWideMountPoint') |
|
| 463 | + ->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) { |
|
| 464 | + if (strpos($path, 'source.txt') !== false) { |
|
| 465 | + return $systemWideMountSource; |
|
| 466 | + } |
|
| 467 | + return $systemWideMountTarget; |
|
| 468 | + }); |
|
| 469 | + |
|
| 470 | + $this->storage->copyKeys($source, $target); |
|
| 471 | + } |
|
| 472 | + |
|
| 473 | + public function getUidAndFilenameCallback() { |
|
| 474 | + $args = func_get_args(); |
|
| 475 | + |
|
| 476 | + $path = $args[0]; |
|
| 477 | + $parts = explode('/', $path); |
|
| 478 | + |
|
| 479 | + return [$parts[1], '/' . implode('/', array_slice($parts, 2))]; |
|
| 480 | + } |
|
| 481 | + |
|
| 482 | + public static function dataProviderCopyRename() { |
|
| 483 | + return [ |
|
| 484 | + ['/user1/files/source.txt', '/user1/files/target.txt', false, false, |
|
| 485 | + '/user1/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 486 | + ['/user1/files/foo/source.txt', '/user1/files/target.txt', false, false, |
|
| 487 | + '/user1/files_encryption/keys/files/foo/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 488 | + ['/user1/files/source.txt', '/user1/files/foo/target.txt', false, false, |
|
| 489 | + '/user1/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/foo/target.txt/'], |
|
| 490 | + ['/user1/files/source.txt', '/user1/files/foo/target.txt', true, true, |
|
| 491 | + '/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/foo/target.txt/'], |
|
| 492 | + ['/user1/files/source.txt', '/user1/files/target.txt', false, true, |
|
| 493 | + '/user1/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/target.txt/'], |
|
| 494 | + ['/user1/files/source.txt', '/user1/files/target.txt', true, false, |
|
| 495 | + '/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 496 | + |
|
| 497 | + ['/user2/files/source.txt', '/user1/files/target.txt', false, false, |
|
| 498 | + '/user2/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 499 | + ['/user2/files/foo/source.txt', '/user1/files/target.txt', false, false, |
|
| 500 | + '/user2/files_encryption/keys/files/foo/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 501 | + ['/user2/files/source.txt', '/user1/files/foo/target.txt', false, false, |
|
| 502 | + '/user2/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/foo/target.txt/'], |
|
| 503 | + ['/user2/files/source.txt', '/user1/files/foo/target.txt', true, true, |
|
| 504 | + '/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/foo/target.txt/'], |
|
| 505 | + ['/user2/files/source.txt', '/user1/files/target.txt', false, true, |
|
| 506 | + '/user2/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/target.txt/'], |
|
| 507 | + ['/user2/files/source.txt', '/user1/files/target.txt', true, false, |
|
| 508 | + '/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], |
|
| 509 | + ]; |
|
| 510 | + } |
|
| 511 | + |
|
| 512 | + /** |
|
| 513 | + * @dataProvider dataTestGetPathToKeys |
|
| 514 | + * |
|
| 515 | + * @param string $path |
|
| 516 | + * @param boolean $systemWideMountPoint |
|
| 517 | + * @param string $storageRoot |
|
| 518 | + * @param string $expected |
|
| 519 | + */ |
|
| 520 | + public function testGetPathToKeys($path, $systemWideMountPoint, $storageRoot, $expected): void { |
|
| 521 | + $this->invokePrivate($this->storage, 'root_dir', [$storageRoot]); |
|
| 522 | + |
|
| 523 | + $this->util->expects($this->any()) |
|
| 524 | + ->method('getUidAndFilename') |
|
| 525 | + ->willReturnCallback([$this, 'getUidAndFilenameCallback']); |
|
| 526 | + $this->util->expects($this->any()) |
|
| 527 | + ->method('isSystemWideMountPoint') |
|
| 528 | + ->willReturn($systemWideMountPoint); |
|
| 529 | + |
|
| 530 | + $this->assertSame($expected, |
|
| 531 | + self::invokePrivate($this->storage, 'getPathToKeys', [$path]) |
|
| 532 | + ); |
|
| 533 | + } |
|
| 534 | + |
|
| 535 | + public static function dataTestGetPathToKeys() { |
|
| 536 | + return [ |
|
| 537 | + ['/user1/files/source.txt', false, '', '/user1/files_encryption/keys/files/source.txt/'], |
|
| 538 | + ['/user1/files/source.txt', true, '', '/files_encryption/keys/files/source.txt/'], |
|
| 539 | + ['/user1/files/source.txt', false, 'storageRoot', '/storageRoot/user1/files_encryption/keys/files/source.txt/'], |
|
| 540 | + ['/user1/files/source.txt', true, 'storageRoot', '/storageRoot/files_encryption/keys/files/source.txt/'], |
|
| 541 | + ]; |
|
| 542 | + } |
|
| 543 | + |
|
| 544 | + public function testKeySetPreparation(): void { |
|
| 545 | + $this->view->expects($this->any()) |
|
| 546 | + ->method('file_exists') |
|
| 547 | + ->willReturn(false); |
|
| 548 | + $this->view->expects($this->any()) |
|
| 549 | + ->method('is_dir') |
|
| 550 | + ->willReturn(false); |
|
| 551 | + $this->view->expects($this->any()) |
|
| 552 | + ->method('mkdir') |
|
| 553 | + ->willReturnCallback([$this, 'mkdirCallback']); |
|
| 554 | + |
|
| 555 | + $this->mkdirStack = [ |
|
| 556 | + '/user1/files_encryption/keys/foo', |
|
| 557 | + '/user1/files_encryption/keys', |
|
| 558 | + '/user1/files_encryption', |
|
| 559 | + '/user1']; |
|
| 560 | + |
|
| 561 | + self::invokePrivate($this->storage, 'keySetPreparation', ['/user1/files_encryption/keys/foo']); |
|
| 562 | + } |
|
| 563 | + |
|
| 564 | + public function mkdirCallback() { |
|
| 565 | + $args = func_get_args(); |
|
| 566 | + $expected = array_pop($this->mkdirStack); |
|
| 567 | + $this->assertSame($expected, $args[0]); |
|
| 568 | + } |
|
| 569 | + |
|
| 570 | + |
|
| 571 | + /** |
|
| 572 | + * @dataProvider dataTestBackupUserKeys |
|
| 573 | + * @param bool $createBackupDir |
|
| 574 | + */ |
|
| 575 | + public function testBackupUserKeys($createBackupDir): void { |
|
| 576 | + $storage = $this->getMockBuilder('OC\Encryption\Keys\Storage') |
|
| 577 | + ->setConstructorArgs([$this->view, $this->util, $this->crypto, $this->config]) |
|
| 578 | + ->onlyMethods(['getTimestamp']) |
|
| 579 | + ->getMock(); |
|
| 580 | + |
|
| 581 | + $storage->expects($this->any())->method('getTimestamp')->willReturn('1234567'); |
|
| 582 | + |
|
| 583 | + $this->view->expects($this->once())->method('file_exists') |
|
| 584 | + ->with('user1/files_encryption/backup')->willReturn(!$createBackupDir); |
|
| 585 | + |
|
| 586 | + if ($createBackupDir) { |
|
| 587 | + $calls = [ |
|
| 588 | + 'user1/files_encryption/backup', |
|
| 589 | + 'user1/files_encryption/backup/test.encryptionModule.1234567', |
|
| 590 | + ]; |
|
| 591 | + $this->view->expects($this->exactly(2))->method('mkdir') |
|
| 592 | + ->willReturnCallback(function ($path) use (&$calls) { |
|
| 593 | + $expected = array_shift($calls); |
|
| 594 | + $this->assertEquals($expected, $path); |
|
| 595 | + }); |
|
| 596 | + } else { |
|
| 597 | + $this->view->expects($this->once())->method('mkdir') |
|
| 598 | + ->with('user1/files_encryption/backup/test.encryptionModule.1234567'); |
|
| 599 | + } |
|
| 600 | + |
|
| 601 | + $this->view->expects($this->once())->method('copy') |
|
| 602 | + ->with( |
|
| 603 | + 'user1/files_encryption/encryptionModule', |
|
| 604 | + 'user1/files_encryption/backup/test.encryptionModule.1234567' |
|
| 605 | + )->willReturn(true); |
|
| 606 | + |
|
| 607 | + $this->assertTrue($storage->backupUserKeys('encryptionModule', 'test', 'user1')); |
|
| 608 | + } |
|
| 609 | + |
|
| 610 | + public static function dataTestBackupUserKeys() { |
|
| 611 | + return [ |
|
| 612 | + [true], [false] |
|
| 613 | + ]; |
|
| 614 | + } |
|
| 615 | 615 | } |
@@ -48,11 +48,11 @@ discard block |
||
| 48 | 48 | |
| 49 | 49 | $this->crypto = $this->createMock(ICrypto::class); |
| 50 | 50 | $this->crypto->method('encrypt') |
| 51 | - ->willReturnCallback(function ($data, $pass) { |
|
| 51 | + ->willReturnCallback(function($data, $pass) { |
|
| 52 | 52 | return $data; |
| 53 | 53 | }); |
| 54 | 54 | $this->crypto->method('decrypt') |
| 55 | - ->willReturnCallback(function ($data, $pass) { |
|
| 55 | + ->willReturnCallback(function($data, $pass) { |
|
| 56 | 56 | return $data; |
| 57 | 57 | }); |
| 58 | 58 | |
@@ -145,13 +145,13 @@ discard block |
||
| 145 | 145 | // existing key if it exists, otherwise versions will break |
| 146 | 146 | $this->util->expects($this->once()) |
| 147 | 147 | ->method('stripPartialFileExtension') |
| 148 | - ->willReturn('user1' . $strippedPartialName); |
|
| 148 | + ->willReturn('user1'.$strippedPartialName); |
|
| 149 | 149 | $this->util->expects($this->any()) |
| 150 | 150 | ->method('isSystemWideMountPoint') |
| 151 | 151 | ->willReturn(false); |
| 152 | 152 | |
| 153 | 153 | $this->crypto->method('decrypt') |
| 154 | - ->willReturnCallback(function ($data, $pass) { |
|
| 154 | + ->willReturnCallback(function($data, $pass) { |
|
| 155 | 155 | return $data; |
| 156 | 156 | }); |
| 157 | 157 | |
@@ -159,28 +159,28 @@ discard block |
||
| 159 | 159 | $this->view->expects($this->exactly(2)) |
| 160 | 160 | ->method('file_exists') |
| 161 | 161 | ->willReturnMap([ |
| 162 | - ['/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey', $originalKeyExists], |
|
| 163 | - ['/user1/files_encryption/keys' . $path . '/encModule/fileKey', true], |
|
| 162 | + ['/user1/files_encryption/keys'.$strippedPartialName.'/encModule/fileKey', $originalKeyExists], |
|
| 163 | + ['/user1/files_encryption/keys'.$path.'/encModule/fileKey', true], |
|
| 164 | 164 | ]); |
| 165 | 165 | |
| 166 | 166 | $this->view->expects($this->once()) |
| 167 | 167 | ->method('file_get_contents') |
| 168 | - ->with($this->equalTo('/user1/files_encryption/keys' . $path . '/encModule/fileKey')) |
|
| 168 | + ->with($this->equalTo('/user1/files_encryption/keys'.$path.'/encModule/fileKey')) |
|
| 169 | 169 | ->willReturn(json_encode(['key' => base64_encode('key2')])); |
| 170 | 170 | } else { |
| 171 | 171 | $this->view->expects($this->once()) |
| 172 | 172 | ->method('file_exists') |
| 173 | - ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')) |
|
| 173 | + ->with($this->equalTo('/user1/files_encryption/keys'.$strippedPartialName.'/encModule/fileKey')) |
|
| 174 | 174 | ->willReturn($originalKeyExists); |
| 175 | 175 | |
| 176 | 176 | $this->view->expects($this->once()) |
| 177 | 177 | ->method('file_get_contents') |
| 178 | - ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')) |
|
| 178 | + ->with($this->equalTo('/user1/files_encryption/keys'.$strippedPartialName.'/encModule/fileKey')) |
|
| 179 | 179 | ->willReturn(json_encode(['key' => base64_encode('key')])); |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | 182 | $this->assertSame($expectedKeyContent, |
| 183 | - $this->storage->getFileKey('user1' . $path, 'fileKey', 'encModule') |
|
| 183 | + $this->storage->getFileKey('user1'.$path, 'fileKey', 'encModule') |
|
| 184 | 184 | ); |
| 185 | 185 | } |
| 186 | 186 | |
@@ -200,7 +200,7 @@ discard block |
||
| 200 | 200 | ->willReturnArgument(0); |
| 201 | 201 | |
| 202 | 202 | $this->crypto->method('encrypt') |
| 203 | - ->willReturnCallback(function ($data, $pass) { |
|
| 203 | + ->willReturnCallback(function($data, $pass) { |
|
| 204 | 204 | return $data; |
| 205 | 205 | }); |
| 206 | 206 | |
@@ -429,7 +429,7 @@ discard block |
||
| 429 | 429 | ->willReturnCallback([$this, 'getUidAndFilenameCallback']); |
| 430 | 430 | $this->util->expects($this->any()) |
| 431 | 431 | ->method('isSystemWideMountPoint') |
| 432 | - ->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) { |
|
| 432 | + ->willReturnCallback(function($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) { |
|
| 433 | 433 | if (strpos($path, 'source.txt') !== false) { |
| 434 | 434 | return $systemWideMountSource; |
| 435 | 435 | } |
@@ -460,7 +460,7 @@ discard block |
||
| 460 | 460 | ->willReturnCallback([$this, 'getUidAndFilenameCallback']); |
| 461 | 461 | $this->util->expects($this->any()) |
| 462 | 462 | ->method('isSystemWideMountPoint') |
| 463 | - ->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) { |
|
| 463 | + ->willReturnCallback(function($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) { |
|
| 464 | 464 | if (strpos($path, 'source.txt') !== false) { |
| 465 | 465 | return $systemWideMountSource; |
| 466 | 466 | } |
@@ -476,7 +476,7 @@ discard block |
||
| 476 | 476 | $path = $args[0]; |
| 477 | 477 | $parts = explode('/', $path); |
| 478 | 478 | |
| 479 | - return [$parts[1], '/' . implode('/', array_slice($parts, 2))]; |
|
| 479 | + return [$parts[1], '/'.implode('/', array_slice($parts, 2))]; |
|
| 480 | 480 | } |
| 481 | 481 | |
| 482 | 482 | public static function dataProviderCopyRename() { |
@@ -589,7 +589,7 @@ discard block |
||
| 589 | 589 | 'user1/files_encryption/backup/test.encryptionModule.1234567', |
| 590 | 590 | ]; |
| 591 | 591 | $this->view->expects($this->exactly(2))->method('mkdir') |
| 592 | - ->willReturnCallback(function ($path) use (&$calls) { |
|
| 592 | + ->willReturnCallback(function($path) use (&$calls) { |
|
| 593 | 593 | $expected = array_shift($calls); |
| 594 | 594 | $this->assertEquals($expected, $path); |
| 595 | 595 | }); |
@@ -29,379 +29,379 @@ |
||
| 29 | 29 | * @package Test\Encryption |
| 30 | 30 | */ |
| 31 | 31 | class DecryptAllTest extends TestCase { |
| 32 | - /** @var \PHPUnit\Framework\MockObject\MockObject | IUserManager */ |
|
| 33 | - protected $userManager; |
|
| 34 | - |
|
| 35 | - /** @var \PHPUnit\Framework\MockObject\MockObject | Manager */ |
|
| 36 | - protected $encryptionManager; |
|
| 37 | - |
|
| 38 | - /** @var \PHPUnit\Framework\MockObject\MockObject | View */ |
|
| 39 | - protected $view; |
|
| 40 | - |
|
| 41 | - /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Input\InputInterface */ |
|
| 42 | - protected $inputInterface; |
|
| 43 | - |
|
| 44 | - /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Output\OutputInterface */ |
|
| 45 | - protected $outputInterface; |
|
| 46 | - |
|
| 47 | - /** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\UserInterface */ |
|
| 48 | - protected $userInterface; |
|
| 49 | - |
|
| 50 | - /** @var DecryptAll */ |
|
| 51 | - protected $instance; |
|
| 52 | - |
|
| 53 | - protected function setUp(): void { |
|
| 54 | - parent::setUp(); |
|
| 55 | - |
|
| 56 | - $this->userManager = $this->getMockBuilder(IUserManager::class) |
|
| 57 | - ->disableOriginalConstructor()->getMock(); |
|
| 58 | - $this->encryptionManager = $this->getMockBuilder('OC\Encryption\Manager') |
|
| 59 | - ->disableOriginalConstructor()->getMock(); |
|
| 60 | - $this->view = $this->getMockBuilder(View::class) |
|
| 61 | - ->disableOriginalConstructor()->getMock(); |
|
| 62 | - $this->inputInterface = $this->getMockBuilder(InputInterface::class) |
|
| 63 | - ->disableOriginalConstructor()->getMock(); |
|
| 64 | - $this->outputInterface = $this->getMockBuilder(OutputInterface::class) |
|
| 65 | - ->disableOriginalConstructor()->getMock(); |
|
| 66 | - $this->outputInterface->expects($this->any())->method('isDecorated') |
|
| 67 | - ->willReturn(false); |
|
| 68 | - $this->userInterface = $this->getMockBuilder(UserInterface::class) |
|
| 69 | - ->disableOriginalConstructor()->getMock(); |
|
| 70 | - |
|
| 71 | - /* We need format method to return a string */ |
|
| 72 | - $outputFormatter = $this->createMock(OutputFormatterInterface::class); |
|
| 73 | - $outputFormatter->method('format')->willReturn('foo'); |
|
| 74 | - $outputFormatter->method('isDecorated')->willReturn(false); |
|
| 75 | - |
|
| 76 | - $this->outputInterface->expects($this->any())->method('getFormatter') |
|
| 77 | - ->willReturn($outputFormatter); |
|
| 78 | - |
|
| 79 | - $this->instance = new DecryptAll($this->encryptionManager, $this->userManager, $this->view); |
|
| 80 | - |
|
| 81 | - $this->invokePrivate($this->instance, 'input', [$this->inputInterface]); |
|
| 82 | - $this->invokePrivate($this->instance, 'output', [$this->outputInterface]); |
|
| 83 | - } |
|
| 84 | - |
|
| 85 | - public static function dataDecryptAll(): array { |
|
| 86 | - return [ |
|
| 87 | - [true, 'user1', true], |
|
| 88 | - [false, 'user1', true], |
|
| 89 | - [true, '0', true], |
|
| 90 | - [false, '0', true], |
|
| 91 | - [true, '', false], |
|
| 92 | - ]; |
|
| 93 | - } |
|
| 94 | - |
|
| 95 | - /** |
|
| 96 | - * @dataProvider dataDecryptAll |
|
| 97 | - * @param bool $prepareResult |
|
| 98 | - * @param string $user |
|
| 99 | - * @param bool $userExistsChecked |
|
| 100 | - */ |
|
| 101 | - public function testDecryptAll($prepareResult, $user, $userExistsChecked): void { |
|
| 102 | - if ($userExistsChecked) { |
|
| 103 | - $this->userManager->expects($this->once())->method('userExists')->willReturn(true); |
|
| 104 | - } else { |
|
| 105 | - $this->userManager->expects($this->never())->method('userExists'); |
|
| 106 | - } |
|
| 107 | - /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject | $instance */ |
|
| 108 | - $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') |
|
| 109 | - ->setConstructorArgs( |
|
| 110 | - [ |
|
| 111 | - $this->encryptionManager, |
|
| 112 | - $this->userManager, |
|
| 113 | - $this->view |
|
| 114 | - ] |
|
| 115 | - ) |
|
| 116 | - ->onlyMethods(['prepareEncryptionModules', 'decryptAllUsersFiles']) |
|
| 117 | - ->getMock(); |
|
| 118 | - |
|
| 119 | - $instance->expects($this->once()) |
|
| 120 | - ->method('prepareEncryptionModules') |
|
| 121 | - ->with($user) |
|
| 122 | - ->willReturn($prepareResult); |
|
| 123 | - |
|
| 124 | - if ($prepareResult) { |
|
| 125 | - $instance->expects($this->once()) |
|
| 126 | - ->method('decryptAllUsersFiles') |
|
| 127 | - ->with($user); |
|
| 128 | - } else { |
|
| 129 | - $instance->expects($this->never())->method('decryptAllUsersFiles'); |
|
| 130 | - } |
|
| 131 | - |
|
| 132 | - $instance->decryptAll($this->inputInterface, $this->outputInterface, $user); |
|
| 133 | - } |
|
| 134 | - |
|
| 135 | - /** |
|
| 136 | - * test decrypt all call with a user who doesn't exists |
|
| 137 | - */ |
|
| 138 | - public function testDecryptAllWrongUser(): void { |
|
| 139 | - $this->userManager->expects($this->once())->method('userExists')->willReturn(false); |
|
| 140 | - $this->outputInterface->expects($this->once())->method('writeln') |
|
| 141 | - ->with('User "user1" does not exist. Please check the username and try again'); |
|
| 142 | - |
|
| 143 | - $this->assertFalse( |
|
| 144 | - $this->instance->decryptAll($this->inputInterface, $this->outputInterface, 'user1') |
|
| 145 | - ); |
|
| 146 | - } |
|
| 147 | - |
|
| 148 | - public static function dataTrueFalse(): array { |
|
| 149 | - return [ |
|
| 150 | - [true], |
|
| 151 | - [false], |
|
| 152 | - ]; |
|
| 153 | - } |
|
| 154 | - |
|
| 155 | - /** |
|
| 156 | - * @dataProvider dataTrueFalse |
|
| 157 | - * @param bool $success |
|
| 158 | - */ |
|
| 159 | - public function testPrepareEncryptionModules($success): void { |
|
| 160 | - $user = 'user1'; |
|
| 161 | - |
|
| 162 | - $dummyEncryptionModule = $this->getMockBuilder('OCP\Encryption\IEncryptionModule') |
|
| 163 | - ->disableOriginalConstructor()->getMock(); |
|
| 164 | - |
|
| 165 | - $dummyEncryptionModule->expects($this->once()) |
|
| 166 | - ->method('prepareDecryptAll') |
|
| 167 | - ->with($this->inputInterface, $this->outputInterface, $user) |
|
| 168 | - ->willReturn($success); |
|
| 169 | - |
|
| 170 | - $callback = function () use ($dummyEncryptionModule) { |
|
| 171 | - return $dummyEncryptionModule; |
|
| 172 | - }; |
|
| 173 | - $moduleDescription = [ |
|
| 174 | - 'id' => 'id', |
|
| 175 | - 'displayName' => 'displayName', |
|
| 176 | - 'callback' => $callback |
|
| 177 | - ]; |
|
| 178 | - |
|
| 179 | - $this->encryptionManager->expects($this->once()) |
|
| 180 | - ->method('getEncryptionModules') |
|
| 181 | - ->willReturn([$moduleDescription]); |
|
| 182 | - |
|
| 183 | - $this->assertSame($success, |
|
| 184 | - $this->invokePrivate($this->instance, 'prepareEncryptionModules', [$user]) |
|
| 185 | - ); |
|
| 186 | - } |
|
| 187 | - |
|
| 188 | - /** |
|
| 189 | - * @dataProvider dataTestDecryptAllUsersFiles |
|
| 190 | - */ |
|
| 191 | - public function testDecryptAllUsersFiles($user): void { |
|
| 192 | - /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject | $instance */ |
|
| 193 | - $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') |
|
| 194 | - ->setConstructorArgs( |
|
| 195 | - [ |
|
| 196 | - $this->encryptionManager, |
|
| 197 | - $this->userManager, |
|
| 198 | - $this->view |
|
| 199 | - ] |
|
| 200 | - ) |
|
| 201 | - ->onlyMethods(['decryptUsersFiles']) |
|
| 202 | - ->getMock(); |
|
| 203 | - |
|
| 204 | - $this->invokePrivate($instance, 'input', [$this->inputInterface]); |
|
| 205 | - $this->invokePrivate($instance, 'output', [$this->outputInterface]); |
|
| 206 | - |
|
| 207 | - if (empty($user)) { |
|
| 208 | - $this->userManager->expects($this->once()) |
|
| 209 | - ->method('getBackends') |
|
| 210 | - ->willReturn([$this->userInterface]); |
|
| 211 | - $this->userInterface->expects($this->any()) |
|
| 212 | - ->method('getUsers') |
|
| 213 | - ->willReturn(['user1', 'user2']); |
|
| 214 | - $calls = [ |
|
| 215 | - 'user1', |
|
| 216 | - 'user2', |
|
| 217 | - ]; |
|
| 218 | - $instance->expects($this->exactly(2)) |
|
| 219 | - ->method('decryptUsersFiles') |
|
| 220 | - ->willReturnCallback(function ($user) use (&$calls) { |
|
| 221 | - $expected = array_shift($calls); |
|
| 222 | - $this->assertEquals($expected, $user); |
|
| 223 | - }); |
|
| 224 | - } else { |
|
| 225 | - $instance->expects($this->once()) |
|
| 226 | - ->method('decryptUsersFiles') |
|
| 227 | - ->with($user); |
|
| 228 | - } |
|
| 229 | - |
|
| 230 | - $this->invokePrivate($instance, 'decryptAllUsersFiles', [$user]); |
|
| 231 | - } |
|
| 232 | - |
|
| 233 | - public static function dataTestDecryptAllUsersFiles(): array { |
|
| 234 | - return [ |
|
| 235 | - ['user1'], |
|
| 236 | - [''] |
|
| 237 | - ]; |
|
| 238 | - } |
|
| 239 | - |
|
| 240 | - public function testDecryptUsersFiles(): void { |
|
| 241 | - /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject $instance */ |
|
| 242 | - $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') |
|
| 243 | - ->setConstructorArgs( |
|
| 244 | - [ |
|
| 245 | - $this->encryptionManager, |
|
| 246 | - $this->userManager, |
|
| 247 | - $this->view |
|
| 248 | - ] |
|
| 249 | - ) |
|
| 250 | - ->onlyMethods(['decryptFile']) |
|
| 251 | - ->getMock(); |
|
| 252 | - |
|
| 253 | - $storage = $this->getMockBuilder(IStorage::class) |
|
| 254 | - ->disableOriginalConstructor()->getMock(); |
|
| 255 | - |
|
| 256 | - |
|
| 257 | - $sharedStorage = $this->getMockBuilder(IStorage::class) |
|
| 258 | - ->disableOriginalConstructor()->getMock(); |
|
| 259 | - |
|
| 260 | - $sharedStorage->expects($this->once()) |
|
| 261 | - ->method('instanceOfStorage') |
|
| 262 | - ->with('OCA\Files_Sharing\SharedStorage') |
|
| 263 | - ->willReturn(true); |
|
| 264 | - |
|
| 265 | - $this->view->expects($this->exactly(2)) |
|
| 266 | - ->method('getDirectoryContent') |
|
| 267 | - ->willReturnMap([ |
|
| 268 | - [ |
|
| 269 | - '/user1/files', '', null, |
|
| 270 | - [ |
|
| 271 | - new FileInfo('path', $storage, 'intPath', ['name' => 'foo', 'type' => 'dir'], null), |
|
| 272 | - new FileInfo('path', $storage, 'intPath', ['name' => 'bar', 'type' => 'file', 'encrypted' => true], null), |
|
| 273 | - new FileInfo('path', $sharedStorage, 'intPath', ['name' => 'shared', 'type' => 'file', 'encrypted' => true], null), |
|
| 274 | - ], |
|
| 275 | - ], |
|
| 276 | - [ |
|
| 277 | - '/user1/files/foo', '', null, |
|
| 278 | - [ |
|
| 279 | - new FileInfo('path', $storage, 'intPath', ['name' => 'subfile', 'type' => 'file', 'encrypted' => true], null) |
|
| 280 | - ], |
|
| 281 | - ], |
|
| 282 | - ]); |
|
| 283 | - |
|
| 284 | - $this->view->expects($this->any())->method('is_dir') |
|
| 285 | - ->willReturnCallback( |
|
| 286 | - function ($path) { |
|
| 287 | - if ($path === '/user1/files/foo') { |
|
| 288 | - return true; |
|
| 289 | - } |
|
| 290 | - return false; |
|
| 291 | - } |
|
| 292 | - ); |
|
| 293 | - |
|
| 294 | - $calls = [ |
|
| 295 | - '/user1/files/bar', |
|
| 296 | - '/user1/files/foo/subfile', |
|
| 297 | - ]; |
|
| 298 | - $instance->expects($this->exactly(2)) |
|
| 299 | - ->method('decryptFile') |
|
| 300 | - ->willReturnCallback(function ($path) use (&$calls) { |
|
| 301 | - $expected = array_shift($calls); |
|
| 302 | - $this->assertEquals($expected, $path); |
|
| 303 | - }); |
|
| 304 | - |
|
| 305 | - |
|
| 306 | - /* We need format method to return a string */ |
|
| 307 | - $outputFormatter = $this->createMock(OutputFormatterInterface::class); |
|
| 308 | - $outputFormatter->method('isDecorated')->willReturn(false); |
|
| 309 | - $outputFormatter->method('format')->willReturn('foo'); |
|
| 310 | - |
|
| 311 | - $output = $this->createMock(OutputInterface::class); |
|
| 312 | - $output->expects($this->any()) |
|
| 313 | - ->method('getFormatter') |
|
| 314 | - ->willReturn($outputFormatter); |
|
| 315 | - $progressBar = new ProgressBar($output); |
|
| 316 | - |
|
| 317 | - $this->invokePrivate($instance, 'decryptUsersFiles', ['user1', $progressBar, '']); |
|
| 318 | - } |
|
| 319 | - |
|
| 320 | - /** |
|
| 321 | - * @dataProvider dataTrueFalse |
|
| 322 | - */ |
|
| 323 | - public function testDecryptFile($isEncrypted): void { |
|
| 324 | - $path = 'test.txt'; |
|
| 325 | - |
|
| 326 | - /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject $instance */ |
|
| 327 | - $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') |
|
| 328 | - ->setConstructorArgs( |
|
| 329 | - [ |
|
| 330 | - $this->encryptionManager, |
|
| 331 | - $this->userManager, |
|
| 332 | - $this->view |
|
| 333 | - ] |
|
| 334 | - ) |
|
| 335 | - ->onlyMethods(['getTimestamp']) |
|
| 336 | - ->getMock(); |
|
| 337 | - |
|
| 338 | - $fileInfo = $this->createMock(FileInfo::class); |
|
| 339 | - $fileInfo->expects($this->any())->method('isEncrypted') |
|
| 340 | - ->willReturn($isEncrypted); |
|
| 341 | - $this->view->expects($this->any())->method('getFileInfo') |
|
| 342 | - ->willReturn($fileInfo); |
|
| 343 | - |
|
| 344 | - if ($isEncrypted) { |
|
| 345 | - $instance->expects($this->any())->method('getTimestamp')->willReturn(42); |
|
| 346 | - |
|
| 347 | - $this->view->expects($this->once()) |
|
| 348 | - ->method('copy') |
|
| 349 | - ->with($path, $path . '.decrypted.42'); |
|
| 350 | - $this->view->expects($this->once()) |
|
| 351 | - ->method('rename') |
|
| 352 | - ->with($path . '.decrypted.42', $path); |
|
| 353 | - } else { |
|
| 354 | - $instance->expects($this->never())->method('getTimestamp'); |
|
| 355 | - $this->view->expects($this->never())->method('copy'); |
|
| 356 | - $this->view->expects($this->never())->method('rename'); |
|
| 357 | - } |
|
| 358 | - $this->assertTrue( |
|
| 359 | - $this->invokePrivate($instance, 'decryptFile', [$path]) |
|
| 360 | - ); |
|
| 361 | - } |
|
| 362 | - |
|
| 363 | - public function testDecryptFileFailure(): void { |
|
| 364 | - $path = 'test.txt'; |
|
| 365 | - |
|
| 366 | - /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject $instance */ |
|
| 367 | - $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') |
|
| 368 | - ->setConstructorArgs( |
|
| 369 | - [ |
|
| 370 | - $this->encryptionManager, |
|
| 371 | - $this->userManager, |
|
| 372 | - $this->view |
|
| 373 | - ] |
|
| 374 | - ) |
|
| 375 | - ->onlyMethods(['getTimestamp']) |
|
| 376 | - ->getMock(); |
|
| 377 | - |
|
| 378 | - |
|
| 379 | - $fileInfo = $this->createMock(FileInfo::class); |
|
| 380 | - $fileInfo->expects($this->any())->method('isEncrypted') |
|
| 381 | - ->willReturn(true); |
|
| 382 | - $this->view->expects($this->any())->method('getFileInfo') |
|
| 383 | - ->willReturn($fileInfo); |
|
| 384 | - |
|
| 385 | - $instance->expects($this->any())->method('getTimestamp')->willReturn(42); |
|
| 386 | - |
|
| 387 | - $this->view->expects($this->once()) |
|
| 388 | - ->method('copy') |
|
| 389 | - ->with($path, $path . '.decrypted.42') |
|
| 390 | - ->willReturnCallback(function () { |
|
| 391 | - throw new DecryptionFailedException(); |
|
| 392 | - }); |
|
| 393 | - |
|
| 394 | - $this->view->expects($this->never())->method('rename'); |
|
| 395 | - $this->view->expects($this->once()) |
|
| 396 | - ->method('file_exists') |
|
| 397 | - ->with($path . '.decrypted.42') |
|
| 398 | - ->willReturn(true); |
|
| 399 | - $this->view->expects($this->once()) |
|
| 400 | - ->method('unlink') |
|
| 401 | - ->with($path . '.decrypted.42'); |
|
| 402 | - |
|
| 403 | - $this->assertFalse( |
|
| 404 | - $this->invokePrivate($instance, 'decryptFile', [$path]) |
|
| 405 | - ); |
|
| 406 | - } |
|
| 32 | + /** @var \PHPUnit\Framework\MockObject\MockObject | IUserManager */ |
|
| 33 | + protected $userManager; |
|
| 34 | + |
|
| 35 | + /** @var \PHPUnit\Framework\MockObject\MockObject | Manager */ |
|
| 36 | + protected $encryptionManager; |
|
| 37 | + |
|
| 38 | + /** @var \PHPUnit\Framework\MockObject\MockObject | View */ |
|
| 39 | + protected $view; |
|
| 40 | + |
|
| 41 | + /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Input\InputInterface */ |
|
| 42 | + protected $inputInterface; |
|
| 43 | + |
|
| 44 | + /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Output\OutputInterface */ |
|
| 45 | + protected $outputInterface; |
|
| 46 | + |
|
| 47 | + /** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\UserInterface */ |
|
| 48 | + protected $userInterface; |
|
| 49 | + |
|
| 50 | + /** @var DecryptAll */ |
|
| 51 | + protected $instance; |
|
| 52 | + |
|
| 53 | + protected function setUp(): void { |
|
| 54 | + parent::setUp(); |
|
| 55 | + |
|
| 56 | + $this->userManager = $this->getMockBuilder(IUserManager::class) |
|
| 57 | + ->disableOriginalConstructor()->getMock(); |
|
| 58 | + $this->encryptionManager = $this->getMockBuilder('OC\Encryption\Manager') |
|
| 59 | + ->disableOriginalConstructor()->getMock(); |
|
| 60 | + $this->view = $this->getMockBuilder(View::class) |
|
| 61 | + ->disableOriginalConstructor()->getMock(); |
|
| 62 | + $this->inputInterface = $this->getMockBuilder(InputInterface::class) |
|
| 63 | + ->disableOriginalConstructor()->getMock(); |
|
| 64 | + $this->outputInterface = $this->getMockBuilder(OutputInterface::class) |
|
| 65 | + ->disableOriginalConstructor()->getMock(); |
|
| 66 | + $this->outputInterface->expects($this->any())->method('isDecorated') |
|
| 67 | + ->willReturn(false); |
|
| 68 | + $this->userInterface = $this->getMockBuilder(UserInterface::class) |
|
| 69 | + ->disableOriginalConstructor()->getMock(); |
|
| 70 | + |
|
| 71 | + /* We need format method to return a string */ |
|
| 72 | + $outputFormatter = $this->createMock(OutputFormatterInterface::class); |
|
| 73 | + $outputFormatter->method('format')->willReturn('foo'); |
|
| 74 | + $outputFormatter->method('isDecorated')->willReturn(false); |
|
| 75 | + |
|
| 76 | + $this->outputInterface->expects($this->any())->method('getFormatter') |
|
| 77 | + ->willReturn($outputFormatter); |
|
| 78 | + |
|
| 79 | + $this->instance = new DecryptAll($this->encryptionManager, $this->userManager, $this->view); |
|
| 80 | + |
|
| 81 | + $this->invokePrivate($this->instance, 'input', [$this->inputInterface]); |
|
| 82 | + $this->invokePrivate($this->instance, 'output', [$this->outputInterface]); |
|
| 83 | + } |
|
| 84 | + |
|
| 85 | + public static function dataDecryptAll(): array { |
|
| 86 | + return [ |
|
| 87 | + [true, 'user1', true], |
|
| 88 | + [false, 'user1', true], |
|
| 89 | + [true, '0', true], |
|
| 90 | + [false, '0', true], |
|
| 91 | + [true, '', false], |
|
| 92 | + ]; |
|
| 93 | + } |
|
| 94 | + |
|
| 95 | + /** |
|
| 96 | + * @dataProvider dataDecryptAll |
|
| 97 | + * @param bool $prepareResult |
|
| 98 | + * @param string $user |
|
| 99 | + * @param bool $userExistsChecked |
|
| 100 | + */ |
|
| 101 | + public function testDecryptAll($prepareResult, $user, $userExistsChecked): void { |
|
| 102 | + if ($userExistsChecked) { |
|
| 103 | + $this->userManager->expects($this->once())->method('userExists')->willReturn(true); |
|
| 104 | + } else { |
|
| 105 | + $this->userManager->expects($this->never())->method('userExists'); |
|
| 106 | + } |
|
| 107 | + /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject | $instance */ |
|
| 108 | + $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') |
|
| 109 | + ->setConstructorArgs( |
|
| 110 | + [ |
|
| 111 | + $this->encryptionManager, |
|
| 112 | + $this->userManager, |
|
| 113 | + $this->view |
|
| 114 | + ] |
|
| 115 | + ) |
|
| 116 | + ->onlyMethods(['prepareEncryptionModules', 'decryptAllUsersFiles']) |
|
| 117 | + ->getMock(); |
|
| 118 | + |
|
| 119 | + $instance->expects($this->once()) |
|
| 120 | + ->method('prepareEncryptionModules') |
|
| 121 | + ->with($user) |
|
| 122 | + ->willReturn($prepareResult); |
|
| 123 | + |
|
| 124 | + if ($prepareResult) { |
|
| 125 | + $instance->expects($this->once()) |
|
| 126 | + ->method('decryptAllUsersFiles') |
|
| 127 | + ->with($user); |
|
| 128 | + } else { |
|
| 129 | + $instance->expects($this->never())->method('decryptAllUsersFiles'); |
|
| 130 | + } |
|
| 131 | + |
|
| 132 | + $instance->decryptAll($this->inputInterface, $this->outputInterface, $user); |
|
| 133 | + } |
|
| 134 | + |
|
| 135 | + /** |
|
| 136 | + * test decrypt all call with a user who doesn't exists |
|
| 137 | + */ |
|
| 138 | + public function testDecryptAllWrongUser(): void { |
|
| 139 | + $this->userManager->expects($this->once())->method('userExists')->willReturn(false); |
|
| 140 | + $this->outputInterface->expects($this->once())->method('writeln') |
|
| 141 | + ->with('User "user1" does not exist. Please check the username and try again'); |
|
| 142 | + |
|
| 143 | + $this->assertFalse( |
|
| 144 | + $this->instance->decryptAll($this->inputInterface, $this->outputInterface, 'user1') |
|
| 145 | + ); |
|
| 146 | + } |
|
| 147 | + |
|
| 148 | + public static function dataTrueFalse(): array { |
|
| 149 | + return [ |
|
| 150 | + [true], |
|
| 151 | + [false], |
|
| 152 | + ]; |
|
| 153 | + } |
|
| 154 | + |
|
| 155 | + /** |
|
| 156 | + * @dataProvider dataTrueFalse |
|
| 157 | + * @param bool $success |
|
| 158 | + */ |
|
| 159 | + public function testPrepareEncryptionModules($success): void { |
|
| 160 | + $user = 'user1'; |
|
| 161 | + |
|
| 162 | + $dummyEncryptionModule = $this->getMockBuilder('OCP\Encryption\IEncryptionModule') |
|
| 163 | + ->disableOriginalConstructor()->getMock(); |
|
| 164 | + |
|
| 165 | + $dummyEncryptionModule->expects($this->once()) |
|
| 166 | + ->method('prepareDecryptAll') |
|
| 167 | + ->with($this->inputInterface, $this->outputInterface, $user) |
|
| 168 | + ->willReturn($success); |
|
| 169 | + |
|
| 170 | + $callback = function () use ($dummyEncryptionModule) { |
|
| 171 | + return $dummyEncryptionModule; |
|
| 172 | + }; |
|
| 173 | + $moduleDescription = [ |
|
| 174 | + 'id' => 'id', |
|
| 175 | + 'displayName' => 'displayName', |
|
| 176 | + 'callback' => $callback |
|
| 177 | + ]; |
|
| 178 | + |
|
| 179 | + $this->encryptionManager->expects($this->once()) |
|
| 180 | + ->method('getEncryptionModules') |
|
| 181 | + ->willReturn([$moduleDescription]); |
|
| 182 | + |
|
| 183 | + $this->assertSame($success, |
|
| 184 | + $this->invokePrivate($this->instance, 'prepareEncryptionModules', [$user]) |
|
| 185 | + ); |
|
| 186 | + } |
|
| 187 | + |
|
| 188 | + /** |
|
| 189 | + * @dataProvider dataTestDecryptAllUsersFiles |
|
| 190 | + */ |
|
| 191 | + public function testDecryptAllUsersFiles($user): void { |
|
| 192 | + /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject | $instance */ |
|
| 193 | + $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') |
|
| 194 | + ->setConstructorArgs( |
|
| 195 | + [ |
|
| 196 | + $this->encryptionManager, |
|
| 197 | + $this->userManager, |
|
| 198 | + $this->view |
|
| 199 | + ] |
|
| 200 | + ) |
|
| 201 | + ->onlyMethods(['decryptUsersFiles']) |
|
| 202 | + ->getMock(); |
|
| 203 | + |
|
| 204 | + $this->invokePrivate($instance, 'input', [$this->inputInterface]); |
|
| 205 | + $this->invokePrivate($instance, 'output', [$this->outputInterface]); |
|
| 206 | + |
|
| 207 | + if (empty($user)) { |
|
| 208 | + $this->userManager->expects($this->once()) |
|
| 209 | + ->method('getBackends') |
|
| 210 | + ->willReturn([$this->userInterface]); |
|
| 211 | + $this->userInterface->expects($this->any()) |
|
| 212 | + ->method('getUsers') |
|
| 213 | + ->willReturn(['user1', 'user2']); |
|
| 214 | + $calls = [ |
|
| 215 | + 'user1', |
|
| 216 | + 'user2', |
|
| 217 | + ]; |
|
| 218 | + $instance->expects($this->exactly(2)) |
|
| 219 | + ->method('decryptUsersFiles') |
|
| 220 | + ->willReturnCallback(function ($user) use (&$calls) { |
|
| 221 | + $expected = array_shift($calls); |
|
| 222 | + $this->assertEquals($expected, $user); |
|
| 223 | + }); |
|
| 224 | + } else { |
|
| 225 | + $instance->expects($this->once()) |
|
| 226 | + ->method('decryptUsersFiles') |
|
| 227 | + ->with($user); |
|
| 228 | + } |
|
| 229 | + |
|
| 230 | + $this->invokePrivate($instance, 'decryptAllUsersFiles', [$user]); |
|
| 231 | + } |
|
| 232 | + |
|
| 233 | + public static function dataTestDecryptAllUsersFiles(): array { |
|
| 234 | + return [ |
|
| 235 | + ['user1'], |
|
| 236 | + [''] |
|
| 237 | + ]; |
|
| 238 | + } |
|
| 239 | + |
|
| 240 | + public function testDecryptUsersFiles(): void { |
|
| 241 | + /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject $instance */ |
|
| 242 | + $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') |
|
| 243 | + ->setConstructorArgs( |
|
| 244 | + [ |
|
| 245 | + $this->encryptionManager, |
|
| 246 | + $this->userManager, |
|
| 247 | + $this->view |
|
| 248 | + ] |
|
| 249 | + ) |
|
| 250 | + ->onlyMethods(['decryptFile']) |
|
| 251 | + ->getMock(); |
|
| 252 | + |
|
| 253 | + $storage = $this->getMockBuilder(IStorage::class) |
|
| 254 | + ->disableOriginalConstructor()->getMock(); |
|
| 255 | + |
|
| 256 | + |
|
| 257 | + $sharedStorage = $this->getMockBuilder(IStorage::class) |
|
| 258 | + ->disableOriginalConstructor()->getMock(); |
|
| 259 | + |
|
| 260 | + $sharedStorage->expects($this->once()) |
|
| 261 | + ->method('instanceOfStorage') |
|
| 262 | + ->with('OCA\Files_Sharing\SharedStorage') |
|
| 263 | + ->willReturn(true); |
|
| 264 | + |
|
| 265 | + $this->view->expects($this->exactly(2)) |
|
| 266 | + ->method('getDirectoryContent') |
|
| 267 | + ->willReturnMap([ |
|
| 268 | + [ |
|
| 269 | + '/user1/files', '', null, |
|
| 270 | + [ |
|
| 271 | + new FileInfo('path', $storage, 'intPath', ['name' => 'foo', 'type' => 'dir'], null), |
|
| 272 | + new FileInfo('path', $storage, 'intPath', ['name' => 'bar', 'type' => 'file', 'encrypted' => true], null), |
|
| 273 | + new FileInfo('path', $sharedStorage, 'intPath', ['name' => 'shared', 'type' => 'file', 'encrypted' => true], null), |
|
| 274 | + ], |
|
| 275 | + ], |
|
| 276 | + [ |
|
| 277 | + '/user1/files/foo', '', null, |
|
| 278 | + [ |
|
| 279 | + new FileInfo('path', $storage, 'intPath', ['name' => 'subfile', 'type' => 'file', 'encrypted' => true], null) |
|
| 280 | + ], |
|
| 281 | + ], |
|
| 282 | + ]); |
|
| 283 | + |
|
| 284 | + $this->view->expects($this->any())->method('is_dir') |
|
| 285 | + ->willReturnCallback( |
|
| 286 | + function ($path) { |
|
| 287 | + if ($path === '/user1/files/foo') { |
|
| 288 | + return true; |
|
| 289 | + } |
|
| 290 | + return false; |
|
| 291 | + } |
|
| 292 | + ); |
|
| 293 | + |
|
| 294 | + $calls = [ |
|
| 295 | + '/user1/files/bar', |
|
| 296 | + '/user1/files/foo/subfile', |
|
| 297 | + ]; |
|
| 298 | + $instance->expects($this->exactly(2)) |
|
| 299 | + ->method('decryptFile') |
|
| 300 | + ->willReturnCallback(function ($path) use (&$calls) { |
|
| 301 | + $expected = array_shift($calls); |
|
| 302 | + $this->assertEquals($expected, $path); |
|
| 303 | + }); |
|
| 304 | + |
|
| 305 | + |
|
| 306 | + /* We need format method to return a string */ |
|
| 307 | + $outputFormatter = $this->createMock(OutputFormatterInterface::class); |
|
| 308 | + $outputFormatter->method('isDecorated')->willReturn(false); |
|
| 309 | + $outputFormatter->method('format')->willReturn('foo'); |
|
| 310 | + |
|
| 311 | + $output = $this->createMock(OutputInterface::class); |
|
| 312 | + $output->expects($this->any()) |
|
| 313 | + ->method('getFormatter') |
|
| 314 | + ->willReturn($outputFormatter); |
|
| 315 | + $progressBar = new ProgressBar($output); |
|
| 316 | + |
|
| 317 | + $this->invokePrivate($instance, 'decryptUsersFiles', ['user1', $progressBar, '']); |
|
| 318 | + } |
|
| 319 | + |
|
| 320 | + /** |
|
| 321 | + * @dataProvider dataTrueFalse |
|
| 322 | + */ |
|
| 323 | + public function testDecryptFile($isEncrypted): void { |
|
| 324 | + $path = 'test.txt'; |
|
| 325 | + |
|
| 326 | + /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject $instance */ |
|
| 327 | + $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') |
|
| 328 | + ->setConstructorArgs( |
|
| 329 | + [ |
|
| 330 | + $this->encryptionManager, |
|
| 331 | + $this->userManager, |
|
| 332 | + $this->view |
|
| 333 | + ] |
|
| 334 | + ) |
|
| 335 | + ->onlyMethods(['getTimestamp']) |
|
| 336 | + ->getMock(); |
|
| 337 | + |
|
| 338 | + $fileInfo = $this->createMock(FileInfo::class); |
|
| 339 | + $fileInfo->expects($this->any())->method('isEncrypted') |
|
| 340 | + ->willReturn($isEncrypted); |
|
| 341 | + $this->view->expects($this->any())->method('getFileInfo') |
|
| 342 | + ->willReturn($fileInfo); |
|
| 343 | + |
|
| 344 | + if ($isEncrypted) { |
|
| 345 | + $instance->expects($this->any())->method('getTimestamp')->willReturn(42); |
|
| 346 | + |
|
| 347 | + $this->view->expects($this->once()) |
|
| 348 | + ->method('copy') |
|
| 349 | + ->with($path, $path . '.decrypted.42'); |
|
| 350 | + $this->view->expects($this->once()) |
|
| 351 | + ->method('rename') |
|
| 352 | + ->with($path . '.decrypted.42', $path); |
|
| 353 | + } else { |
|
| 354 | + $instance->expects($this->never())->method('getTimestamp'); |
|
| 355 | + $this->view->expects($this->never())->method('copy'); |
|
| 356 | + $this->view->expects($this->never())->method('rename'); |
|
| 357 | + } |
|
| 358 | + $this->assertTrue( |
|
| 359 | + $this->invokePrivate($instance, 'decryptFile', [$path]) |
|
| 360 | + ); |
|
| 361 | + } |
|
| 362 | + |
|
| 363 | + public function testDecryptFileFailure(): void { |
|
| 364 | + $path = 'test.txt'; |
|
| 365 | + |
|
| 366 | + /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject $instance */ |
|
| 367 | + $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') |
|
| 368 | + ->setConstructorArgs( |
|
| 369 | + [ |
|
| 370 | + $this->encryptionManager, |
|
| 371 | + $this->userManager, |
|
| 372 | + $this->view |
|
| 373 | + ] |
|
| 374 | + ) |
|
| 375 | + ->onlyMethods(['getTimestamp']) |
|
| 376 | + ->getMock(); |
|
| 377 | + |
|
| 378 | + |
|
| 379 | + $fileInfo = $this->createMock(FileInfo::class); |
|
| 380 | + $fileInfo->expects($this->any())->method('isEncrypted') |
|
| 381 | + ->willReturn(true); |
|
| 382 | + $this->view->expects($this->any())->method('getFileInfo') |
|
| 383 | + ->willReturn($fileInfo); |
|
| 384 | + |
|
| 385 | + $instance->expects($this->any())->method('getTimestamp')->willReturn(42); |
|
| 386 | + |
|
| 387 | + $this->view->expects($this->once()) |
|
| 388 | + ->method('copy') |
|
| 389 | + ->with($path, $path . '.decrypted.42') |
|
| 390 | + ->willReturnCallback(function () { |
|
| 391 | + throw new DecryptionFailedException(); |
|
| 392 | + }); |
|
| 393 | + |
|
| 394 | + $this->view->expects($this->never())->method('rename'); |
|
| 395 | + $this->view->expects($this->once()) |
|
| 396 | + ->method('file_exists') |
|
| 397 | + ->with($path . '.decrypted.42') |
|
| 398 | + ->willReturn(true); |
|
| 399 | + $this->view->expects($this->once()) |
|
| 400 | + ->method('unlink') |
|
| 401 | + ->with($path . '.decrypted.42'); |
|
| 402 | + |
|
| 403 | + $this->assertFalse( |
|
| 404 | + $this->invokePrivate($instance, 'decryptFile', [$path]) |
|
| 405 | + ); |
|
| 406 | + } |
|
| 407 | 407 | } |
@@ -167,7 +167,7 @@ discard block |
||
| 167 | 167 | ->with($this->inputInterface, $this->outputInterface, $user) |
| 168 | 168 | ->willReturn($success); |
| 169 | 169 | |
| 170 | - $callback = function () use ($dummyEncryptionModule) { |
|
| 170 | + $callback = function() use ($dummyEncryptionModule) { |
|
| 171 | 171 | return $dummyEncryptionModule; |
| 172 | 172 | }; |
| 173 | 173 | $moduleDescription = [ |
@@ -217,7 +217,7 @@ discard block |
||
| 217 | 217 | ]; |
| 218 | 218 | $instance->expects($this->exactly(2)) |
| 219 | 219 | ->method('decryptUsersFiles') |
| 220 | - ->willReturnCallback(function ($user) use (&$calls) { |
|
| 220 | + ->willReturnCallback(function($user) use (&$calls) { |
|
| 221 | 221 | $expected = array_shift($calls); |
| 222 | 222 | $this->assertEquals($expected, $user); |
| 223 | 223 | }); |
@@ -283,7 +283,7 @@ discard block |
||
| 283 | 283 | |
| 284 | 284 | $this->view->expects($this->any())->method('is_dir') |
| 285 | 285 | ->willReturnCallback( |
| 286 | - function ($path) { |
|
| 286 | + function($path) { |
|
| 287 | 287 | if ($path === '/user1/files/foo') { |
| 288 | 288 | return true; |
| 289 | 289 | } |
@@ -297,7 +297,7 @@ discard block |
||
| 297 | 297 | ]; |
| 298 | 298 | $instance->expects($this->exactly(2)) |
| 299 | 299 | ->method('decryptFile') |
| 300 | - ->willReturnCallback(function ($path) use (&$calls) { |
|
| 300 | + ->willReturnCallback(function($path) use (&$calls) { |
|
| 301 | 301 | $expected = array_shift($calls); |
| 302 | 302 | $this->assertEquals($expected, $path); |
| 303 | 303 | }); |
@@ -346,10 +346,10 @@ discard block |
||
| 346 | 346 | |
| 347 | 347 | $this->view->expects($this->once()) |
| 348 | 348 | ->method('copy') |
| 349 | - ->with($path, $path . '.decrypted.42'); |
|
| 349 | + ->with($path, $path.'.decrypted.42'); |
|
| 350 | 350 | $this->view->expects($this->once()) |
| 351 | 351 | ->method('rename') |
| 352 | - ->with($path . '.decrypted.42', $path); |
|
| 352 | + ->with($path.'.decrypted.42', $path); |
|
| 353 | 353 | } else { |
| 354 | 354 | $instance->expects($this->never())->method('getTimestamp'); |
| 355 | 355 | $this->view->expects($this->never())->method('copy'); |
@@ -386,19 +386,19 @@ discard block |
||
| 386 | 386 | |
| 387 | 387 | $this->view->expects($this->once()) |
| 388 | 388 | ->method('copy') |
| 389 | - ->with($path, $path . '.decrypted.42') |
|
| 390 | - ->willReturnCallback(function () { |
|
| 389 | + ->with($path, $path.'.decrypted.42') |
|
| 390 | + ->willReturnCallback(function() { |
|
| 391 | 391 | throw new DecryptionFailedException(); |
| 392 | 392 | }); |
| 393 | 393 | |
| 394 | 394 | $this->view->expects($this->never())->method('rename'); |
| 395 | 395 | $this->view->expects($this->once()) |
| 396 | 396 | ->method('file_exists') |
| 397 | - ->with($path . '.decrypted.42') |
|
| 397 | + ->with($path.'.decrypted.42') |
|
| 398 | 398 | ->willReturn(true); |
| 399 | 399 | $this->view->expects($this->once()) |
| 400 | 400 | ->method('unlink') |
| 401 | - ->with($path . '.decrypted.42'); |
|
| 401 | + ->with($path.'.decrypted.42'); |
|
| 402 | 402 | |
| 403 | 403 | $this->assertFalse( |
| 404 | 404 | $this->invokePrivate($instance, 'decryptFile', [$path]) |
@@ -25,1044 +25,1044 @@ |
||
| 25 | 25 | use Test\TestCase; |
| 26 | 26 | |
| 27 | 27 | class ContactsStoreTest extends TestCase { |
| 28 | - private ContactsStore $contactsStore; |
|
| 29 | - private StatusService|MockObject $statusService; |
|
| 30 | - /** @var IManager|MockObject */ |
|
| 31 | - private $contactsManager; |
|
| 32 | - /** @var ProfileManager */ |
|
| 33 | - private $profileManager; |
|
| 34 | - /** @var IUserManager|MockObject */ |
|
| 35 | - private $userManager; |
|
| 36 | - /** @var IURLGenerator */ |
|
| 37 | - private $urlGenerator; |
|
| 38 | - /** @var IGroupManager|MockObject */ |
|
| 39 | - private $groupManager; |
|
| 40 | - /** @var IConfig|MockObject */ |
|
| 41 | - private $config; |
|
| 42 | - /** @var KnownUserService|MockObject */ |
|
| 43 | - private $knownUserService; |
|
| 44 | - /** @var IL10NFactory */ |
|
| 45 | - private $l10nFactory; |
|
| 46 | - |
|
| 47 | - protected function setUp(): void { |
|
| 48 | - parent::setUp(); |
|
| 49 | - |
|
| 50 | - $this->contactsManager = $this->createMock(IManager::class); |
|
| 51 | - $this->statusService = $this->createMock(StatusService::class); |
|
| 52 | - $this->userManager = $this->createMock(IUserManager::class); |
|
| 53 | - $this->profileManager = $this->createMock(ProfileManager::class); |
|
| 54 | - $this->urlGenerator = $this->createMock(IURLGenerator::class); |
|
| 55 | - $this->groupManager = $this->createMock(IGroupManager::class); |
|
| 56 | - $this->config = $this->createMock(IConfig::class); |
|
| 57 | - $this->knownUserService = $this->createMock(KnownUserService::class); |
|
| 58 | - $this->l10nFactory = $this->createMock(IL10NFactory::class); |
|
| 59 | - $this->contactsStore = new ContactsStore( |
|
| 60 | - $this->contactsManager, |
|
| 61 | - $this->statusService, |
|
| 62 | - $this->config, |
|
| 63 | - $this->profileManager, |
|
| 64 | - $this->userManager, |
|
| 65 | - $this->urlGenerator, |
|
| 66 | - $this->groupManager, |
|
| 67 | - $this->knownUserService, |
|
| 68 | - $this->l10nFactory, |
|
| 69 | - ); |
|
| 70 | - } |
|
| 71 | - |
|
| 72 | - public function testGetContactsWithoutFilter(): void { |
|
| 73 | - /** @var IUser|MockObject $user */ |
|
| 74 | - $user = $this->createMock(IUser::class); |
|
| 75 | - $this->contactsManager->expects($this->once()) |
|
| 76 | - ->method('search') |
|
| 77 | - ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 78 | - ->willReturn([ |
|
| 79 | - [ |
|
| 80 | - 'UID' => 123, |
|
| 81 | - ], |
|
| 82 | - [ |
|
| 83 | - 'UID' => 567, |
|
| 84 | - 'FN' => 'Darren Roner', |
|
| 85 | - 'EMAIL' => [ |
|
| 86 | - '[email protected]' |
|
| 87 | - ], |
|
| 88 | - ], |
|
| 89 | - ]); |
|
| 90 | - $user->expects($this->exactly(2)) |
|
| 91 | - ->method('getUID') |
|
| 92 | - ->willReturn('user123'); |
|
| 93 | - |
|
| 94 | - $entries = $this->contactsStore->getContacts($user, ''); |
|
| 95 | - |
|
| 96 | - $this->assertCount(2, $entries); |
|
| 97 | - $this->assertEquals([ |
|
| 98 | - '[email protected]' |
|
| 99 | - ], $entries[1]->getEMailAddresses()); |
|
| 100 | - } |
|
| 101 | - |
|
| 102 | - public function testGetContactsHidesOwnEntry(): void { |
|
| 103 | - /** @var IUser|MockObject $user */ |
|
| 104 | - $user = $this->createMock(IUser::class); |
|
| 105 | - $this->contactsManager->expects($this->once()) |
|
| 106 | - ->method('search') |
|
| 107 | - ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 108 | - ->willReturn([ |
|
| 109 | - [ |
|
| 110 | - 'UID' => 'user123', |
|
| 111 | - ], |
|
| 112 | - [ |
|
| 113 | - 'UID' => 567, |
|
| 114 | - 'FN' => 'Darren Roner', |
|
| 115 | - 'EMAIL' => [ |
|
| 116 | - '[email protected]' |
|
| 117 | - ], |
|
| 118 | - ], |
|
| 119 | - ]); |
|
| 120 | - $user->expects($this->exactly(2)) |
|
| 121 | - ->method('getUID') |
|
| 122 | - ->willReturn('user123'); |
|
| 123 | - |
|
| 124 | - $entries = $this->contactsStore->getContacts($user, ''); |
|
| 125 | - |
|
| 126 | - $this->assertCount(1, $entries); |
|
| 127 | - } |
|
| 128 | - |
|
| 129 | - public function testGetContactsWithoutBinaryImage(): void { |
|
| 130 | - /** @var IUser|MockObject $user */ |
|
| 131 | - $user = $this->createMock(IUser::class); |
|
| 132 | - $this->urlGenerator->expects($this->any()) |
|
| 133 | - ->method('linkToRouteAbsolute') |
|
| 134 | - ->with('core.GuestAvatar.getAvatar', $this->anything()) |
|
| 135 | - ->willReturn('https://urlToNcAvatar.test'); |
|
| 136 | - $this->contactsManager->expects($this->once()) |
|
| 137 | - ->method('search') |
|
| 138 | - ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 139 | - ->willReturn([ |
|
| 140 | - [ |
|
| 141 | - 'UID' => 123, |
|
| 142 | - ], |
|
| 143 | - [ |
|
| 144 | - 'UID' => 567, |
|
| 145 | - 'FN' => 'Darren Roner', |
|
| 146 | - 'EMAIL' => [ |
|
| 147 | - '[email protected]' |
|
| 148 | - ], |
|
| 149 | - 'PHOTO' => base64_encode('photophotophoto'), |
|
| 150 | - ], |
|
| 151 | - ]); |
|
| 152 | - $user->expects($this->exactly(2)) |
|
| 153 | - ->method('getUID') |
|
| 154 | - ->willReturn('user123'); |
|
| 155 | - |
|
| 156 | - $entries = $this->contactsStore->getContacts($user, ''); |
|
| 157 | - |
|
| 158 | - $this->assertCount(2, $entries); |
|
| 159 | - $this->assertSame('https://urlToNcAvatar.test', $entries[1]->getAvatar()); |
|
| 160 | - } |
|
| 161 | - |
|
| 162 | - public function testGetContactsWithoutAvatarURI(): void { |
|
| 163 | - /** @var IUser|MockObject $user */ |
|
| 164 | - $user = $this->createMock(IUser::class); |
|
| 165 | - $this->contactsManager->expects($this->once()) |
|
| 166 | - ->method('search') |
|
| 167 | - ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 168 | - ->willReturn([ |
|
| 169 | - [ |
|
| 170 | - 'UID' => 123, |
|
| 171 | - ], |
|
| 172 | - [ |
|
| 173 | - 'UID' => 567, |
|
| 174 | - 'FN' => 'Darren Roner', |
|
| 175 | - 'EMAIL' => [ |
|
| 176 | - '[email protected]' |
|
| 177 | - ], |
|
| 178 | - 'PHOTO' => 'VALUE=uri:https://photo', |
|
| 179 | - ], |
|
| 180 | - ]); |
|
| 181 | - $user->expects($this->exactly(2)) |
|
| 182 | - ->method('getUID') |
|
| 183 | - ->willReturn('user123'); |
|
| 184 | - |
|
| 185 | - $entries = $this->contactsStore->getContacts($user, ''); |
|
| 186 | - |
|
| 187 | - $this->assertCount(2, $entries); |
|
| 188 | - $this->assertEquals('https://photo', $entries[1]->getAvatar()); |
|
| 189 | - } |
|
| 190 | - |
|
| 191 | - public function testGetContactsWhenUserIsInExcludeGroups(): void { |
|
| 192 | - $this->config |
|
| 193 | - ->method('getAppValue') |
|
| 194 | - ->willReturnMap([ |
|
| 195 | - ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 196 | - ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'], |
|
| 197 | - ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'], |
|
| 198 | - ['core', 'shareapi_exclude_groups', 'no', 'yes'], |
|
| 199 | - ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], |
|
| 200 | - ['core', 'shareapi_exclude_groups_list', '', '["group1", "group5", "group6"]'], |
|
| 201 | - ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'], |
|
| 202 | - ]); |
|
| 203 | - |
|
| 204 | - /** @var IUser|MockObject $currentUser */ |
|
| 205 | - $currentUser = $this->createMock(IUser::class); |
|
| 206 | - $currentUser->expects($this->exactly(2)) |
|
| 207 | - ->method('getUID') |
|
| 208 | - ->willReturn('user001'); |
|
| 209 | - |
|
| 210 | - $this->groupManager->expects($this->once()) |
|
| 211 | - ->method('getUserGroupIds') |
|
| 212 | - ->with($this->equalTo($currentUser)) |
|
| 213 | - ->willReturn(['group1', 'group2', 'group3']); |
|
| 214 | - |
|
| 215 | - |
|
| 216 | - $this->contactsManager->expects($this->once()) |
|
| 217 | - ->method('search') |
|
| 218 | - ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 219 | - ->willReturn([ |
|
| 220 | - [ |
|
| 221 | - 'UID' => 'user123', |
|
| 222 | - 'isLocalSystemBook' => true |
|
| 223 | - ], |
|
| 224 | - [ |
|
| 225 | - 'UID' => 'user12345', |
|
| 226 | - 'isLocalSystemBook' => true |
|
| 227 | - ], |
|
| 228 | - ]); |
|
| 229 | - |
|
| 230 | - |
|
| 231 | - $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 232 | - |
|
| 233 | - $this->assertCount(0, $entries); |
|
| 234 | - } |
|
| 235 | - |
|
| 236 | - public function testGetContactsOnlyShareIfInTheSameGroup(): void { |
|
| 237 | - $this->config |
|
| 238 | - ->method('getAppValue') |
|
| 239 | - ->willReturnMap([ |
|
| 240 | - ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 241 | - ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'], |
|
| 242 | - ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'], |
|
| 243 | - ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 244 | - ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], |
|
| 245 | - ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'], |
|
| 246 | - ]); |
|
| 247 | - |
|
| 248 | - /** @var IUser|MockObject $currentUser */ |
|
| 249 | - $currentUser = $this->createMock(IUser::class); |
|
| 250 | - $currentUser->expects($this->exactly(2)) |
|
| 251 | - ->method('getUID') |
|
| 252 | - ->willReturn('user001'); |
|
| 253 | - |
|
| 254 | - $user1 = $this->createMock(IUser::class); |
|
| 255 | - $user2 = $this->createMock(IUser::class); |
|
| 256 | - $user3 = $this->createMock(IUser::class); |
|
| 257 | - |
|
| 258 | - $calls = [ |
|
| 259 | - [[$currentUser], ['group1', 'group2', 'group3']], |
|
| 260 | - [[$user1], ['group1']], |
|
| 261 | - [[$user2], ['group2', 'group3']], |
|
| 262 | - [[$user3], ['group8', 'group9']], |
|
| 263 | - ]; |
|
| 264 | - $this->groupManager->expects($this->exactly(4)) |
|
| 265 | - ->method('getUserGroupIds') |
|
| 266 | - ->willReturnCallback(function () use (&$calls): array { |
|
| 267 | - $expected = array_shift($calls); |
|
| 268 | - $this->assertEquals($expected[0], func_get_args()); |
|
| 269 | - return $expected[1]; |
|
| 270 | - }); |
|
| 271 | - |
|
| 272 | - $this->userManager->expects($this->exactly(3)) |
|
| 273 | - ->method('get') |
|
| 274 | - ->willReturnMap([ |
|
| 275 | - ['user1', $user1], |
|
| 276 | - ['user2', $user2], |
|
| 277 | - ['user3', $user3], |
|
| 278 | - ]); |
|
| 279 | - |
|
| 280 | - $this->contactsManager->expects($this->once()) |
|
| 281 | - ->method('search') |
|
| 282 | - ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 283 | - ->willReturn([ |
|
| 284 | - [ |
|
| 285 | - 'UID' => 'user1', |
|
| 286 | - 'isLocalSystemBook' => true |
|
| 287 | - ], |
|
| 288 | - [ |
|
| 289 | - 'UID' => 'user2', |
|
| 290 | - 'isLocalSystemBook' => true |
|
| 291 | - ], |
|
| 292 | - [ |
|
| 293 | - 'UID' => 'user3', |
|
| 294 | - 'isLocalSystemBook' => true |
|
| 295 | - ], |
|
| 296 | - [ |
|
| 297 | - 'UID' => 'contact', |
|
| 298 | - ], |
|
| 299 | - ]); |
|
| 300 | - |
|
| 301 | - $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 302 | - |
|
| 303 | - $this->assertCount(3, $entries); |
|
| 304 | - $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 305 | - $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 306 | - $this->assertEquals('contact', $entries[2]->getProperty('UID')); |
|
| 307 | - } |
|
| 308 | - |
|
| 309 | - public function testGetContactsOnlyEnumerateIfInTheSameGroup(): void { |
|
| 310 | - $this->config |
|
| 311 | - ->method('getAppValue') |
|
| 312 | - ->willReturnMap([ |
|
| 313 | - ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 314 | - ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'], |
|
| 315 | - ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'], |
|
| 316 | - ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 317 | - ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], |
|
| 318 | - ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'], |
|
| 319 | - ]); |
|
| 320 | - |
|
| 321 | - /** @var IUser|MockObject $currentUser */ |
|
| 322 | - $currentUser = $this->createMock(IUser::class); |
|
| 323 | - $currentUser->expects($this->exactly(2)) |
|
| 324 | - ->method('getUID') |
|
| 325 | - ->willReturn('user001'); |
|
| 326 | - |
|
| 327 | - $user1 = $this->createMock(IUser::class); |
|
| 328 | - $user2 = $this->createMock(IUser::class); |
|
| 329 | - $user3 = $this->createMock(IUser::class); |
|
| 330 | - |
|
| 331 | - $calls = [ |
|
| 332 | - [[$currentUser], ['group1', 'group2', 'group3']], |
|
| 333 | - [[$user1], ['group1']], |
|
| 334 | - [[$user2], ['group2', 'group3']], |
|
| 335 | - [[$user3], ['group8', 'group9']], |
|
| 336 | - ]; |
|
| 337 | - $this->groupManager->expects($this->exactly(4)) |
|
| 338 | - ->method('getUserGroupIds') |
|
| 339 | - ->willReturnCallback(function () use (&$calls): array { |
|
| 340 | - $expected = array_shift($calls); |
|
| 341 | - $this->assertEquals($expected[0], func_get_args()); |
|
| 342 | - return $expected[1]; |
|
| 343 | - }); |
|
| 344 | - |
|
| 345 | - $this->userManager->expects($this->exactly(3)) |
|
| 346 | - ->method('get') |
|
| 347 | - ->willReturnMap([ |
|
| 348 | - ['user1', $user1], |
|
| 349 | - ['user2', $user2], |
|
| 350 | - ['user3', $user3], |
|
| 351 | - ]); |
|
| 352 | - |
|
| 353 | - $this->contactsManager->expects($this->once()) |
|
| 354 | - ->method('search') |
|
| 355 | - ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 356 | - ->willReturn([ |
|
| 357 | - [ |
|
| 358 | - 'UID' => 'user1', |
|
| 359 | - 'isLocalSystemBook' => true |
|
| 360 | - ], |
|
| 361 | - [ |
|
| 362 | - 'UID' => 'user2', |
|
| 363 | - 'isLocalSystemBook' => true |
|
| 364 | - ], |
|
| 365 | - [ |
|
| 366 | - 'UID' => 'user3', |
|
| 367 | - 'isLocalSystemBook' => true |
|
| 368 | - ], |
|
| 369 | - [ |
|
| 370 | - 'UID' => 'contact', |
|
| 371 | - ], |
|
| 372 | - ]); |
|
| 373 | - |
|
| 374 | - $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 375 | - |
|
| 376 | - $this->assertCount(3, $entries); |
|
| 377 | - $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 378 | - $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 379 | - $this->assertEquals('contact', $entries[2]->getProperty('UID')); |
|
| 380 | - } |
|
| 381 | - |
|
| 382 | - public function testGetContactsOnlyEnumerateIfPhoneBookMatch(): void { |
|
| 383 | - $this->config |
|
| 384 | - ->method('getAppValue') |
|
| 385 | - ->willReturnMap([ |
|
| 386 | - ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 387 | - ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'], |
|
| 388 | - ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'], |
|
| 389 | - ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 390 | - ['core', 'shareapi_only_share_with_group_members', 'no', 'no'], |
|
| 391 | - ]); |
|
| 392 | - |
|
| 393 | - /** @var IUser|MockObject $currentUser */ |
|
| 394 | - $currentUser = $this->createMock(IUser::class); |
|
| 395 | - $currentUser->expects($this->exactly(2)) |
|
| 396 | - ->method('getUID') |
|
| 397 | - ->willReturn('user001'); |
|
| 398 | - |
|
| 399 | - $this->groupManager->expects($this->once()) |
|
| 400 | - ->method('getUserGroupIds') |
|
| 401 | - ->with($this->equalTo($currentUser)) |
|
| 402 | - ->willReturn(['group1', 'group2', 'group3']); |
|
| 403 | - |
|
| 404 | - $this->knownUserService->method('isKnownToUser') |
|
| 405 | - ->willReturnMap([ |
|
| 406 | - ['user001', 'user1', true], |
|
| 407 | - ['user001', 'user2', true], |
|
| 408 | - ['user001', 'user3', false], |
|
| 409 | - ]); |
|
| 410 | - |
|
| 411 | - $this->contactsManager->expects($this->once()) |
|
| 412 | - ->method('search') |
|
| 413 | - ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 414 | - ->willReturn([ |
|
| 415 | - [ |
|
| 416 | - 'UID' => 'user1', |
|
| 417 | - 'isLocalSystemBook' => true |
|
| 418 | - ], |
|
| 419 | - [ |
|
| 420 | - 'UID' => 'user2', |
|
| 421 | - 'isLocalSystemBook' => true |
|
| 422 | - ], |
|
| 423 | - [ |
|
| 424 | - 'UID' => 'user3', |
|
| 425 | - 'isLocalSystemBook' => true |
|
| 426 | - ], |
|
| 427 | - [ |
|
| 428 | - 'UID' => 'contact', |
|
| 429 | - ], |
|
| 430 | - ]); |
|
| 431 | - |
|
| 432 | - $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 433 | - |
|
| 434 | - $this->assertCount(3, $entries); |
|
| 435 | - $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 436 | - $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 437 | - $this->assertEquals('contact', $entries[2]->getProperty('UID')); |
|
| 438 | - } |
|
| 439 | - |
|
| 440 | - public function testGetContactsOnlyEnumerateIfPhoneBookMatchWithOwnGroupsOnly(): void { |
|
| 441 | - $this->config |
|
| 442 | - ->method('getAppValue') |
|
| 443 | - ->willReturnMap([ |
|
| 444 | - ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 445 | - ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'], |
|
| 446 | - ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'], |
|
| 447 | - ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 448 | - ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], |
|
| 449 | - ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'], |
|
| 450 | - ]); |
|
| 451 | - |
|
| 452 | - /** @var IUser|MockObject $currentUser */ |
|
| 453 | - $currentUser = $this->createMock(IUser::class); |
|
| 454 | - $currentUser->expects($this->exactly(2)) |
|
| 455 | - ->method('getUID') |
|
| 456 | - ->willReturn('user001'); |
|
| 457 | - |
|
| 458 | - $user1 = $this->createMock(IUser::class); |
|
| 459 | - $user2 = $this->createMock(IUser::class); |
|
| 460 | - $user3 = $this->createMock(IUser::class); |
|
| 461 | - |
|
| 462 | - $calls = [ |
|
| 463 | - [[$currentUser], ['group1', 'group2', 'group3']], |
|
| 464 | - [[$user1], ['group1']], |
|
| 465 | - [[$user2], ['group2', 'group3']], |
|
| 466 | - [[$user3], ['group8', 'group9']], |
|
| 467 | - ]; |
|
| 468 | - $this->groupManager->expects($this->exactly(4)) |
|
| 469 | - ->method('getUserGroupIds') |
|
| 470 | - ->willReturnCallback(function () use (&$calls): array { |
|
| 471 | - $expected = array_shift($calls); |
|
| 472 | - $this->assertEquals($expected[0], func_get_args()); |
|
| 473 | - return $expected[1]; |
|
| 474 | - }); |
|
| 475 | - |
|
| 476 | - $this->userManager->expects($this->exactly(3)) |
|
| 477 | - ->method('get') |
|
| 478 | - ->willReturnMap([ |
|
| 479 | - ['user1', $user1], |
|
| 480 | - ['user2', $user2], |
|
| 481 | - ['user3', $user3], |
|
| 482 | - ]); |
|
| 483 | - |
|
| 484 | - $this->knownUserService->method('isKnownToUser') |
|
| 485 | - ->willReturnMap([ |
|
| 486 | - ['user001', 'user1', true], |
|
| 487 | - ['user001', 'user2', true], |
|
| 488 | - ['user001', 'user3', true], |
|
| 489 | - ]); |
|
| 490 | - |
|
| 491 | - $this->contactsManager->expects($this->once()) |
|
| 492 | - ->method('search') |
|
| 493 | - ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 494 | - ->willReturn([ |
|
| 495 | - [ |
|
| 496 | - 'UID' => 'user1', |
|
| 497 | - 'isLocalSystemBook' => true |
|
| 498 | - ], |
|
| 499 | - [ |
|
| 500 | - 'UID' => 'user2', |
|
| 501 | - 'isLocalSystemBook' => true |
|
| 502 | - ], |
|
| 503 | - [ |
|
| 504 | - 'UID' => 'user3', |
|
| 505 | - 'isLocalSystemBook' => true |
|
| 506 | - ], |
|
| 507 | - [ |
|
| 508 | - 'UID' => 'contact', |
|
| 509 | - ], |
|
| 510 | - ]); |
|
| 511 | - |
|
| 512 | - $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 513 | - |
|
| 514 | - $this->assertCount(3, $entries); |
|
| 515 | - $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 516 | - $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 517 | - $this->assertEquals('contact', $entries[2]->getProperty('UID')); |
|
| 518 | - } |
|
| 519 | - |
|
| 520 | - public function testGetContactsOnlyEnumerateIfPhoneBookOrSameGroup(): void { |
|
| 521 | - $this->config |
|
| 522 | - ->method('getAppValue') |
|
| 523 | - ->willReturnMap([ |
|
| 524 | - ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 525 | - ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'], |
|
| 526 | - ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'], |
|
| 527 | - ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 528 | - ['core', 'shareapi_only_share_with_group_members', 'no', 'no'], |
|
| 529 | - ]); |
|
| 530 | - |
|
| 531 | - /** @var IUser|MockObject $currentUser */ |
|
| 532 | - $currentUser = $this->createMock(IUser::class); |
|
| 533 | - $currentUser->expects($this->exactly(2)) |
|
| 534 | - ->method('getUID') |
|
| 535 | - ->willReturn('user001'); |
|
| 536 | - |
|
| 537 | - $user1 = $this->createMock(IUser::class); |
|
| 538 | - |
|
| 539 | - $calls = [ |
|
| 540 | - [[$currentUser], ['group1', 'group2', 'group3']], |
|
| 541 | - [[$user1], ['group1']], |
|
| 542 | - ]; |
|
| 543 | - $this->groupManager->expects($this->exactly(2)) |
|
| 544 | - ->method('getUserGroupIds') |
|
| 545 | - ->willReturnCallback(function () use (&$calls): array { |
|
| 546 | - $expected = array_shift($calls); |
|
| 547 | - $this->assertEquals($expected[0], func_get_args()); |
|
| 548 | - return $expected[1]; |
|
| 549 | - }); |
|
| 550 | - |
|
| 551 | - $this->userManager->expects($this->once()) |
|
| 552 | - ->method('get') |
|
| 553 | - ->with('user1') |
|
| 554 | - ->willReturn($user1); |
|
| 555 | - |
|
| 556 | - $this->knownUserService->method('isKnownToUser') |
|
| 557 | - ->willReturnMap([ |
|
| 558 | - ['user001', 'user1', false], |
|
| 559 | - ['user001', 'user2', true], |
|
| 560 | - ['user001', 'user3', true], |
|
| 561 | - ]); |
|
| 562 | - |
|
| 563 | - $this->contactsManager->expects($this->once()) |
|
| 564 | - ->method('search') |
|
| 565 | - ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 566 | - ->willReturn([ |
|
| 567 | - [ |
|
| 568 | - 'UID' => 'user1', |
|
| 569 | - 'isLocalSystemBook' => true |
|
| 570 | - ], |
|
| 571 | - [ |
|
| 572 | - 'UID' => 'user2', |
|
| 573 | - 'isLocalSystemBook' => true |
|
| 574 | - ], |
|
| 575 | - [ |
|
| 576 | - 'UID' => 'user3', |
|
| 577 | - 'isLocalSystemBook' => true |
|
| 578 | - ], |
|
| 579 | - [ |
|
| 580 | - 'UID' => 'contact', |
|
| 581 | - ], |
|
| 582 | - ]); |
|
| 583 | - |
|
| 584 | - $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 585 | - |
|
| 586 | - $this->assertCount(4, $entries); |
|
| 587 | - $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 588 | - $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 589 | - $this->assertEquals('user3', $entries[2]->getProperty('UID')); |
|
| 590 | - $this->assertEquals('contact', $entries[3]->getProperty('UID')); |
|
| 591 | - } |
|
| 592 | - |
|
| 593 | - public function testGetContactsOnlyEnumerateIfPhoneBookOrSameGroupInOwnGroupsOnly(): void { |
|
| 594 | - $this->config |
|
| 595 | - ->method('getAppValue') |
|
| 596 | - ->willReturnMap([ |
|
| 597 | - ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 598 | - ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'], |
|
| 599 | - ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'], |
|
| 600 | - ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 601 | - ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], |
|
| 602 | - ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'], |
|
| 603 | - ]); |
|
| 604 | - |
|
| 605 | - /** @var IUser|MockObject $currentUser */ |
|
| 606 | - $currentUser = $this->createMock(IUser::class); |
|
| 607 | - $currentUser->expects($this->exactly(2)) |
|
| 608 | - ->method('getUID') |
|
| 609 | - ->willReturn('user001'); |
|
| 610 | - |
|
| 611 | - $user1 = $this->createMock(IUser::class); |
|
| 612 | - $user2 = $this->createMock(IUser::class); |
|
| 613 | - $user3 = $this->createMock(IUser::class); |
|
| 614 | - |
|
| 615 | - $calls = [ |
|
| 616 | - [[$currentUser], ['group1', 'group2', 'group3']], |
|
| 617 | - [[$user1], ['group1']], |
|
| 618 | - [[$user2], ['group2', 'group3']], |
|
| 619 | - [[$user3], ['group8', 'group9']], |
|
| 620 | - ]; |
|
| 621 | - $this->groupManager->expects($this->exactly(4)) |
|
| 622 | - ->method('getUserGroupIds') |
|
| 623 | - ->willReturnCallback(function () use (&$calls): array { |
|
| 624 | - $expected = array_shift($calls); |
|
| 625 | - $this->assertEquals($expected[0], func_get_args()); |
|
| 626 | - return $expected[1]; |
|
| 627 | - }); |
|
| 628 | - |
|
| 629 | - $this->userManager->expects($this->exactly(3)) |
|
| 630 | - ->method('get') |
|
| 631 | - ->willReturnMap([ |
|
| 632 | - ['user1', $user1], |
|
| 633 | - ['user2', $user2], |
|
| 634 | - ['user3', $user3], |
|
| 635 | - ]); |
|
| 636 | - |
|
| 637 | - $this->knownUserService->method('isKnownToUser') |
|
| 638 | - ->willReturnMap([ |
|
| 639 | - ['user001', 'user1', false], |
|
| 640 | - ['user001', 'user2', true], |
|
| 641 | - ['user001', 'user3', true], |
|
| 642 | - ]); |
|
| 643 | - |
|
| 644 | - $this->contactsManager->expects($this->once()) |
|
| 645 | - ->method('search') |
|
| 646 | - ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 647 | - ->willReturn([ |
|
| 648 | - [ |
|
| 649 | - 'UID' => 'user1', |
|
| 650 | - 'isLocalSystemBook' => true |
|
| 651 | - ], |
|
| 652 | - [ |
|
| 653 | - 'UID' => 'user2', |
|
| 654 | - 'isLocalSystemBook' => true |
|
| 655 | - ], |
|
| 656 | - [ |
|
| 657 | - 'UID' => 'user3', |
|
| 658 | - 'isLocalSystemBook' => true |
|
| 659 | - ], |
|
| 660 | - [ |
|
| 661 | - 'UID' => 'contact', |
|
| 662 | - ], |
|
| 663 | - ]); |
|
| 664 | - |
|
| 665 | - $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 666 | - |
|
| 667 | - $this->assertCount(3, $entries); |
|
| 668 | - $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 669 | - $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 670 | - $this->assertEquals('contact', $entries[2]->getProperty('UID')); |
|
| 671 | - } |
|
| 672 | - |
|
| 673 | - public function testGetContactsWithFilter(): void { |
|
| 674 | - $this->config |
|
| 675 | - ->method('getAppValue') |
|
| 676 | - ->willReturnMap([ |
|
| 677 | - ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'], |
|
| 678 | - ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'], |
|
| 679 | - ]); |
|
| 680 | - |
|
| 681 | - /** @var IUser|MockObject $user */ |
|
| 682 | - $user = $this->createMock(IUser::class); |
|
| 683 | - $this->contactsManager->expects($this->any()) |
|
| 684 | - ->method('search') |
|
| 685 | - ->willReturn([ |
|
| 686 | - [ |
|
| 687 | - 'UID' => 'a567', |
|
| 688 | - 'FN' => 'Darren Roner', |
|
| 689 | - 'EMAIL' => [ |
|
| 690 | - '[email protected]', |
|
| 691 | - ], |
|
| 692 | - 'isLocalSystemBook' => true, |
|
| 693 | - ], |
|
| 694 | - [ |
|
| 695 | - 'UID' => 'john', |
|
| 696 | - 'FN' => 'John Doe', |
|
| 697 | - 'EMAIL' => [ |
|
| 698 | - '[email protected]', |
|
| 699 | - ], |
|
| 700 | - 'isLocalSystemBook' => true, |
|
| 701 | - ], |
|
| 702 | - [ |
|
| 703 | - 'FN' => 'Anne D', |
|
| 704 | - 'EMAIL' => [ |
|
| 705 | - '[email protected]', |
|
| 706 | - ], |
|
| 707 | - 'isLocalSystemBook' => false, |
|
| 708 | - ], |
|
| 709 | - ]); |
|
| 710 | - $user->expects($this->any()) |
|
| 711 | - ->method('getUID') |
|
| 712 | - ->willReturn('user123'); |
|
| 713 | - |
|
| 714 | - // Complete match on UID should match |
|
| 715 | - $entry = $this->contactsStore->getContacts($user, 'a567'); |
|
| 716 | - $this->assertSame(2, count($entry)); |
|
| 717 | - $this->assertEquals([ |
|
| 718 | - '[email protected]' |
|
| 719 | - ], $entry[0]->getEMailAddresses()); |
|
| 720 | - |
|
| 721 | - // Partial match on UID should not match |
|
| 722 | - $entry = $this->contactsStore->getContacts($user, 'a56'); |
|
| 723 | - $this->assertSame(1, count($entry)); |
|
| 724 | - $this->assertEquals([ |
|
| 725 | - '[email protected]' |
|
| 726 | - ], $entry[0]->getEMailAddresses()); |
|
| 727 | - |
|
| 728 | - // Complete match on email should match |
|
| 729 | - $entry = $this->contactsStore->getContacts($user, '[email protected]'); |
|
| 730 | - $this->assertSame(2, count($entry)); |
|
| 731 | - $this->assertEquals([ |
|
| 732 | - '[email protected]' |
|
| 733 | - ], $entry[0]->getEMailAddresses()); |
|
| 734 | - $this->assertEquals([ |
|
| 735 | - '[email protected]' |
|
| 736 | - ], $entry[1]->getEMailAddresses()); |
|
| 737 | - |
|
| 738 | - // Partial match on email should not match |
|
| 739 | - $entry = $this->contactsStore->getContacts($user, '[email protected]'); |
|
| 740 | - $this->assertSame(1, count($entry)); |
|
| 741 | - $this->assertEquals([ |
|
| 742 | - '[email protected]' |
|
| 743 | - ], $entry[0]->getEMailAddresses()); |
|
| 744 | - |
|
| 745 | - // Match on FN should not match |
|
| 746 | - $entry = $this->contactsStore->getContacts($user, 'Darren Roner'); |
|
| 747 | - $this->assertSame(1, count($entry)); |
|
| 748 | - $this->assertEquals([ |
|
| 749 | - '[email protected]' |
|
| 750 | - ], $entry[0]->getEMailAddresses()); |
|
| 751 | - |
|
| 752 | - // Don't filter users in local addressbook |
|
| 753 | - $entry = $this->contactsStore->getContacts($user, 'Anne D'); |
|
| 754 | - $this->assertSame(1, count($entry)); |
|
| 755 | - $this->assertEquals([ |
|
| 756 | - '[email protected]' |
|
| 757 | - ], $entry[0]->getEMailAddresses()); |
|
| 758 | - } |
|
| 759 | - |
|
| 760 | - public function testGetContactsWithFilterWithoutFullMatch(): void { |
|
| 761 | - $this->config |
|
| 762 | - ->method('getAppValue') |
|
| 763 | - ->willReturnMap([ |
|
| 764 | - ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'], |
|
| 765 | - ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'no'], |
|
| 766 | - ]); |
|
| 767 | - |
|
| 768 | - /** @var IUser|MockObject $user */ |
|
| 769 | - $user = $this->createMock(IUser::class); |
|
| 770 | - $this->contactsManager->expects($this->any()) |
|
| 771 | - ->method('search') |
|
| 772 | - ->willReturn([ |
|
| 773 | - [ |
|
| 774 | - 'UID' => 'a567', |
|
| 775 | - 'FN' => 'Darren Roner', |
|
| 776 | - 'EMAIL' => [ |
|
| 777 | - '[email protected]', |
|
| 778 | - ], |
|
| 779 | - 'isLocalSystemBook' => true, |
|
| 780 | - ], |
|
| 781 | - [ |
|
| 782 | - 'UID' => 'john', |
|
| 783 | - 'FN' => 'John Doe', |
|
| 784 | - 'EMAIL' => [ |
|
| 785 | - '[email protected]', |
|
| 786 | - ], |
|
| 787 | - 'isLocalSystemBook' => true, |
|
| 788 | - ], |
|
| 789 | - [ |
|
| 790 | - 'FN' => 'Anne D', |
|
| 791 | - 'EMAIL' => [ |
|
| 792 | - '[email protected]', |
|
| 793 | - ], |
|
| 794 | - 'isLocalSystemBook' => false, |
|
| 795 | - ], |
|
| 796 | - ]); |
|
| 797 | - $user->expects($this->any()) |
|
| 798 | - ->method('getUID') |
|
| 799 | - ->willReturn('user123'); |
|
| 800 | - |
|
| 801 | - // Complete match on UID should not match |
|
| 802 | - $entry = $this->contactsStore->getContacts($user, 'a567'); |
|
| 803 | - $this->assertSame(1, count($entry)); |
|
| 804 | - $this->assertEquals([ |
|
| 805 | - '[email protected]' |
|
| 806 | - ], $entry[0]->getEMailAddresses()); |
|
| 807 | - |
|
| 808 | - // Partial match on UID should not match |
|
| 809 | - $entry = $this->contactsStore->getContacts($user, 'a56'); |
|
| 810 | - $this->assertSame(1, count($entry)); |
|
| 811 | - $this->assertEquals([ |
|
| 812 | - '[email protected]' |
|
| 813 | - ], $entry[0]->getEMailAddresses()); |
|
| 814 | - |
|
| 815 | - // Complete match on email should not match |
|
| 816 | - $entry = $this->contactsStore->getContacts($user, '[email protected]'); |
|
| 817 | - $this->assertSame(1, count($entry)); |
|
| 818 | - $this->assertEquals([ |
|
| 819 | - '[email protected]' |
|
| 820 | - ], $entry[0]->getEMailAddresses()); |
|
| 821 | - |
|
| 822 | - // Partial match on email should not match |
|
| 823 | - $entry = $this->contactsStore->getContacts($user, '[email protected]'); |
|
| 824 | - $this->assertSame(1, count($entry)); |
|
| 825 | - $this->assertEquals([ |
|
| 826 | - '[email protected]' |
|
| 827 | - ], $entry[0]->getEMailAddresses()); |
|
| 828 | - |
|
| 829 | - // Match on FN should not match |
|
| 830 | - $entry = $this->contactsStore->getContacts($user, 'Darren Roner'); |
|
| 831 | - $this->assertSame(1, count($entry)); |
|
| 832 | - $this->assertEquals([ |
|
| 833 | - '[email protected]' |
|
| 834 | - ], $entry[0]->getEMailAddresses()); |
|
| 835 | - |
|
| 836 | - // Don't filter users in local addressbook |
|
| 837 | - $entry = $this->contactsStore->getContacts($user, 'Anne D'); |
|
| 838 | - $this->assertSame(1, count($entry)); |
|
| 839 | - $this->assertEquals([ |
|
| 840 | - '[email protected]' |
|
| 841 | - ], $entry[0]->getEMailAddresses()); |
|
| 842 | - } |
|
| 843 | - |
|
| 844 | - public function testFindOneUser(): void { |
|
| 845 | - $this->config |
|
| 846 | - ->method('getAppValue') |
|
| 847 | - ->willReturnMap([ |
|
| 848 | - ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 849 | - ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'], |
|
| 850 | - ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'], |
|
| 851 | - ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'], |
|
| 852 | - ['core', 'shareapi_exclude_groups', 'no', 'yes'], |
|
| 853 | - ['core', 'shareapi_exclude_groups_list', '', ''], |
|
| 854 | - ['core', 'shareapi_only_share_with_group_members', 'no', 'no'], |
|
| 855 | - ]); |
|
| 856 | - |
|
| 857 | - /** @var IUser|MockObject $user */ |
|
| 858 | - $user = $this->createMock(IUser::class); |
|
| 859 | - $this->contactsManager->expects($this->once()) |
|
| 860 | - ->method('search') |
|
| 861 | - ->with($this->equalTo('a567'), $this->equalTo(['UID'])) |
|
| 862 | - ->willReturn([ |
|
| 863 | - [ |
|
| 864 | - 'UID' => 123, |
|
| 865 | - 'isLocalSystemBook' => false |
|
| 866 | - ], |
|
| 867 | - [ |
|
| 868 | - 'UID' => 'a567', |
|
| 869 | - 'FN' => 'Darren Roner', |
|
| 870 | - 'EMAIL' => [ |
|
| 871 | - '[email protected]' |
|
| 872 | - ], |
|
| 873 | - 'isLocalSystemBook' => true |
|
| 874 | - ], |
|
| 875 | - ]); |
|
| 876 | - $user->expects($this->any()) |
|
| 877 | - ->method('getUID') |
|
| 878 | - ->willReturn('user123'); |
|
| 879 | - |
|
| 880 | - $entry = $this->contactsStore->findOne($user, 0, 'a567'); |
|
| 881 | - |
|
| 882 | - $this->assertEquals([ |
|
| 883 | - '[email protected]' |
|
| 884 | - ], $entry->getEMailAddresses()); |
|
| 885 | - } |
|
| 886 | - |
|
| 887 | - public function testFindOneEMail(): void { |
|
| 888 | - /** @var IUser|MockObject $user */ |
|
| 889 | - $user = $this->createMock(IUser::class); |
|
| 890 | - $this->contactsManager->expects($this->once()) |
|
| 891 | - ->method('search') |
|
| 892 | - ->with($this->equalTo('[email protected]'), $this->equalTo(['EMAIL'])) |
|
| 893 | - ->willReturn([ |
|
| 894 | - [ |
|
| 895 | - 'UID' => 123, |
|
| 896 | - 'isLocalSystemBook' => false |
|
| 897 | - ], |
|
| 898 | - [ |
|
| 899 | - 'UID' => 'a567', |
|
| 900 | - 'FN' => 'Darren Roner', |
|
| 901 | - 'EMAIL' => [ |
|
| 902 | - '[email protected]' |
|
| 903 | - ], |
|
| 904 | - 'isLocalSystemBook' => false |
|
| 905 | - ], |
|
| 906 | - ]); |
|
| 907 | - $user->expects($this->any()) |
|
| 908 | - ->method('getUID') |
|
| 909 | - ->willReturn('user123'); |
|
| 910 | - |
|
| 911 | - $entry = $this->contactsStore->findOne($user, 4, '[email protected]'); |
|
| 912 | - |
|
| 913 | - $this->assertEquals([ |
|
| 914 | - '[email protected]' |
|
| 915 | - ], $entry->getEMailAddresses()); |
|
| 916 | - } |
|
| 917 | - |
|
| 918 | - public function testFindOneNotSupportedType(): void { |
|
| 919 | - /** @var IUser|MockObject $user */ |
|
| 920 | - $user = $this->createMock(IUser::class); |
|
| 921 | - |
|
| 922 | - $entry = $this->contactsStore->findOne($user, 42, '[email protected]'); |
|
| 923 | - |
|
| 924 | - $this->assertEquals(null, $entry); |
|
| 925 | - } |
|
| 926 | - |
|
| 927 | - public function testFindOneNoMatches(): void { |
|
| 928 | - /** @var IUser|MockObject $user */ |
|
| 929 | - $user = $this->createMock(IUser::class); |
|
| 930 | - $this->contactsManager->expects($this->once()) |
|
| 931 | - ->method('search') |
|
| 932 | - ->with($this->equalTo('a567'), $this->equalTo(['UID'])) |
|
| 933 | - ->willReturn([ |
|
| 934 | - [ |
|
| 935 | - 'UID' => 123, |
|
| 936 | - 'isLocalSystemBook' => false |
|
| 937 | - ], |
|
| 938 | - [ |
|
| 939 | - 'UID' => 'a567', |
|
| 940 | - 'FN' => 'Darren Roner', |
|
| 941 | - 'EMAIL' => [ |
|
| 942 | - '[email protected]' |
|
| 943 | - ], |
|
| 944 | - 'isLocalSystemBook' => false |
|
| 945 | - ], |
|
| 946 | - ]); |
|
| 947 | - $user->expects($this->never()) |
|
| 948 | - ->method('getUID'); |
|
| 949 | - |
|
| 950 | - $entry = $this->contactsStore->findOne($user, 0, 'a567'); |
|
| 951 | - |
|
| 952 | - $this->assertEquals(null, $entry); |
|
| 953 | - } |
|
| 954 | - |
|
| 955 | - public function testGetRecentStatusFirst(): void { |
|
| 956 | - $user = $this->createMock(IUser::class); |
|
| 957 | - $status1 = new UserStatus(); |
|
| 958 | - $status1->setUserId('user1'); |
|
| 959 | - $status2 = new UserStatus(); |
|
| 960 | - $status2->setUserId('user2'); |
|
| 961 | - $this->statusService->expects(self::once()) |
|
| 962 | - ->method('findAllRecentStatusChanges') |
|
| 963 | - ->willReturn([ |
|
| 964 | - $status1, |
|
| 965 | - $status2, |
|
| 966 | - ]); |
|
| 967 | - $user1 = $this->createMock(IUser::class); |
|
| 968 | - $user1->method('getCloudId')->willReturn('user1@localcloud'); |
|
| 969 | - $user2 = $this->createMock(IUser::class); |
|
| 970 | - $user2->method('getCloudId')->willReturn('user2@localcloud'); |
|
| 971 | - $this->userManager->expects(self::exactly(2)) |
|
| 972 | - ->method('get') |
|
| 973 | - ->willReturnCallback(function ($uid) use ($user1, $user2) { |
|
| 974 | - return match ($uid) { |
|
| 975 | - 'user1' => $user1, |
|
| 976 | - 'user2' => $user2, |
|
| 977 | - }; |
|
| 978 | - }); |
|
| 979 | - $this->contactsManager |
|
| 980 | - ->expects(self::exactly(3)) |
|
| 981 | - ->method('search') |
|
| 982 | - ->willReturnCallback(function ($uid, $searchProps, $options) { |
|
| 983 | - return match ([$uid, $options['limit'] ?? null]) { |
|
| 984 | - ['user1@localcloud', 1] => [ |
|
| 985 | - [ |
|
| 986 | - 'UID' => 'user1', |
|
| 987 | - 'URI' => 'user1.vcf', |
|
| 988 | - ], |
|
| 989 | - ], |
|
| 990 | - ['user2@localcloud' => [], 1], // Simulate not found |
|
| 991 | - ['', 4] => [ |
|
| 992 | - [ |
|
| 993 | - 'UID' => 'contact1', |
|
| 994 | - 'URI' => 'contact1.vcf', |
|
| 995 | - ], |
|
| 996 | - [ |
|
| 997 | - 'UID' => 'contact2', |
|
| 998 | - 'URI' => 'contact2.vcf', |
|
| 999 | - ], |
|
| 1000 | - ], |
|
| 1001 | - default => [], |
|
| 1002 | - }; |
|
| 1003 | - }); |
|
| 1004 | - |
|
| 1005 | - $contacts = $this->contactsStore->getContacts( |
|
| 1006 | - $user, |
|
| 1007 | - null, |
|
| 1008 | - 5, |
|
| 1009 | - ); |
|
| 1010 | - |
|
| 1011 | - self::assertCount(3, $contacts); |
|
| 1012 | - self::assertEquals('user1', $contacts[0]->getProperty('UID')); |
|
| 1013 | - self::assertEquals('contact1', $contacts[1]->getProperty('UID')); |
|
| 1014 | - self::assertEquals('contact2', $contacts[2]->getProperty('UID')); |
|
| 1015 | - } |
|
| 1016 | - |
|
| 1017 | - public function testPaginateRecentStatus(): void { |
|
| 1018 | - $user = $this->createMock(IUser::class); |
|
| 1019 | - $status1 = new UserStatus(); |
|
| 1020 | - $status1->setUserId('user1'); |
|
| 1021 | - $status2 = new UserStatus(); |
|
| 1022 | - $status2->setUserId('user2'); |
|
| 1023 | - $status3 = new UserStatus(); |
|
| 1024 | - $status3->setUserId('user3'); |
|
| 1025 | - $this->statusService->expects(self::never()) |
|
| 1026 | - ->method('findAllRecentStatusChanges'); |
|
| 1027 | - $this->contactsManager |
|
| 1028 | - ->expects(self::exactly(2)) |
|
| 1029 | - ->method('search') |
|
| 1030 | - ->willReturnCallback(function ($uid, $searchProps, $options) { |
|
| 1031 | - return match ([$uid, $options['limit'] ?? null, $options['offset'] ?? null]) { |
|
| 1032 | - ['', 2, 0] => [ |
|
| 1033 | - [ |
|
| 1034 | - 'UID' => 'contact1', |
|
| 1035 | - 'URI' => 'contact1.vcf', |
|
| 1036 | - ], |
|
| 1037 | - [ |
|
| 1038 | - 'UID' => 'contact2', |
|
| 1039 | - 'URI' => 'contact2.vcf', |
|
| 1040 | - ], |
|
| 1041 | - ], |
|
| 1042 | - ['', 2, 3] => [ |
|
| 1043 | - [ |
|
| 1044 | - 'UID' => 'contact3', |
|
| 1045 | - 'URI' => 'contact3.vcf', |
|
| 1046 | - ], |
|
| 1047 | - ], |
|
| 1048 | - default => [], |
|
| 1049 | - }; |
|
| 1050 | - }); |
|
| 1051 | - |
|
| 1052 | - $page1 = $this->contactsStore->getContacts( |
|
| 1053 | - $user, |
|
| 1054 | - null, |
|
| 1055 | - 2, |
|
| 1056 | - 0, |
|
| 1057 | - ); |
|
| 1058 | - $page2 = $this->contactsStore->getContacts( |
|
| 1059 | - $user, |
|
| 1060 | - null, |
|
| 1061 | - 2, |
|
| 1062 | - 3, |
|
| 1063 | - ); |
|
| 1064 | - |
|
| 1065 | - self::assertCount(2, $page1); |
|
| 1066 | - self::assertCount(1, $page2); |
|
| 1067 | - } |
|
| 28 | + private ContactsStore $contactsStore; |
|
| 29 | + private StatusService|MockObject $statusService; |
|
| 30 | + /** @var IManager|MockObject */ |
|
| 31 | + private $contactsManager; |
|
| 32 | + /** @var ProfileManager */ |
|
| 33 | + private $profileManager; |
|
| 34 | + /** @var IUserManager|MockObject */ |
|
| 35 | + private $userManager; |
|
| 36 | + /** @var IURLGenerator */ |
|
| 37 | + private $urlGenerator; |
|
| 38 | + /** @var IGroupManager|MockObject */ |
|
| 39 | + private $groupManager; |
|
| 40 | + /** @var IConfig|MockObject */ |
|
| 41 | + private $config; |
|
| 42 | + /** @var KnownUserService|MockObject */ |
|
| 43 | + private $knownUserService; |
|
| 44 | + /** @var IL10NFactory */ |
|
| 45 | + private $l10nFactory; |
|
| 46 | + |
|
| 47 | + protected function setUp(): void { |
|
| 48 | + parent::setUp(); |
|
| 49 | + |
|
| 50 | + $this->contactsManager = $this->createMock(IManager::class); |
|
| 51 | + $this->statusService = $this->createMock(StatusService::class); |
|
| 52 | + $this->userManager = $this->createMock(IUserManager::class); |
|
| 53 | + $this->profileManager = $this->createMock(ProfileManager::class); |
|
| 54 | + $this->urlGenerator = $this->createMock(IURLGenerator::class); |
|
| 55 | + $this->groupManager = $this->createMock(IGroupManager::class); |
|
| 56 | + $this->config = $this->createMock(IConfig::class); |
|
| 57 | + $this->knownUserService = $this->createMock(KnownUserService::class); |
|
| 58 | + $this->l10nFactory = $this->createMock(IL10NFactory::class); |
|
| 59 | + $this->contactsStore = new ContactsStore( |
|
| 60 | + $this->contactsManager, |
|
| 61 | + $this->statusService, |
|
| 62 | + $this->config, |
|
| 63 | + $this->profileManager, |
|
| 64 | + $this->userManager, |
|
| 65 | + $this->urlGenerator, |
|
| 66 | + $this->groupManager, |
|
| 67 | + $this->knownUserService, |
|
| 68 | + $this->l10nFactory, |
|
| 69 | + ); |
|
| 70 | + } |
|
| 71 | + |
|
| 72 | + public function testGetContactsWithoutFilter(): void { |
|
| 73 | + /** @var IUser|MockObject $user */ |
|
| 74 | + $user = $this->createMock(IUser::class); |
|
| 75 | + $this->contactsManager->expects($this->once()) |
|
| 76 | + ->method('search') |
|
| 77 | + ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 78 | + ->willReturn([ |
|
| 79 | + [ |
|
| 80 | + 'UID' => 123, |
|
| 81 | + ], |
|
| 82 | + [ |
|
| 83 | + 'UID' => 567, |
|
| 84 | + 'FN' => 'Darren Roner', |
|
| 85 | + 'EMAIL' => [ |
|
| 86 | + '[email protected]' |
|
| 87 | + ], |
|
| 88 | + ], |
|
| 89 | + ]); |
|
| 90 | + $user->expects($this->exactly(2)) |
|
| 91 | + ->method('getUID') |
|
| 92 | + ->willReturn('user123'); |
|
| 93 | + |
|
| 94 | + $entries = $this->contactsStore->getContacts($user, ''); |
|
| 95 | + |
|
| 96 | + $this->assertCount(2, $entries); |
|
| 97 | + $this->assertEquals([ |
|
| 98 | + '[email protected]' |
|
| 99 | + ], $entries[1]->getEMailAddresses()); |
|
| 100 | + } |
|
| 101 | + |
|
| 102 | + public function testGetContactsHidesOwnEntry(): void { |
|
| 103 | + /** @var IUser|MockObject $user */ |
|
| 104 | + $user = $this->createMock(IUser::class); |
|
| 105 | + $this->contactsManager->expects($this->once()) |
|
| 106 | + ->method('search') |
|
| 107 | + ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 108 | + ->willReturn([ |
|
| 109 | + [ |
|
| 110 | + 'UID' => 'user123', |
|
| 111 | + ], |
|
| 112 | + [ |
|
| 113 | + 'UID' => 567, |
|
| 114 | + 'FN' => 'Darren Roner', |
|
| 115 | + 'EMAIL' => [ |
|
| 116 | + '[email protected]' |
|
| 117 | + ], |
|
| 118 | + ], |
|
| 119 | + ]); |
|
| 120 | + $user->expects($this->exactly(2)) |
|
| 121 | + ->method('getUID') |
|
| 122 | + ->willReturn('user123'); |
|
| 123 | + |
|
| 124 | + $entries = $this->contactsStore->getContacts($user, ''); |
|
| 125 | + |
|
| 126 | + $this->assertCount(1, $entries); |
|
| 127 | + } |
|
| 128 | + |
|
| 129 | + public function testGetContactsWithoutBinaryImage(): void { |
|
| 130 | + /** @var IUser|MockObject $user */ |
|
| 131 | + $user = $this->createMock(IUser::class); |
|
| 132 | + $this->urlGenerator->expects($this->any()) |
|
| 133 | + ->method('linkToRouteAbsolute') |
|
| 134 | + ->with('core.GuestAvatar.getAvatar', $this->anything()) |
|
| 135 | + ->willReturn('https://urlToNcAvatar.test'); |
|
| 136 | + $this->contactsManager->expects($this->once()) |
|
| 137 | + ->method('search') |
|
| 138 | + ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 139 | + ->willReturn([ |
|
| 140 | + [ |
|
| 141 | + 'UID' => 123, |
|
| 142 | + ], |
|
| 143 | + [ |
|
| 144 | + 'UID' => 567, |
|
| 145 | + 'FN' => 'Darren Roner', |
|
| 146 | + 'EMAIL' => [ |
|
| 147 | + '[email protected]' |
|
| 148 | + ], |
|
| 149 | + 'PHOTO' => base64_encode('photophotophoto'), |
|
| 150 | + ], |
|
| 151 | + ]); |
|
| 152 | + $user->expects($this->exactly(2)) |
|
| 153 | + ->method('getUID') |
|
| 154 | + ->willReturn('user123'); |
|
| 155 | + |
|
| 156 | + $entries = $this->contactsStore->getContacts($user, ''); |
|
| 157 | + |
|
| 158 | + $this->assertCount(2, $entries); |
|
| 159 | + $this->assertSame('https://urlToNcAvatar.test', $entries[1]->getAvatar()); |
|
| 160 | + } |
|
| 161 | + |
|
| 162 | + public function testGetContactsWithoutAvatarURI(): void { |
|
| 163 | + /** @var IUser|MockObject $user */ |
|
| 164 | + $user = $this->createMock(IUser::class); |
|
| 165 | + $this->contactsManager->expects($this->once()) |
|
| 166 | + ->method('search') |
|
| 167 | + ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 168 | + ->willReturn([ |
|
| 169 | + [ |
|
| 170 | + 'UID' => 123, |
|
| 171 | + ], |
|
| 172 | + [ |
|
| 173 | + 'UID' => 567, |
|
| 174 | + 'FN' => 'Darren Roner', |
|
| 175 | + 'EMAIL' => [ |
|
| 176 | + '[email protected]' |
|
| 177 | + ], |
|
| 178 | + 'PHOTO' => 'VALUE=uri:https://photo', |
|
| 179 | + ], |
|
| 180 | + ]); |
|
| 181 | + $user->expects($this->exactly(2)) |
|
| 182 | + ->method('getUID') |
|
| 183 | + ->willReturn('user123'); |
|
| 184 | + |
|
| 185 | + $entries = $this->contactsStore->getContacts($user, ''); |
|
| 186 | + |
|
| 187 | + $this->assertCount(2, $entries); |
|
| 188 | + $this->assertEquals('https://photo', $entries[1]->getAvatar()); |
|
| 189 | + } |
|
| 190 | + |
|
| 191 | + public function testGetContactsWhenUserIsInExcludeGroups(): void { |
|
| 192 | + $this->config |
|
| 193 | + ->method('getAppValue') |
|
| 194 | + ->willReturnMap([ |
|
| 195 | + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 196 | + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'], |
|
| 197 | + ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'], |
|
| 198 | + ['core', 'shareapi_exclude_groups', 'no', 'yes'], |
|
| 199 | + ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], |
|
| 200 | + ['core', 'shareapi_exclude_groups_list', '', '["group1", "group5", "group6"]'], |
|
| 201 | + ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'], |
|
| 202 | + ]); |
|
| 203 | + |
|
| 204 | + /** @var IUser|MockObject $currentUser */ |
|
| 205 | + $currentUser = $this->createMock(IUser::class); |
|
| 206 | + $currentUser->expects($this->exactly(2)) |
|
| 207 | + ->method('getUID') |
|
| 208 | + ->willReturn('user001'); |
|
| 209 | + |
|
| 210 | + $this->groupManager->expects($this->once()) |
|
| 211 | + ->method('getUserGroupIds') |
|
| 212 | + ->with($this->equalTo($currentUser)) |
|
| 213 | + ->willReturn(['group1', 'group2', 'group3']); |
|
| 214 | + |
|
| 215 | + |
|
| 216 | + $this->contactsManager->expects($this->once()) |
|
| 217 | + ->method('search') |
|
| 218 | + ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 219 | + ->willReturn([ |
|
| 220 | + [ |
|
| 221 | + 'UID' => 'user123', |
|
| 222 | + 'isLocalSystemBook' => true |
|
| 223 | + ], |
|
| 224 | + [ |
|
| 225 | + 'UID' => 'user12345', |
|
| 226 | + 'isLocalSystemBook' => true |
|
| 227 | + ], |
|
| 228 | + ]); |
|
| 229 | + |
|
| 230 | + |
|
| 231 | + $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 232 | + |
|
| 233 | + $this->assertCount(0, $entries); |
|
| 234 | + } |
|
| 235 | + |
|
| 236 | + public function testGetContactsOnlyShareIfInTheSameGroup(): void { |
|
| 237 | + $this->config |
|
| 238 | + ->method('getAppValue') |
|
| 239 | + ->willReturnMap([ |
|
| 240 | + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 241 | + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'], |
|
| 242 | + ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'], |
|
| 243 | + ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 244 | + ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], |
|
| 245 | + ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'], |
|
| 246 | + ]); |
|
| 247 | + |
|
| 248 | + /** @var IUser|MockObject $currentUser */ |
|
| 249 | + $currentUser = $this->createMock(IUser::class); |
|
| 250 | + $currentUser->expects($this->exactly(2)) |
|
| 251 | + ->method('getUID') |
|
| 252 | + ->willReturn('user001'); |
|
| 253 | + |
|
| 254 | + $user1 = $this->createMock(IUser::class); |
|
| 255 | + $user2 = $this->createMock(IUser::class); |
|
| 256 | + $user3 = $this->createMock(IUser::class); |
|
| 257 | + |
|
| 258 | + $calls = [ |
|
| 259 | + [[$currentUser], ['group1', 'group2', 'group3']], |
|
| 260 | + [[$user1], ['group1']], |
|
| 261 | + [[$user2], ['group2', 'group3']], |
|
| 262 | + [[$user3], ['group8', 'group9']], |
|
| 263 | + ]; |
|
| 264 | + $this->groupManager->expects($this->exactly(4)) |
|
| 265 | + ->method('getUserGroupIds') |
|
| 266 | + ->willReturnCallback(function () use (&$calls): array { |
|
| 267 | + $expected = array_shift($calls); |
|
| 268 | + $this->assertEquals($expected[0], func_get_args()); |
|
| 269 | + return $expected[1]; |
|
| 270 | + }); |
|
| 271 | + |
|
| 272 | + $this->userManager->expects($this->exactly(3)) |
|
| 273 | + ->method('get') |
|
| 274 | + ->willReturnMap([ |
|
| 275 | + ['user1', $user1], |
|
| 276 | + ['user2', $user2], |
|
| 277 | + ['user3', $user3], |
|
| 278 | + ]); |
|
| 279 | + |
|
| 280 | + $this->contactsManager->expects($this->once()) |
|
| 281 | + ->method('search') |
|
| 282 | + ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 283 | + ->willReturn([ |
|
| 284 | + [ |
|
| 285 | + 'UID' => 'user1', |
|
| 286 | + 'isLocalSystemBook' => true |
|
| 287 | + ], |
|
| 288 | + [ |
|
| 289 | + 'UID' => 'user2', |
|
| 290 | + 'isLocalSystemBook' => true |
|
| 291 | + ], |
|
| 292 | + [ |
|
| 293 | + 'UID' => 'user3', |
|
| 294 | + 'isLocalSystemBook' => true |
|
| 295 | + ], |
|
| 296 | + [ |
|
| 297 | + 'UID' => 'contact', |
|
| 298 | + ], |
|
| 299 | + ]); |
|
| 300 | + |
|
| 301 | + $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 302 | + |
|
| 303 | + $this->assertCount(3, $entries); |
|
| 304 | + $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 305 | + $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 306 | + $this->assertEquals('contact', $entries[2]->getProperty('UID')); |
|
| 307 | + } |
|
| 308 | + |
|
| 309 | + public function testGetContactsOnlyEnumerateIfInTheSameGroup(): void { |
|
| 310 | + $this->config |
|
| 311 | + ->method('getAppValue') |
|
| 312 | + ->willReturnMap([ |
|
| 313 | + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 314 | + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'], |
|
| 315 | + ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'], |
|
| 316 | + ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 317 | + ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], |
|
| 318 | + ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'], |
|
| 319 | + ]); |
|
| 320 | + |
|
| 321 | + /** @var IUser|MockObject $currentUser */ |
|
| 322 | + $currentUser = $this->createMock(IUser::class); |
|
| 323 | + $currentUser->expects($this->exactly(2)) |
|
| 324 | + ->method('getUID') |
|
| 325 | + ->willReturn('user001'); |
|
| 326 | + |
|
| 327 | + $user1 = $this->createMock(IUser::class); |
|
| 328 | + $user2 = $this->createMock(IUser::class); |
|
| 329 | + $user3 = $this->createMock(IUser::class); |
|
| 330 | + |
|
| 331 | + $calls = [ |
|
| 332 | + [[$currentUser], ['group1', 'group2', 'group3']], |
|
| 333 | + [[$user1], ['group1']], |
|
| 334 | + [[$user2], ['group2', 'group3']], |
|
| 335 | + [[$user3], ['group8', 'group9']], |
|
| 336 | + ]; |
|
| 337 | + $this->groupManager->expects($this->exactly(4)) |
|
| 338 | + ->method('getUserGroupIds') |
|
| 339 | + ->willReturnCallback(function () use (&$calls): array { |
|
| 340 | + $expected = array_shift($calls); |
|
| 341 | + $this->assertEquals($expected[0], func_get_args()); |
|
| 342 | + return $expected[1]; |
|
| 343 | + }); |
|
| 344 | + |
|
| 345 | + $this->userManager->expects($this->exactly(3)) |
|
| 346 | + ->method('get') |
|
| 347 | + ->willReturnMap([ |
|
| 348 | + ['user1', $user1], |
|
| 349 | + ['user2', $user2], |
|
| 350 | + ['user3', $user3], |
|
| 351 | + ]); |
|
| 352 | + |
|
| 353 | + $this->contactsManager->expects($this->once()) |
|
| 354 | + ->method('search') |
|
| 355 | + ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 356 | + ->willReturn([ |
|
| 357 | + [ |
|
| 358 | + 'UID' => 'user1', |
|
| 359 | + 'isLocalSystemBook' => true |
|
| 360 | + ], |
|
| 361 | + [ |
|
| 362 | + 'UID' => 'user2', |
|
| 363 | + 'isLocalSystemBook' => true |
|
| 364 | + ], |
|
| 365 | + [ |
|
| 366 | + 'UID' => 'user3', |
|
| 367 | + 'isLocalSystemBook' => true |
|
| 368 | + ], |
|
| 369 | + [ |
|
| 370 | + 'UID' => 'contact', |
|
| 371 | + ], |
|
| 372 | + ]); |
|
| 373 | + |
|
| 374 | + $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 375 | + |
|
| 376 | + $this->assertCount(3, $entries); |
|
| 377 | + $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 378 | + $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 379 | + $this->assertEquals('contact', $entries[2]->getProperty('UID')); |
|
| 380 | + } |
|
| 381 | + |
|
| 382 | + public function testGetContactsOnlyEnumerateIfPhoneBookMatch(): void { |
|
| 383 | + $this->config |
|
| 384 | + ->method('getAppValue') |
|
| 385 | + ->willReturnMap([ |
|
| 386 | + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 387 | + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'], |
|
| 388 | + ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'], |
|
| 389 | + ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 390 | + ['core', 'shareapi_only_share_with_group_members', 'no', 'no'], |
|
| 391 | + ]); |
|
| 392 | + |
|
| 393 | + /** @var IUser|MockObject $currentUser */ |
|
| 394 | + $currentUser = $this->createMock(IUser::class); |
|
| 395 | + $currentUser->expects($this->exactly(2)) |
|
| 396 | + ->method('getUID') |
|
| 397 | + ->willReturn('user001'); |
|
| 398 | + |
|
| 399 | + $this->groupManager->expects($this->once()) |
|
| 400 | + ->method('getUserGroupIds') |
|
| 401 | + ->with($this->equalTo($currentUser)) |
|
| 402 | + ->willReturn(['group1', 'group2', 'group3']); |
|
| 403 | + |
|
| 404 | + $this->knownUserService->method('isKnownToUser') |
|
| 405 | + ->willReturnMap([ |
|
| 406 | + ['user001', 'user1', true], |
|
| 407 | + ['user001', 'user2', true], |
|
| 408 | + ['user001', 'user3', false], |
|
| 409 | + ]); |
|
| 410 | + |
|
| 411 | + $this->contactsManager->expects($this->once()) |
|
| 412 | + ->method('search') |
|
| 413 | + ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 414 | + ->willReturn([ |
|
| 415 | + [ |
|
| 416 | + 'UID' => 'user1', |
|
| 417 | + 'isLocalSystemBook' => true |
|
| 418 | + ], |
|
| 419 | + [ |
|
| 420 | + 'UID' => 'user2', |
|
| 421 | + 'isLocalSystemBook' => true |
|
| 422 | + ], |
|
| 423 | + [ |
|
| 424 | + 'UID' => 'user3', |
|
| 425 | + 'isLocalSystemBook' => true |
|
| 426 | + ], |
|
| 427 | + [ |
|
| 428 | + 'UID' => 'contact', |
|
| 429 | + ], |
|
| 430 | + ]); |
|
| 431 | + |
|
| 432 | + $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 433 | + |
|
| 434 | + $this->assertCount(3, $entries); |
|
| 435 | + $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 436 | + $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 437 | + $this->assertEquals('contact', $entries[2]->getProperty('UID')); |
|
| 438 | + } |
|
| 439 | + |
|
| 440 | + public function testGetContactsOnlyEnumerateIfPhoneBookMatchWithOwnGroupsOnly(): void { |
|
| 441 | + $this->config |
|
| 442 | + ->method('getAppValue') |
|
| 443 | + ->willReturnMap([ |
|
| 444 | + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 445 | + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'], |
|
| 446 | + ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'], |
|
| 447 | + ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 448 | + ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], |
|
| 449 | + ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'], |
|
| 450 | + ]); |
|
| 451 | + |
|
| 452 | + /** @var IUser|MockObject $currentUser */ |
|
| 453 | + $currentUser = $this->createMock(IUser::class); |
|
| 454 | + $currentUser->expects($this->exactly(2)) |
|
| 455 | + ->method('getUID') |
|
| 456 | + ->willReturn('user001'); |
|
| 457 | + |
|
| 458 | + $user1 = $this->createMock(IUser::class); |
|
| 459 | + $user2 = $this->createMock(IUser::class); |
|
| 460 | + $user3 = $this->createMock(IUser::class); |
|
| 461 | + |
|
| 462 | + $calls = [ |
|
| 463 | + [[$currentUser], ['group1', 'group2', 'group3']], |
|
| 464 | + [[$user1], ['group1']], |
|
| 465 | + [[$user2], ['group2', 'group3']], |
|
| 466 | + [[$user3], ['group8', 'group9']], |
|
| 467 | + ]; |
|
| 468 | + $this->groupManager->expects($this->exactly(4)) |
|
| 469 | + ->method('getUserGroupIds') |
|
| 470 | + ->willReturnCallback(function () use (&$calls): array { |
|
| 471 | + $expected = array_shift($calls); |
|
| 472 | + $this->assertEquals($expected[0], func_get_args()); |
|
| 473 | + return $expected[1]; |
|
| 474 | + }); |
|
| 475 | + |
|
| 476 | + $this->userManager->expects($this->exactly(3)) |
|
| 477 | + ->method('get') |
|
| 478 | + ->willReturnMap([ |
|
| 479 | + ['user1', $user1], |
|
| 480 | + ['user2', $user2], |
|
| 481 | + ['user3', $user3], |
|
| 482 | + ]); |
|
| 483 | + |
|
| 484 | + $this->knownUserService->method('isKnownToUser') |
|
| 485 | + ->willReturnMap([ |
|
| 486 | + ['user001', 'user1', true], |
|
| 487 | + ['user001', 'user2', true], |
|
| 488 | + ['user001', 'user3', true], |
|
| 489 | + ]); |
|
| 490 | + |
|
| 491 | + $this->contactsManager->expects($this->once()) |
|
| 492 | + ->method('search') |
|
| 493 | + ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 494 | + ->willReturn([ |
|
| 495 | + [ |
|
| 496 | + 'UID' => 'user1', |
|
| 497 | + 'isLocalSystemBook' => true |
|
| 498 | + ], |
|
| 499 | + [ |
|
| 500 | + 'UID' => 'user2', |
|
| 501 | + 'isLocalSystemBook' => true |
|
| 502 | + ], |
|
| 503 | + [ |
|
| 504 | + 'UID' => 'user3', |
|
| 505 | + 'isLocalSystemBook' => true |
|
| 506 | + ], |
|
| 507 | + [ |
|
| 508 | + 'UID' => 'contact', |
|
| 509 | + ], |
|
| 510 | + ]); |
|
| 511 | + |
|
| 512 | + $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 513 | + |
|
| 514 | + $this->assertCount(3, $entries); |
|
| 515 | + $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 516 | + $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 517 | + $this->assertEquals('contact', $entries[2]->getProperty('UID')); |
|
| 518 | + } |
|
| 519 | + |
|
| 520 | + public function testGetContactsOnlyEnumerateIfPhoneBookOrSameGroup(): void { |
|
| 521 | + $this->config |
|
| 522 | + ->method('getAppValue') |
|
| 523 | + ->willReturnMap([ |
|
| 524 | + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 525 | + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'], |
|
| 526 | + ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'], |
|
| 527 | + ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 528 | + ['core', 'shareapi_only_share_with_group_members', 'no', 'no'], |
|
| 529 | + ]); |
|
| 530 | + |
|
| 531 | + /** @var IUser|MockObject $currentUser */ |
|
| 532 | + $currentUser = $this->createMock(IUser::class); |
|
| 533 | + $currentUser->expects($this->exactly(2)) |
|
| 534 | + ->method('getUID') |
|
| 535 | + ->willReturn('user001'); |
|
| 536 | + |
|
| 537 | + $user1 = $this->createMock(IUser::class); |
|
| 538 | + |
|
| 539 | + $calls = [ |
|
| 540 | + [[$currentUser], ['group1', 'group2', 'group3']], |
|
| 541 | + [[$user1], ['group1']], |
|
| 542 | + ]; |
|
| 543 | + $this->groupManager->expects($this->exactly(2)) |
|
| 544 | + ->method('getUserGroupIds') |
|
| 545 | + ->willReturnCallback(function () use (&$calls): array { |
|
| 546 | + $expected = array_shift($calls); |
|
| 547 | + $this->assertEquals($expected[0], func_get_args()); |
|
| 548 | + return $expected[1]; |
|
| 549 | + }); |
|
| 550 | + |
|
| 551 | + $this->userManager->expects($this->once()) |
|
| 552 | + ->method('get') |
|
| 553 | + ->with('user1') |
|
| 554 | + ->willReturn($user1); |
|
| 555 | + |
|
| 556 | + $this->knownUserService->method('isKnownToUser') |
|
| 557 | + ->willReturnMap([ |
|
| 558 | + ['user001', 'user1', false], |
|
| 559 | + ['user001', 'user2', true], |
|
| 560 | + ['user001', 'user3', true], |
|
| 561 | + ]); |
|
| 562 | + |
|
| 563 | + $this->contactsManager->expects($this->once()) |
|
| 564 | + ->method('search') |
|
| 565 | + ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 566 | + ->willReturn([ |
|
| 567 | + [ |
|
| 568 | + 'UID' => 'user1', |
|
| 569 | + 'isLocalSystemBook' => true |
|
| 570 | + ], |
|
| 571 | + [ |
|
| 572 | + 'UID' => 'user2', |
|
| 573 | + 'isLocalSystemBook' => true |
|
| 574 | + ], |
|
| 575 | + [ |
|
| 576 | + 'UID' => 'user3', |
|
| 577 | + 'isLocalSystemBook' => true |
|
| 578 | + ], |
|
| 579 | + [ |
|
| 580 | + 'UID' => 'contact', |
|
| 581 | + ], |
|
| 582 | + ]); |
|
| 583 | + |
|
| 584 | + $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 585 | + |
|
| 586 | + $this->assertCount(4, $entries); |
|
| 587 | + $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 588 | + $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 589 | + $this->assertEquals('user3', $entries[2]->getProperty('UID')); |
|
| 590 | + $this->assertEquals('contact', $entries[3]->getProperty('UID')); |
|
| 591 | + } |
|
| 592 | + |
|
| 593 | + public function testGetContactsOnlyEnumerateIfPhoneBookOrSameGroupInOwnGroupsOnly(): void { |
|
| 594 | + $this->config |
|
| 595 | + ->method('getAppValue') |
|
| 596 | + ->willReturnMap([ |
|
| 597 | + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 598 | + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'], |
|
| 599 | + ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'], |
|
| 600 | + ['core', 'shareapi_exclude_groups', 'no', 'no'], |
|
| 601 | + ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], |
|
| 602 | + ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'], |
|
| 603 | + ]); |
|
| 604 | + |
|
| 605 | + /** @var IUser|MockObject $currentUser */ |
|
| 606 | + $currentUser = $this->createMock(IUser::class); |
|
| 607 | + $currentUser->expects($this->exactly(2)) |
|
| 608 | + ->method('getUID') |
|
| 609 | + ->willReturn('user001'); |
|
| 610 | + |
|
| 611 | + $user1 = $this->createMock(IUser::class); |
|
| 612 | + $user2 = $this->createMock(IUser::class); |
|
| 613 | + $user3 = $this->createMock(IUser::class); |
|
| 614 | + |
|
| 615 | + $calls = [ |
|
| 616 | + [[$currentUser], ['group1', 'group2', 'group3']], |
|
| 617 | + [[$user1], ['group1']], |
|
| 618 | + [[$user2], ['group2', 'group3']], |
|
| 619 | + [[$user3], ['group8', 'group9']], |
|
| 620 | + ]; |
|
| 621 | + $this->groupManager->expects($this->exactly(4)) |
|
| 622 | + ->method('getUserGroupIds') |
|
| 623 | + ->willReturnCallback(function () use (&$calls): array { |
|
| 624 | + $expected = array_shift($calls); |
|
| 625 | + $this->assertEquals($expected[0], func_get_args()); |
|
| 626 | + return $expected[1]; |
|
| 627 | + }); |
|
| 628 | + |
|
| 629 | + $this->userManager->expects($this->exactly(3)) |
|
| 630 | + ->method('get') |
|
| 631 | + ->willReturnMap([ |
|
| 632 | + ['user1', $user1], |
|
| 633 | + ['user2', $user2], |
|
| 634 | + ['user3', $user3], |
|
| 635 | + ]); |
|
| 636 | + |
|
| 637 | + $this->knownUserService->method('isKnownToUser') |
|
| 638 | + ->willReturnMap([ |
|
| 639 | + ['user001', 'user1', false], |
|
| 640 | + ['user001', 'user2', true], |
|
| 641 | + ['user001', 'user3', true], |
|
| 642 | + ]); |
|
| 643 | + |
|
| 644 | + $this->contactsManager->expects($this->once()) |
|
| 645 | + ->method('search') |
|
| 646 | + ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL'])) |
|
| 647 | + ->willReturn([ |
|
| 648 | + [ |
|
| 649 | + 'UID' => 'user1', |
|
| 650 | + 'isLocalSystemBook' => true |
|
| 651 | + ], |
|
| 652 | + [ |
|
| 653 | + 'UID' => 'user2', |
|
| 654 | + 'isLocalSystemBook' => true |
|
| 655 | + ], |
|
| 656 | + [ |
|
| 657 | + 'UID' => 'user3', |
|
| 658 | + 'isLocalSystemBook' => true |
|
| 659 | + ], |
|
| 660 | + [ |
|
| 661 | + 'UID' => 'contact', |
|
| 662 | + ], |
|
| 663 | + ]); |
|
| 664 | + |
|
| 665 | + $entries = $this->contactsStore->getContacts($currentUser, ''); |
|
| 666 | + |
|
| 667 | + $this->assertCount(3, $entries); |
|
| 668 | + $this->assertEquals('user1', $entries[0]->getProperty('UID')); |
|
| 669 | + $this->assertEquals('user2', $entries[1]->getProperty('UID')); |
|
| 670 | + $this->assertEquals('contact', $entries[2]->getProperty('UID')); |
|
| 671 | + } |
|
| 672 | + |
|
| 673 | + public function testGetContactsWithFilter(): void { |
|
| 674 | + $this->config |
|
| 675 | + ->method('getAppValue') |
|
| 676 | + ->willReturnMap([ |
|
| 677 | + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'], |
|
| 678 | + ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'], |
|
| 679 | + ]); |
|
| 680 | + |
|
| 681 | + /** @var IUser|MockObject $user */ |
|
| 682 | + $user = $this->createMock(IUser::class); |
|
| 683 | + $this->contactsManager->expects($this->any()) |
|
| 684 | + ->method('search') |
|
| 685 | + ->willReturn([ |
|
| 686 | + [ |
|
| 687 | + 'UID' => 'a567', |
|
| 688 | + 'FN' => 'Darren Roner', |
|
| 689 | + 'EMAIL' => [ |
|
| 690 | + '[email protected]', |
|
| 691 | + ], |
|
| 692 | + 'isLocalSystemBook' => true, |
|
| 693 | + ], |
|
| 694 | + [ |
|
| 695 | + 'UID' => 'john', |
|
| 696 | + 'FN' => 'John Doe', |
|
| 697 | + 'EMAIL' => [ |
|
| 698 | + '[email protected]', |
|
| 699 | + ], |
|
| 700 | + 'isLocalSystemBook' => true, |
|
| 701 | + ], |
|
| 702 | + [ |
|
| 703 | + 'FN' => 'Anne D', |
|
| 704 | + 'EMAIL' => [ |
|
| 705 | + '[email protected]', |
|
| 706 | + ], |
|
| 707 | + 'isLocalSystemBook' => false, |
|
| 708 | + ], |
|
| 709 | + ]); |
|
| 710 | + $user->expects($this->any()) |
|
| 711 | + ->method('getUID') |
|
| 712 | + ->willReturn('user123'); |
|
| 713 | + |
|
| 714 | + // Complete match on UID should match |
|
| 715 | + $entry = $this->contactsStore->getContacts($user, 'a567'); |
|
| 716 | + $this->assertSame(2, count($entry)); |
|
| 717 | + $this->assertEquals([ |
|
| 718 | + '[email protected]' |
|
| 719 | + ], $entry[0]->getEMailAddresses()); |
|
| 720 | + |
|
| 721 | + // Partial match on UID should not match |
|
| 722 | + $entry = $this->contactsStore->getContacts($user, 'a56'); |
|
| 723 | + $this->assertSame(1, count($entry)); |
|
| 724 | + $this->assertEquals([ |
|
| 725 | + '[email protected]' |
|
| 726 | + ], $entry[0]->getEMailAddresses()); |
|
| 727 | + |
|
| 728 | + // Complete match on email should match |
|
| 729 | + $entry = $this->contactsStore->getContacts($user, '[email protected]'); |
|
| 730 | + $this->assertSame(2, count($entry)); |
|
| 731 | + $this->assertEquals([ |
|
| 732 | + '[email protected]' |
|
| 733 | + ], $entry[0]->getEMailAddresses()); |
|
| 734 | + $this->assertEquals([ |
|
| 735 | + '[email protected]' |
|
| 736 | + ], $entry[1]->getEMailAddresses()); |
|
| 737 | + |
|
| 738 | + // Partial match on email should not match |
|
| 739 | + $entry = $this->contactsStore->getContacts($user, '[email protected]'); |
|
| 740 | + $this->assertSame(1, count($entry)); |
|
| 741 | + $this->assertEquals([ |
|
| 742 | + '[email protected]' |
|
| 743 | + ], $entry[0]->getEMailAddresses()); |
|
| 744 | + |
|
| 745 | + // Match on FN should not match |
|
| 746 | + $entry = $this->contactsStore->getContacts($user, 'Darren Roner'); |
|
| 747 | + $this->assertSame(1, count($entry)); |
|
| 748 | + $this->assertEquals([ |
|
| 749 | + '[email protected]' |
|
| 750 | + ], $entry[0]->getEMailAddresses()); |
|
| 751 | + |
|
| 752 | + // Don't filter users in local addressbook |
|
| 753 | + $entry = $this->contactsStore->getContacts($user, 'Anne D'); |
|
| 754 | + $this->assertSame(1, count($entry)); |
|
| 755 | + $this->assertEquals([ |
|
| 756 | + '[email protected]' |
|
| 757 | + ], $entry[0]->getEMailAddresses()); |
|
| 758 | + } |
|
| 759 | + |
|
| 760 | + public function testGetContactsWithFilterWithoutFullMatch(): void { |
|
| 761 | + $this->config |
|
| 762 | + ->method('getAppValue') |
|
| 763 | + ->willReturnMap([ |
|
| 764 | + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'], |
|
| 765 | + ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'no'], |
|
| 766 | + ]); |
|
| 767 | + |
|
| 768 | + /** @var IUser|MockObject $user */ |
|
| 769 | + $user = $this->createMock(IUser::class); |
|
| 770 | + $this->contactsManager->expects($this->any()) |
|
| 771 | + ->method('search') |
|
| 772 | + ->willReturn([ |
|
| 773 | + [ |
|
| 774 | + 'UID' => 'a567', |
|
| 775 | + 'FN' => 'Darren Roner', |
|
| 776 | + 'EMAIL' => [ |
|
| 777 | + '[email protected]', |
|
| 778 | + ], |
|
| 779 | + 'isLocalSystemBook' => true, |
|
| 780 | + ], |
|
| 781 | + [ |
|
| 782 | + 'UID' => 'john', |
|
| 783 | + 'FN' => 'John Doe', |
|
| 784 | + 'EMAIL' => [ |
|
| 785 | + '[email protected]', |
|
| 786 | + ], |
|
| 787 | + 'isLocalSystemBook' => true, |
|
| 788 | + ], |
|
| 789 | + [ |
|
| 790 | + 'FN' => 'Anne D', |
|
| 791 | + 'EMAIL' => [ |
|
| 792 | + '[email protected]', |
|
| 793 | + ], |
|
| 794 | + 'isLocalSystemBook' => false, |
|
| 795 | + ], |
|
| 796 | + ]); |
|
| 797 | + $user->expects($this->any()) |
|
| 798 | + ->method('getUID') |
|
| 799 | + ->willReturn('user123'); |
|
| 800 | + |
|
| 801 | + // Complete match on UID should not match |
|
| 802 | + $entry = $this->contactsStore->getContacts($user, 'a567'); |
|
| 803 | + $this->assertSame(1, count($entry)); |
|
| 804 | + $this->assertEquals([ |
|
| 805 | + '[email protected]' |
|
| 806 | + ], $entry[0]->getEMailAddresses()); |
|
| 807 | + |
|
| 808 | + // Partial match on UID should not match |
|
| 809 | + $entry = $this->contactsStore->getContacts($user, 'a56'); |
|
| 810 | + $this->assertSame(1, count($entry)); |
|
| 811 | + $this->assertEquals([ |
|
| 812 | + '[email protected]' |
|
| 813 | + ], $entry[0]->getEMailAddresses()); |
|
| 814 | + |
|
| 815 | + // Complete match on email should not match |
|
| 816 | + $entry = $this->contactsStore->getContacts($user, '[email protected]'); |
|
| 817 | + $this->assertSame(1, count($entry)); |
|
| 818 | + $this->assertEquals([ |
|
| 819 | + '[email protected]' |
|
| 820 | + ], $entry[0]->getEMailAddresses()); |
|
| 821 | + |
|
| 822 | + // Partial match on email should not match |
|
| 823 | + $entry = $this->contactsStore->getContacts($user, '[email protected]'); |
|
| 824 | + $this->assertSame(1, count($entry)); |
|
| 825 | + $this->assertEquals([ |
|
| 826 | + '[email protected]' |
|
| 827 | + ], $entry[0]->getEMailAddresses()); |
|
| 828 | + |
|
| 829 | + // Match on FN should not match |
|
| 830 | + $entry = $this->contactsStore->getContacts($user, 'Darren Roner'); |
|
| 831 | + $this->assertSame(1, count($entry)); |
|
| 832 | + $this->assertEquals([ |
|
| 833 | + '[email protected]' |
|
| 834 | + ], $entry[0]->getEMailAddresses()); |
|
| 835 | + |
|
| 836 | + // Don't filter users in local addressbook |
|
| 837 | + $entry = $this->contactsStore->getContacts($user, 'Anne D'); |
|
| 838 | + $this->assertSame(1, count($entry)); |
|
| 839 | + $this->assertEquals([ |
|
| 840 | + '[email protected]' |
|
| 841 | + ], $entry[0]->getEMailAddresses()); |
|
| 842 | + } |
|
| 843 | + |
|
| 844 | + public function testFindOneUser(): void { |
|
| 845 | + $this->config |
|
| 846 | + ->method('getAppValue') |
|
| 847 | + ->willReturnMap([ |
|
| 848 | + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'], |
|
| 849 | + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'], |
|
| 850 | + ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'], |
|
| 851 | + ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'], |
|
| 852 | + ['core', 'shareapi_exclude_groups', 'no', 'yes'], |
|
| 853 | + ['core', 'shareapi_exclude_groups_list', '', ''], |
|
| 854 | + ['core', 'shareapi_only_share_with_group_members', 'no', 'no'], |
|
| 855 | + ]); |
|
| 856 | + |
|
| 857 | + /** @var IUser|MockObject $user */ |
|
| 858 | + $user = $this->createMock(IUser::class); |
|
| 859 | + $this->contactsManager->expects($this->once()) |
|
| 860 | + ->method('search') |
|
| 861 | + ->with($this->equalTo('a567'), $this->equalTo(['UID'])) |
|
| 862 | + ->willReturn([ |
|
| 863 | + [ |
|
| 864 | + 'UID' => 123, |
|
| 865 | + 'isLocalSystemBook' => false |
|
| 866 | + ], |
|
| 867 | + [ |
|
| 868 | + 'UID' => 'a567', |
|
| 869 | + 'FN' => 'Darren Roner', |
|
| 870 | + 'EMAIL' => [ |
|
| 871 | + '[email protected]' |
|
| 872 | + ], |
|
| 873 | + 'isLocalSystemBook' => true |
|
| 874 | + ], |
|
| 875 | + ]); |
|
| 876 | + $user->expects($this->any()) |
|
| 877 | + ->method('getUID') |
|
| 878 | + ->willReturn('user123'); |
|
| 879 | + |
|
| 880 | + $entry = $this->contactsStore->findOne($user, 0, 'a567'); |
|
| 881 | + |
|
| 882 | + $this->assertEquals([ |
|
| 883 | + '[email protected]' |
|
| 884 | + ], $entry->getEMailAddresses()); |
|
| 885 | + } |
|
| 886 | + |
|
| 887 | + public function testFindOneEMail(): void { |
|
| 888 | + /** @var IUser|MockObject $user */ |
|
| 889 | + $user = $this->createMock(IUser::class); |
|
| 890 | + $this->contactsManager->expects($this->once()) |
|
| 891 | + ->method('search') |
|
| 892 | + ->with($this->equalTo('[email protected]'), $this->equalTo(['EMAIL'])) |
|
| 893 | + ->willReturn([ |
|
| 894 | + [ |
|
| 895 | + 'UID' => 123, |
|
| 896 | + 'isLocalSystemBook' => false |
|
| 897 | + ], |
|
| 898 | + [ |
|
| 899 | + 'UID' => 'a567', |
|
| 900 | + 'FN' => 'Darren Roner', |
|
| 901 | + 'EMAIL' => [ |
|
| 902 | + '[email protected]' |
|
| 903 | + ], |
|
| 904 | + 'isLocalSystemBook' => false |
|
| 905 | + ], |
|
| 906 | + ]); |
|
| 907 | + $user->expects($this->any()) |
|
| 908 | + ->method('getUID') |
|
| 909 | + ->willReturn('user123'); |
|
| 910 | + |
|
| 911 | + $entry = $this->contactsStore->findOne($user, 4, '[email protected]'); |
|
| 912 | + |
|
| 913 | + $this->assertEquals([ |
|
| 914 | + '[email protected]' |
|
| 915 | + ], $entry->getEMailAddresses()); |
|
| 916 | + } |
|
| 917 | + |
|
| 918 | + public function testFindOneNotSupportedType(): void { |
|
| 919 | + /** @var IUser|MockObject $user */ |
|
| 920 | + $user = $this->createMock(IUser::class); |
|
| 921 | + |
|
| 922 | + $entry = $this->contactsStore->findOne($user, 42, '[email protected]'); |
|
| 923 | + |
|
| 924 | + $this->assertEquals(null, $entry); |
|
| 925 | + } |
|
| 926 | + |
|
| 927 | + public function testFindOneNoMatches(): void { |
|
| 928 | + /** @var IUser|MockObject $user */ |
|
| 929 | + $user = $this->createMock(IUser::class); |
|
| 930 | + $this->contactsManager->expects($this->once()) |
|
| 931 | + ->method('search') |
|
| 932 | + ->with($this->equalTo('a567'), $this->equalTo(['UID'])) |
|
| 933 | + ->willReturn([ |
|
| 934 | + [ |
|
| 935 | + 'UID' => 123, |
|
| 936 | + 'isLocalSystemBook' => false |
|
| 937 | + ], |
|
| 938 | + [ |
|
| 939 | + 'UID' => 'a567', |
|
| 940 | + 'FN' => 'Darren Roner', |
|
| 941 | + 'EMAIL' => [ |
|
| 942 | + '[email protected]' |
|
| 943 | + ], |
|
| 944 | + 'isLocalSystemBook' => false |
|
| 945 | + ], |
|
| 946 | + ]); |
|
| 947 | + $user->expects($this->never()) |
|
| 948 | + ->method('getUID'); |
|
| 949 | + |
|
| 950 | + $entry = $this->contactsStore->findOne($user, 0, 'a567'); |
|
| 951 | + |
|
| 952 | + $this->assertEquals(null, $entry); |
|
| 953 | + } |
|
| 954 | + |
|
| 955 | + public function testGetRecentStatusFirst(): void { |
|
| 956 | + $user = $this->createMock(IUser::class); |
|
| 957 | + $status1 = new UserStatus(); |
|
| 958 | + $status1->setUserId('user1'); |
|
| 959 | + $status2 = new UserStatus(); |
|
| 960 | + $status2->setUserId('user2'); |
|
| 961 | + $this->statusService->expects(self::once()) |
|
| 962 | + ->method('findAllRecentStatusChanges') |
|
| 963 | + ->willReturn([ |
|
| 964 | + $status1, |
|
| 965 | + $status2, |
|
| 966 | + ]); |
|
| 967 | + $user1 = $this->createMock(IUser::class); |
|
| 968 | + $user1->method('getCloudId')->willReturn('user1@localcloud'); |
|
| 969 | + $user2 = $this->createMock(IUser::class); |
|
| 970 | + $user2->method('getCloudId')->willReturn('user2@localcloud'); |
|
| 971 | + $this->userManager->expects(self::exactly(2)) |
|
| 972 | + ->method('get') |
|
| 973 | + ->willReturnCallback(function ($uid) use ($user1, $user2) { |
|
| 974 | + return match ($uid) { |
|
| 975 | + 'user1' => $user1, |
|
| 976 | + 'user2' => $user2, |
|
| 977 | + }; |
|
| 978 | + }); |
|
| 979 | + $this->contactsManager |
|
| 980 | + ->expects(self::exactly(3)) |
|
| 981 | + ->method('search') |
|
| 982 | + ->willReturnCallback(function ($uid, $searchProps, $options) { |
|
| 983 | + return match ([$uid, $options['limit'] ?? null]) { |
|
| 984 | + ['user1@localcloud', 1] => [ |
|
| 985 | + [ |
|
| 986 | + 'UID' => 'user1', |
|
| 987 | + 'URI' => 'user1.vcf', |
|
| 988 | + ], |
|
| 989 | + ], |
|
| 990 | + ['user2@localcloud' => [], 1], // Simulate not found |
|
| 991 | + ['', 4] => [ |
|
| 992 | + [ |
|
| 993 | + 'UID' => 'contact1', |
|
| 994 | + 'URI' => 'contact1.vcf', |
|
| 995 | + ], |
|
| 996 | + [ |
|
| 997 | + 'UID' => 'contact2', |
|
| 998 | + 'URI' => 'contact2.vcf', |
|
| 999 | + ], |
|
| 1000 | + ], |
|
| 1001 | + default => [], |
|
| 1002 | + }; |
|
| 1003 | + }); |
|
| 1004 | + |
|
| 1005 | + $contacts = $this->contactsStore->getContacts( |
|
| 1006 | + $user, |
|
| 1007 | + null, |
|
| 1008 | + 5, |
|
| 1009 | + ); |
|
| 1010 | + |
|
| 1011 | + self::assertCount(3, $contacts); |
|
| 1012 | + self::assertEquals('user1', $contacts[0]->getProperty('UID')); |
|
| 1013 | + self::assertEquals('contact1', $contacts[1]->getProperty('UID')); |
|
| 1014 | + self::assertEquals('contact2', $contacts[2]->getProperty('UID')); |
|
| 1015 | + } |
|
| 1016 | + |
|
| 1017 | + public function testPaginateRecentStatus(): void { |
|
| 1018 | + $user = $this->createMock(IUser::class); |
|
| 1019 | + $status1 = new UserStatus(); |
|
| 1020 | + $status1->setUserId('user1'); |
|
| 1021 | + $status2 = new UserStatus(); |
|
| 1022 | + $status2->setUserId('user2'); |
|
| 1023 | + $status3 = new UserStatus(); |
|
| 1024 | + $status3->setUserId('user3'); |
|
| 1025 | + $this->statusService->expects(self::never()) |
|
| 1026 | + ->method('findAllRecentStatusChanges'); |
|
| 1027 | + $this->contactsManager |
|
| 1028 | + ->expects(self::exactly(2)) |
|
| 1029 | + ->method('search') |
|
| 1030 | + ->willReturnCallback(function ($uid, $searchProps, $options) { |
|
| 1031 | + return match ([$uid, $options['limit'] ?? null, $options['offset'] ?? null]) { |
|
| 1032 | + ['', 2, 0] => [ |
|
| 1033 | + [ |
|
| 1034 | + 'UID' => 'contact1', |
|
| 1035 | + 'URI' => 'contact1.vcf', |
|
| 1036 | + ], |
|
| 1037 | + [ |
|
| 1038 | + 'UID' => 'contact2', |
|
| 1039 | + 'URI' => 'contact2.vcf', |
|
| 1040 | + ], |
|
| 1041 | + ], |
|
| 1042 | + ['', 2, 3] => [ |
|
| 1043 | + [ |
|
| 1044 | + 'UID' => 'contact3', |
|
| 1045 | + 'URI' => 'contact3.vcf', |
|
| 1046 | + ], |
|
| 1047 | + ], |
|
| 1048 | + default => [], |
|
| 1049 | + }; |
|
| 1050 | + }); |
|
| 1051 | + |
|
| 1052 | + $page1 = $this->contactsStore->getContacts( |
|
| 1053 | + $user, |
|
| 1054 | + null, |
|
| 1055 | + 2, |
|
| 1056 | + 0, |
|
| 1057 | + ); |
|
| 1058 | + $page2 = $this->contactsStore->getContacts( |
|
| 1059 | + $user, |
|
| 1060 | + null, |
|
| 1061 | + 2, |
|
| 1062 | + 3, |
|
| 1063 | + ); |
|
| 1064 | + |
|
| 1065 | + self::assertCount(2, $page1); |
|
| 1066 | + self::assertCount(1, $page2); |
|
| 1067 | + } |
|
| 1068 | 1068 | } |
@@ -26,7 +26,7 @@ discard block |
||
| 26 | 26 | |
| 27 | 27 | class ContactsStoreTest extends TestCase { |
| 28 | 28 | private ContactsStore $contactsStore; |
| 29 | - private StatusService|MockObject $statusService; |
|
| 29 | + private StatusService | MockObject $statusService; |
|
| 30 | 30 | /** @var IManager|MockObject */ |
| 31 | 31 | private $contactsManager; |
| 32 | 32 | /** @var ProfileManager */ |
@@ -263,7 +263,7 @@ discard block |
||
| 263 | 263 | ]; |
| 264 | 264 | $this->groupManager->expects($this->exactly(4)) |
| 265 | 265 | ->method('getUserGroupIds') |
| 266 | - ->willReturnCallback(function () use (&$calls): array { |
|
| 266 | + ->willReturnCallback(function() use (&$calls): array { |
|
| 267 | 267 | $expected = array_shift($calls); |
| 268 | 268 | $this->assertEquals($expected[0], func_get_args()); |
| 269 | 269 | return $expected[1]; |
@@ -336,7 +336,7 @@ discard block |
||
| 336 | 336 | ]; |
| 337 | 337 | $this->groupManager->expects($this->exactly(4)) |
| 338 | 338 | ->method('getUserGroupIds') |
| 339 | - ->willReturnCallback(function () use (&$calls): array { |
|
| 339 | + ->willReturnCallback(function() use (&$calls): array { |
|
| 340 | 340 | $expected = array_shift($calls); |
| 341 | 341 | $this->assertEquals($expected[0], func_get_args()); |
| 342 | 342 | return $expected[1]; |
@@ -467,7 +467,7 @@ discard block |
||
| 467 | 467 | ]; |
| 468 | 468 | $this->groupManager->expects($this->exactly(4)) |
| 469 | 469 | ->method('getUserGroupIds') |
| 470 | - ->willReturnCallback(function () use (&$calls): array { |
|
| 470 | + ->willReturnCallback(function() use (&$calls): array { |
|
| 471 | 471 | $expected = array_shift($calls); |
| 472 | 472 | $this->assertEquals($expected[0], func_get_args()); |
| 473 | 473 | return $expected[1]; |
@@ -542,7 +542,7 @@ discard block |
||
| 542 | 542 | ]; |
| 543 | 543 | $this->groupManager->expects($this->exactly(2)) |
| 544 | 544 | ->method('getUserGroupIds') |
| 545 | - ->willReturnCallback(function () use (&$calls): array { |
|
| 545 | + ->willReturnCallback(function() use (&$calls): array { |
|
| 546 | 546 | $expected = array_shift($calls); |
| 547 | 547 | $this->assertEquals($expected[0], func_get_args()); |
| 548 | 548 | return $expected[1]; |
@@ -620,7 +620,7 @@ discard block |
||
| 620 | 620 | ]; |
| 621 | 621 | $this->groupManager->expects($this->exactly(4)) |
| 622 | 622 | ->method('getUserGroupIds') |
| 623 | - ->willReturnCallback(function () use (&$calls): array { |
|
| 623 | + ->willReturnCallback(function() use (&$calls): array { |
|
| 624 | 624 | $expected = array_shift($calls); |
| 625 | 625 | $this->assertEquals($expected[0], func_get_args()); |
| 626 | 626 | return $expected[1]; |
@@ -970,7 +970,7 @@ discard block |
||
| 970 | 970 | $user2->method('getCloudId')->willReturn('user2@localcloud'); |
| 971 | 971 | $this->userManager->expects(self::exactly(2)) |
| 972 | 972 | ->method('get') |
| 973 | - ->willReturnCallback(function ($uid) use ($user1, $user2) { |
|
| 973 | + ->willReturnCallback(function($uid) use ($user1, $user2) { |
|
| 974 | 974 | return match ($uid) { |
| 975 | 975 | 'user1' => $user1, |
| 976 | 976 | 'user2' => $user2, |
@@ -979,7 +979,7 @@ discard block |
||
| 979 | 979 | $this->contactsManager |
| 980 | 980 | ->expects(self::exactly(3)) |
| 981 | 981 | ->method('search') |
| 982 | - ->willReturnCallback(function ($uid, $searchProps, $options) { |
|
| 982 | + ->willReturnCallback(function($uid, $searchProps, $options) { |
|
| 983 | 983 | return match ([$uid, $options['limit'] ?? null]) { |
| 984 | 984 | ['user1@localcloud', 1] => [ |
| 985 | 985 | [ |
@@ -1027,7 +1027,7 @@ discard block |
||
| 1027 | 1027 | $this->contactsManager |
| 1028 | 1028 | ->expects(self::exactly(2)) |
| 1029 | 1029 | ->method('search') |
| 1030 | - ->willReturnCallback(function ($uid, $searchProps, $options) { |
|
| 1030 | + ->willReturnCallback(function($uid, $searchProps, $options) { |
|
| 1031 | 1031 | return match ([$uid, $options['limit'] ?? null, $options['offset'] ?? null]) { |
| 1032 | 1032 | ['', 2, 0] => [ |
| 1033 | 1033 | [ |
@@ -20,182 +20,182 @@ |
||
| 20 | 20 | use Test\TestCase; |
| 21 | 21 | |
| 22 | 22 | class ManagerTest extends TestCase { |
| 23 | - /** @var ContactsStore|MockObject */ |
|
| 24 | - private $contactsStore; |
|
| 25 | - |
|
| 26 | - /** @var IAppManager|MockObject */ |
|
| 27 | - private $appManager; |
|
| 28 | - |
|
| 29 | - /** @var IConfig|MockObject */ |
|
| 30 | - private $config; |
|
| 31 | - |
|
| 32 | - /** @var ActionProviderStore|MockObject */ |
|
| 33 | - private $actionProviderStore; |
|
| 34 | - |
|
| 35 | - private Manager $manager; |
|
| 36 | - |
|
| 37 | - protected function setUp(): void { |
|
| 38 | - parent::setUp(); |
|
| 39 | - |
|
| 40 | - $this->contactsStore = $this->createMock(ContactsStore::class); |
|
| 41 | - $this->actionProviderStore = $this->createMock(ActionProviderStore::class); |
|
| 42 | - $this->appManager = $this->createMock(IAppManager::class); |
|
| 43 | - $this->config = $this->createMock(IConfig::class); |
|
| 44 | - |
|
| 45 | - $this->manager = new Manager($this->contactsStore, $this->actionProviderStore, $this->appManager, $this->config); |
|
| 46 | - } |
|
| 47 | - |
|
| 48 | - private function generateTestEntries(): array { |
|
| 49 | - $entries = []; |
|
| 50 | - foreach (range('Z', 'A') as $char) { |
|
| 51 | - $entry = $this->createMock(Entry::class); |
|
| 52 | - $entry->expects($this->any()) |
|
| 53 | - ->method('getFullName') |
|
| 54 | - ->willReturn('Contact ' . $char); |
|
| 55 | - $entries[] = $entry; |
|
| 56 | - } |
|
| 57 | - return $entries; |
|
| 58 | - } |
|
| 59 | - |
|
| 60 | - public function testGetFilteredEntries(): void { |
|
| 61 | - $filter = 'con'; |
|
| 62 | - $user = $this->createMock(IUser::class); |
|
| 63 | - $entries = $this->generateTestEntries(); |
|
| 64 | - $provider = $this->createMock(IProvider::class); |
|
| 65 | - |
|
| 66 | - $this->config->expects($this->exactly(2)) |
|
| 67 | - ->method('getSystemValueInt') |
|
| 68 | - ->willReturnMap([ |
|
| 69 | - ['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 25], |
|
| 70 | - ['sharing.minSearchStringLength', 0, 0], |
|
| 71 | - ]); |
|
| 72 | - $this->contactsStore->expects($this->once()) |
|
| 73 | - ->method('getContacts') |
|
| 74 | - ->with($user, $filter) |
|
| 75 | - ->willReturn($entries); |
|
| 76 | - $this->actionProviderStore->expects($this->once()) |
|
| 77 | - ->method('getProviders') |
|
| 78 | - ->with($user) |
|
| 79 | - ->willReturn([$provider]); |
|
| 80 | - $provider->expects($this->exactly(25)) |
|
| 81 | - ->method('process'); |
|
| 82 | - $this->appManager->expects($this->once()) |
|
| 83 | - ->method('isEnabledForUser') |
|
| 84 | - ->with($this->equalTo('contacts'), $user) |
|
| 85 | - ->willReturn(false); |
|
| 86 | - $expected = [ |
|
| 87 | - 'contacts' => array_slice($entries, 0, 25), |
|
| 88 | - 'contactsAppEnabled' => false, |
|
| 89 | - ]; |
|
| 90 | - |
|
| 91 | - $data = $this->manager->getEntries($user, $filter); |
|
| 92 | - |
|
| 93 | - $this->assertEquals($expected, $data); |
|
| 94 | - } |
|
| 95 | - |
|
| 96 | - public function testGetFilteredEntriesLimit(): void { |
|
| 97 | - $filter = 'con'; |
|
| 98 | - $user = $this->createMock(IUser::class); |
|
| 99 | - $entries = $this->generateTestEntries(); |
|
| 100 | - $provider = $this->createMock(IProvider::class); |
|
| 101 | - |
|
| 102 | - $this->config->expects($this->exactly(2)) |
|
| 103 | - ->method('getSystemValueInt') |
|
| 104 | - ->willReturnMap([ |
|
| 105 | - ['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 3], |
|
| 106 | - ['sharing.minSearchStringLength', 0, 0], |
|
| 107 | - ]); |
|
| 108 | - $this->contactsStore->expects($this->once()) |
|
| 109 | - ->method('getContacts') |
|
| 110 | - ->with($user, $filter) |
|
| 111 | - ->willReturn($entries); |
|
| 112 | - $this->actionProviderStore->expects($this->once()) |
|
| 113 | - ->method('getProviders') |
|
| 114 | - ->with($user) |
|
| 115 | - ->willReturn([$provider]); |
|
| 116 | - $provider->expects($this->exactly(3)) |
|
| 117 | - ->method('process'); |
|
| 118 | - $this->appManager->expects($this->once()) |
|
| 119 | - ->method('isEnabledForUser') |
|
| 120 | - ->with($this->equalTo('contacts'), $user) |
|
| 121 | - ->willReturn(false); |
|
| 122 | - $expected = [ |
|
| 123 | - 'contacts' => array_slice($entries, 0, 3), |
|
| 124 | - 'contactsAppEnabled' => false, |
|
| 125 | - ]; |
|
| 126 | - |
|
| 127 | - $data = $this->manager->getEntries($user, $filter); |
|
| 128 | - |
|
| 129 | - $this->assertEquals($expected, $data); |
|
| 130 | - } |
|
| 131 | - |
|
| 132 | - public function testGetFilteredEntriesMinSearchStringLength(): void { |
|
| 133 | - $filter = 'con'; |
|
| 134 | - $user = $this->createMock(IUser::class); |
|
| 135 | - $provider = $this->createMock(IProvider::class); |
|
| 136 | - |
|
| 137 | - $this->config->expects($this->exactly(2)) |
|
| 138 | - ->method('getSystemValueInt') |
|
| 139 | - ->willReturnMap([ |
|
| 140 | - ['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 3], |
|
| 141 | - ['sharing.minSearchStringLength', 0, 4], |
|
| 142 | - ]); |
|
| 143 | - $this->appManager->expects($this->once()) |
|
| 144 | - ->method('isEnabledForUser') |
|
| 145 | - ->with($this->equalTo('contacts'), $user) |
|
| 146 | - ->willReturn(false); |
|
| 147 | - $expected = [ |
|
| 148 | - 'contacts' => [], |
|
| 149 | - 'contactsAppEnabled' => false, |
|
| 150 | - ]; |
|
| 151 | - |
|
| 152 | - $data = $this->manager->getEntries($user, $filter); |
|
| 153 | - |
|
| 154 | - $this->assertEquals($expected, $data); |
|
| 155 | - } |
|
| 156 | - |
|
| 157 | - public function testFindOne(): void { |
|
| 158 | - $shareTypeFilter = 42; |
|
| 159 | - $shareWithFilter = 'foobar'; |
|
| 160 | - |
|
| 161 | - $user = $this->createMock(IUser::class); |
|
| 162 | - $entry = current($this->generateTestEntries()); |
|
| 163 | - $provider = $this->createMock(IProvider::class); |
|
| 164 | - $this->contactsStore->expects($this->once()) |
|
| 165 | - ->method('findOne') |
|
| 166 | - ->with($user, $shareTypeFilter, $shareWithFilter) |
|
| 167 | - ->willReturn($entry); |
|
| 168 | - $this->actionProviderStore->expects($this->once()) |
|
| 169 | - ->method('getProviders') |
|
| 170 | - ->with($user) |
|
| 171 | - ->willReturn([$provider]); |
|
| 172 | - $provider->expects($this->once()) |
|
| 173 | - ->method('process'); |
|
| 174 | - |
|
| 175 | - $data = $this->manager->findOne($user, $shareTypeFilter, $shareWithFilter); |
|
| 176 | - |
|
| 177 | - $this->assertEquals($entry, $data); |
|
| 178 | - } |
|
| 179 | - |
|
| 180 | - public function testFindOne404(): void { |
|
| 181 | - $shareTypeFilter = 42; |
|
| 182 | - $shareWithFilter = 'foobar'; |
|
| 183 | - |
|
| 184 | - $user = $this->createMock(IUser::class); |
|
| 185 | - $provider = $this->createMock(IProvider::class); |
|
| 186 | - $this->contactsStore->expects($this->once()) |
|
| 187 | - ->method('findOne') |
|
| 188 | - ->with($user, $shareTypeFilter, $shareWithFilter) |
|
| 189 | - ->willReturn(null); |
|
| 190 | - $this->actionProviderStore->expects($this->never()) |
|
| 191 | - ->method('getProviders') |
|
| 192 | - ->with($user) |
|
| 193 | - ->willReturn([$provider]); |
|
| 194 | - $provider->expects($this->never()) |
|
| 195 | - ->method('process'); |
|
| 196 | - |
|
| 197 | - $data = $this->manager->findOne($user, $shareTypeFilter, $shareWithFilter); |
|
| 198 | - |
|
| 199 | - $this->assertEquals(null, $data); |
|
| 200 | - } |
|
| 23 | + /** @var ContactsStore|MockObject */ |
|
| 24 | + private $contactsStore; |
|
| 25 | + |
|
| 26 | + /** @var IAppManager|MockObject */ |
|
| 27 | + private $appManager; |
|
| 28 | + |
|
| 29 | + /** @var IConfig|MockObject */ |
|
| 30 | + private $config; |
|
| 31 | + |
|
| 32 | + /** @var ActionProviderStore|MockObject */ |
|
| 33 | + private $actionProviderStore; |
|
| 34 | + |
|
| 35 | + private Manager $manager; |
|
| 36 | + |
|
| 37 | + protected function setUp(): void { |
|
| 38 | + parent::setUp(); |
|
| 39 | + |
|
| 40 | + $this->contactsStore = $this->createMock(ContactsStore::class); |
|
| 41 | + $this->actionProviderStore = $this->createMock(ActionProviderStore::class); |
|
| 42 | + $this->appManager = $this->createMock(IAppManager::class); |
|
| 43 | + $this->config = $this->createMock(IConfig::class); |
|
| 44 | + |
|
| 45 | + $this->manager = new Manager($this->contactsStore, $this->actionProviderStore, $this->appManager, $this->config); |
|
| 46 | + } |
|
| 47 | + |
|
| 48 | + private function generateTestEntries(): array { |
|
| 49 | + $entries = []; |
|
| 50 | + foreach (range('Z', 'A') as $char) { |
|
| 51 | + $entry = $this->createMock(Entry::class); |
|
| 52 | + $entry->expects($this->any()) |
|
| 53 | + ->method('getFullName') |
|
| 54 | + ->willReturn('Contact ' . $char); |
|
| 55 | + $entries[] = $entry; |
|
| 56 | + } |
|
| 57 | + return $entries; |
|
| 58 | + } |
|
| 59 | + |
|
| 60 | + public function testGetFilteredEntries(): void { |
|
| 61 | + $filter = 'con'; |
|
| 62 | + $user = $this->createMock(IUser::class); |
|
| 63 | + $entries = $this->generateTestEntries(); |
|
| 64 | + $provider = $this->createMock(IProvider::class); |
|
| 65 | + |
|
| 66 | + $this->config->expects($this->exactly(2)) |
|
| 67 | + ->method('getSystemValueInt') |
|
| 68 | + ->willReturnMap([ |
|
| 69 | + ['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 25], |
|
| 70 | + ['sharing.minSearchStringLength', 0, 0], |
|
| 71 | + ]); |
|
| 72 | + $this->contactsStore->expects($this->once()) |
|
| 73 | + ->method('getContacts') |
|
| 74 | + ->with($user, $filter) |
|
| 75 | + ->willReturn($entries); |
|
| 76 | + $this->actionProviderStore->expects($this->once()) |
|
| 77 | + ->method('getProviders') |
|
| 78 | + ->with($user) |
|
| 79 | + ->willReturn([$provider]); |
|
| 80 | + $provider->expects($this->exactly(25)) |
|
| 81 | + ->method('process'); |
|
| 82 | + $this->appManager->expects($this->once()) |
|
| 83 | + ->method('isEnabledForUser') |
|
| 84 | + ->with($this->equalTo('contacts'), $user) |
|
| 85 | + ->willReturn(false); |
|
| 86 | + $expected = [ |
|
| 87 | + 'contacts' => array_slice($entries, 0, 25), |
|
| 88 | + 'contactsAppEnabled' => false, |
|
| 89 | + ]; |
|
| 90 | + |
|
| 91 | + $data = $this->manager->getEntries($user, $filter); |
|
| 92 | + |
|
| 93 | + $this->assertEquals($expected, $data); |
|
| 94 | + } |
|
| 95 | + |
|
| 96 | + public function testGetFilteredEntriesLimit(): void { |
|
| 97 | + $filter = 'con'; |
|
| 98 | + $user = $this->createMock(IUser::class); |
|
| 99 | + $entries = $this->generateTestEntries(); |
|
| 100 | + $provider = $this->createMock(IProvider::class); |
|
| 101 | + |
|
| 102 | + $this->config->expects($this->exactly(2)) |
|
| 103 | + ->method('getSystemValueInt') |
|
| 104 | + ->willReturnMap([ |
|
| 105 | + ['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 3], |
|
| 106 | + ['sharing.minSearchStringLength', 0, 0], |
|
| 107 | + ]); |
|
| 108 | + $this->contactsStore->expects($this->once()) |
|
| 109 | + ->method('getContacts') |
|
| 110 | + ->with($user, $filter) |
|
| 111 | + ->willReturn($entries); |
|
| 112 | + $this->actionProviderStore->expects($this->once()) |
|
| 113 | + ->method('getProviders') |
|
| 114 | + ->with($user) |
|
| 115 | + ->willReturn([$provider]); |
|
| 116 | + $provider->expects($this->exactly(3)) |
|
| 117 | + ->method('process'); |
|
| 118 | + $this->appManager->expects($this->once()) |
|
| 119 | + ->method('isEnabledForUser') |
|
| 120 | + ->with($this->equalTo('contacts'), $user) |
|
| 121 | + ->willReturn(false); |
|
| 122 | + $expected = [ |
|
| 123 | + 'contacts' => array_slice($entries, 0, 3), |
|
| 124 | + 'contactsAppEnabled' => false, |
|
| 125 | + ]; |
|
| 126 | + |
|
| 127 | + $data = $this->manager->getEntries($user, $filter); |
|
| 128 | + |
|
| 129 | + $this->assertEquals($expected, $data); |
|
| 130 | + } |
|
| 131 | + |
|
| 132 | + public function testGetFilteredEntriesMinSearchStringLength(): void { |
|
| 133 | + $filter = 'con'; |
|
| 134 | + $user = $this->createMock(IUser::class); |
|
| 135 | + $provider = $this->createMock(IProvider::class); |
|
| 136 | + |
|
| 137 | + $this->config->expects($this->exactly(2)) |
|
| 138 | + ->method('getSystemValueInt') |
|
| 139 | + ->willReturnMap([ |
|
| 140 | + ['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 3], |
|
| 141 | + ['sharing.minSearchStringLength', 0, 4], |
|
| 142 | + ]); |
|
| 143 | + $this->appManager->expects($this->once()) |
|
| 144 | + ->method('isEnabledForUser') |
|
| 145 | + ->with($this->equalTo('contacts'), $user) |
|
| 146 | + ->willReturn(false); |
|
| 147 | + $expected = [ |
|
| 148 | + 'contacts' => [], |
|
| 149 | + 'contactsAppEnabled' => false, |
|
| 150 | + ]; |
|
| 151 | + |
|
| 152 | + $data = $this->manager->getEntries($user, $filter); |
|
| 153 | + |
|
| 154 | + $this->assertEquals($expected, $data); |
|
| 155 | + } |
|
| 156 | + |
|
| 157 | + public function testFindOne(): void { |
|
| 158 | + $shareTypeFilter = 42; |
|
| 159 | + $shareWithFilter = 'foobar'; |
|
| 160 | + |
|
| 161 | + $user = $this->createMock(IUser::class); |
|
| 162 | + $entry = current($this->generateTestEntries()); |
|
| 163 | + $provider = $this->createMock(IProvider::class); |
|
| 164 | + $this->contactsStore->expects($this->once()) |
|
| 165 | + ->method('findOne') |
|
| 166 | + ->with($user, $shareTypeFilter, $shareWithFilter) |
|
| 167 | + ->willReturn($entry); |
|
| 168 | + $this->actionProviderStore->expects($this->once()) |
|
| 169 | + ->method('getProviders') |
|
| 170 | + ->with($user) |
|
| 171 | + ->willReturn([$provider]); |
|
| 172 | + $provider->expects($this->once()) |
|
| 173 | + ->method('process'); |
|
| 174 | + |
|
| 175 | + $data = $this->manager->findOne($user, $shareTypeFilter, $shareWithFilter); |
|
| 176 | + |
|
| 177 | + $this->assertEquals($entry, $data); |
|
| 178 | + } |
|
| 179 | + |
|
| 180 | + public function testFindOne404(): void { |
|
| 181 | + $shareTypeFilter = 42; |
|
| 182 | + $shareWithFilter = 'foobar'; |
|
| 183 | + |
|
| 184 | + $user = $this->createMock(IUser::class); |
|
| 185 | + $provider = $this->createMock(IProvider::class); |
|
| 186 | + $this->contactsStore->expects($this->once()) |
|
| 187 | + ->method('findOne') |
|
| 188 | + ->with($user, $shareTypeFilter, $shareWithFilter) |
|
| 189 | + ->willReturn(null); |
|
| 190 | + $this->actionProviderStore->expects($this->never()) |
|
| 191 | + ->method('getProviders') |
|
| 192 | + ->with($user) |
|
| 193 | + ->willReturn([$provider]); |
|
| 194 | + $provider->expects($this->never()) |
|
| 195 | + ->method('process'); |
|
| 196 | + |
|
| 197 | + $data = $this->manager->findOne($user, $shareTypeFilter, $shareWithFilter); |
|
| 198 | + |
|
| 199 | + $this->assertEquals(null, $data); |
|
| 200 | + } |
|
| 201 | 201 | } |
@@ -25,568 +25,568 @@ |
||
| 25 | 25 | * Class ClientTest |
| 26 | 26 | */ |
| 27 | 27 | class ClientTest extends \Test\TestCase { |
| 28 | - /** @var \GuzzleHttp\Client|MockObject */ |
|
| 29 | - private $guzzleClient; |
|
| 30 | - /** @var CertificateManager|MockObject */ |
|
| 31 | - private $certificateManager; |
|
| 32 | - /** @var Client */ |
|
| 33 | - private $client; |
|
| 34 | - /** @var IConfig|MockObject */ |
|
| 35 | - private $config; |
|
| 36 | - /** @var IRemoteHostValidator|MockObject */ |
|
| 37 | - private IRemoteHostValidator $remoteHostValidator; |
|
| 38 | - private LoggerInterface $logger; |
|
| 39 | - /** @var array */ |
|
| 40 | - private $defaultRequestOptions; |
|
| 41 | - |
|
| 42 | - protected function setUp(): void { |
|
| 43 | - parent::setUp(); |
|
| 44 | - $this->config = $this->createMock(IConfig::class); |
|
| 45 | - $this->guzzleClient = $this->createMock(\GuzzleHttp\Client::class); |
|
| 46 | - $this->certificateManager = $this->createMock(ICertificateManager::class); |
|
| 47 | - $this->remoteHostValidator = $this->createMock(IRemoteHostValidator::class); |
|
| 48 | - $this->logger = $this->createMock(LoggerInterface::class); |
|
| 49 | - $this->client = new Client( |
|
| 50 | - $this->config, |
|
| 51 | - $this->certificateManager, |
|
| 52 | - $this->guzzleClient, |
|
| 53 | - $this->remoteHostValidator, |
|
| 54 | - $this->logger, |
|
| 55 | - ); |
|
| 56 | - } |
|
| 57 | - |
|
| 58 | - public function testGetProxyUri(): void { |
|
| 59 | - $this->config |
|
| 60 | - ->method('getSystemValueString') |
|
| 61 | - ->with('proxy', '') |
|
| 62 | - ->willReturn(''); |
|
| 63 | - $this->assertNull(self::invokePrivate($this->client, 'getProxyUri')); |
|
| 64 | - } |
|
| 65 | - |
|
| 66 | - public function testGetProxyUriProxyHostEmptyPassword(): void { |
|
| 67 | - $this->config |
|
| 68 | - ->method('getSystemValue') |
|
| 69 | - ->will($this->returnValueMap([ |
|
| 70 | - ['proxyexclude', [], []], |
|
| 71 | - ])); |
|
| 72 | - |
|
| 73 | - $this->config |
|
| 74 | - ->method('getSystemValueString') |
|
| 75 | - ->will($this->returnValueMap([ |
|
| 76 | - ['proxy', '', 'foo'], |
|
| 77 | - ['proxyuserpwd', '', ''], |
|
| 78 | - ])); |
|
| 79 | - |
|
| 80 | - $this->assertEquals([ |
|
| 81 | - 'http' => 'foo', |
|
| 82 | - 'https' => 'foo' |
|
| 83 | - ], self::invokePrivate($this->client, 'getProxyUri')); |
|
| 84 | - } |
|
| 85 | - |
|
| 86 | - public function testGetProxyUriProxyHostWithPassword(): void { |
|
| 87 | - $this->config |
|
| 88 | - ->expects($this->once()) |
|
| 89 | - ->method('getSystemValue') |
|
| 90 | - ->with('proxyexclude', []) |
|
| 91 | - ->willReturn([]); |
|
| 92 | - $this->config |
|
| 93 | - ->expects($this->exactly(2)) |
|
| 94 | - ->method('getSystemValueString') |
|
| 95 | - ->willReturnMap([ |
|
| 96 | - ['proxy', '', 'foo'], |
|
| 97 | - ['proxyuserpwd', '', 'username:password'], |
|
| 98 | - ]); |
|
| 99 | - $this->assertEquals([ |
|
| 100 | - 'http' => 'username:password@foo', |
|
| 101 | - 'https' => 'username:password@foo' |
|
| 102 | - ], self::invokePrivate($this->client, 'getProxyUri')); |
|
| 103 | - } |
|
| 104 | - |
|
| 105 | - public function testGetProxyUriProxyHostWithPasswordAndExclude(): void { |
|
| 106 | - $this->config |
|
| 107 | - ->expects($this->once()) |
|
| 108 | - ->method('getSystemValue') |
|
| 109 | - ->with('proxyexclude', []) |
|
| 110 | - ->willReturn(['bar']); |
|
| 111 | - $this->config |
|
| 112 | - ->expects($this->exactly(2)) |
|
| 113 | - ->method('getSystemValueString') |
|
| 114 | - ->willReturnMap([ |
|
| 115 | - ['proxy', '', 'foo'], |
|
| 116 | - ['proxyuserpwd', '', 'username:password'], |
|
| 117 | - ]); |
|
| 118 | - $this->assertEquals([ |
|
| 119 | - 'http' => 'username:password@foo', |
|
| 120 | - 'https' => 'username:password@foo', |
|
| 121 | - 'no' => ['bar'] |
|
| 122 | - ], self::invokePrivate($this->client, 'getProxyUri')); |
|
| 123 | - } |
|
| 124 | - |
|
| 125 | - public function testPreventLocalAddressThrowOnInvalidUri(): void { |
|
| 126 | - $this->expectException(LocalServerException::class); |
|
| 127 | - $this->expectExceptionMessage('Could not detect any host'); |
|
| 128 | - |
|
| 129 | - self::invokePrivate($this->client, 'preventLocalAddress', ['!@#$', []]); |
|
| 130 | - } |
|
| 131 | - |
|
| 132 | - public static function dataPreventLocalAddress(): array { |
|
| 133 | - return [ |
|
| 134 | - ['https://localhost/foo.bar'], |
|
| 135 | - ['https://localHost/foo.bar'], |
|
| 136 | - ['https://random-host/foo.bar'], |
|
| 137 | - ['https://[::1]/bla.blub'], |
|
| 138 | - ['https://[::]/bla.blub'], |
|
| 139 | - ['https://192.168.0.1'], |
|
| 140 | - ['https://172.16.42.1'], |
|
| 141 | - ['https://[fdf8:f53b:82e4::53]/secret.ics'], |
|
| 142 | - ['https://[fe80::200:5aee:feaa:20a2]/secret.ics'], |
|
| 143 | - ['https://[0:0:0:0:0:0:10.0.0.1]/secret.ics'], |
|
| 144 | - ['https://[0:0:0:0:0:ffff:127.0.0.0]/secret.ics'], |
|
| 145 | - ['https://10.0.0.1'], |
|
| 146 | - ['https://another-host.local'], |
|
| 147 | - ['https://service.localhost'], |
|
| 148 | - ['https://normal.host.com'], |
|
| 149 | - ['https://com.one-.nextcloud-one.com'], |
|
| 150 | - ]; |
|
| 151 | - } |
|
| 152 | - |
|
| 153 | - /** |
|
| 154 | - * @dataProvider dataPreventLocalAddress |
|
| 155 | - * @param string $uri |
|
| 156 | - */ |
|
| 157 | - public function testPreventLocalAddressDisabledByGlobalConfig(string $uri): void { |
|
| 158 | - $this->config->expects($this->once()) |
|
| 159 | - ->method('getSystemValueBool') |
|
| 160 | - ->with('allow_local_remote_servers', false) |
|
| 161 | - ->willReturn(true); |
|
| 162 | - |
|
| 163 | - self::invokePrivate($this->client, 'preventLocalAddress', [$uri, []]); |
|
| 164 | - } |
|
| 165 | - |
|
| 166 | - /** |
|
| 167 | - * @dataProvider dataPreventLocalAddress |
|
| 168 | - * @param string $uri |
|
| 169 | - */ |
|
| 170 | - public function testPreventLocalAddressDisabledByOption(string $uri): void { |
|
| 171 | - $this->config->expects($this->never()) |
|
| 172 | - ->method('getSystemValueBool'); |
|
| 173 | - |
|
| 174 | - self::invokePrivate($this->client, 'preventLocalAddress', [$uri, [ |
|
| 175 | - 'nextcloud' => ['allow_local_address' => true], |
|
| 176 | - ]]); |
|
| 177 | - } |
|
| 178 | - |
|
| 179 | - /** |
|
| 180 | - * @dataProvider dataPreventLocalAddress |
|
| 181 | - * @param string $uri |
|
| 182 | - */ |
|
| 183 | - public function testPreventLocalAddressOnGet(string $uri): void { |
|
| 184 | - $host = parse_url($uri, PHP_URL_HOST); |
|
| 185 | - $this->expectException(LocalServerException::class); |
|
| 186 | - $this->remoteHostValidator |
|
| 187 | - ->method('isValid') |
|
| 188 | - ->with($host) |
|
| 189 | - ->willReturn(false); |
|
| 190 | - |
|
| 191 | - $this->client->get($uri); |
|
| 192 | - } |
|
| 193 | - |
|
| 194 | - /** |
|
| 195 | - * @dataProvider dataPreventLocalAddress |
|
| 196 | - * @param string $uri |
|
| 197 | - */ |
|
| 198 | - public function testPreventLocalAddressOnHead(string $uri): void { |
|
| 199 | - $host = parse_url($uri, PHP_URL_HOST); |
|
| 200 | - $this->expectException(LocalServerException::class); |
|
| 201 | - $this->remoteHostValidator |
|
| 202 | - ->method('isValid') |
|
| 203 | - ->with($host) |
|
| 204 | - ->willReturn(false); |
|
| 205 | - |
|
| 206 | - $this->client->head($uri); |
|
| 207 | - } |
|
| 208 | - |
|
| 209 | - /** |
|
| 210 | - * @dataProvider dataPreventLocalAddress |
|
| 211 | - * @param string $uri |
|
| 212 | - */ |
|
| 213 | - public function testPreventLocalAddressOnPost(string $uri): void { |
|
| 214 | - $host = parse_url($uri, PHP_URL_HOST); |
|
| 215 | - $this->expectException(LocalServerException::class); |
|
| 216 | - $this->remoteHostValidator |
|
| 217 | - ->method('isValid') |
|
| 218 | - ->with($host) |
|
| 219 | - ->willReturn(false); |
|
| 220 | - |
|
| 221 | - $this->client->post($uri); |
|
| 222 | - } |
|
| 223 | - |
|
| 224 | - /** |
|
| 225 | - * @dataProvider dataPreventLocalAddress |
|
| 226 | - * @param string $uri |
|
| 227 | - */ |
|
| 228 | - public function testPreventLocalAddressOnPut(string $uri): void { |
|
| 229 | - $host = parse_url($uri, PHP_URL_HOST); |
|
| 230 | - $this->expectException(LocalServerException::class); |
|
| 231 | - $this->remoteHostValidator |
|
| 232 | - ->method('isValid') |
|
| 233 | - ->with($host) |
|
| 234 | - ->willReturn(false); |
|
| 235 | - |
|
| 236 | - $this->client->put($uri); |
|
| 237 | - } |
|
| 238 | - |
|
| 239 | - /** |
|
| 240 | - * @dataProvider dataPreventLocalAddress |
|
| 241 | - * @param string $uri |
|
| 242 | - */ |
|
| 243 | - public function testPreventLocalAddressOnDelete(string $uri): void { |
|
| 244 | - $host = parse_url($uri, PHP_URL_HOST); |
|
| 245 | - $this->expectException(LocalServerException::class); |
|
| 246 | - $this->remoteHostValidator |
|
| 247 | - ->method('isValid') |
|
| 248 | - ->with($host) |
|
| 249 | - ->willReturn(false); |
|
| 250 | - |
|
| 251 | - $this->client->delete($uri); |
|
| 252 | - } |
|
| 253 | - |
|
| 254 | - private function setUpDefaultRequestOptions(): void { |
|
| 255 | - $this->config |
|
| 256 | - ->method('getSystemValue') |
|
| 257 | - ->will($this->returnValueMap([ |
|
| 258 | - ['proxyexclude', [], []], |
|
| 259 | - ])); |
|
| 260 | - $this->config |
|
| 261 | - ->method('getSystemValueString') |
|
| 262 | - ->will($this->returnValueMap([ |
|
| 263 | - ['proxy', '', 'foo'], |
|
| 264 | - ['proxyuserpwd', '', ''], |
|
| 265 | - ])); |
|
| 266 | - $this->config |
|
| 267 | - ->method('getSystemValueBool') |
|
| 268 | - ->will($this->returnValueMap([ |
|
| 269 | - ['installed', false, true], |
|
| 270 | - ['allow_local_remote_servers', false, true], |
|
| 271 | - ])); |
|
| 272 | - |
|
| 273 | - $this->certificateManager |
|
| 274 | - ->expects($this->once()) |
|
| 275 | - ->method('getAbsoluteBundlePath') |
|
| 276 | - ->with() |
|
| 277 | - ->willReturn('/my/path.crt'); |
|
| 278 | - |
|
| 279 | - $this->defaultRequestOptions = [ |
|
| 280 | - 'verify' => '/my/path.crt', |
|
| 281 | - 'proxy' => [ |
|
| 282 | - 'http' => 'foo', |
|
| 283 | - 'https' => 'foo' |
|
| 284 | - ], |
|
| 285 | - 'headers' => [ |
|
| 286 | - 'User-Agent' => 'Nextcloud Server Crawler', |
|
| 287 | - 'Accept-Encoding' => 'gzip', |
|
| 288 | - ], |
|
| 289 | - 'timeout' => 30, |
|
| 290 | - 'nextcloud' => [ |
|
| 291 | - 'allow_local_address' => true, |
|
| 292 | - ], |
|
| 293 | - ]; |
|
| 294 | - } |
|
| 295 | - |
|
| 296 | - public function testGet(): void { |
|
| 297 | - $this->setUpDefaultRequestOptions(); |
|
| 298 | - |
|
| 299 | - $this->guzzleClient->method('request') |
|
| 300 | - ->with('get', 'http://localhost/', $this->defaultRequestOptions) |
|
| 301 | - ->willReturn(new Response(418)); |
|
| 302 | - $this->assertEquals(418, $this->client->get('http://localhost/', [])->getStatusCode()); |
|
| 303 | - } |
|
| 304 | - |
|
| 305 | - public function testGetWithOptions(): void { |
|
| 306 | - $this->setUpDefaultRequestOptions(); |
|
| 307 | - |
|
| 308 | - $options = array_merge($this->defaultRequestOptions, [ |
|
| 309 | - 'verify' => false, |
|
| 310 | - 'proxy' => [ |
|
| 311 | - 'http' => 'bar', |
|
| 312 | - 'https' => 'bar' |
|
| 313 | - ], |
|
| 314 | - ]); |
|
| 315 | - |
|
| 316 | - $this->guzzleClient->method('request') |
|
| 317 | - ->with('get', 'http://localhost/', $options) |
|
| 318 | - ->willReturn(new Response(418)); |
|
| 319 | - $this->assertEquals(418, $this->client->get('http://localhost/', $options)->getStatusCode()); |
|
| 320 | - } |
|
| 321 | - |
|
| 322 | - public function testPost(): void { |
|
| 323 | - $this->setUpDefaultRequestOptions(); |
|
| 324 | - |
|
| 325 | - $this->guzzleClient->method('request') |
|
| 326 | - ->with('post', 'http://localhost/', $this->defaultRequestOptions) |
|
| 327 | - ->willReturn(new Response(418)); |
|
| 328 | - $this->assertEquals(418, $this->client->post('http://localhost/', [])->getStatusCode()); |
|
| 329 | - } |
|
| 330 | - |
|
| 331 | - public function testPostWithOptions(): void { |
|
| 332 | - $this->setUpDefaultRequestOptions(); |
|
| 333 | - |
|
| 334 | - $options = array_merge($this->defaultRequestOptions, [ |
|
| 335 | - 'verify' => false, |
|
| 336 | - 'proxy' => [ |
|
| 337 | - 'http' => 'bar', |
|
| 338 | - 'https' => 'bar' |
|
| 339 | - ], |
|
| 340 | - ]); |
|
| 341 | - |
|
| 342 | - $this->guzzleClient->method('request') |
|
| 343 | - ->with('post', 'http://localhost/', $options) |
|
| 344 | - ->willReturn(new Response(418)); |
|
| 345 | - $this->assertEquals(418, $this->client->post('http://localhost/', $options)->getStatusCode()); |
|
| 346 | - } |
|
| 347 | - |
|
| 348 | - public function testPut(): void { |
|
| 349 | - $this->setUpDefaultRequestOptions(); |
|
| 350 | - |
|
| 351 | - $this->guzzleClient->method('request') |
|
| 352 | - ->with('put', 'http://localhost/', $this->defaultRequestOptions) |
|
| 353 | - ->willReturn(new Response(418)); |
|
| 354 | - $this->assertEquals(418, $this->client->put('http://localhost/', [])->getStatusCode()); |
|
| 355 | - } |
|
| 356 | - |
|
| 357 | - public function testPutWithOptions(): void { |
|
| 358 | - $this->setUpDefaultRequestOptions(); |
|
| 359 | - |
|
| 360 | - $options = array_merge($this->defaultRequestOptions, [ |
|
| 361 | - 'verify' => false, |
|
| 362 | - 'proxy' => [ |
|
| 363 | - 'http' => 'bar', |
|
| 364 | - 'https' => 'bar' |
|
| 365 | - ], |
|
| 366 | - ]); |
|
| 367 | - |
|
| 368 | - $this->guzzleClient->method('request') |
|
| 369 | - ->with('put', 'http://localhost/', $options) |
|
| 370 | - ->willReturn(new Response(418)); |
|
| 371 | - $this->assertEquals(418, $this->client->put('http://localhost/', $options)->getStatusCode()); |
|
| 372 | - } |
|
| 373 | - |
|
| 374 | - public function testDelete(): void { |
|
| 375 | - $this->setUpDefaultRequestOptions(); |
|
| 376 | - |
|
| 377 | - $this->guzzleClient->method('request') |
|
| 378 | - ->with('delete', 'http://localhost/', $this->defaultRequestOptions) |
|
| 379 | - ->willReturn(new Response(418)); |
|
| 380 | - $this->assertEquals(418, $this->client->delete('http://localhost/', [])->getStatusCode()); |
|
| 381 | - } |
|
| 382 | - |
|
| 383 | - public function testDeleteWithOptions(): void { |
|
| 384 | - $this->setUpDefaultRequestOptions(); |
|
| 385 | - |
|
| 386 | - $options = array_merge($this->defaultRequestOptions, [ |
|
| 387 | - 'verify' => false, |
|
| 388 | - 'proxy' => [ |
|
| 389 | - 'http' => 'bar', |
|
| 390 | - 'https' => 'bar' |
|
| 391 | - ], |
|
| 392 | - ]); |
|
| 393 | - |
|
| 394 | - $this->guzzleClient->method('request') |
|
| 395 | - ->with('delete', 'http://localhost/', $options) |
|
| 396 | - ->willReturn(new Response(418)); |
|
| 397 | - $this->assertEquals(418, $this->client->delete('http://localhost/', $options)->getStatusCode()); |
|
| 398 | - } |
|
| 399 | - |
|
| 400 | - public function testOptions(): void { |
|
| 401 | - $this->setUpDefaultRequestOptions(); |
|
| 402 | - |
|
| 403 | - $this->guzzleClient->method('request') |
|
| 404 | - ->with('options', 'http://localhost/', $this->defaultRequestOptions) |
|
| 405 | - ->willReturn(new Response(418)); |
|
| 406 | - $this->assertEquals(418, $this->client->options('http://localhost/', [])->getStatusCode()); |
|
| 407 | - } |
|
| 408 | - |
|
| 409 | - public function testOptionsWithOptions(): void { |
|
| 410 | - $this->setUpDefaultRequestOptions(); |
|
| 411 | - |
|
| 412 | - $options = array_merge($this->defaultRequestOptions, [ |
|
| 413 | - 'verify' => false, |
|
| 414 | - 'proxy' => [ |
|
| 415 | - 'http' => 'bar', |
|
| 416 | - 'https' => 'bar' |
|
| 417 | - ], |
|
| 418 | - ]); |
|
| 419 | - |
|
| 420 | - $this->guzzleClient->method('request') |
|
| 421 | - ->with('options', 'http://localhost/', $options) |
|
| 422 | - ->willReturn(new Response(418)); |
|
| 423 | - $this->assertEquals(418, $this->client->options('http://localhost/', $options)->getStatusCode()); |
|
| 424 | - } |
|
| 425 | - |
|
| 426 | - public function testHead(): void { |
|
| 427 | - $this->setUpDefaultRequestOptions(); |
|
| 428 | - |
|
| 429 | - $this->guzzleClient->method('request') |
|
| 430 | - ->with('head', 'http://localhost/', $this->defaultRequestOptions) |
|
| 431 | - ->willReturn(new Response(418)); |
|
| 432 | - $this->assertEquals(418, $this->client->head('http://localhost/', [])->getStatusCode()); |
|
| 433 | - } |
|
| 434 | - |
|
| 435 | - public function testHeadWithOptions(): void { |
|
| 436 | - $this->setUpDefaultRequestOptions(); |
|
| 437 | - |
|
| 438 | - $options = array_merge($this->defaultRequestOptions, [ |
|
| 439 | - 'verify' => false, |
|
| 440 | - 'proxy' => [ |
|
| 441 | - 'http' => 'bar', |
|
| 442 | - 'https' => 'bar' |
|
| 443 | - ], |
|
| 444 | - ]); |
|
| 445 | - |
|
| 446 | - $this->guzzleClient->method('request') |
|
| 447 | - ->with('head', 'http://localhost/', $options) |
|
| 448 | - ->willReturn(new Response(418)); |
|
| 449 | - $this->assertEquals(418, $this->client->head('http://localhost/', $options)->getStatusCode()); |
|
| 450 | - } |
|
| 451 | - |
|
| 452 | - public function testSetDefaultOptionsWithNotInstalled(): void { |
|
| 453 | - $this->config |
|
| 454 | - ->expects($this->exactly(2)) |
|
| 455 | - ->method('getSystemValueBool') |
|
| 456 | - ->willReturnMap([ |
|
| 457 | - ['installed', false, false], |
|
| 458 | - ['allow_local_remote_servers', false, false], |
|
| 459 | - ]); |
|
| 460 | - $this->config |
|
| 461 | - ->expects($this->once()) |
|
| 462 | - ->method('getSystemValueString') |
|
| 463 | - ->with('proxy', '') |
|
| 464 | - ->willReturn(''); |
|
| 465 | - $this->certificateManager |
|
| 466 | - ->expects($this->never()) |
|
| 467 | - ->method('listCertificates'); |
|
| 468 | - |
|
| 469 | - $this->assertEquals([ |
|
| 470 | - 'verify' => \OC::$SERVERROOT . '/resources/config/ca-bundle.crt', |
|
| 471 | - 'headers' => [ |
|
| 472 | - 'User-Agent' => 'Nextcloud Server Crawler', |
|
| 473 | - 'Accept-Encoding' => 'gzip', |
|
| 474 | - ], |
|
| 475 | - 'timeout' => 30, |
|
| 476 | - 'nextcloud' => [ |
|
| 477 | - 'allow_local_address' => false, |
|
| 478 | - ], |
|
| 479 | - 'allow_redirects' => [ |
|
| 480 | - 'on_redirect' => function ( |
|
| 481 | - \Psr\Http\Message\RequestInterface $request, |
|
| 482 | - \Psr\Http\Message\ResponseInterface $response, |
|
| 483 | - \Psr\Http\Message\UriInterface $uri, |
|
| 484 | - ) { |
|
| 485 | - }, |
|
| 486 | - ], |
|
| 487 | - ], self::invokePrivate($this->client, 'buildRequestOptions', [[]])); |
|
| 488 | - } |
|
| 489 | - |
|
| 490 | - public function testSetDefaultOptionsWithProxy(): void { |
|
| 491 | - $this->config |
|
| 492 | - ->expects($this->exactly(2)) |
|
| 493 | - ->method('getSystemValueBool') |
|
| 494 | - ->willReturnMap([ |
|
| 495 | - ['installed', false, true], |
|
| 496 | - ['allow_local_remote_servers', false, false], |
|
| 497 | - ]); |
|
| 498 | - $this->config |
|
| 499 | - ->expects($this->once()) |
|
| 500 | - ->method('getSystemValue') |
|
| 501 | - ->with('proxyexclude', []) |
|
| 502 | - ->willReturn([]); |
|
| 503 | - $this->config |
|
| 504 | - ->expects($this->exactly(2)) |
|
| 505 | - ->method('getSystemValueString') |
|
| 506 | - ->willReturnMap([ |
|
| 507 | - ['proxy', '', 'foo'], |
|
| 508 | - ['proxyuserpwd', '', ''], |
|
| 509 | - ]); |
|
| 510 | - $this->certificateManager |
|
| 511 | - ->expects($this->once()) |
|
| 512 | - ->method('getAbsoluteBundlePath') |
|
| 513 | - ->with() |
|
| 514 | - ->willReturn('/my/path.crt'); |
|
| 515 | - |
|
| 516 | - $this->assertEquals([ |
|
| 517 | - 'verify' => '/my/path.crt', |
|
| 518 | - 'proxy' => [ |
|
| 519 | - 'http' => 'foo', |
|
| 520 | - 'https' => 'foo' |
|
| 521 | - ], |
|
| 522 | - 'headers' => [ |
|
| 523 | - 'User-Agent' => 'Nextcloud Server Crawler', |
|
| 524 | - 'Accept-Encoding' => 'gzip', |
|
| 525 | - ], |
|
| 526 | - 'timeout' => 30, |
|
| 527 | - 'nextcloud' => [ |
|
| 528 | - 'allow_local_address' => false, |
|
| 529 | - ], |
|
| 530 | - 'allow_redirects' => [ |
|
| 531 | - 'on_redirect' => function ( |
|
| 532 | - \Psr\Http\Message\RequestInterface $request, |
|
| 533 | - \Psr\Http\Message\ResponseInterface $response, |
|
| 534 | - \Psr\Http\Message\UriInterface $uri, |
|
| 535 | - ) { |
|
| 536 | - }, |
|
| 537 | - ], |
|
| 538 | - ], self::invokePrivate($this->client, 'buildRequestOptions', [[]])); |
|
| 539 | - } |
|
| 540 | - |
|
| 541 | - public function testSetDefaultOptionsWithProxyAndExclude(): void { |
|
| 542 | - $this->config |
|
| 543 | - ->expects($this->exactly(2)) |
|
| 544 | - ->method('getSystemValueBool') |
|
| 545 | - ->willReturnMap([ |
|
| 546 | - ['installed', false, true], |
|
| 547 | - ['allow_local_remote_servers', false, false], |
|
| 548 | - ]); |
|
| 549 | - $this->config |
|
| 550 | - ->expects($this->once()) |
|
| 551 | - ->method('getSystemValue') |
|
| 552 | - ->with('proxyexclude', []) |
|
| 553 | - ->willReturn(['bar']); |
|
| 554 | - $this->config |
|
| 555 | - ->expects($this->exactly(2)) |
|
| 556 | - ->method('getSystemValueString') |
|
| 557 | - ->willReturnMap([ |
|
| 558 | - ['proxy', '', 'foo'], |
|
| 559 | - ['proxyuserpwd', '', ''], |
|
| 560 | - ]); |
|
| 561 | - $this->certificateManager |
|
| 562 | - ->expects($this->once()) |
|
| 563 | - ->method('getAbsoluteBundlePath') |
|
| 564 | - ->with() |
|
| 565 | - ->willReturn('/my/path.crt'); |
|
| 566 | - |
|
| 567 | - $this->assertEquals([ |
|
| 568 | - 'verify' => '/my/path.crt', |
|
| 569 | - 'proxy' => [ |
|
| 570 | - 'http' => 'foo', |
|
| 571 | - 'https' => 'foo', |
|
| 572 | - 'no' => ['bar'] |
|
| 573 | - ], |
|
| 574 | - 'headers' => [ |
|
| 575 | - 'User-Agent' => 'Nextcloud Server Crawler', |
|
| 576 | - 'Accept-Encoding' => 'gzip', |
|
| 577 | - ], |
|
| 578 | - 'timeout' => 30, |
|
| 579 | - 'nextcloud' => [ |
|
| 580 | - 'allow_local_address' => false, |
|
| 581 | - ], |
|
| 582 | - 'allow_redirects' => [ |
|
| 583 | - 'on_redirect' => function ( |
|
| 584 | - \Psr\Http\Message\RequestInterface $request, |
|
| 585 | - \Psr\Http\Message\ResponseInterface $response, |
|
| 586 | - \Psr\Http\Message\UriInterface $uri, |
|
| 587 | - ) { |
|
| 588 | - }, |
|
| 589 | - ], |
|
| 590 | - ], self::invokePrivate($this->client, 'buildRequestOptions', [[]])); |
|
| 591 | - } |
|
| 28 | + /** @var \GuzzleHttp\Client|MockObject */ |
|
| 29 | + private $guzzleClient; |
|
| 30 | + /** @var CertificateManager|MockObject */ |
|
| 31 | + private $certificateManager; |
|
| 32 | + /** @var Client */ |
|
| 33 | + private $client; |
|
| 34 | + /** @var IConfig|MockObject */ |
|
| 35 | + private $config; |
|
| 36 | + /** @var IRemoteHostValidator|MockObject */ |
|
| 37 | + private IRemoteHostValidator $remoteHostValidator; |
|
| 38 | + private LoggerInterface $logger; |
|
| 39 | + /** @var array */ |
|
| 40 | + private $defaultRequestOptions; |
|
| 41 | + |
|
| 42 | + protected function setUp(): void { |
|
| 43 | + parent::setUp(); |
|
| 44 | + $this->config = $this->createMock(IConfig::class); |
|
| 45 | + $this->guzzleClient = $this->createMock(\GuzzleHttp\Client::class); |
|
| 46 | + $this->certificateManager = $this->createMock(ICertificateManager::class); |
|
| 47 | + $this->remoteHostValidator = $this->createMock(IRemoteHostValidator::class); |
|
| 48 | + $this->logger = $this->createMock(LoggerInterface::class); |
|
| 49 | + $this->client = new Client( |
|
| 50 | + $this->config, |
|
| 51 | + $this->certificateManager, |
|
| 52 | + $this->guzzleClient, |
|
| 53 | + $this->remoteHostValidator, |
|
| 54 | + $this->logger, |
|
| 55 | + ); |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + public function testGetProxyUri(): void { |
|
| 59 | + $this->config |
|
| 60 | + ->method('getSystemValueString') |
|
| 61 | + ->with('proxy', '') |
|
| 62 | + ->willReturn(''); |
|
| 63 | + $this->assertNull(self::invokePrivate($this->client, 'getProxyUri')); |
|
| 64 | + } |
|
| 65 | + |
|
| 66 | + public function testGetProxyUriProxyHostEmptyPassword(): void { |
|
| 67 | + $this->config |
|
| 68 | + ->method('getSystemValue') |
|
| 69 | + ->will($this->returnValueMap([ |
|
| 70 | + ['proxyexclude', [], []], |
|
| 71 | + ])); |
|
| 72 | + |
|
| 73 | + $this->config |
|
| 74 | + ->method('getSystemValueString') |
|
| 75 | + ->will($this->returnValueMap([ |
|
| 76 | + ['proxy', '', 'foo'], |
|
| 77 | + ['proxyuserpwd', '', ''], |
|
| 78 | + ])); |
|
| 79 | + |
|
| 80 | + $this->assertEquals([ |
|
| 81 | + 'http' => 'foo', |
|
| 82 | + 'https' => 'foo' |
|
| 83 | + ], self::invokePrivate($this->client, 'getProxyUri')); |
|
| 84 | + } |
|
| 85 | + |
|
| 86 | + public function testGetProxyUriProxyHostWithPassword(): void { |
|
| 87 | + $this->config |
|
| 88 | + ->expects($this->once()) |
|
| 89 | + ->method('getSystemValue') |
|
| 90 | + ->with('proxyexclude', []) |
|
| 91 | + ->willReturn([]); |
|
| 92 | + $this->config |
|
| 93 | + ->expects($this->exactly(2)) |
|
| 94 | + ->method('getSystemValueString') |
|
| 95 | + ->willReturnMap([ |
|
| 96 | + ['proxy', '', 'foo'], |
|
| 97 | + ['proxyuserpwd', '', 'username:password'], |
|
| 98 | + ]); |
|
| 99 | + $this->assertEquals([ |
|
| 100 | + 'http' => 'username:password@foo', |
|
| 101 | + 'https' => 'username:password@foo' |
|
| 102 | + ], self::invokePrivate($this->client, 'getProxyUri')); |
|
| 103 | + } |
|
| 104 | + |
|
| 105 | + public function testGetProxyUriProxyHostWithPasswordAndExclude(): void { |
|
| 106 | + $this->config |
|
| 107 | + ->expects($this->once()) |
|
| 108 | + ->method('getSystemValue') |
|
| 109 | + ->with('proxyexclude', []) |
|
| 110 | + ->willReturn(['bar']); |
|
| 111 | + $this->config |
|
| 112 | + ->expects($this->exactly(2)) |
|
| 113 | + ->method('getSystemValueString') |
|
| 114 | + ->willReturnMap([ |
|
| 115 | + ['proxy', '', 'foo'], |
|
| 116 | + ['proxyuserpwd', '', 'username:password'], |
|
| 117 | + ]); |
|
| 118 | + $this->assertEquals([ |
|
| 119 | + 'http' => 'username:password@foo', |
|
| 120 | + 'https' => 'username:password@foo', |
|
| 121 | + 'no' => ['bar'] |
|
| 122 | + ], self::invokePrivate($this->client, 'getProxyUri')); |
|
| 123 | + } |
|
| 124 | + |
|
| 125 | + public function testPreventLocalAddressThrowOnInvalidUri(): void { |
|
| 126 | + $this->expectException(LocalServerException::class); |
|
| 127 | + $this->expectExceptionMessage('Could not detect any host'); |
|
| 128 | + |
|
| 129 | + self::invokePrivate($this->client, 'preventLocalAddress', ['!@#$', []]); |
|
| 130 | + } |
|
| 131 | + |
|
| 132 | + public static function dataPreventLocalAddress(): array { |
|
| 133 | + return [ |
|
| 134 | + ['https://localhost/foo.bar'], |
|
| 135 | + ['https://localHost/foo.bar'], |
|
| 136 | + ['https://random-host/foo.bar'], |
|
| 137 | + ['https://[::1]/bla.blub'], |
|
| 138 | + ['https://[::]/bla.blub'], |
|
| 139 | + ['https://192.168.0.1'], |
|
| 140 | + ['https://172.16.42.1'], |
|
| 141 | + ['https://[fdf8:f53b:82e4::53]/secret.ics'], |
|
| 142 | + ['https://[fe80::200:5aee:feaa:20a2]/secret.ics'], |
|
| 143 | + ['https://[0:0:0:0:0:0:10.0.0.1]/secret.ics'], |
|
| 144 | + ['https://[0:0:0:0:0:ffff:127.0.0.0]/secret.ics'], |
|
| 145 | + ['https://10.0.0.1'], |
|
| 146 | + ['https://another-host.local'], |
|
| 147 | + ['https://service.localhost'], |
|
| 148 | + ['https://normal.host.com'], |
|
| 149 | + ['https://com.one-.nextcloud-one.com'], |
|
| 150 | + ]; |
|
| 151 | + } |
|
| 152 | + |
|
| 153 | + /** |
|
| 154 | + * @dataProvider dataPreventLocalAddress |
|
| 155 | + * @param string $uri |
|
| 156 | + */ |
|
| 157 | + public function testPreventLocalAddressDisabledByGlobalConfig(string $uri): void { |
|
| 158 | + $this->config->expects($this->once()) |
|
| 159 | + ->method('getSystemValueBool') |
|
| 160 | + ->with('allow_local_remote_servers', false) |
|
| 161 | + ->willReturn(true); |
|
| 162 | + |
|
| 163 | + self::invokePrivate($this->client, 'preventLocalAddress', [$uri, []]); |
|
| 164 | + } |
|
| 165 | + |
|
| 166 | + /** |
|
| 167 | + * @dataProvider dataPreventLocalAddress |
|
| 168 | + * @param string $uri |
|
| 169 | + */ |
|
| 170 | + public function testPreventLocalAddressDisabledByOption(string $uri): void { |
|
| 171 | + $this->config->expects($this->never()) |
|
| 172 | + ->method('getSystemValueBool'); |
|
| 173 | + |
|
| 174 | + self::invokePrivate($this->client, 'preventLocalAddress', [$uri, [ |
|
| 175 | + 'nextcloud' => ['allow_local_address' => true], |
|
| 176 | + ]]); |
|
| 177 | + } |
|
| 178 | + |
|
| 179 | + /** |
|
| 180 | + * @dataProvider dataPreventLocalAddress |
|
| 181 | + * @param string $uri |
|
| 182 | + */ |
|
| 183 | + public function testPreventLocalAddressOnGet(string $uri): void { |
|
| 184 | + $host = parse_url($uri, PHP_URL_HOST); |
|
| 185 | + $this->expectException(LocalServerException::class); |
|
| 186 | + $this->remoteHostValidator |
|
| 187 | + ->method('isValid') |
|
| 188 | + ->with($host) |
|
| 189 | + ->willReturn(false); |
|
| 190 | + |
|
| 191 | + $this->client->get($uri); |
|
| 192 | + } |
|
| 193 | + |
|
| 194 | + /** |
|
| 195 | + * @dataProvider dataPreventLocalAddress |
|
| 196 | + * @param string $uri |
|
| 197 | + */ |
|
| 198 | + public function testPreventLocalAddressOnHead(string $uri): void { |
|
| 199 | + $host = parse_url($uri, PHP_URL_HOST); |
|
| 200 | + $this->expectException(LocalServerException::class); |
|
| 201 | + $this->remoteHostValidator |
|
| 202 | + ->method('isValid') |
|
| 203 | + ->with($host) |
|
| 204 | + ->willReturn(false); |
|
| 205 | + |
|
| 206 | + $this->client->head($uri); |
|
| 207 | + } |
|
| 208 | + |
|
| 209 | + /** |
|
| 210 | + * @dataProvider dataPreventLocalAddress |
|
| 211 | + * @param string $uri |
|
| 212 | + */ |
|
| 213 | + public function testPreventLocalAddressOnPost(string $uri): void { |
|
| 214 | + $host = parse_url($uri, PHP_URL_HOST); |
|
| 215 | + $this->expectException(LocalServerException::class); |
|
| 216 | + $this->remoteHostValidator |
|
| 217 | + ->method('isValid') |
|
| 218 | + ->with($host) |
|
| 219 | + ->willReturn(false); |
|
| 220 | + |
|
| 221 | + $this->client->post($uri); |
|
| 222 | + } |
|
| 223 | + |
|
| 224 | + /** |
|
| 225 | + * @dataProvider dataPreventLocalAddress |
|
| 226 | + * @param string $uri |
|
| 227 | + */ |
|
| 228 | + public function testPreventLocalAddressOnPut(string $uri): void { |
|
| 229 | + $host = parse_url($uri, PHP_URL_HOST); |
|
| 230 | + $this->expectException(LocalServerException::class); |
|
| 231 | + $this->remoteHostValidator |
|
| 232 | + ->method('isValid') |
|
| 233 | + ->with($host) |
|
| 234 | + ->willReturn(false); |
|
| 235 | + |
|
| 236 | + $this->client->put($uri); |
|
| 237 | + } |
|
| 238 | + |
|
| 239 | + /** |
|
| 240 | + * @dataProvider dataPreventLocalAddress |
|
| 241 | + * @param string $uri |
|
| 242 | + */ |
|
| 243 | + public function testPreventLocalAddressOnDelete(string $uri): void { |
|
| 244 | + $host = parse_url($uri, PHP_URL_HOST); |
|
| 245 | + $this->expectException(LocalServerException::class); |
|
| 246 | + $this->remoteHostValidator |
|
| 247 | + ->method('isValid') |
|
| 248 | + ->with($host) |
|
| 249 | + ->willReturn(false); |
|
| 250 | + |
|
| 251 | + $this->client->delete($uri); |
|
| 252 | + } |
|
| 253 | + |
|
| 254 | + private function setUpDefaultRequestOptions(): void { |
|
| 255 | + $this->config |
|
| 256 | + ->method('getSystemValue') |
|
| 257 | + ->will($this->returnValueMap([ |
|
| 258 | + ['proxyexclude', [], []], |
|
| 259 | + ])); |
|
| 260 | + $this->config |
|
| 261 | + ->method('getSystemValueString') |
|
| 262 | + ->will($this->returnValueMap([ |
|
| 263 | + ['proxy', '', 'foo'], |
|
| 264 | + ['proxyuserpwd', '', ''], |
|
| 265 | + ])); |
|
| 266 | + $this->config |
|
| 267 | + ->method('getSystemValueBool') |
|
| 268 | + ->will($this->returnValueMap([ |
|
| 269 | + ['installed', false, true], |
|
| 270 | + ['allow_local_remote_servers', false, true], |
|
| 271 | + ])); |
|
| 272 | + |
|
| 273 | + $this->certificateManager |
|
| 274 | + ->expects($this->once()) |
|
| 275 | + ->method('getAbsoluteBundlePath') |
|
| 276 | + ->with() |
|
| 277 | + ->willReturn('/my/path.crt'); |
|
| 278 | + |
|
| 279 | + $this->defaultRequestOptions = [ |
|
| 280 | + 'verify' => '/my/path.crt', |
|
| 281 | + 'proxy' => [ |
|
| 282 | + 'http' => 'foo', |
|
| 283 | + 'https' => 'foo' |
|
| 284 | + ], |
|
| 285 | + 'headers' => [ |
|
| 286 | + 'User-Agent' => 'Nextcloud Server Crawler', |
|
| 287 | + 'Accept-Encoding' => 'gzip', |
|
| 288 | + ], |
|
| 289 | + 'timeout' => 30, |
|
| 290 | + 'nextcloud' => [ |
|
| 291 | + 'allow_local_address' => true, |
|
| 292 | + ], |
|
| 293 | + ]; |
|
| 294 | + } |
|
| 295 | + |
|
| 296 | + public function testGet(): void { |
|
| 297 | + $this->setUpDefaultRequestOptions(); |
|
| 298 | + |
|
| 299 | + $this->guzzleClient->method('request') |
|
| 300 | + ->with('get', 'http://localhost/', $this->defaultRequestOptions) |
|
| 301 | + ->willReturn(new Response(418)); |
|
| 302 | + $this->assertEquals(418, $this->client->get('http://localhost/', [])->getStatusCode()); |
|
| 303 | + } |
|
| 304 | + |
|
| 305 | + public function testGetWithOptions(): void { |
|
| 306 | + $this->setUpDefaultRequestOptions(); |
|
| 307 | + |
|
| 308 | + $options = array_merge($this->defaultRequestOptions, [ |
|
| 309 | + 'verify' => false, |
|
| 310 | + 'proxy' => [ |
|
| 311 | + 'http' => 'bar', |
|
| 312 | + 'https' => 'bar' |
|
| 313 | + ], |
|
| 314 | + ]); |
|
| 315 | + |
|
| 316 | + $this->guzzleClient->method('request') |
|
| 317 | + ->with('get', 'http://localhost/', $options) |
|
| 318 | + ->willReturn(new Response(418)); |
|
| 319 | + $this->assertEquals(418, $this->client->get('http://localhost/', $options)->getStatusCode()); |
|
| 320 | + } |
|
| 321 | + |
|
| 322 | + public function testPost(): void { |
|
| 323 | + $this->setUpDefaultRequestOptions(); |
|
| 324 | + |
|
| 325 | + $this->guzzleClient->method('request') |
|
| 326 | + ->with('post', 'http://localhost/', $this->defaultRequestOptions) |
|
| 327 | + ->willReturn(new Response(418)); |
|
| 328 | + $this->assertEquals(418, $this->client->post('http://localhost/', [])->getStatusCode()); |
|
| 329 | + } |
|
| 330 | + |
|
| 331 | + public function testPostWithOptions(): void { |
|
| 332 | + $this->setUpDefaultRequestOptions(); |
|
| 333 | + |
|
| 334 | + $options = array_merge($this->defaultRequestOptions, [ |
|
| 335 | + 'verify' => false, |
|
| 336 | + 'proxy' => [ |
|
| 337 | + 'http' => 'bar', |
|
| 338 | + 'https' => 'bar' |
|
| 339 | + ], |
|
| 340 | + ]); |
|
| 341 | + |
|
| 342 | + $this->guzzleClient->method('request') |
|
| 343 | + ->with('post', 'http://localhost/', $options) |
|
| 344 | + ->willReturn(new Response(418)); |
|
| 345 | + $this->assertEquals(418, $this->client->post('http://localhost/', $options)->getStatusCode()); |
|
| 346 | + } |
|
| 347 | + |
|
| 348 | + public function testPut(): void { |
|
| 349 | + $this->setUpDefaultRequestOptions(); |
|
| 350 | + |
|
| 351 | + $this->guzzleClient->method('request') |
|
| 352 | + ->with('put', 'http://localhost/', $this->defaultRequestOptions) |
|
| 353 | + ->willReturn(new Response(418)); |
|
| 354 | + $this->assertEquals(418, $this->client->put('http://localhost/', [])->getStatusCode()); |
|
| 355 | + } |
|
| 356 | + |
|
| 357 | + public function testPutWithOptions(): void { |
|
| 358 | + $this->setUpDefaultRequestOptions(); |
|
| 359 | + |
|
| 360 | + $options = array_merge($this->defaultRequestOptions, [ |
|
| 361 | + 'verify' => false, |
|
| 362 | + 'proxy' => [ |
|
| 363 | + 'http' => 'bar', |
|
| 364 | + 'https' => 'bar' |
|
| 365 | + ], |
|
| 366 | + ]); |
|
| 367 | + |
|
| 368 | + $this->guzzleClient->method('request') |
|
| 369 | + ->with('put', 'http://localhost/', $options) |
|
| 370 | + ->willReturn(new Response(418)); |
|
| 371 | + $this->assertEquals(418, $this->client->put('http://localhost/', $options)->getStatusCode()); |
|
| 372 | + } |
|
| 373 | + |
|
| 374 | + public function testDelete(): void { |
|
| 375 | + $this->setUpDefaultRequestOptions(); |
|
| 376 | + |
|
| 377 | + $this->guzzleClient->method('request') |
|
| 378 | + ->with('delete', 'http://localhost/', $this->defaultRequestOptions) |
|
| 379 | + ->willReturn(new Response(418)); |
|
| 380 | + $this->assertEquals(418, $this->client->delete('http://localhost/', [])->getStatusCode()); |
|
| 381 | + } |
|
| 382 | + |
|
| 383 | + public function testDeleteWithOptions(): void { |
|
| 384 | + $this->setUpDefaultRequestOptions(); |
|
| 385 | + |
|
| 386 | + $options = array_merge($this->defaultRequestOptions, [ |
|
| 387 | + 'verify' => false, |
|
| 388 | + 'proxy' => [ |
|
| 389 | + 'http' => 'bar', |
|
| 390 | + 'https' => 'bar' |
|
| 391 | + ], |
|
| 392 | + ]); |
|
| 393 | + |
|
| 394 | + $this->guzzleClient->method('request') |
|
| 395 | + ->with('delete', 'http://localhost/', $options) |
|
| 396 | + ->willReturn(new Response(418)); |
|
| 397 | + $this->assertEquals(418, $this->client->delete('http://localhost/', $options)->getStatusCode()); |
|
| 398 | + } |
|
| 399 | + |
|
| 400 | + public function testOptions(): void { |
|
| 401 | + $this->setUpDefaultRequestOptions(); |
|
| 402 | + |
|
| 403 | + $this->guzzleClient->method('request') |
|
| 404 | + ->with('options', 'http://localhost/', $this->defaultRequestOptions) |
|
| 405 | + ->willReturn(new Response(418)); |
|
| 406 | + $this->assertEquals(418, $this->client->options('http://localhost/', [])->getStatusCode()); |
|
| 407 | + } |
|
| 408 | + |
|
| 409 | + public function testOptionsWithOptions(): void { |
|
| 410 | + $this->setUpDefaultRequestOptions(); |
|
| 411 | + |
|
| 412 | + $options = array_merge($this->defaultRequestOptions, [ |
|
| 413 | + 'verify' => false, |
|
| 414 | + 'proxy' => [ |
|
| 415 | + 'http' => 'bar', |
|
| 416 | + 'https' => 'bar' |
|
| 417 | + ], |
|
| 418 | + ]); |
|
| 419 | + |
|
| 420 | + $this->guzzleClient->method('request') |
|
| 421 | + ->with('options', 'http://localhost/', $options) |
|
| 422 | + ->willReturn(new Response(418)); |
|
| 423 | + $this->assertEquals(418, $this->client->options('http://localhost/', $options)->getStatusCode()); |
|
| 424 | + } |
|
| 425 | + |
|
| 426 | + public function testHead(): void { |
|
| 427 | + $this->setUpDefaultRequestOptions(); |
|
| 428 | + |
|
| 429 | + $this->guzzleClient->method('request') |
|
| 430 | + ->with('head', 'http://localhost/', $this->defaultRequestOptions) |
|
| 431 | + ->willReturn(new Response(418)); |
|
| 432 | + $this->assertEquals(418, $this->client->head('http://localhost/', [])->getStatusCode()); |
|
| 433 | + } |
|
| 434 | + |
|
| 435 | + public function testHeadWithOptions(): void { |
|
| 436 | + $this->setUpDefaultRequestOptions(); |
|
| 437 | + |
|
| 438 | + $options = array_merge($this->defaultRequestOptions, [ |
|
| 439 | + 'verify' => false, |
|
| 440 | + 'proxy' => [ |
|
| 441 | + 'http' => 'bar', |
|
| 442 | + 'https' => 'bar' |
|
| 443 | + ], |
|
| 444 | + ]); |
|
| 445 | + |
|
| 446 | + $this->guzzleClient->method('request') |
|
| 447 | + ->with('head', 'http://localhost/', $options) |
|
| 448 | + ->willReturn(new Response(418)); |
|
| 449 | + $this->assertEquals(418, $this->client->head('http://localhost/', $options)->getStatusCode()); |
|
| 450 | + } |
|
| 451 | + |
|
| 452 | + public function testSetDefaultOptionsWithNotInstalled(): void { |
|
| 453 | + $this->config |
|
| 454 | + ->expects($this->exactly(2)) |
|
| 455 | + ->method('getSystemValueBool') |
|
| 456 | + ->willReturnMap([ |
|
| 457 | + ['installed', false, false], |
|
| 458 | + ['allow_local_remote_servers', false, false], |
|
| 459 | + ]); |
|
| 460 | + $this->config |
|
| 461 | + ->expects($this->once()) |
|
| 462 | + ->method('getSystemValueString') |
|
| 463 | + ->with('proxy', '') |
|
| 464 | + ->willReturn(''); |
|
| 465 | + $this->certificateManager |
|
| 466 | + ->expects($this->never()) |
|
| 467 | + ->method('listCertificates'); |
|
| 468 | + |
|
| 469 | + $this->assertEquals([ |
|
| 470 | + 'verify' => \OC::$SERVERROOT . '/resources/config/ca-bundle.crt', |
|
| 471 | + 'headers' => [ |
|
| 472 | + 'User-Agent' => 'Nextcloud Server Crawler', |
|
| 473 | + 'Accept-Encoding' => 'gzip', |
|
| 474 | + ], |
|
| 475 | + 'timeout' => 30, |
|
| 476 | + 'nextcloud' => [ |
|
| 477 | + 'allow_local_address' => false, |
|
| 478 | + ], |
|
| 479 | + 'allow_redirects' => [ |
|
| 480 | + 'on_redirect' => function ( |
|
| 481 | + \Psr\Http\Message\RequestInterface $request, |
|
| 482 | + \Psr\Http\Message\ResponseInterface $response, |
|
| 483 | + \Psr\Http\Message\UriInterface $uri, |
|
| 484 | + ) { |
|
| 485 | + }, |
|
| 486 | + ], |
|
| 487 | + ], self::invokePrivate($this->client, 'buildRequestOptions', [[]])); |
|
| 488 | + } |
|
| 489 | + |
|
| 490 | + public function testSetDefaultOptionsWithProxy(): void { |
|
| 491 | + $this->config |
|
| 492 | + ->expects($this->exactly(2)) |
|
| 493 | + ->method('getSystemValueBool') |
|
| 494 | + ->willReturnMap([ |
|
| 495 | + ['installed', false, true], |
|
| 496 | + ['allow_local_remote_servers', false, false], |
|
| 497 | + ]); |
|
| 498 | + $this->config |
|
| 499 | + ->expects($this->once()) |
|
| 500 | + ->method('getSystemValue') |
|
| 501 | + ->with('proxyexclude', []) |
|
| 502 | + ->willReturn([]); |
|
| 503 | + $this->config |
|
| 504 | + ->expects($this->exactly(2)) |
|
| 505 | + ->method('getSystemValueString') |
|
| 506 | + ->willReturnMap([ |
|
| 507 | + ['proxy', '', 'foo'], |
|
| 508 | + ['proxyuserpwd', '', ''], |
|
| 509 | + ]); |
|
| 510 | + $this->certificateManager |
|
| 511 | + ->expects($this->once()) |
|
| 512 | + ->method('getAbsoluteBundlePath') |
|
| 513 | + ->with() |
|
| 514 | + ->willReturn('/my/path.crt'); |
|
| 515 | + |
|
| 516 | + $this->assertEquals([ |
|
| 517 | + 'verify' => '/my/path.crt', |
|
| 518 | + 'proxy' => [ |
|
| 519 | + 'http' => 'foo', |
|
| 520 | + 'https' => 'foo' |
|
| 521 | + ], |
|
| 522 | + 'headers' => [ |
|
| 523 | + 'User-Agent' => 'Nextcloud Server Crawler', |
|
| 524 | + 'Accept-Encoding' => 'gzip', |
|
| 525 | + ], |
|
| 526 | + 'timeout' => 30, |
|
| 527 | + 'nextcloud' => [ |
|
| 528 | + 'allow_local_address' => false, |
|
| 529 | + ], |
|
| 530 | + 'allow_redirects' => [ |
|
| 531 | + 'on_redirect' => function ( |
|
| 532 | + \Psr\Http\Message\RequestInterface $request, |
|
| 533 | + \Psr\Http\Message\ResponseInterface $response, |
|
| 534 | + \Psr\Http\Message\UriInterface $uri, |
|
| 535 | + ) { |
|
| 536 | + }, |
|
| 537 | + ], |
|
| 538 | + ], self::invokePrivate($this->client, 'buildRequestOptions', [[]])); |
|
| 539 | + } |
|
| 540 | + |
|
| 541 | + public function testSetDefaultOptionsWithProxyAndExclude(): void { |
|
| 542 | + $this->config |
|
| 543 | + ->expects($this->exactly(2)) |
|
| 544 | + ->method('getSystemValueBool') |
|
| 545 | + ->willReturnMap([ |
|
| 546 | + ['installed', false, true], |
|
| 547 | + ['allow_local_remote_servers', false, false], |
|
| 548 | + ]); |
|
| 549 | + $this->config |
|
| 550 | + ->expects($this->once()) |
|
| 551 | + ->method('getSystemValue') |
|
| 552 | + ->with('proxyexclude', []) |
|
| 553 | + ->willReturn(['bar']); |
|
| 554 | + $this->config |
|
| 555 | + ->expects($this->exactly(2)) |
|
| 556 | + ->method('getSystemValueString') |
|
| 557 | + ->willReturnMap([ |
|
| 558 | + ['proxy', '', 'foo'], |
|
| 559 | + ['proxyuserpwd', '', ''], |
|
| 560 | + ]); |
|
| 561 | + $this->certificateManager |
|
| 562 | + ->expects($this->once()) |
|
| 563 | + ->method('getAbsoluteBundlePath') |
|
| 564 | + ->with() |
|
| 565 | + ->willReturn('/my/path.crt'); |
|
| 566 | + |
|
| 567 | + $this->assertEquals([ |
|
| 568 | + 'verify' => '/my/path.crt', |
|
| 569 | + 'proxy' => [ |
|
| 570 | + 'http' => 'foo', |
|
| 571 | + 'https' => 'foo', |
|
| 572 | + 'no' => ['bar'] |
|
| 573 | + ], |
|
| 574 | + 'headers' => [ |
|
| 575 | + 'User-Agent' => 'Nextcloud Server Crawler', |
|
| 576 | + 'Accept-Encoding' => 'gzip', |
|
| 577 | + ], |
|
| 578 | + 'timeout' => 30, |
|
| 579 | + 'nextcloud' => [ |
|
| 580 | + 'allow_local_address' => false, |
|
| 581 | + ], |
|
| 582 | + 'allow_redirects' => [ |
|
| 583 | + 'on_redirect' => function ( |
|
| 584 | + \Psr\Http\Message\RequestInterface $request, |
|
| 585 | + \Psr\Http\Message\ResponseInterface $response, |
|
| 586 | + \Psr\Http\Message\UriInterface $uri, |
|
| 587 | + ) { |
|
| 588 | + }, |
|
| 589 | + ], |
|
| 590 | + ], self::invokePrivate($this->client, 'buildRequestOptions', [[]])); |
|
| 591 | + } |
|
| 592 | 592 | } |
@@ -24,474 +24,474 @@ |
||
| 24 | 24 | use Test\TestCase; |
| 25 | 25 | |
| 26 | 26 | class LookupPluginTest extends TestCase { |
| 27 | - /** @var IConfig|MockObject */ |
|
| 28 | - protected $config; |
|
| 29 | - /** @var IClientService|MockObject */ |
|
| 30 | - protected $clientService; |
|
| 31 | - /** @var IUserSession|MockObject */ |
|
| 32 | - protected $userSession; |
|
| 33 | - /** @var ICloudIdManager|MockObject */ |
|
| 34 | - protected $cloudIdManager; |
|
| 35 | - /** @var LookupPlugin */ |
|
| 36 | - protected $plugin; |
|
| 37 | - /** @var LoggerInterface|MockObject */ |
|
| 38 | - protected $logger; |
|
| 39 | - |
|
| 40 | - protected function setUp(): void { |
|
| 41 | - parent::setUp(); |
|
| 42 | - |
|
| 43 | - $this->userSession = $this->createMock(IUserSession::class); |
|
| 44 | - $this->cloudIdManager = $this->createMock(ICloudIdManager::class); |
|
| 45 | - $this->config = $this->createMock(IConfig::class); |
|
| 46 | - $this->logger = $this->createMock(LoggerInterface::class); |
|
| 47 | - $this->clientService = $this->createMock(IClientService::class); |
|
| 48 | - $cloudId = $this->createMock(ICloudId::class); |
|
| 49 | - $cloudId->expects($this->any())->method('getRemote')->willReturn('myNextcloud.net'); |
|
| 50 | - $user = $this->createMock(IUser::class); |
|
| 51 | - $user->expects($this->any())->method('getCloudId')->willReturn('[email protected]'); |
|
| 52 | - $this->userSession->expects($this->any())->method('getUser') |
|
| 53 | - ->willReturn($user); |
|
| 54 | - $this->cloudIdManager->expects($this->any())->method('resolveCloudId') |
|
| 55 | - ->willReturnCallback(function ($cloudId) { |
|
| 56 | - if ($cloudId === '[email protected]') { |
|
| 57 | - return new CloudId('[email protected]', 'user', 'myNextcloud.net'); |
|
| 58 | - } |
|
| 59 | - return new CloudId('[email protected]', 'user', 'someNextcloud.net'); |
|
| 60 | - }); |
|
| 61 | - |
|
| 62 | - |
|
| 63 | - $this->plugin = new LookupPlugin( |
|
| 64 | - $this->config, |
|
| 65 | - $this->clientService, |
|
| 66 | - $this->userSession, |
|
| 67 | - $this->cloudIdManager, |
|
| 68 | - $this->logger |
|
| 69 | - ); |
|
| 70 | - } |
|
| 71 | - |
|
| 72 | - public function testSearchNoLookupServerURI(): void { |
|
| 73 | - $this->config->expects($this->once()) |
|
| 74 | - ->method('getAppValue') |
|
| 75 | - ->with('files_sharing', 'lookupServerEnabled', 'no') |
|
| 76 | - ->willReturn('yes'); |
|
| 77 | - $this->config->expects($this->exactly(2)) |
|
| 78 | - ->method('getSystemValueBool') |
|
| 79 | - ->willReturnMap([ |
|
| 80 | - ['gs.enabled', false, true], |
|
| 81 | - ['has_internet_connection', true, true], |
|
| 82 | - ]); |
|
| 83 | - |
|
| 84 | - $this->config->expects($this->once()) |
|
| 85 | - ->method('getSystemValueString') |
|
| 86 | - ->with('lookup_server', 'https://lookup.nextcloud.com') |
|
| 87 | - ->willReturn(''); |
|
| 88 | - |
|
| 89 | - $this->clientService->expects($this->never()) |
|
| 90 | - ->method('newClient'); |
|
| 91 | - |
|
| 92 | - /** @var ISearchResult|MockObject $searchResult */ |
|
| 93 | - $searchResult = $this->createMock(ISearchResult::class); |
|
| 94 | - |
|
| 95 | - $this->plugin->search('foobar', 10, 0, $searchResult); |
|
| 96 | - } |
|
| 97 | - |
|
| 98 | - public function testSearchNoInternet(): void { |
|
| 99 | - $this->config->expects($this->once()) |
|
| 100 | - ->method('getAppValue') |
|
| 101 | - ->with('files_sharing', 'lookupServerEnabled', 'no') |
|
| 102 | - ->willReturn('yes'); |
|
| 103 | - $this->config->expects($this->exactly(2)) |
|
| 104 | - ->method('getSystemValueBool') |
|
| 105 | - ->willReturnMap([ |
|
| 106 | - ['gs.enabled', false, false], |
|
| 107 | - ['has_internet_connection', true, false], |
|
| 108 | - ]); |
|
| 109 | - |
|
| 110 | - $this->clientService->expects($this->never()) |
|
| 111 | - ->method('newClient'); |
|
| 112 | - |
|
| 113 | - /** @var ISearchResult|MockObject $searchResult */ |
|
| 114 | - $searchResult = $this->createMock(ISearchResult::class); |
|
| 115 | - |
|
| 116 | - $this->plugin->search('foobar', 10, 0, $searchResult); |
|
| 117 | - } |
|
| 118 | - |
|
| 119 | - /** |
|
| 120 | - * @dataProvider searchDataProvider |
|
| 121 | - * @param array $searchParams |
|
| 122 | - */ |
|
| 123 | - public function testSearch(array $searchParams): void { |
|
| 124 | - $type = new SearchResultType('lookup'); |
|
| 125 | - |
|
| 126 | - /** @var ISearchResult|MockObject $searchResult */ |
|
| 127 | - $searchResult = $this->createMock(ISearchResult::class); |
|
| 128 | - $searchResult->expects($this->once()) |
|
| 129 | - ->method('addResultSet') |
|
| 130 | - ->with($type, $searchParams['expectedResult'], []); |
|
| 131 | - |
|
| 132 | - $this->config->expects($this->once()) |
|
| 133 | - ->method('getAppValue') |
|
| 134 | - ->with('files_sharing', 'lookupServerEnabled', 'no') |
|
| 135 | - ->willReturn('yes'); |
|
| 136 | - $this->config->expects($this->exactly(2)) |
|
| 137 | - ->method('getSystemValueBool') |
|
| 138 | - ->willReturnMap([ |
|
| 139 | - ['gs.enabled', false, true], |
|
| 140 | - ['has_internet_connection', true, true], |
|
| 141 | - ]); |
|
| 142 | - |
|
| 143 | - $this->config->expects($this->once()) |
|
| 144 | - ->method('getSystemValueString') |
|
| 145 | - ->with('lookup_server', 'https://lookup.nextcloud.com') |
|
| 146 | - ->willReturn($searchParams['server']); |
|
| 147 | - |
|
| 148 | - $response = $this->createMock(IResponse::class); |
|
| 149 | - $response->expects($this->once()) |
|
| 150 | - ->method('getBody') |
|
| 151 | - ->willReturn(json_encode($searchParams['resultBody'])); |
|
| 152 | - |
|
| 153 | - $client = $this->createMock(IClient::class); |
|
| 154 | - $client->expects($this->once()) |
|
| 155 | - ->method('get') |
|
| 156 | - ->willReturnCallback(function ($url) use ($searchParams, $response) { |
|
| 157 | - $this->assertSame(strpos($url, $searchParams['server'] . '/users?search='), 0); |
|
| 158 | - $this->assertNotFalse(strpos($url, urlencode($searchParams['search']))); |
|
| 159 | - return $response; |
|
| 160 | - }); |
|
| 161 | - |
|
| 162 | - $this->clientService->expects($this->once()) |
|
| 163 | - ->method('newClient') |
|
| 164 | - ->willReturn($client); |
|
| 165 | - |
|
| 166 | - $moreResults = $this->plugin->search( |
|
| 167 | - $searchParams['search'], |
|
| 168 | - $searchParams['limit'], |
|
| 169 | - $searchParams['offset'], |
|
| 170 | - $searchResult |
|
| 171 | - ); |
|
| 172 | - |
|
| 173 | - $this->assertFalse($moreResults); |
|
| 174 | - } |
|
| 175 | - |
|
| 176 | - |
|
| 177 | - /** |
|
| 178 | - * @dataProvider dataSearchEnableDisableLookupServer |
|
| 179 | - * @param array $searchParams |
|
| 180 | - * @param bool $GSEnabled |
|
| 181 | - * @param bool $LookupEnabled |
|
| 182 | - */ |
|
| 183 | - public function testSearchEnableDisableLookupServer(array $searchParams, $GSEnabled, $LookupEnabled): void { |
|
| 184 | - $type = new SearchResultType('lookup'); |
|
| 185 | - |
|
| 186 | - /** @var ISearchResult|MockObject $searchResult */ |
|
| 187 | - $searchResult = $this->createMock(ISearchResult::class); |
|
| 188 | - |
|
| 189 | - $this->config->expects($this->once()) |
|
| 190 | - ->method('getAppValue') |
|
| 191 | - ->with('files_sharing', 'lookupServerEnabled', 'no') |
|
| 192 | - ->willReturn($LookupEnabled ? 'yes' : 'no'); |
|
| 193 | - if ($GSEnabled) { |
|
| 194 | - $searchResult->expects($this->once()) |
|
| 195 | - ->method('addResultSet') |
|
| 196 | - ->with($type, $searchParams['expectedResult'], []); |
|
| 197 | - |
|
| 198 | - $this->config->expects($this->exactly(2)) |
|
| 199 | - ->method('getSystemValueBool') |
|
| 200 | - ->willReturnMap([ |
|
| 201 | - ['gs.enabled', false, $GSEnabled], |
|
| 202 | - ['has_internet_connection', true, true], |
|
| 203 | - ]); |
|
| 204 | - $this->config->expects($this->once()) |
|
| 205 | - ->method('getSystemValueString') |
|
| 206 | - ->with('lookup_server', 'https://lookup.nextcloud.com') |
|
| 207 | - ->willReturn($searchParams['server']); |
|
| 208 | - |
|
| 209 | - $response = $this->createMock(IResponse::class); |
|
| 210 | - $response->expects($this->once()) |
|
| 211 | - ->method('getBody') |
|
| 212 | - ->willReturn(json_encode($searchParams['resultBody'])); |
|
| 213 | - |
|
| 214 | - $client = $this->createMock(IClient::class); |
|
| 215 | - $client->expects($this->once()) |
|
| 216 | - ->method('get') |
|
| 217 | - ->willReturnCallback(function ($url) use ($searchParams, $response) { |
|
| 218 | - $this->assertSame(strpos($url, $searchParams['server'] . '/users?search='), 0); |
|
| 219 | - $this->assertNotFalse(strpos($url, urlencode($searchParams['search']))); |
|
| 220 | - return $response; |
|
| 221 | - }); |
|
| 222 | - |
|
| 223 | - $this->clientService->expects($this->once()) |
|
| 224 | - ->method('newClient') |
|
| 225 | - ->willReturn($client); |
|
| 226 | - } else { |
|
| 227 | - $searchResult->expects($this->never())->method('addResultSet'); |
|
| 228 | - $this->config->expects($this->exactly(2)) |
|
| 229 | - ->method('getSystemValueBool') |
|
| 230 | - ->willReturnMap([ |
|
| 231 | - ['gs.enabled', false, $GSEnabled], |
|
| 232 | - ['has_internet_connection', true, true], |
|
| 233 | - ]); |
|
| 234 | - } |
|
| 235 | - $moreResults = $this->plugin->search( |
|
| 236 | - $searchParams['search'], |
|
| 237 | - $searchParams['limit'], |
|
| 238 | - $searchParams['offset'], |
|
| 239 | - $searchResult |
|
| 240 | - ); |
|
| 241 | - |
|
| 242 | - $this->assertFalse($moreResults); |
|
| 243 | - } |
|
| 244 | - |
|
| 245 | - |
|
| 246 | - public function testSearchGSDisabled(): void { |
|
| 247 | - $this->config->expects($this->atLeastOnce()) |
|
| 248 | - ->method('getSystemValueBool') |
|
| 249 | - ->willReturnMap([ |
|
| 250 | - ['has_internet_connection', true, true], |
|
| 251 | - ['gs.enabled', false, false], |
|
| 252 | - ]); |
|
| 253 | - |
|
| 254 | - /** @var ISearchResult|MockObject $searchResult */ |
|
| 255 | - $searchResult = $this->createMock(ISearchResult::class); |
|
| 256 | - $searchResult->expects($this->never()) |
|
| 257 | - ->method('addResultSet'); |
|
| 258 | - $searchResult->expects($this->never()) |
|
| 259 | - ->method('markExactIdMatch'); |
|
| 260 | - |
|
| 261 | - $this->assertFalse($this->plugin->search('irr', 10, 0, $searchResult)); |
|
| 262 | - } |
|
| 263 | - |
|
| 264 | - public static function dataSearchEnableDisableLookupServer(): array { |
|
| 265 | - $fedIDs = [ |
|
| 266 | - '[email protected]', |
|
| 267 | - '[email protected]', |
|
| 268 | - '[email protected]', |
|
| 269 | - ]; |
|
| 270 | - |
|
| 271 | - return [ |
|
| 272 | - [[ |
|
| 273 | - 'search' => 'foo', |
|
| 274 | - 'limit' => 10, |
|
| 275 | - 'offset' => 0, |
|
| 276 | - 'server' => 'https://lookup.example.io', |
|
| 277 | - 'resultBody' => [ |
|
| 278 | - ['federationId' => $fedIDs[0]], |
|
| 279 | - ['federationId' => $fedIDs[1]], |
|
| 280 | - ['federationId' => $fedIDs[2]], |
|
| 281 | - ], |
|
| 282 | - 'expectedResult' => [ |
|
| 283 | - [ |
|
| 284 | - 'label' => $fedIDs[0], |
|
| 285 | - 'value' => [ |
|
| 286 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 287 | - 'globalScale' => true, |
|
| 288 | - 'shareWith' => $fedIDs[0] |
|
| 289 | - ], |
|
| 290 | - 'extra' => ['federationId' => $fedIDs[0]], |
|
| 291 | - ], |
|
| 292 | - [ |
|
| 293 | - 'label' => $fedIDs[1], |
|
| 294 | - 'value' => [ |
|
| 295 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 296 | - 'globalScale' => true, |
|
| 297 | - 'shareWith' => $fedIDs[1] |
|
| 298 | - ], |
|
| 299 | - 'extra' => ['federationId' => $fedIDs[1]], |
|
| 300 | - ], |
|
| 301 | - [ |
|
| 302 | - 'label' => $fedIDs[2], |
|
| 303 | - 'value' => [ |
|
| 304 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 305 | - 'globalScale' => true, |
|
| 306 | - 'shareWith' => $fedIDs[2] |
|
| 307 | - ], |
|
| 308 | - 'extra' => ['federationId' => $fedIDs[2]], |
|
| 309 | - ], |
|
| 310 | - ] |
|
| 311 | - ],// GS , Lookup |
|
| 312 | - true, true |
|
| 313 | - ], |
|
| 314 | - [[ |
|
| 315 | - 'search' => 'foo', |
|
| 316 | - 'limit' => 10, |
|
| 317 | - 'offset' => 0, |
|
| 318 | - 'server' => 'https://lookup.example.io', |
|
| 319 | - 'resultBody' => [ |
|
| 320 | - ['federationId' => $fedIDs[0]], |
|
| 321 | - ['federationId' => $fedIDs[1]], |
|
| 322 | - ['federationId' => $fedIDs[2]], |
|
| 323 | - ], |
|
| 324 | - 'expectedResult' => [ |
|
| 325 | - [ |
|
| 326 | - 'label' => $fedIDs[0], |
|
| 327 | - 'value' => [ |
|
| 328 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 329 | - 'globalScale' => true, |
|
| 330 | - 'shareWith' => $fedIDs[0] |
|
| 331 | - ], |
|
| 332 | - 'extra' => ['federationId' => $fedIDs[0]], |
|
| 333 | - ], |
|
| 334 | - [ |
|
| 335 | - 'label' => $fedIDs[1], |
|
| 336 | - 'value' => [ |
|
| 337 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 338 | - 'globalScale' => true, |
|
| 339 | - 'shareWith' => $fedIDs[1] |
|
| 340 | - ], |
|
| 341 | - 'extra' => ['federationId' => $fedIDs[1]], |
|
| 342 | - ], |
|
| 343 | - [ |
|
| 344 | - 'label' => $fedIDs[2], |
|
| 345 | - 'value' => [ |
|
| 346 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 347 | - 'globalScale' => true, |
|
| 348 | - 'shareWith' => $fedIDs[2] |
|
| 349 | - ], |
|
| 350 | - 'extra' => ['federationId' => $fedIDs[2]], |
|
| 351 | - ], |
|
| 352 | - ] |
|
| 353 | - ],// GS , Lookup |
|
| 354 | - true, false |
|
| 355 | - ], |
|
| 356 | - [[ |
|
| 357 | - 'search' => 'foo', |
|
| 358 | - 'limit' => 10, |
|
| 359 | - 'offset' => 0, |
|
| 360 | - 'server' => 'https://lookup.example.io', |
|
| 361 | - 'resultBody' => [ |
|
| 362 | - ['federationId' => $fedIDs[0]], |
|
| 363 | - ['federationId' => $fedIDs[1]], |
|
| 364 | - ['federationId' => $fedIDs[2]], |
|
| 365 | - ], |
|
| 366 | - 'expectedResult' => [ |
|
| 367 | - [ |
|
| 368 | - 'label' => $fedIDs[0], |
|
| 369 | - 'value' => [ |
|
| 370 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 371 | - 'shareWith' => $fedIDs[0] |
|
| 372 | - ], |
|
| 373 | - 'extra' => ['federationId' => $fedIDs[0]], |
|
| 374 | - ], |
|
| 375 | - [ |
|
| 376 | - 'label' => $fedIDs[1], |
|
| 377 | - 'value' => [ |
|
| 378 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 379 | - 'shareWith' => $fedIDs[1] |
|
| 380 | - ], |
|
| 381 | - 'extra' => ['federationId' => $fedIDs[1]], |
|
| 382 | - ], |
|
| 383 | - [ |
|
| 384 | - 'label' => $fedIDs[2], |
|
| 385 | - 'value' => [ |
|
| 386 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 387 | - 'shareWith' => $fedIDs[2] |
|
| 388 | - ], |
|
| 389 | - 'extra' => ['federationId' => $fedIDs[2]], |
|
| 390 | - ], |
|
| 391 | - ] |
|
| 392 | - ],// GS , Lookup |
|
| 393 | - false, true |
|
| 394 | - ], |
|
| 395 | - [[ |
|
| 396 | - 'search' => 'foo', |
|
| 397 | - 'limit' => 10, |
|
| 398 | - 'offset' => 0, |
|
| 399 | - 'server' => 'https://lookup.example.io', |
|
| 400 | - 'resultBody' => [ |
|
| 401 | - ['federationId' => $fedIDs[0]], |
|
| 402 | - ['federationId' => $fedIDs[1]], |
|
| 403 | - ['federationId' => $fedIDs[2]], |
|
| 404 | - ], |
|
| 405 | - 'expectedResult' => [ |
|
| 406 | - [ |
|
| 407 | - 'label' => $fedIDs[0], |
|
| 408 | - 'value' => [ |
|
| 409 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 410 | - 'shareWith' => $fedIDs[0] |
|
| 411 | - ], |
|
| 412 | - 'extra' => ['federationId' => $fedIDs[0]], |
|
| 413 | - ], |
|
| 414 | - [ |
|
| 415 | - 'label' => $fedIDs[1], |
|
| 416 | - 'value' => [ |
|
| 417 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 418 | - 'shareWith' => $fedIDs[1] |
|
| 419 | - ], |
|
| 420 | - 'extra' => ['federationId' => $fedIDs[1]], |
|
| 421 | - ], |
|
| 422 | - [ |
|
| 423 | - 'label' => $fedIDs[2], |
|
| 424 | - 'value' => [ |
|
| 425 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 426 | - 'shareWith' => $fedIDs[2] |
|
| 427 | - ], |
|
| 428 | - 'extra' => ['federationId' => $fedIDs[2]], |
|
| 429 | - ], |
|
| 430 | - ] |
|
| 431 | - ],// GS , Lookup |
|
| 432 | - false, false |
|
| 433 | - ], |
|
| 434 | - ]; |
|
| 435 | - } |
|
| 436 | - |
|
| 437 | - public static function searchDataProvider(): array { |
|
| 438 | - $fedIDs = [ |
|
| 439 | - '[email protected]', |
|
| 440 | - '[email protected]', |
|
| 441 | - '[email protected]', |
|
| 442 | - ]; |
|
| 443 | - |
|
| 444 | - return [ |
|
| 445 | - // #0, standard search with results |
|
| 446 | - [[ |
|
| 447 | - 'search' => 'foo', |
|
| 448 | - 'limit' => 10, |
|
| 449 | - 'offset' => 0, |
|
| 450 | - 'server' => 'https://lookup.example.io', |
|
| 451 | - 'resultBody' => [ |
|
| 452 | - ['federationId' => $fedIDs[0]], |
|
| 453 | - ['federationId' => $fedIDs[1]], |
|
| 454 | - ['federationId' => $fedIDs[2]], |
|
| 455 | - ], |
|
| 456 | - 'expectedResult' => [ |
|
| 457 | - [ |
|
| 458 | - 'label' => $fedIDs[0], |
|
| 459 | - 'value' => [ |
|
| 460 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 461 | - 'globalScale' => true, |
|
| 462 | - 'shareWith' => $fedIDs[0] |
|
| 463 | - ], |
|
| 464 | - 'extra' => ['federationId' => $fedIDs[0]], |
|
| 465 | - ], |
|
| 466 | - [ |
|
| 467 | - 'label' => $fedIDs[1], |
|
| 468 | - 'value' => [ |
|
| 469 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 470 | - 'globalScale' => true, |
|
| 471 | - 'shareWith' => $fedIDs[1] |
|
| 472 | - ], |
|
| 473 | - 'extra' => ['federationId' => $fedIDs[1]], |
|
| 474 | - ], |
|
| 475 | - [ |
|
| 476 | - 'label' => $fedIDs[2], |
|
| 477 | - 'value' => [ |
|
| 478 | - 'shareType' => IShare::TYPE_REMOTE, |
|
| 479 | - 'globalScale' => true, |
|
| 480 | - 'shareWith' => $fedIDs[2] |
|
| 481 | - ], |
|
| 482 | - 'extra' => ['federationId' => $fedIDs[2]], |
|
| 483 | - ], |
|
| 484 | - ] |
|
| 485 | - ]], |
|
| 486 | - // #1, search without results |
|
| 487 | - [[ |
|
| 488 | - 'search' => 'foo', |
|
| 489 | - 'limit' => 10, |
|
| 490 | - 'offset' => 0, |
|
| 491 | - 'server' => 'https://lookup.example.io', |
|
| 492 | - 'resultBody' => [], |
|
| 493 | - 'expectedResult' => [], |
|
| 494 | - ]], |
|
| 495 | - ]; |
|
| 496 | - } |
|
| 27 | + /** @var IConfig|MockObject */ |
|
| 28 | + protected $config; |
|
| 29 | + /** @var IClientService|MockObject */ |
|
| 30 | + protected $clientService; |
|
| 31 | + /** @var IUserSession|MockObject */ |
|
| 32 | + protected $userSession; |
|
| 33 | + /** @var ICloudIdManager|MockObject */ |
|
| 34 | + protected $cloudIdManager; |
|
| 35 | + /** @var LookupPlugin */ |
|
| 36 | + protected $plugin; |
|
| 37 | + /** @var LoggerInterface|MockObject */ |
|
| 38 | + protected $logger; |
|
| 39 | + |
|
| 40 | + protected function setUp(): void { |
|
| 41 | + parent::setUp(); |
|
| 42 | + |
|
| 43 | + $this->userSession = $this->createMock(IUserSession::class); |
|
| 44 | + $this->cloudIdManager = $this->createMock(ICloudIdManager::class); |
|
| 45 | + $this->config = $this->createMock(IConfig::class); |
|
| 46 | + $this->logger = $this->createMock(LoggerInterface::class); |
|
| 47 | + $this->clientService = $this->createMock(IClientService::class); |
|
| 48 | + $cloudId = $this->createMock(ICloudId::class); |
|
| 49 | + $cloudId->expects($this->any())->method('getRemote')->willReturn('myNextcloud.net'); |
|
| 50 | + $user = $this->createMock(IUser::class); |
|
| 51 | + $user->expects($this->any())->method('getCloudId')->willReturn('[email protected]'); |
|
| 52 | + $this->userSession->expects($this->any())->method('getUser') |
|
| 53 | + ->willReturn($user); |
|
| 54 | + $this->cloudIdManager->expects($this->any())->method('resolveCloudId') |
|
| 55 | + ->willReturnCallback(function ($cloudId) { |
|
| 56 | + if ($cloudId === '[email protected]') { |
|
| 57 | + return new CloudId('[email protected]', 'user', 'myNextcloud.net'); |
|
| 58 | + } |
|
| 59 | + return new CloudId('[email protected]', 'user', 'someNextcloud.net'); |
|
| 60 | + }); |
|
| 61 | + |
|
| 62 | + |
|
| 63 | + $this->plugin = new LookupPlugin( |
|
| 64 | + $this->config, |
|
| 65 | + $this->clientService, |
|
| 66 | + $this->userSession, |
|
| 67 | + $this->cloudIdManager, |
|
| 68 | + $this->logger |
|
| 69 | + ); |
|
| 70 | + } |
|
| 71 | + |
|
| 72 | + public function testSearchNoLookupServerURI(): void { |
|
| 73 | + $this->config->expects($this->once()) |
|
| 74 | + ->method('getAppValue') |
|
| 75 | + ->with('files_sharing', 'lookupServerEnabled', 'no') |
|
| 76 | + ->willReturn('yes'); |
|
| 77 | + $this->config->expects($this->exactly(2)) |
|
| 78 | + ->method('getSystemValueBool') |
|
| 79 | + ->willReturnMap([ |
|
| 80 | + ['gs.enabled', false, true], |
|
| 81 | + ['has_internet_connection', true, true], |
|
| 82 | + ]); |
|
| 83 | + |
|
| 84 | + $this->config->expects($this->once()) |
|
| 85 | + ->method('getSystemValueString') |
|
| 86 | + ->with('lookup_server', 'https://lookup.nextcloud.com') |
|
| 87 | + ->willReturn(''); |
|
| 88 | + |
|
| 89 | + $this->clientService->expects($this->never()) |
|
| 90 | + ->method('newClient'); |
|
| 91 | + |
|
| 92 | + /** @var ISearchResult|MockObject $searchResult */ |
|
| 93 | + $searchResult = $this->createMock(ISearchResult::class); |
|
| 94 | + |
|
| 95 | + $this->plugin->search('foobar', 10, 0, $searchResult); |
|
| 96 | + } |
|
| 97 | + |
|
| 98 | + public function testSearchNoInternet(): void { |
|
| 99 | + $this->config->expects($this->once()) |
|
| 100 | + ->method('getAppValue') |
|
| 101 | + ->with('files_sharing', 'lookupServerEnabled', 'no') |
|
| 102 | + ->willReturn('yes'); |
|
| 103 | + $this->config->expects($this->exactly(2)) |
|
| 104 | + ->method('getSystemValueBool') |
|
| 105 | + ->willReturnMap([ |
|
| 106 | + ['gs.enabled', false, false], |
|
| 107 | + ['has_internet_connection', true, false], |
|
| 108 | + ]); |
|
| 109 | + |
|
| 110 | + $this->clientService->expects($this->never()) |
|
| 111 | + ->method('newClient'); |
|
| 112 | + |
|
| 113 | + /** @var ISearchResult|MockObject $searchResult */ |
|
| 114 | + $searchResult = $this->createMock(ISearchResult::class); |
|
| 115 | + |
|
| 116 | + $this->plugin->search('foobar', 10, 0, $searchResult); |
|
| 117 | + } |
|
| 118 | + |
|
| 119 | + /** |
|
| 120 | + * @dataProvider searchDataProvider |
|
| 121 | + * @param array $searchParams |
|
| 122 | + */ |
|
| 123 | + public function testSearch(array $searchParams): void { |
|
| 124 | + $type = new SearchResultType('lookup'); |
|
| 125 | + |
|
| 126 | + /** @var ISearchResult|MockObject $searchResult */ |
|
| 127 | + $searchResult = $this->createMock(ISearchResult::class); |
|
| 128 | + $searchResult->expects($this->once()) |
|
| 129 | + ->method('addResultSet') |
|
| 130 | + ->with($type, $searchParams['expectedResult'], []); |
|
| 131 | + |
|
| 132 | + $this->config->expects($this->once()) |
|
| 133 | + ->method('getAppValue') |
|
| 134 | + ->with('files_sharing', 'lookupServerEnabled', 'no') |
|
| 135 | + ->willReturn('yes'); |
|
| 136 | + $this->config->expects($this->exactly(2)) |
|
| 137 | + ->method('getSystemValueBool') |
|
| 138 | + ->willReturnMap([ |
|
| 139 | + ['gs.enabled', false, true], |
|
| 140 | + ['has_internet_connection', true, true], |
|
| 141 | + ]); |
|
| 142 | + |
|
| 143 | + $this->config->expects($this->once()) |
|
| 144 | + ->method('getSystemValueString') |
|
| 145 | + ->with('lookup_server', 'https://lookup.nextcloud.com') |
|
| 146 | + ->willReturn($searchParams['server']); |
|
| 147 | + |
|
| 148 | + $response = $this->createMock(IResponse::class); |
|
| 149 | + $response->expects($this->once()) |
|
| 150 | + ->method('getBody') |
|
| 151 | + ->willReturn(json_encode($searchParams['resultBody'])); |
|
| 152 | + |
|
| 153 | + $client = $this->createMock(IClient::class); |
|
| 154 | + $client->expects($this->once()) |
|
| 155 | + ->method('get') |
|
| 156 | + ->willReturnCallback(function ($url) use ($searchParams, $response) { |
|
| 157 | + $this->assertSame(strpos($url, $searchParams['server'] . '/users?search='), 0); |
|
| 158 | + $this->assertNotFalse(strpos($url, urlencode($searchParams['search']))); |
|
| 159 | + return $response; |
|
| 160 | + }); |
|
| 161 | + |
|
| 162 | + $this->clientService->expects($this->once()) |
|
| 163 | + ->method('newClient') |
|
| 164 | + ->willReturn($client); |
|
| 165 | + |
|
| 166 | + $moreResults = $this->plugin->search( |
|
| 167 | + $searchParams['search'], |
|
| 168 | + $searchParams['limit'], |
|
| 169 | + $searchParams['offset'], |
|
| 170 | + $searchResult |
|
| 171 | + ); |
|
| 172 | + |
|
| 173 | + $this->assertFalse($moreResults); |
|
| 174 | + } |
|
| 175 | + |
|
| 176 | + |
|
| 177 | + /** |
|
| 178 | + * @dataProvider dataSearchEnableDisableLookupServer |
|
| 179 | + * @param array $searchParams |
|
| 180 | + * @param bool $GSEnabled |
|
| 181 | + * @param bool $LookupEnabled |
|
| 182 | + */ |
|
| 183 | + public function testSearchEnableDisableLookupServer(array $searchParams, $GSEnabled, $LookupEnabled): void { |
|
| 184 | + $type = new SearchResultType('lookup'); |
|
| 185 | + |
|
| 186 | + /** @var ISearchResult|MockObject $searchResult */ |
|
| 187 | + $searchResult = $this->createMock(ISearchResult::class); |
|
| 188 | + |
|
| 189 | + $this->config->expects($this->once()) |
|
| 190 | + ->method('getAppValue') |
|
| 191 | + ->with('files_sharing', 'lookupServerEnabled', 'no') |
|
| 192 | + ->willReturn($LookupEnabled ? 'yes' : 'no'); |
|
| 193 | + if ($GSEnabled) { |
|
| 194 | + $searchResult->expects($this->once()) |
|
| 195 | + ->method('addResultSet') |
|
| 196 | + ->with($type, $searchParams['expectedResult'], []); |
|
| 197 | + |
|
| 198 | + $this->config->expects($this->exactly(2)) |
|
| 199 | + ->method('getSystemValueBool') |
|
| 200 | + ->willReturnMap([ |
|
| 201 | + ['gs.enabled', false, $GSEnabled], |
|
| 202 | + ['has_internet_connection', true, true], |
|
| 203 | + ]); |
|
| 204 | + $this->config->expects($this->once()) |
|
| 205 | + ->method('getSystemValueString') |
|
| 206 | + ->with('lookup_server', 'https://lookup.nextcloud.com') |
|
| 207 | + ->willReturn($searchParams['server']); |
|
| 208 | + |
|
| 209 | + $response = $this->createMock(IResponse::class); |
|
| 210 | + $response->expects($this->once()) |
|
| 211 | + ->method('getBody') |
|
| 212 | + ->willReturn(json_encode($searchParams['resultBody'])); |
|
| 213 | + |
|
| 214 | + $client = $this->createMock(IClient::class); |
|
| 215 | + $client->expects($this->once()) |
|
| 216 | + ->method('get') |
|
| 217 | + ->willReturnCallback(function ($url) use ($searchParams, $response) { |
|
| 218 | + $this->assertSame(strpos($url, $searchParams['server'] . '/users?search='), 0); |
|
| 219 | + $this->assertNotFalse(strpos($url, urlencode($searchParams['search']))); |
|
| 220 | + return $response; |
|
| 221 | + }); |
|
| 222 | + |
|
| 223 | + $this->clientService->expects($this->once()) |
|
| 224 | + ->method('newClient') |
|
| 225 | + ->willReturn($client); |
|
| 226 | + } else { |
|
| 227 | + $searchResult->expects($this->never())->method('addResultSet'); |
|
| 228 | + $this->config->expects($this->exactly(2)) |
|
| 229 | + ->method('getSystemValueBool') |
|
| 230 | + ->willReturnMap([ |
|
| 231 | + ['gs.enabled', false, $GSEnabled], |
|
| 232 | + ['has_internet_connection', true, true], |
|
| 233 | + ]); |
|
| 234 | + } |
|
| 235 | + $moreResults = $this->plugin->search( |
|
| 236 | + $searchParams['search'], |
|
| 237 | + $searchParams['limit'], |
|
| 238 | + $searchParams['offset'], |
|
| 239 | + $searchResult |
|
| 240 | + ); |
|
| 241 | + |
|
| 242 | + $this->assertFalse($moreResults); |
|
| 243 | + } |
|
| 244 | + |
|
| 245 | + |
|
| 246 | + public function testSearchGSDisabled(): void { |
|
| 247 | + $this->config->expects($this->atLeastOnce()) |
|
| 248 | + ->method('getSystemValueBool') |
|
| 249 | + ->willReturnMap([ |
|
| 250 | + ['has_internet_connection', true, true], |
|
| 251 | + ['gs.enabled', false, false], |
|
| 252 | + ]); |
|
| 253 | + |
|
| 254 | + /** @var ISearchResult|MockObject $searchResult */ |
|
| 255 | + $searchResult = $this->createMock(ISearchResult::class); |
|
| 256 | + $searchResult->expects($this->never()) |
|
| 257 | + ->method('addResultSet'); |
|
| 258 | + $searchResult->expects($this->never()) |
|
| 259 | + ->method('markExactIdMatch'); |
|
| 260 | + |
|
| 261 | + $this->assertFalse($this->plugin->search('irr', 10, 0, $searchResult)); |
|
| 262 | + } |
|
| 263 | + |
|
| 264 | + public static function dataSearchEnableDisableLookupServer(): array { |
|
| 265 | + $fedIDs = [ |
|
| 266 | + '[email protected]', |
|
| 267 | + '[email protected]', |
|
| 268 | + '[email protected]', |
|
| 269 | + ]; |
|
| 270 | + |
|
| 271 | + return [ |
|
| 272 | + [[ |
|
| 273 | + 'search' => 'foo', |
|
| 274 | + 'limit' => 10, |
|
| 275 | + 'offset' => 0, |
|
| 276 | + 'server' => 'https://lookup.example.io', |
|
| 277 | + 'resultBody' => [ |
|
| 278 | + ['federationId' => $fedIDs[0]], |
|
| 279 | + ['federationId' => $fedIDs[1]], |
|
| 280 | + ['federationId' => $fedIDs[2]], |
|
| 281 | + ], |
|
| 282 | + 'expectedResult' => [ |
|
| 283 | + [ |
|
| 284 | + 'label' => $fedIDs[0], |
|
| 285 | + 'value' => [ |
|
| 286 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 287 | + 'globalScale' => true, |
|
| 288 | + 'shareWith' => $fedIDs[0] |
|
| 289 | + ], |
|
| 290 | + 'extra' => ['federationId' => $fedIDs[0]], |
|
| 291 | + ], |
|
| 292 | + [ |
|
| 293 | + 'label' => $fedIDs[1], |
|
| 294 | + 'value' => [ |
|
| 295 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 296 | + 'globalScale' => true, |
|
| 297 | + 'shareWith' => $fedIDs[1] |
|
| 298 | + ], |
|
| 299 | + 'extra' => ['federationId' => $fedIDs[1]], |
|
| 300 | + ], |
|
| 301 | + [ |
|
| 302 | + 'label' => $fedIDs[2], |
|
| 303 | + 'value' => [ |
|
| 304 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 305 | + 'globalScale' => true, |
|
| 306 | + 'shareWith' => $fedIDs[2] |
|
| 307 | + ], |
|
| 308 | + 'extra' => ['federationId' => $fedIDs[2]], |
|
| 309 | + ], |
|
| 310 | + ] |
|
| 311 | + ],// GS , Lookup |
|
| 312 | + true, true |
|
| 313 | + ], |
|
| 314 | + [[ |
|
| 315 | + 'search' => 'foo', |
|
| 316 | + 'limit' => 10, |
|
| 317 | + 'offset' => 0, |
|
| 318 | + 'server' => 'https://lookup.example.io', |
|
| 319 | + 'resultBody' => [ |
|
| 320 | + ['federationId' => $fedIDs[0]], |
|
| 321 | + ['federationId' => $fedIDs[1]], |
|
| 322 | + ['federationId' => $fedIDs[2]], |
|
| 323 | + ], |
|
| 324 | + 'expectedResult' => [ |
|
| 325 | + [ |
|
| 326 | + 'label' => $fedIDs[0], |
|
| 327 | + 'value' => [ |
|
| 328 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 329 | + 'globalScale' => true, |
|
| 330 | + 'shareWith' => $fedIDs[0] |
|
| 331 | + ], |
|
| 332 | + 'extra' => ['federationId' => $fedIDs[0]], |
|
| 333 | + ], |
|
| 334 | + [ |
|
| 335 | + 'label' => $fedIDs[1], |
|
| 336 | + 'value' => [ |
|
| 337 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 338 | + 'globalScale' => true, |
|
| 339 | + 'shareWith' => $fedIDs[1] |
|
| 340 | + ], |
|
| 341 | + 'extra' => ['federationId' => $fedIDs[1]], |
|
| 342 | + ], |
|
| 343 | + [ |
|
| 344 | + 'label' => $fedIDs[2], |
|
| 345 | + 'value' => [ |
|
| 346 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 347 | + 'globalScale' => true, |
|
| 348 | + 'shareWith' => $fedIDs[2] |
|
| 349 | + ], |
|
| 350 | + 'extra' => ['federationId' => $fedIDs[2]], |
|
| 351 | + ], |
|
| 352 | + ] |
|
| 353 | + ],// GS , Lookup |
|
| 354 | + true, false |
|
| 355 | + ], |
|
| 356 | + [[ |
|
| 357 | + 'search' => 'foo', |
|
| 358 | + 'limit' => 10, |
|
| 359 | + 'offset' => 0, |
|
| 360 | + 'server' => 'https://lookup.example.io', |
|
| 361 | + 'resultBody' => [ |
|
| 362 | + ['federationId' => $fedIDs[0]], |
|
| 363 | + ['federationId' => $fedIDs[1]], |
|
| 364 | + ['federationId' => $fedIDs[2]], |
|
| 365 | + ], |
|
| 366 | + 'expectedResult' => [ |
|
| 367 | + [ |
|
| 368 | + 'label' => $fedIDs[0], |
|
| 369 | + 'value' => [ |
|
| 370 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 371 | + 'shareWith' => $fedIDs[0] |
|
| 372 | + ], |
|
| 373 | + 'extra' => ['federationId' => $fedIDs[0]], |
|
| 374 | + ], |
|
| 375 | + [ |
|
| 376 | + 'label' => $fedIDs[1], |
|
| 377 | + 'value' => [ |
|
| 378 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 379 | + 'shareWith' => $fedIDs[1] |
|
| 380 | + ], |
|
| 381 | + 'extra' => ['federationId' => $fedIDs[1]], |
|
| 382 | + ], |
|
| 383 | + [ |
|
| 384 | + 'label' => $fedIDs[2], |
|
| 385 | + 'value' => [ |
|
| 386 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 387 | + 'shareWith' => $fedIDs[2] |
|
| 388 | + ], |
|
| 389 | + 'extra' => ['federationId' => $fedIDs[2]], |
|
| 390 | + ], |
|
| 391 | + ] |
|
| 392 | + ],// GS , Lookup |
|
| 393 | + false, true |
|
| 394 | + ], |
|
| 395 | + [[ |
|
| 396 | + 'search' => 'foo', |
|
| 397 | + 'limit' => 10, |
|
| 398 | + 'offset' => 0, |
|
| 399 | + 'server' => 'https://lookup.example.io', |
|
| 400 | + 'resultBody' => [ |
|
| 401 | + ['federationId' => $fedIDs[0]], |
|
| 402 | + ['federationId' => $fedIDs[1]], |
|
| 403 | + ['federationId' => $fedIDs[2]], |
|
| 404 | + ], |
|
| 405 | + 'expectedResult' => [ |
|
| 406 | + [ |
|
| 407 | + 'label' => $fedIDs[0], |
|
| 408 | + 'value' => [ |
|
| 409 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 410 | + 'shareWith' => $fedIDs[0] |
|
| 411 | + ], |
|
| 412 | + 'extra' => ['federationId' => $fedIDs[0]], |
|
| 413 | + ], |
|
| 414 | + [ |
|
| 415 | + 'label' => $fedIDs[1], |
|
| 416 | + 'value' => [ |
|
| 417 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 418 | + 'shareWith' => $fedIDs[1] |
|
| 419 | + ], |
|
| 420 | + 'extra' => ['federationId' => $fedIDs[1]], |
|
| 421 | + ], |
|
| 422 | + [ |
|
| 423 | + 'label' => $fedIDs[2], |
|
| 424 | + 'value' => [ |
|
| 425 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 426 | + 'shareWith' => $fedIDs[2] |
|
| 427 | + ], |
|
| 428 | + 'extra' => ['federationId' => $fedIDs[2]], |
|
| 429 | + ], |
|
| 430 | + ] |
|
| 431 | + ],// GS , Lookup |
|
| 432 | + false, false |
|
| 433 | + ], |
|
| 434 | + ]; |
|
| 435 | + } |
|
| 436 | + |
|
| 437 | + public static function searchDataProvider(): array { |
|
| 438 | + $fedIDs = [ |
|
| 439 | + '[email protected]', |
|
| 440 | + '[email protected]', |
|
| 441 | + '[email protected]', |
|
| 442 | + ]; |
|
| 443 | + |
|
| 444 | + return [ |
|
| 445 | + // #0, standard search with results |
|
| 446 | + [[ |
|
| 447 | + 'search' => 'foo', |
|
| 448 | + 'limit' => 10, |
|
| 449 | + 'offset' => 0, |
|
| 450 | + 'server' => 'https://lookup.example.io', |
|
| 451 | + 'resultBody' => [ |
|
| 452 | + ['federationId' => $fedIDs[0]], |
|
| 453 | + ['federationId' => $fedIDs[1]], |
|
| 454 | + ['federationId' => $fedIDs[2]], |
|
| 455 | + ], |
|
| 456 | + 'expectedResult' => [ |
|
| 457 | + [ |
|
| 458 | + 'label' => $fedIDs[0], |
|
| 459 | + 'value' => [ |
|
| 460 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 461 | + 'globalScale' => true, |
|
| 462 | + 'shareWith' => $fedIDs[0] |
|
| 463 | + ], |
|
| 464 | + 'extra' => ['federationId' => $fedIDs[0]], |
|
| 465 | + ], |
|
| 466 | + [ |
|
| 467 | + 'label' => $fedIDs[1], |
|
| 468 | + 'value' => [ |
|
| 469 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 470 | + 'globalScale' => true, |
|
| 471 | + 'shareWith' => $fedIDs[1] |
|
| 472 | + ], |
|
| 473 | + 'extra' => ['federationId' => $fedIDs[1]], |
|
| 474 | + ], |
|
| 475 | + [ |
|
| 476 | + 'label' => $fedIDs[2], |
|
| 477 | + 'value' => [ |
|
| 478 | + 'shareType' => IShare::TYPE_REMOTE, |
|
| 479 | + 'globalScale' => true, |
|
| 480 | + 'shareWith' => $fedIDs[2] |
|
| 481 | + ], |
|
| 482 | + 'extra' => ['federationId' => $fedIDs[2]], |
|
| 483 | + ], |
|
| 484 | + ] |
|
| 485 | + ]], |
|
| 486 | + // #1, search without results |
|
| 487 | + [[ |
|
| 488 | + 'search' => 'foo', |
|
| 489 | + 'limit' => 10, |
|
| 490 | + 'offset' => 0, |
|
| 491 | + 'server' => 'https://lookup.example.io', |
|
| 492 | + 'resultBody' => [], |
|
| 493 | + 'expectedResult' => [], |
|
| 494 | + ]], |
|
| 495 | + ]; |
|
| 496 | + } |
|
| 497 | 497 | } |
@@ -12,346 +12,346 @@ |
||
| 12 | 12 | use Psr\Log\LoggerInterface; |
| 13 | 13 | |
| 14 | 14 | class DetectionTest extends \Test\TestCase { |
| 15 | - /** @var Detection */ |
|
| 16 | - private $detection; |
|
| 17 | - |
|
| 18 | - protected function setUp(): void { |
|
| 19 | - parent::setUp(); |
|
| 20 | - $this->detection = new Detection( |
|
| 21 | - \OC::$server->getURLGenerator(), |
|
| 22 | - \OC::$server->get(LoggerInterface::class), |
|
| 23 | - \OC::$SERVERROOT . '/config/', |
|
| 24 | - \OC::$SERVERROOT . '/resources/config/' |
|
| 25 | - ); |
|
| 26 | - } |
|
| 27 | - |
|
| 28 | - public static function dataDetectPath(): array { |
|
| 29 | - return [ |
|
| 30 | - ['foo.txt', 'text/plain'], |
|
| 31 | - ['foo.png', 'image/png'], |
|
| 32 | - ['foo.bar.png', 'image/png'], |
|
| 33 | - ['.hidden.png', 'image/png'], |
|
| 34 | - ['.hidden.foo.png', 'image/png'], |
|
| 35 | - ['.hidden/foo.png', 'image/png'], |
|
| 36 | - ['.hidden/.hidden.png', 'image/png'], |
|
| 37 | - ['test.jpg/foo.png', 'image/png'], |
|
| 38 | - ['.png', 'application/octet-stream'], |
|
| 39 | - ['..hidden', 'application/octet-stream'], |
|
| 40 | - ['foo', 'application/octet-stream'], |
|
| 41 | - ['', 'application/octet-stream'], |
|
| 42 | - ['foo.png.ocTransferId123456789.part', 'image/png'], |
|
| 43 | - ['foo.png.v1234567890', 'image/png'], |
|
| 44 | - ]; |
|
| 45 | - } |
|
| 46 | - |
|
| 47 | - /** |
|
| 48 | - * @dataProvider dataDetectPath |
|
| 49 | - * |
|
| 50 | - * @param string $path |
|
| 51 | - * @param string $expected |
|
| 52 | - */ |
|
| 53 | - public function testDetectPath(string $path, string $expected): void { |
|
| 54 | - $this->assertEquals($expected, $this->detection->detectPath($path)); |
|
| 55 | - } |
|
| 56 | - |
|
| 57 | - public static function dataDetectContent(): array { |
|
| 58 | - return [ |
|
| 59 | - ['/', 'httpd/unix-directory'], |
|
| 60 | - ['/data.tar.gz', 'application/gzip'], |
|
| 61 | - ['/data.zip', 'application/zip'], |
|
| 62 | - ['/testimage.mp3', 'audio/mpeg'], |
|
| 63 | - ['/testimage.png', 'image/png'], |
|
| 64 | - ]; |
|
| 65 | - } |
|
| 66 | - |
|
| 67 | - /** |
|
| 68 | - * @dataProvider dataDetectContent |
|
| 69 | - * |
|
| 70 | - * @param string $path |
|
| 71 | - * @param string $expected |
|
| 72 | - */ |
|
| 73 | - public function testDetectContent(string $path, string $expected): void { |
|
| 74 | - $this->assertEquals($expected, $this->detection->detectContent(\OC::$SERVERROOT . '/tests/data' . $path)); |
|
| 75 | - } |
|
| 76 | - |
|
| 77 | - public static function dataDetect(): array { |
|
| 78 | - return [ |
|
| 79 | - ['/', 'httpd/unix-directory'], |
|
| 80 | - ['/data.tar.gz', 'application/gzip'], |
|
| 81 | - ['/data.zip', 'application/zip'], |
|
| 82 | - ['/testimagelarge.svg', 'image/svg+xml'], |
|
| 83 | - ['/testimage.png', 'image/png'], |
|
| 84 | - ]; |
|
| 85 | - } |
|
| 86 | - |
|
| 87 | - /** |
|
| 88 | - * @dataProvider dataDetect |
|
| 89 | - * |
|
| 90 | - * @param string $path |
|
| 91 | - * @param string $expected |
|
| 92 | - */ |
|
| 93 | - public function testDetect(string $path, string $expected): void { |
|
| 94 | - $this->assertEquals($expected, $this->detection->detect(\OC::$SERVERROOT . '/tests/data' . $path)); |
|
| 95 | - } |
|
| 96 | - |
|
| 97 | - public function testDetectString(): void { |
|
| 98 | - $result = $this->detection->detectString('/data/data.tar.gz'); |
|
| 99 | - $expected = 'text/plain'; |
|
| 100 | - $this->assertEquals($expected, $result); |
|
| 101 | - } |
|
| 102 | - |
|
| 103 | - public static function dataMimeTypeCustom(): array { |
|
| 104 | - return [ |
|
| 105 | - ['123', 'foobar/123'], |
|
| 106 | - ['a123', 'foobar/123'], |
|
| 107 | - ['bar', 'foobar/bar'], |
|
| 108 | - ]; |
|
| 109 | - } |
|
| 110 | - |
|
| 111 | - /** |
|
| 112 | - * @dataProvider dataMimeTypeCustom |
|
| 113 | - * |
|
| 114 | - * @param string $ext |
|
| 115 | - * @param string $mime |
|
| 116 | - */ |
|
| 117 | - public function testDetectMimeTypeCustom(string $ext, string $mime): void { |
|
| 118 | - $confDir = sys_get_temp_dir(); |
|
| 119 | - file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([])); |
|
| 120 | - |
|
| 121 | - /** @var IURLGenerator $urlGenerator */ |
|
| 122 | - $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 123 | - ->disableOriginalConstructor() |
|
| 124 | - ->getMock(); |
|
| 125 | - |
|
| 126 | - /** @var LoggerInterface $logger */ |
|
| 127 | - $logger = $this->createMock(LoggerInterface::class); |
|
| 128 | - |
|
| 129 | - // Create new mapping file |
|
| 130 | - file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([$ext => [$mime]])); |
|
| 131 | - |
|
| 132 | - $detection = new Detection($urlGenerator, $logger, $confDir, $confDir); |
|
| 133 | - $mappings = $detection->getAllMappings(); |
|
| 134 | - $this->assertArrayHasKey($ext, $mappings); |
|
| 135 | - $this->assertEquals($mime, $detection->detectPath('foo.' . $ext)); |
|
| 136 | - } |
|
| 137 | - |
|
| 138 | - public static function dataGetSecureMimeType(): array { |
|
| 139 | - return [ |
|
| 140 | - ['image/svg+xml', 'text/plain'], |
|
| 141 | - ['image/png', 'image/png'], |
|
| 142 | - ]; |
|
| 143 | - } |
|
| 144 | - |
|
| 145 | - /** |
|
| 146 | - * @dataProvider dataGetSecureMimeType |
|
| 147 | - * |
|
| 148 | - * @param string $mimeType |
|
| 149 | - * @param string $expected |
|
| 150 | - */ |
|
| 151 | - public function testGetSecureMimeType(string $mimeType, string $expected): void { |
|
| 152 | - $this->assertEquals($expected, $this->detection->getSecureMimeType($mimeType)); |
|
| 153 | - } |
|
| 154 | - |
|
| 155 | - public function testMimeTypeIcon(): void { |
|
| 156 | - if (!class_exists('org\\bovigo\\vfs\\vfsStream')) { |
|
| 157 | - $this->markTestSkipped('Package vfsStream not installed'); |
|
| 158 | - } |
|
| 159 | - $confDir = \org\bovigo\vfs\vfsStream::setup(); |
|
| 160 | - $mimetypealiases_dist = \org\bovigo\vfs\vfsStream::newFile('mimetypealiases.dist.json')->at($confDir); |
|
| 161 | - |
|
| 162 | - //Empty alias file |
|
| 163 | - $mimetypealiases_dist->setContent(json_encode([], JSON_FORCE_OBJECT)); |
|
| 164 | - |
|
| 165 | - |
|
| 166 | - /* |
|
| 15 | + /** @var Detection */ |
|
| 16 | + private $detection; |
|
| 17 | + |
|
| 18 | + protected function setUp(): void { |
|
| 19 | + parent::setUp(); |
|
| 20 | + $this->detection = new Detection( |
|
| 21 | + \OC::$server->getURLGenerator(), |
|
| 22 | + \OC::$server->get(LoggerInterface::class), |
|
| 23 | + \OC::$SERVERROOT . '/config/', |
|
| 24 | + \OC::$SERVERROOT . '/resources/config/' |
|
| 25 | + ); |
|
| 26 | + } |
|
| 27 | + |
|
| 28 | + public static function dataDetectPath(): array { |
|
| 29 | + return [ |
|
| 30 | + ['foo.txt', 'text/plain'], |
|
| 31 | + ['foo.png', 'image/png'], |
|
| 32 | + ['foo.bar.png', 'image/png'], |
|
| 33 | + ['.hidden.png', 'image/png'], |
|
| 34 | + ['.hidden.foo.png', 'image/png'], |
|
| 35 | + ['.hidden/foo.png', 'image/png'], |
|
| 36 | + ['.hidden/.hidden.png', 'image/png'], |
|
| 37 | + ['test.jpg/foo.png', 'image/png'], |
|
| 38 | + ['.png', 'application/octet-stream'], |
|
| 39 | + ['..hidden', 'application/octet-stream'], |
|
| 40 | + ['foo', 'application/octet-stream'], |
|
| 41 | + ['', 'application/octet-stream'], |
|
| 42 | + ['foo.png.ocTransferId123456789.part', 'image/png'], |
|
| 43 | + ['foo.png.v1234567890', 'image/png'], |
|
| 44 | + ]; |
|
| 45 | + } |
|
| 46 | + |
|
| 47 | + /** |
|
| 48 | + * @dataProvider dataDetectPath |
|
| 49 | + * |
|
| 50 | + * @param string $path |
|
| 51 | + * @param string $expected |
|
| 52 | + */ |
|
| 53 | + public function testDetectPath(string $path, string $expected): void { |
|
| 54 | + $this->assertEquals($expected, $this->detection->detectPath($path)); |
|
| 55 | + } |
|
| 56 | + |
|
| 57 | + public static function dataDetectContent(): array { |
|
| 58 | + return [ |
|
| 59 | + ['/', 'httpd/unix-directory'], |
|
| 60 | + ['/data.tar.gz', 'application/gzip'], |
|
| 61 | + ['/data.zip', 'application/zip'], |
|
| 62 | + ['/testimage.mp3', 'audio/mpeg'], |
|
| 63 | + ['/testimage.png', 'image/png'], |
|
| 64 | + ]; |
|
| 65 | + } |
|
| 66 | + |
|
| 67 | + /** |
|
| 68 | + * @dataProvider dataDetectContent |
|
| 69 | + * |
|
| 70 | + * @param string $path |
|
| 71 | + * @param string $expected |
|
| 72 | + */ |
|
| 73 | + public function testDetectContent(string $path, string $expected): void { |
|
| 74 | + $this->assertEquals($expected, $this->detection->detectContent(\OC::$SERVERROOT . '/tests/data' . $path)); |
|
| 75 | + } |
|
| 76 | + |
|
| 77 | + public static function dataDetect(): array { |
|
| 78 | + return [ |
|
| 79 | + ['/', 'httpd/unix-directory'], |
|
| 80 | + ['/data.tar.gz', 'application/gzip'], |
|
| 81 | + ['/data.zip', 'application/zip'], |
|
| 82 | + ['/testimagelarge.svg', 'image/svg+xml'], |
|
| 83 | + ['/testimage.png', 'image/png'], |
|
| 84 | + ]; |
|
| 85 | + } |
|
| 86 | + |
|
| 87 | + /** |
|
| 88 | + * @dataProvider dataDetect |
|
| 89 | + * |
|
| 90 | + * @param string $path |
|
| 91 | + * @param string $expected |
|
| 92 | + */ |
|
| 93 | + public function testDetect(string $path, string $expected): void { |
|
| 94 | + $this->assertEquals($expected, $this->detection->detect(\OC::$SERVERROOT . '/tests/data' . $path)); |
|
| 95 | + } |
|
| 96 | + |
|
| 97 | + public function testDetectString(): void { |
|
| 98 | + $result = $this->detection->detectString('/data/data.tar.gz'); |
|
| 99 | + $expected = 'text/plain'; |
|
| 100 | + $this->assertEquals($expected, $result); |
|
| 101 | + } |
|
| 102 | + |
|
| 103 | + public static function dataMimeTypeCustom(): array { |
|
| 104 | + return [ |
|
| 105 | + ['123', 'foobar/123'], |
|
| 106 | + ['a123', 'foobar/123'], |
|
| 107 | + ['bar', 'foobar/bar'], |
|
| 108 | + ]; |
|
| 109 | + } |
|
| 110 | + |
|
| 111 | + /** |
|
| 112 | + * @dataProvider dataMimeTypeCustom |
|
| 113 | + * |
|
| 114 | + * @param string $ext |
|
| 115 | + * @param string $mime |
|
| 116 | + */ |
|
| 117 | + public function testDetectMimeTypeCustom(string $ext, string $mime): void { |
|
| 118 | + $confDir = sys_get_temp_dir(); |
|
| 119 | + file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([])); |
|
| 120 | + |
|
| 121 | + /** @var IURLGenerator $urlGenerator */ |
|
| 122 | + $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 123 | + ->disableOriginalConstructor() |
|
| 124 | + ->getMock(); |
|
| 125 | + |
|
| 126 | + /** @var LoggerInterface $logger */ |
|
| 127 | + $logger = $this->createMock(LoggerInterface::class); |
|
| 128 | + |
|
| 129 | + // Create new mapping file |
|
| 130 | + file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([$ext => [$mime]])); |
|
| 131 | + |
|
| 132 | + $detection = new Detection($urlGenerator, $logger, $confDir, $confDir); |
|
| 133 | + $mappings = $detection->getAllMappings(); |
|
| 134 | + $this->assertArrayHasKey($ext, $mappings); |
|
| 135 | + $this->assertEquals($mime, $detection->detectPath('foo.' . $ext)); |
|
| 136 | + } |
|
| 137 | + |
|
| 138 | + public static function dataGetSecureMimeType(): array { |
|
| 139 | + return [ |
|
| 140 | + ['image/svg+xml', 'text/plain'], |
|
| 141 | + ['image/png', 'image/png'], |
|
| 142 | + ]; |
|
| 143 | + } |
|
| 144 | + |
|
| 145 | + /** |
|
| 146 | + * @dataProvider dataGetSecureMimeType |
|
| 147 | + * |
|
| 148 | + * @param string $mimeType |
|
| 149 | + * @param string $expected |
|
| 150 | + */ |
|
| 151 | + public function testGetSecureMimeType(string $mimeType, string $expected): void { |
|
| 152 | + $this->assertEquals($expected, $this->detection->getSecureMimeType($mimeType)); |
|
| 153 | + } |
|
| 154 | + |
|
| 155 | + public function testMimeTypeIcon(): void { |
|
| 156 | + if (!class_exists('org\\bovigo\\vfs\\vfsStream')) { |
|
| 157 | + $this->markTestSkipped('Package vfsStream not installed'); |
|
| 158 | + } |
|
| 159 | + $confDir = \org\bovigo\vfs\vfsStream::setup(); |
|
| 160 | + $mimetypealiases_dist = \org\bovigo\vfs\vfsStream::newFile('mimetypealiases.dist.json')->at($confDir); |
|
| 161 | + |
|
| 162 | + //Empty alias file |
|
| 163 | + $mimetypealiases_dist->setContent(json_encode([], JSON_FORCE_OBJECT)); |
|
| 164 | + |
|
| 165 | + |
|
| 166 | + /* |
|
| 167 | 167 | * Test dir mimetype |
| 168 | 168 | */ |
| 169 | 169 | |
| 170 | - //Mock UrlGenerator |
|
| 171 | - $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 172 | - ->disableOriginalConstructor() |
|
| 173 | - ->getMock(); |
|
| 170 | + //Mock UrlGenerator |
|
| 171 | + $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 172 | + ->disableOriginalConstructor() |
|
| 173 | + ->getMock(); |
|
| 174 | 174 | |
| 175 | - /** @var LoggerInterface $logger */ |
|
| 176 | - $logger = $this->createMock(LoggerInterface::class); |
|
| 175 | + /** @var LoggerInterface $logger */ |
|
| 176 | + $logger = $this->createMock(LoggerInterface::class); |
|
| 177 | 177 | |
| 178 | - //Only call the url generator once |
|
| 179 | - $urlGenerator->expects($this->once()) |
|
| 180 | - ->method('imagePath') |
|
| 181 | - ->with($this->equalTo('core'), $this->equalTo('filetypes/folder.png')) |
|
| 182 | - ->willReturn('folder.svg'); |
|
| 178 | + //Only call the url generator once |
|
| 179 | + $urlGenerator->expects($this->once()) |
|
| 180 | + ->method('imagePath') |
|
| 181 | + ->with($this->equalTo('core'), $this->equalTo('filetypes/folder.png')) |
|
| 182 | + ->willReturn('folder.svg'); |
|
| 183 | 183 | |
| 184 | - $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 185 | - $mimeType = $detection->mimeTypeIcon('dir'); |
|
| 186 | - $this->assertEquals('folder.svg', $mimeType); |
|
| 184 | + $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 185 | + $mimeType = $detection->mimeTypeIcon('dir'); |
|
| 186 | + $this->assertEquals('folder.svg', $mimeType); |
|
| 187 | 187 | |
| 188 | 188 | |
| 189 | - /* |
|
| 189 | + /* |
|
| 190 | 190 | * Test dir-shareed mimetype |
| 191 | 191 | */ |
| 192 | - //Mock UrlGenerator |
|
| 193 | - $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 194 | - ->disableOriginalConstructor() |
|
| 195 | - ->getMock(); |
|
| 192 | + //Mock UrlGenerator |
|
| 193 | + $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 194 | + ->disableOriginalConstructor() |
|
| 195 | + ->getMock(); |
|
| 196 | 196 | |
| 197 | - //Only call the url generator once |
|
| 198 | - $urlGenerator->expects($this->once()) |
|
| 199 | - ->method('imagePath') |
|
| 200 | - ->with($this->equalTo('core'), $this->equalTo('filetypes/folder-shared.png')) |
|
| 201 | - ->willReturn('folder-shared.svg'); |
|
| 197 | + //Only call the url generator once |
|
| 198 | + $urlGenerator->expects($this->once()) |
|
| 199 | + ->method('imagePath') |
|
| 200 | + ->with($this->equalTo('core'), $this->equalTo('filetypes/folder-shared.png')) |
|
| 201 | + ->willReturn('folder-shared.svg'); |
|
| 202 | 202 | |
| 203 | - $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 204 | - $mimeType = $detection->mimeTypeIcon('dir-shared'); |
|
| 205 | - $this->assertEquals('folder-shared.svg', $mimeType); |
|
| 203 | + $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 204 | + $mimeType = $detection->mimeTypeIcon('dir-shared'); |
|
| 205 | + $this->assertEquals('folder-shared.svg', $mimeType); |
|
| 206 | 206 | |
| 207 | 207 | |
| 208 | - /* |
|
| 208 | + /* |
|
| 209 | 209 | * Test dir external |
| 210 | 210 | */ |
| 211 | 211 | |
| 212 | - //Mock UrlGenerator |
|
| 213 | - $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 214 | - ->disableOriginalConstructor() |
|
| 215 | - ->getMock(); |
|
| 212 | + //Mock UrlGenerator |
|
| 213 | + $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 214 | + ->disableOriginalConstructor() |
|
| 215 | + ->getMock(); |
|
| 216 | 216 | |
| 217 | - //Only call the url generator once |
|
| 218 | - $urlGenerator->expects($this->once()) |
|
| 219 | - ->method('imagePath') |
|
| 220 | - ->with($this->equalTo('core'), $this->equalTo('filetypes/folder-external.png')) |
|
| 221 | - ->willReturn('folder-external.svg'); |
|
| 217 | + //Only call the url generator once |
|
| 218 | + $urlGenerator->expects($this->once()) |
|
| 219 | + ->method('imagePath') |
|
| 220 | + ->with($this->equalTo('core'), $this->equalTo('filetypes/folder-external.png')) |
|
| 221 | + ->willReturn('folder-external.svg'); |
|
| 222 | 222 | |
| 223 | - $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 224 | - $mimeType = $detection->mimeTypeIcon('dir-external'); |
|
| 225 | - $this->assertEquals('folder-external.svg', $mimeType); |
|
| 223 | + $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 224 | + $mimeType = $detection->mimeTypeIcon('dir-external'); |
|
| 225 | + $this->assertEquals('folder-external.svg', $mimeType); |
|
| 226 | 226 | |
| 227 | 227 | |
| 228 | - /* |
|
| 228 | + /* |
|
| 229 | 229 | * Test complete mimetype |
| 230 | 230 | */ |
| 231 | 231 | |
| 232 | - //Mock UrlGenerator |
|
| 233 | - $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 234 | - ->disableOriginalConstructor() |
|
| 235 | - ->getMock(); |
|
| 232 | + //Mock UrlGenerator |
|
| 233 | + $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 234 | + ->disableOriginalConstructor() |
|
| 235 | + ->getMock(); |
|
| 236 | 236 | |
| 237 | - //Only call the url generator once |
|
| 238 | - $urlGenerator->expects($this->once()) |
|
| 239 | - ->method('imagePath') |
|
| 240 | - ->with($this->equalTo('core'), $this->equalTo('filetypes/my-type.png')) |
|
| 241 | - ->willReturn('my-type.svg'); |
|
| 237 | + //Only call the url generator once |
|
| 238 | + $urlGenerator->expects($this->once()) |
|
| 239 | + ->method('imagePath') |
|
| 240 | + ->with($this->equalTo('core'), $this->equalTo('filetypes/my-type.png')) |
|
| 241 | + ->willReturn('my-type.svg'); |
|
| 242 | 242 | |
| 243 | - $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 244 | - $mimeType = $detection->mimeTypeIcon('my-type'); |
|
| 245 | - $this->assertEquals('my-type.svg', $mimeType); |
|
| 243 | + $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 244 | + $mimeType = $detection->mimeTypeIcon('my-type'); |
|
| 245 | + $this->assertEquals('my-type.svg', $mimeType); |
|
| 246 | 246 | |
| 247 | 247 | |
| 248 | - /* |
|
| 248 | + /* |
|
| 249 | 249 | * Test subtype |
| 250 | 250 | */ |
| 251 | 251 | |
| 252 | - //Mock UrlGenerator |
|
| 253 | - $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 254 | - ->disableOriginalConstructor() |
|
| 255 | - ->getMock(); |
|
| 256 | - |
|
| 257 | - //Only call the url generator once |
|
| 258 | - $calls = [ |
|
| 259 | - ['core', 'filetypes/my-type.png'], |
|
| 260 | - ['core', 'filetypes/my.png'], |
|
| 261 | - ]; |
|
| 262 | - $urlGenerator->expects($this->exactly(2)) |
|
| 263 | - ->method('imagePath') |
|
| 264 | - ->willReturnCallback( |
|
| 265 | - function ($appName, $file) use (&$calls) { |
|
| 266 | - $expected = array_shift($calls); |
|
| 267 | - $this->assertEquals($expected, [$appName, $file]); |
|
| 268 | - if ($file === 'filetypes/my.png') { |
|
| 269 | - return 'my.svg'; |
|
| 270 | - } |
|
| 271 | - throw new \RuntimeException(); |
|
| 272 | - } |
|
| 273 | - ); |
|
| 274 | - |
|
| 275 | - $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 276 | - $mimeType = $detection->mimeTypeIcon('my-type'); |
|
| 277 | - $this->assertEquals('my.svg', $mimeType); |
|
| 278 | - |
|
| 279 | - |
|
| 280 | - /* |
|
| 252 | + //Mock UrlGenerator |
|
| 253 | + $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 254 | + ->disableOriginalConstructor() |
|
| 255 | + ->getMock(); |
|
| 256 | + |
|
| 257 | + //Only call the url generator once |
|
| 258 | + $calls = [ |
|
| 259 | + ['core', 'filetypes/my-type.png'], |
|
| 260 | + ['core', 'filetypes/my.png'], |
|
| 261 | + ]; |
|
| 262 | + $urlGenerator->expects($this->exactly(2)) |
|
| 263 | + ->method('imagePath') |
|
| 264 | + ->willReturnCallback( |
|
| 265 | + function ($appName, $file) use (&$calls) { |
|
| 266 | + $expected = array_shift($calls); |
|
| 267 | + $this->assertEquals($expected, [$appName, $file]); |
|
| 268 | + if ($file === 'filetypes/my.png') { |
|
| 269 | + return 'my.svg'; |
|
| 270 | + } |
|
| 271 | + throw new \RuntimeException(); |
|
| 272 | + } |
|
| 273 | + ); |
|
| 274 | + |
|
| 275 | + $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 276 | + $mimeType = $detection->mimeTypeIcon('my-type'); |
|
| 277 | + $this->assertEquals('my.svg', $mimeType); |
|
| 278 | + |
|
| 279 | + |
|
| 280 | + /* |
|
| 281 | 281 | * Test default mimetype |
| 282 | 282 | */ |
| 283 | 283 | |
| 284 | - //Mock UrlGenerator |
|
| 285 | - $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 286 | - ->disableOriginalConstructor() |
|
| 287 | - ->getMock(); |
|
| 288 | - |
|
| 289 | - //Only call the url generator once |
|
| 290 | - $calls = [ |
|
| 291 | - ['core', 'filetypes/foo-bar.png'], |
|
| 292 | - ['core', 'filetypes/foo.png'], |
|
| 293 | - ['core', 'filetypes/file.png'], |
|
| 294 | - ]; |
|
| 295 | - $urlGenerator->expects($this->exactly(3)) |
|
| 296 | - ->method('imagePath') |
|
| 297 | - ->willReturnCallback( |
|
| 298 | - function ($appName, $file) use (&$calls) { |
|
| 299 | - $expected = array_shift($calls); |
|
| 300 | - $this->assertEquals($expected, [$appName, $file]); |
|
| 301 | - if ($file === 'filetypes/file.png') { |
|
| 302 | - return 'file.svg'; |
|
| 303 | - } |
|
| 304 | - throw new \RuntimeException(); |
|
| 305 | - } |
|
| 306 | - ); |
|
| 307 | - |
|
| 308 | - $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 309 | - $mimeType = $detection->mimeTypeIcon('foo-bar'); |
|
| 310 | - $this->assertEquals('file.svg', $mimeType); |
|
| 311 | - |
|
| 312 | - /* |
|
| 284 | + //Mock UrlGenerator |
|
| 285 | + $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 286 | + ->disableOriginalConstructor() |
|
| 287 | + ->getMock(); |
|
| 288 | + |
|
| 289 | + //Only call the url generator once |
|
| 290 | + $calls = [ |
|
| 291 | + ['core', 'filetypes/foo-bar.png'], |
|
| 292 | + ['core', 'filetypes/foo.png'], |
|
| 293 | + ['core', 'filetypes/file.png'], |
|
| 294 | + ]; |
|
| 295 | + $urlGenerator->expects($this->exactly(3)) |
|
| 296 | + ->method('imagePath') |
|
| 297 | + ->willReturnCallback( |
|
| 298 | + function ($appName, $file) use (&$calls) { |
|
| 299 | + $expected = array_shift($calls); |
|
| 300 | + $this->assertEquals($expected, [$appName, $file]); |
|
| 301 | + if ($file === 'filetypes/file.png') { |
|
| 302 | + return 'file.svg'; |
|
| 303 | + } |
|
| 304 | + throw new \RuntimeException(); |
|
| 305 | + } |
|
| 306 | + ); |
|
| 307 | + |
|
| 308 | + $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 309 | + $mimeType = $detection->mimeTypeIcon('foo-bar'); |
|
| 310 | + $this->assertEquals('file.svg', $mimeType); |
|
| 311 | + |
|
| 312 | + /* |
|
| 313 | 313 | * Test chaching |
| 314 | 314 | */ |
| 315 | 315 | |
| 316 | - //Mock UrlGenerator |
|
| 317 | - $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 318 | - ->disableOriginalConstructor() |
|
| 319 | - ->getMock(); |
|
| 316 | + //Mock UrlGenerator |
|
| 317 | + $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 318 | + ->disableOriginalConstructor() |
|
| 319 | + ->getMock(); |
|
| 320 | 320 | |
| 321 | - //Only call the url generator once |
|
| 322 | - $urlGenerator->expects($this->once()) |
|
| 323 | - ->method('imagePath') |
|
| 324 | - ->with($this->equalTo('core'), $this->equalTo('filetypes/foo-bar.png')) |
|
| 325 | - ->willReturn('foo-bar.svg'); |
|
| 321 | + //Only call the url generator once |
|
| 322 | + $urlGenerator->expects($this->once()) |
|
| 323 | + ->method('imagePath') |
|
| 324 | + ->with($this->equalTo('core'), $this->equalTo('filetypes/foo-bar.png')) |
|
| 325 | + ->willReturn('foo-bar.svg'); |
|
| 326 | 326 | |
| 327 | - $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 328 | - $mimeType = $detection->mimeTypeIcon('foo-bar'); |
|
| 329 | - $this->assertEquals('foo-bar.svg', $mimeType); |
|
| 330 | - $mimeType = $detection->mimeTypeIcon('foo-bar'); |
|
| 331 | - $this->assertEquals('foo-bar.svg', $mimeType); |
|
| 327 | + $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 328 | + $mimeType = $detection->mimeTypeIcon('foo-bar'); |
|
| 329 | + $this->assertEquals('foo-bar.svg', $mimeType); |
|
| 330 | + $mimeType = $detection->mimeTypeIcon('foo-bar'); |
|
| 331 | + $this->assertEquals('foo-bar.svg', $mimeType); |
|
| 332 | 332 | |
| 333 | 333 | |
| 334 | 334 | |
| 335 | - /* |
|
| 335 | + /* |
|
| 336 | 336 | * Test aliases |
| 337 | 337 | */ |
| 338 | 338 | |
| 339 | - //Put alias |
|
| 340 | - $mimetypealiases_dist->setContent(json_encode(['foo' => 'foobar/baz'], JSON_FORCE_OBJECT)); |
|
| 339 | + //Put alias |
|
| 340 | + $mimetypealiases_dist->setContent(json_encode(['foo' => 'foobar/baz'], JSON_FORCE_OBJECT)); |
|
| 341 | 341 | |
| 342 | - //Mock UrlGenerator |
|
| 343 | - $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 344 | - ->disableOriginalConstructor() |
|
| 345 | - ->getMock(); |
|
| 342 | + //Mock UrlGenerator |
|
| 343 | + $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
|
| 344 | + ->disableOriginalConstructor() |
|
| 345 | + ->getMock(); |
|
| 346 | 346 | |
| 347 | - //Only call the url generator once |
|
| 348 | - $urlGenerator->expects($this->once()) |
|
| 349 | - ->method('imagePath') |
|
| 350 | - ->with($this->equalTo('core'), $this->equalTo('filetypes/foobar-baz.png')) |
|
| 351 | - ->willReturn('foobar-baz.svg'); |
|
| 347 | + //Only call the url generator once |
|
| 348 | + $urlGenerator->expects($this->once()) |
|
| 349 | + ->method('imagePath') |
|
| 350 | + ->with($this->equalTo('core'), $this->equalTo('filetypes/foobar-baz.png')) |
|
| 351 | + ->willReturn('foobar-baz.svg'); |
|
| 352 | 352 | |
| 353 | - $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 354 | - $mimeType = $detection->mimeTypeIcon('foo'); |
|
| 355 | - $this->assertEquals('foobar-baz.svg', $mimeType); |
|
| 356 | - } |
|
| 353 | + $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url()); |
|
| 354 | + $mimeType = $detection->mimeTypeIcon('foo'); |
|
| 355 | + $this->assertEquals('foobar-baz.svg', $mimeType); |
|
| 356 | + } |
|
| 357 | 357 | } |
@@ -20,8 +20,8 @@ discard block |
||
| 20 | 20 | $this->detection = new Detection( |
| 21 | 21 | \OC::$server->getURLGenerator(), |
| 22 | 22 | \OC::$server->get(LoggerInterface::class), |
| 23 | - \OC::$SERVERROOT . '/config/', |
|
| 24 | - \OC::$SERVERROOT . '/resources/config/' |
|
| 23 | + \OC::$SERVERROOT.'/config/', |
|
| 24 | + \OC::$SERVERROOT.'/resources/config/' |
|
| 25 | 25 | ); |
| 26 | 26 | } |
| 27 | 27 | |
@@ -71,7 +71,7 @@ discard block |
||
| 71 | 71 | * @param string $expected |
| 72 | 72 | */ |
| 73 | 73 | public function testDetectContent(string $path, string $expected): void { |
| 74 | - $this->assertEquals($expected, $this->detection->detectContent(\OC::$SERVERROOT . '/tests/data' . $path)); |
|
| 74 | + $this->assertEquals($expected, $this->detection->detectContent(\OC::$SERVERROOT.'/tests/data'.$path)); |
|
| 75 | 75 | } |
| 76 | 76 | |
| 77 | 77 | public static function dataDetect(): array { |
@@ -91,7 +91,7 @@ discard block |
||
| 91 | 91 | * @param string $expected |
| 92 | 92 | */ |
| 93 | 93 | public function testDetect(string $path, string $expected): void { |
| 94 | - $this->assertEquals($expected, $this->detection->detect(\OC::$SERVERROOT . '/tests/data' . $path)); |
|
| 94 | + $this->assertEquals($expected, $this->detection->detect(\OC::$SERVERROOT.'/tests/data'.$path)); |
|
| 95 | 95 | } |
| 96 | 96 | |
| 97 | 97 | public function testDetectString(): void { |
@@ -116,7 +116,7 @@ discard block |
||
| 116 | 116 | */ |
| 117 | 117 | public function testDetectMimeTypeCustom(string $ext, string $mime): void { |
| 118 | 118 | $confDir = sys_get_temp_dir(); |
| 119 | - file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([])); |
|
| 119 | + file_put_contents($confDir.'/mimetypemapping.dist.json', json_encode([])); |
|
| 120 | 120 | |
| 121 | 121 | /** @var IURLGenerator $urlGenerator */ |
| 122 | 122 | $urlGenerator = $this->getMockBuilder(IURLGenerator::class) |
@@ -127,12 +127,12 @@ discard block |
||
| 127 | 127 | $logger = $this->createMock(LoggerInterface::class); |
| 128 | 128 | |
| 129 | 129 | // Create new mapping file |
| 130 | - file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([$ext => [$mime]])); |
|
| 130 | + file_put_contents($confDir.'/mimetypemapping.dist.json', json_encode([$ext => [$mime]])); |
|
| 131 | 131 | |
| 132 | 132 | $detection = new Detection($urlGenerator, $logger, $confDir, $confDir); |
| 133 | 133 | $mappings = $detection->getAllMappings(); |
| 134 | 134 | $this->assertArrayHasKey($ext, $mappings); |
| 135 | - $this->assertEquals($mime, $detection->detectPath('foo.' . $ext)); |
|
| 135 | + $this->assertEquals($mime, $detection->detectPath('foo.'.$ext)); |
|
| 136 | 136 | } |
| 137 | 137 | |
| 138 | 138 | public static function dataGetSecureMimeType(): array { |
@@ -262,7 +262,7 @@ discard block |
||
| 262 | 262 | $urlGenerator->expects($this->exactly(2)) |
| 263 | 263 | ->method('imagePath') |
| 264 | 264 | ->willReturnCallback( |
| 265 | - function ($appName, $file) use (&$calls) { |
|
| 265 | + function($appName, $file) use (&$calls) { |
|
| 266 | 266 | $expected = array_shift($calls); |
| 267 | 267 | $this->assertEquals($expected, [$appName, $file]); |
| 268 | 268 | if ($file === 'filetypes/my.png') { |
@@ -295,7 +295,7 @@ discard block |
||
| 295 | 295 | $urlGenerator->expects($this->exactly(3)) |
| 296 | 296 | ->method('imagePath') |
| 297 | 297 | ->willReturnCallback( |
| 298 | - function ($appName, $file) use (&$calls) { |
|
| 298 | + function($appName, $file) use (&$calls) { |
|
| 299 | 299 | $expected = array_shift($calls); |
| 300 | 300 | $this->assertEquals($expected, [$appName, $file]); |
| 301 | 301 | if ($file === 'filetypes/file.png') { |