@@ -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') { |