Passed
Push — master ( 691aa8...315510 )
by Blizzz
17:05 queued 13s
created
lib/public/Files/ObjectStore/IObjectStoreMultiPartUpload.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -32,28 +32,28 @@
 block discarded – undo
32 32
  * @since 26.0.0
33 33
  */
34 34
 interface IObjectStoreMultiPartUpload {
35
-	/**
36
-	 * @since 26.0.0
37
-	 */
38
-	public function initiateMultipartUpload(string $urn): string;
39
-
40
-	/**
41
-	 * @since 26.0.0
42
-	 */
43
-	public function uploadMultipartPart(string $urn, string $uploadId, int $partId, $stream, $size): Result;
44
-
45
-	/**
46
-	 * @since 26.0.0
47
-	 */
48
-	public function completeMultipartUpload(string $urn, string $uploadId, array $result): int;
49
-
50
-	/**
51
-	 * @since 26.0.0
52
-	 */
53
-	public function abortMultipartUpload(string $urn, string $uploadId): void;
54
-
55
-	/**
56
-	 * @since 26.0.0
57
-	 */
58
-	public function getMultipartUploads(string $urn, string $uploadId): array;
35
+    /**
36
+     * @since 26.0.0
37
+     */
38
+    public function initiateMultipartUpload(string $urn): string;
39
+
40
+    /**
41
+     * @since 26.0.0
42
+     */
43
+    public function uploadMultipartPart(string $urn, string $uploadId, int $partId, $stream, $size): Result;
44
+
45
+    /**
46
+     * @since 26.0.0
47
+     */
48
+    public function completeMultipartUpload(string $urn, string $uploadId, array $result): int;
49
+
50
+    /**
51
+     * @since 26.0.0
52
+     */
53
+    public function abortMultipartUpload(string $urn, string $uploadId): void;
54
+
55
+    /**
56
+     * @since 26.0.0
57
+     */
58
+    public function getMultipartUploads(string $urn, string $uploadId): array;
59 59
 }
Please login to merge, or discard this patch.
lib/public/Files/Storage/IChunkedFileWrite.php 1 patch
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -32,39 +32,39 @@
 block discarded – undo
32 32
  * @since 26.0.0
33 33
  */
34 34
 interface IChunkedFileWrite extends IStorage {
35
-	/**
36
-	 * @param string $targetPath Relative target path in the storage
37
-	 * @return string writeToken to be used with the other methods to uniquely identify the file write operation
38
-	 * @throws GenericFileException
39
-	 * @since 26.0.0
40
-	 */
41
-	public function startChunkedWrite(string $targetPath): string;
35
+    /**
36
+     * @param string $targetPath Relative target path in the storage
37
+     * @return string writeToken to be used with the other methods to uniquely identify the file write operation
38
+     * @throws GenericFileException
39
+     * @since 26.0.0
40
+     */
41
+    public function startChunkedWrite(string $targetPath): string;
42 42
 
43
-	/**
44
-	 * @param string $targetPath
45
-	 * @param string $writeToken
46
-	 * @param string $chunkId
47
-	 * @param resource $data
48
-	 * @param int|null $size
49
-	 * @throws GenericFileException
50
-	 * @since 26.0.0
51
-	 */
52
-	public function putChunkedWritePart(string $targetPath, string $writeToken, string $chunkId, $data, int $size = null): ?array;
43
+    /**
44
+     * @param string $targetPath
45
+     * @param string $writeToken
46
+     * @param string $chunkId
47
+     * @param resource $data
48
+     * @param int|null $size
49
+     * @throws GenericFileException
50
+     * @since 26.0.0
51
+     */
52
+    public function putChunkedWritePart(string $targetPath, string $writeToken, string $chunkId, $data, int $size = null): ?array;
53 53
 
54
-	/**
55
-	 * @param string $targetPath
56
-	 * @param string $writeToken
57
-	 * @return int
58
-	 * @throws GenericFileException
59
-	 * @since 26.0.0
60
-	 */
61
-	public function completeChunkedWrite(string $targetPath, string $writeToken): int;
54
+    /**
55
+     * @param string $targetPath
56
+     * @param string $writeToken
57
+     * @return int
58
+     * @throws GenericFileException
59
+     * @since 26.0.0
60
+     */
61
+    public function completeChunkedWrite(string $targetPath, string $writeToken): int;
62 62
 
63
-	/**
64
-	 * @param string $targetPath
65
-	 * @param string $writeToken
66
-	 * @throws GenericFileException
67
-	 * @since 26.0.0
68
-	 */
69
-	public function cancelChunkedWrite(string $targetPath, string $writeToken): void;
63
+    /**
64
+     * @param string $targetPath
65
+     * @param string $writeToken
66
+     * @throws GenericFileException
67
+     * @since 26.0.0
68
+     */
69
+    public function cancelChunkedWrite(string $targetPath, string $writeToken): void;
70 70
 }
Please login to merge, or discard this patch.
lib/private/Files/ObjectStore/S3.php 2 patches
Indentation   +63 added lines, -63 removed lines patch added patch discarded remove patch
@@ -29,74 +29,74 @@
 block discarded – undo
29 29
 use OCP\Files\ObjectStore\IObjectStoreMultiPartUpload;
30 30
 
31 31
 class S3 implements IObjectStore, IObjectStoreMultiPartUpload {
32
-	use S3ConnectionTrait;
33
-	use S3ObjectTrait;
32
+    use S3ConnectionTrait;
33
+    use S3ObjectTrait;
34 34
 
35
-	public function __construct($parameters) {
36
-		$parameters['primary_storage'] = true;
37
-		$this->parseParams($parameters);
38
-	}
35
+    public function __construct($parameters) {
36
+        $parameters['primary_storage'] = true;
37
+        $this->parseParams($parameters);
38
+    }
39 39
 
40
-	/**
41
-	 * @return string the container or bucket name where objects are stored
42
-	 * @since 7.0.0
43
-	 */
44
-	public function getStorageId() {
45
-		return $this->id;
46
-	}
40
+    /**
41
+     * @return string the container or bucket name where objects are stored
42
+     * @since 7.0.0
43
+     */
44
+    public function getStorageId() {
45
+        return $this->id;
46
+    }
47 47
 
48
-	public function initiateMultipartUpload(string $urn): string {
49
-		$upload = $this->getConnection()->createMultipartUpload([
50
-			'Bucket' => $this->bucket,
51
-			'Key' => $urn,
52
-		]);
53
-		$uploadId = $upload->get('UploadId');
54
-		if ($uploadId === null) {
55
-			throw new Exception('No upload id returned');
56
-		}
57
-		return (string)$uploadId;
58
-	}
48
+    public function initiateMultipartUpload(string $urn): string {
49
+        $upload = $this->getConnection()->createMultipartUpload([
50
+            'Bucket' => $this->bucket,
51
+            'Key' => $urn,
52
+        ]);
53
+        $uploadId = $upload->get('UploadId');
54
+        if ($uploadId === null) {
55
+            throw new Exception('No upload id returned');
56
+        }
57
+        return (string)$uploadId;
58
+    }
59 59
 
60
-	public function uploadMultipartPart(string $urn, string $uploadId, int $partId, $stream, $size): Result {
61
-		return $this->getConnection()->uploadPart([
62
-			'Body' => $stream,
63
-			'Bucket' => $this->bucket,
64
-			'Key' => $urn,
65
-			'ContentLength' => $size,
66
-			'PartNumber' => $partId,
67
-			'UploadId' => $uploadId,
68
-		]);
69
-	}
60
+    public function uploadMultipartPart(string $urn, string $uploadId, int $partId, $stream, $size): Result {
61
+        return $this->getConnection()->uploadPart([
62
+            'Body' => $stream,
63
+            'Bucket' => $this->bucket,
64
+            'Key' => $urn,
65
+            'ContentLength' => $size,
66
+            'PartNumber' => $partId,
67
+            'UploadId' => $uploadId,
68
+        ]);
69
+    }
70 70
 
71
-	public function getMultipartUploads(string $urn, string $uploadId): array {
72
-		$parts = $this->getConnection()->listParts([
73
-			'Bucket' => $this->bucket,
74
-			'Key' => $urn,
75
-			'UploadId' => $uploadId,
76
-			'MaxParts' => 10000
77
-		]);
78
-		return $parts->get('Parts') ?? [];
79
-	}
71
+    public function getMultipartUploads(string $urn, string $uploadId): array {
72
+        $parts = $this->getConnection()->listParts([
73
+            'Bucket' => $this->bucket,
74
+            'Key' => $urn,
75
+            'UploadId' => $uploadId,
76
+            'MaxParts' => 10000
77
+        ]);
78
+        return $parts->get('Parts') ?? [];
79
+    }
80 80
 
81
-	public function completeMultipartUpload(string $urn, string $uploadId, array $result): int {
82
-		$this->getConnection()->completeMultipartUpload([
83
-			'Bucket' => $this->bucket,
84
-			'Key' => $urn,
85
-			'UploadId' => $uploadId,
86
-			'MultipartUpload' => ['Parts' => $result],
87
-		]);
88
-		$stat = $this->getConnection()->headObject([
89
-			'Bucket' => $this->bucket,
90
-			'Key' => $urn,
91
-		]);
92
-		return (int)$stat->get('ContentLength');
93
-	}
81
+    public function completeMultipartUpload(string $urn, string $uploadId, array $result): int {
82
+        $this->getConnection()->completeMultipartUpload([
83
+            'Bucket' => $this->bucket,
84
+            'Key' => $urn,
85
+            'UploadId' => $uploadId,
86
+            'MultipartUpload' => ['Parts' => $result],
87
+        ]);
88
+        $stat = $this->getConnection()->headObject([
89
+            'Bucket' => $this->bucket,
90
+            'Key' => $urn,
91
+        ]);
92
+        return (int)$stat->get('ContentLength');
93
+    }
94 94
 
95
-	public function abortMultipartUpload($urn, $uploadId): void {
96
-		$this->getConnection()->abortMultipartUpload([
97
-			'Bucket' => $this->bucket,
98
-			'Key' => $urn,
99
-			'UploadId' => $uploadId
100
-		]);
101
-	}
95
+    public function abortMultipartUpload($urn, $uploadId): void {
96
+        $this->getConnection()->abortMultipartUpload([
97
+            'Bucket' => $this->bucket,
98
+            'Key' => $urn,
99
+            'UploadId' => $uploadId
100
+        ]);
101
+    }
102 102
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -54,7 +54,7 @@  discard block
 block discarded – undo
54 54
 		if ($uploadId === null) {
55 55
 			throw new Exception('No upload id returned');
56 56
 		}
57
-		return (string)$uploadId;
57
+		return (string) $uploadId;
58 58
 	}
59 59
 
60 60
 	public function uploadMultipartPart(string $urn, string $uploadId, int $partId, $stream, $size): Result {
@@ -89,7 +89,7 @@  discard block
 block discarded – undo
89 89
 			'Bucket' => $this->bucket,
90 90
 			'Key' => $urn,
91 91
 		]);
92
-		return (int)$stat->get('ContentLength');
92
+		return (int) $stat->get('ContentLength');
93 93
 	}
94 94
 
95 95
 	public function abortMultipartUpload($urn, $uploadId): void {
Please login to merge, or discard this patch.
lib/private/Files/ObjectStore/ObjectStoreStorage.php 2 patches
Indentation   +649 added lines, -649 removed lines patch added patch discarded remove patch
@@ -47,656 +47,656 @@
 block discarded – undo
47 47
 use OCP\Files\Storage\IStorage;
48 48
 
49 49
 class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFileWrite {
50
-	use CopyDirectory;
51
-
52
-	/**
53
-	 * @var \OCP\Files\ObjectStore\IObjectStore $objectStore
54
-	 */
55
-	protected $objectStore;
56
-	/**
57
-	 * @var string $id
58
-	 */
59
-	protected $id;
60
-	/**
61
-	 * @var \OC\User\User $user
62
-	 */
63
-	protected $user;
64
-
65
-	private $objectPrefix = 'urn:oid:';
66
-
67
-	private $logger;
68
-
69
-	/** @var bool */
70
-	protected $validateWrites = true;
71
-
72
-	public function __construct($params) {
73
-		if (isset($params['objectstore']) && $params['objectstore'] instanceof IObjectStore) {
74
-			$this->objectStore = $params['objectstore'];
75
-		} else {
76
-			throw new \Exception('missing IObjectStore instance');
77
-		}
78
-		if (isset($params['storageid'])) {
79
-			$this->id = 'object::store:' . $params['storageid'];
80
-		} else {
81
-			$this->id = 'object::store:' . $this->objectStore->getStorageId();
82
-		}
83
-		if (isset($params['objectPrefix'])) {
84
-			$this->objectPrefix = $params['objectPrefix'];
85
-		}
86
-		if (isset($params['validateWrites'])) {
87
-			$this->validateWrites = (bool)$params['validateWrites'];
88
-		}
89
-		//initialize cache with root directory in cache
90
-		if (!$this->is_dir('/')) {
91
-			$this->mkdir('/');
92
-		}
93
-
94
-		$this->logger = \OC::$server->getLogger();
95
-	}
96
-
97
-	public function mkdir($path) {
98
-		$path = $this->normalizePath($path);
99
-		if ($this->file_exists($path)) {
100
-			return false;
101
-		}
102
-
103
-		$mTime = time();
104
-		$data = [
105
-			'mimetype' => 'httpd/unix-directory',
106
-			'size' => 0,
107
-			'mtime' => $mTime,
108
-			'storage_mtime' => $mTime,
109
-			'permissions' => \OCP\Constants::PERMISSION_ALL,
110
-		];
111
-		if ($path === '') {
112
-			//create root on the fly
113
-			$data['etag'] = $this->getETag('');
114
-			$this->getCache()->put('', $data);
115
-			return true;
116
-		} else {
117
-			// if parent does not exist, create it
118
-			$parent = $this->normalizePath(dirname($path));
119
-			$parentType = $this->filetype($parent);
120
-			if ($parentType === false) {
121
-				if (!$this->mkdir($parent)) {
122
-					// something went wrong
123
-					return false;
124
-				}
125
-			} elseif ($parentType === 'file') {
126
-				// parent is a file
127
-				return false;
128
-			}
129
-			// finally create the new dir
130
-			$mTime = time(); // update mtime
131
-			$data['mtime'] = $mTime;
132
-			$data['storage_mtime'] = $mTime;
133
-			$data['etag'] = $this->getETag($path);
134
-			$this->getCache()->put($path, $data);
135
-			return true;
136
-		}
137
-	}
138
-
139
-	/**
140
-	 * @param string $path
141
-	 * @return string
142
-	 */
143
-	private function normalizePath($path) {
144
-		$path = trim($path, '/');
145
-		//FIXME why do we sometimes get a path like 'files//username'?
146
-		$path = str_replace('//', '/', $path);
147
-
148
-		// dirname('/folder') returns '.' but internally (in the cache) we store the root as ''
149
-		if (!$path || $path === '.') {
150
-			$path = '';
151
-		}
152
-
153
-		return $path;
154
-	}
155
-
156
-	/**
157
-	 * Object Stores use a NoopScanner because metadata is directly stored in
158
-	 * the file cache and cannot really scan the filesystem. The storage passed in is not used anywhere.
159
-	 *
160
-	 * @param string $path
161
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
162
-	 * @return \OC\Files\ObjectStore\NoopScanner
163
-	 */
164
-	public function getScanner($path = '', $storage = null) {
165
-		if (!$storage) {
166
-			$storage = $this;
167
-		}
168
-		if (!isset($this->scanner)) {
169
-			$this->scanner = new NoopScanner($storage);
170
-		}
171
-		return $this->scanner;
172
-	}
173
-
174
-	public function getId() {
175
-		return $this->id;
176
-	}
177
-
178
-	public function rmdir($path) {
179
-		$path = $this->normalizePath($path);
180
-
181
-		if (!$this->is_dir($path)) {
182
-			return false;
183
-		}
184
-
185
-		if (!$this->rmObjects($path)) {
186
-			return false;
187
-		}
188
-
189
-		$this->getCache()->remove($path);
190
-
191
-		return true;
192
-	}
193
-
194
-	private function rmObjects($path) {
195
-		$children = $this->getCache()->getFolderContents($path);
196
-		foreach ($children as $child) {
197
-			if ($child['mimetype'] === 'httpd/unix-directory') {
198
-				if (!$this->rmObjects($child['path'])) {
199
-					return false;
200
-				}
201
-			} else {
202
-				if (!$this->unlink($child['path'])) {
203
-					return false;
204
-				}
205
-			}
206
-		}
207
-
208
-		return true;
209
-	}
210
-
211
-	public function unlink($path) {
212
-		$path = $this->normalizePath($path);
213
-		$stat = $this->stat($path);
214
-
215
-		if ($stat && isset($stat['fileid'])) {
216
-			if ($stat['mimetype'] === 'httpd/unix-directory') {
217
-				return $this->rmdir($path);
218
-			}
219
-			try {
220
-				$this->objectStore->deleteObject($this->getURN($stat['fileid']));
221
-			} catch (\Exception $ex) {
222
-				if ($ex->getCode() !== 404) {
223
-					$this->logger->logException($ex, [
224
-						'app' => 'objectstore',
225
-						'message' => 'Could not delete object ' . $this->getURN($stat['fileid']) . ' for ' . $path,
226
-					]);
227
-					return false;
228
-				}
229
-				//removing from cache is ok as it does not exist in the objectstore anyway
230
-			}
231
-			$this->getCache()->remove($path);
232
-			return true;
233
-		}
234
-		return false;
235
-	}
236
-
237
-	public function stat($path) {
238
-		$path = $this->normalizePath($path);
239
-		$cacheEntry = $this->getCache()->get($path);
240
-		if ($cacheEntry instanceof CacheEntry) {
241
-			return $cacheEntry->getData();
242
-		} else {
243
-			return false;
244
-		}
245
-	}
246
-
247
-	public function getPermissions($path) {
248
-		$stat = $this->stat($path);
249
-
250
-		if (is_array($stat) && isset($stat['permissions'])) {
251
-			return $stat['permissions'];
252
-		}
253
-
254
-		return parent::getPermissions($path);
255
-	}
256
-
257
-	/**
258
-	 * Override this method if you need a different unique resource identifier for your object storage implementation.
259
-	 * The default implementations just appends the fileId to 'urn:oid:'. Make sure the URN is unique over all users.
260
-	 * You may need a mapping table to store your URN if it cannot be generated from the fileid.
261
-	 *
262
-	 * @param int $fileId the fileid
263
-	 * @return null|string the unified resource name used to identify the object
264
-	 */
265
-	public function getURN($fileId) {
266
-		if (is_numeric($fileId)) {
267
-			return $this->objectPrefix . $fileId;
268
-		}
269
-		return null;
270
-	}
271
-
272
-	public function opendir($path) {
273
-		$path = $this->normalizePath($path);
274
-
275
-		try {
276
-			$files = [];
277
-			$folderContents = $this->getCache()->getFolderContents($path);
278
-			foreach ($folderContents as $file) {
279
-				$files[] = $file['name'];
280
-			}
281
-
282
-			return IteratorDirectory::wrap($files);
283
-		} catch (\Exception $e) {
284
-			$this->logger->logException($e);
285
-			return false;
286
-		}
287
-	}
288
-
289
-	public function filetype($path) {
290
-		$path = $this->normalizePath($path);
291
-		$stat = $this->stat($path);
292
-		if ($stat) {
293
-			if ($stat['mimetype'] === 'httpd/unix-directory') {
294
-				return 'dir';
295
-			}
296
-			return 'file';
297
-		} else {
298
-			return false;
299
-		}
300
-	}
301
-
302
-	public function fopen($path, $mode) {
303
-		$path = $this->normalizePath($path);
304
-
305
-		if (strrpos($path, '.') !== false) {
306
-			$ext = substr($path, strrpos($path, '.'));
307
-		} else {
308
-			$ext = '';
309
-		}
310
-
311
-		switch ($mode) {
312
-			case 'r':
313
-			case 'rb':
314
-				$stat = $this->stat($path);
315
-				if (is_array($stat)) {
316
-					$filesize = $stat['size'] ?? 0;
317
-					// Reading 0 sized files is a waste of time
318
-					if ($filesize === 0) {
319
-						return fopen('php://memory', $mode);
320
-					}
321
-
322
-					try {
323
-						$handle = $this->objectStore->readObject($this->getURN($stat['fileid']));
324
-						if ($handle === false) {
325
-							return false; // keep backward compatibility
326
-						}
327
-						$streamStat = fstat($handle);
328
-						$actualSize = $streamStat['size'] ?? -1;
329
-						if ($actualSize > -1 && $actualSize !== $filesize) {
330
-							$this->getCache()->update((int)$stat['fileid'], ['size' => $actualSize]);
331
-						}
332
-						return $handle;
333
-					} catch (NotFoundException $e) {
334
-						$this->logger->logException($e, [
335
-							'app' => 'objectstore',
336
-							'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
337
-						]);
338
-						throw $e;
339
-					} catch (\Exception $ex) {
340
-						$this->logger->logException($ex, [
341
-							'app' => 'objectstore',
342
-							'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
343
-						]);
344
-						return false;
345
-					}
346
-				} else {
347
-					return false;
348
-				}
349
-				// no break
350
-			case 'w':
351
-			case 'wb':
352
-			case 'w+':
353
-			case 'wb+':
354
-				$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
355
-				$handle = fopen($tmpFile, $mode);
356
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
357
-					$this->writeBack($tmpFile, $path);
358
-					unlink($tmpFile);
359
-				});
360
-			case 'a':
361
-			case 'ab':
362
-			case 'r+':
363
-			case 'a+':
364
-			case 'x':
365
-			case 'x+':
366
-			case 'c':
367
-			case 'c+':
368
-				$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
369
-				if ($this->file_exists($path)) {
370
-					$source = $this->fopen($path, 'r');
371
-					file_put_contents($tmpFile, $source);
372
-				}
373
-				$handle = fopen($tmpFile, $mode);
374
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
375
-					$this->writeBack($tmpFile, $path);
376
-					unlink($tmpFile);
377
-				});
378
-		}
379
-		return false;
380
-	}
381
-
382
-	public function file_exists($path) {
383
-		$path = $this->normalizePath($path);
384
-		return (bool)$this->stat($path);
385
-	}
386
-
387
-	public function rename($source, $target) {
388
-		$source = $this->normalizePath($source);
389
-		$target = $this->normalizePath($target);
390
-		$this->remove($target);
391
-		$this->getCache()->move($source, $target);
392
-		$this->touch(dirname($target));
393
-		return true;
394
-	}
395
-
396
-	public function getMimeType($path) {
397
-		$path = $this->normalizePath($path);
398
-		return parent::getMimeType($path);
399
-	}
400
-
401
-	public function touch($path, $mtime = null) {
402
-		if (is_null($mtime)) {
403
-			$mtime = time();
404
-		}
405
-
406
-		$path = $this->normalizePath($path);
407
-		$dirName = dirname($path);
408
-		$parentExists = $this->is_dir($dirName);
409
-		if (!$parentExists) {
410
-			return false;
411
-		}
412
-
413
-		$stat = $this->stat($path);
414
-		if (is_array($stat)) {
415
-			// update existing mtime in db
416
-			$stat['mtime'] = $mtime;
417
-			$this->getCache()->update($stat['fileid'], $stat);
418
-		} else {
419
-			try {
420
-				//create a empty file, need to have at least on char to make it
421
-				// work with all object storage implementations
422
-				$this->file_put_contents($path, ' ');
423
-				$mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
424
-				$stat = [
425
-					'etag' => $this->getETag($path),
426
-					'mimetype' => $mimeType,
427
-					'size' => 0,
428
-					'mtime' => $mtime,
429
-					'storage_mtime' => $mtime,
430
-					'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
431
-				];
432
-				$this->getCache()->put($path, $stat);
433
-			} catch (\Exception $ex) {
434
-				$this->logger->logException($ex, [
435
-					'app' => 'objectstore',
436
-					'message' => 'Could not create object for ' . $path,
437
-				]);
438
-				throw $ex;
439
-			}
440
-		}
441
-		return true;
442
-	}
443
-
444
-	public function writeBack($tmpFile, $path) {
445
-		$size = filesize($tmpFile);
446
-		$this->writeStream($path, fopen($tmpFile, 'r'), $size);
447
-	}
448
-
449
-	/**
450
-	 * external changes are not supported, exclusive access to the object storage is assumed
451
-	 *
452
-	 * @param string $path
453
-	 * @param int $time
454
-	 * @return false
455
-	 */
456
-	public function hasUpdated($path, $time) {
457
-		return false;
458
-	}
459
-
460
-	public function needsPartFile() {
461
-		return false;
462
-	}
463
-
464
-	public function file_put_contents($path, $data) {
465
-		$handle = $this->fopen($path, 'w+');
466
-		$result = fwrite($handle, $data);
467
-		fclose($handle);
468
-		return $result;
469
-	}
470
-
471
-	public function writeStream(string $path, $stream, int $size = null): int {
472
-		$stat = $this->stat($path);
473
-		if (empty($stat)) {
474
-			// create new file
475
-			$stat = [
476
-				'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
477
-			];
478
-		}
479
-		// update stat with new data
480
-		$mTime = time();
481
-		$stat['size'] = (int)$size;
482
-		$stat['mtime'] = $mTime;
483
-		$stat['storage_mtime'] = $mTime;
484
-
485
-		$mimetypeDetector = \OC::$server->getMimeTypeDetector();
486
-		$mimetype = $mimetypeDetector->detectPath($path);
487
-
488
-		$stat['mimetype'] = $mimetype;
489
-		$stat['etag'] = $this->getETag($path);
490
-		$stat['checksum'] = '';
491
-
492
-		$exists = $this->getCache()->inCache($path);
493
-		$uploadPath = $exists ? $path : $path . '.part';
494
-
495
-		if ($exists) {
496
-			$fileId = $stat['fileid'];
497
-		} else {
498
-			$fileId = $this->getCache()->put($uploadPath, $stat);
499
-		}
500
-
501
-		$urn = $this->getURN($fileId);
502
-		try {
503
-			//upload to object storage
504
-			if ($size === null) {
505
-				$countStream = CountWrapper::wrap($stream, function ($writtenSize) use ($fileId, &$size) {
506
-					$this->getCache()->update($fileId, [
507
-						'size' => $writtenSize,
508
-					]);
509
-					$size = $writtenSize;
510
-				});
511
-				$this->objectStore->writeObject($urn, $countStream, $mimetype);
512
-				if (is_resource($countStream)) {
513
-					fclose($countStream);
514
-				}
515
-				$stat['size'] = $size;
516
-			} else {
517
-				$this->objectStore->writeObject($urn, $stream, $mimetype);
518
-				if (is_resource($stream)) {
519
-					fclose($stream);
520
-				}
521
-			}
522
-		} catch (\Exception $ex) {
523
-			if (!$exists) {
524
-				/*
50
+    use CopyDirectory;
51
+
52
+    /**
53
+     * @var \OCP\Files\ObjectStore\IObjectStore $objectStore
54
+     */
55
+    protected $objectStore;
56
+    /**
57
+     * @var string $id
58
+     */
59
+    protected $id;
60
+    /**
61
+     * @var \OC\User\User $user
62
+     */
63
+    protected $user;
64
+
65
+    private $objectPrefix = 'urn:oid:';
66
+
67
+    private $logger;
68
+
69
+    /** @var bool */
70
+    protected $validateWrites = true;
71
+
72
+    public function __construct($params) {
73
+        if (isset($params['objectstore']) && $params['objectstore'] instanceof IObjectStore) {
74
+            $this->objectStore = $params['objectstore'];
75
+        } else {
76
+            throw new \Exception('missing IObjectStore instance');
77
+        }
78
+        if (isset($params['storageid'])) {
79
+            $this->id = 'object::store:' . $params['storageid'];
80
+        } else {
81
+            $this->id = 'object::store:' . $this->objectStore->getStorageId();
82
+        }
83
+        if (isset($params['objectPrefix'])) {
84
+            $this->objectPrefix = $params['objectPrefix'];
85
+        }
86
+        if (isset($params['validateWrites'])) {
87
+            $this->validateWrites = (bool)$params['validateWrites'];
88
+        }
89
+        //initialize cache with root directory in cache
90
+        if (!$this->is_dir('/')) {
91
+            $this->mkdir('/');
92
+        }
93
+
94
+        $this->logger = \OC::$server->getLogger();
95
+    }
96
+
97
+    public function mkdir($path) {
98
+        $path = $this->normalizePath($path);
99
+        if ($this->file_exists($path)) {
100
+            return false;
101
+        }
102
+
103
+        $mTime = time();
104
+        $data = [
105
+            'mimetype' => 'httpd/unix-directory',
106
+            'size' => 0,
107
+            'mtime' => $mTime,
108
+            'storage_mtime' => $mTime,
109
+            'permissions' => \OCP\Constants::PERMISSION_ALL,
110
+        ];
111
+        if ($path === '') {
112
+            //create root on the fly
113
+            $data['etag'] = $this->getETag('');
114
+            $this->getCache()->put('', $data);
115
+            return true;
116
+        } else {
117
+            // if parent does not exist, create it
118
+            $parent = $this->normalizePath(dirname($path));
119
+            $parentType = $this->filetype($parent);
120
+            if ($parentType === false) {
121
+                if (!$this->mkdir($parent)) {
122
+                    // something went wrong
123
+                    return false;
124
+                }
125
+            } elseif ($parentType === 'file') {
126
+                // parent is a file
127
+                return false;
128
+            }
129
+            // finally create the new dir
130
+            $mTime = time(); // update mtime
131
+            $data['mtime'] = $mTime;
132
+            $data['storage_mtime'] = $mTime;
133
+            $data['etag'] = $this->getETag($path);
134
+            $this->getCache()->put($path, $data);
135
+            return true;
136
+        }
137
+    }
138
+
139
+    /**
140
+     * @param string $path
141
+     * @return string
142
+     */
143
+    private function normalizePath($path) {
144
+        $path = trim($path, '/');
145
+        //FIXME why do we sometimes get a path like 'files//username'?
146
+        $path = str_replace('//', '/', $path);
147
+
148
+        // dirname('/folder') returns '.' but internally (in the cache) we store the root as ''
149
+        if (!$path || $path === '.') {
150
+            $path = '';
151
+        }
152
+
153
+        return $path;
154
+    }
155
+
156
+    /**
157
+     * Object Stores use a NoopScanner because metadata is directly stored in
158
+     * the file cache and cannot really scan the filesystem. The storage passed in is not used anywhere.
159
+     *
160
+     * @param string $path
161
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
162
+     * @return \OC\Files\ObjectStore\NoopScanner
163
+     */
164
+    public function getScanner($path = '', $storage = null) {
165
+        if (!$storage) {
166
+            $storage = $this;
167
+        }
168
+        if (!isset($this->scanner)) {
169
+            $this->scanner = new NoopScanner($storage);
170
+        }
171
+        return $this->scanner;
172
+    }
173
+
174
+    public function getId() {
175
+        return $this->id;
176
+    }
177
+
178
+    public function rmdir($path) {
179
+        $path = $this->normalizePath($path);
180
+
181
+        if (!$this->is_dir($path)) {
182
+            return false;
183
+        }
184
+
185
+        if (!$this->rmObjects($path)) {
186
+            return false;
187
+        }
188
+
189
+        $this->getCache()->remove($path);
190
+
191
+        return true;
192
+    }
193
+
194
+    private function rmObjects($path) {
195
+        $children = $this->getCache()->getFolderContents($path);
196
+        foreach ($children as $child) {
197
+            if ($child['mimetype'] === 'httpd/unix-directory') {
198
+                if (!$this->rmObjects($child['path'])) {
199
+                    return false;
200
+                }
201
+            } else {
202
+                if (!$this->unlink($child['path'])) {
203
+                    return false;
204
+                }
205
+            }
206
+        }
207
+
208
+        return true;
209
+    }
210
+
211
+    public function unlink($path) {
212
+        $path = $this->normalizePath($path);
213
+        $stat = $this->stat($path);
214
+
215
+        if ($stat && isset($stat['fileid'])) {
216
+            if ($stat['mimetype'] === 'httpd/unix-directory') {
217
+                return $this->rmdir($path);
218
+            }
219
+            try {
220
+                $this->objectStore->deleteObject($this->getURN($stat['fileid']));
221
+            } catch (\Exception $ex) {
222
+                if ($ex->getCode() !== 404) {
223
+                    $this->logger->logException($ex, [
224
+                        'app' => 'objectstore',
225
+                        'message' => 'Could not delete object ' . $this->getURN($stat['fileid']) . ' for ' . $path,
226
+                    ]);
227
+                    return false;
228
+                }
229
+                //removing from cache is ok as it does not exist in the objectstore anyway
230
+            }
231
+            $this->getCache()->remove($path);
232
+            return true;
233
+        }
234
+        return false;
235
+    }
236
+
237
+    public function stat($path) {
238
+        $path = $this->normalizePath($path);
239
+        $cacheEntry = $this->getCache()->get($path);
240
+        if ($cacheEntry instanceof CacheEntry) {
241
+            return $cacheEntry->getData();
242
+        } else {
243
+            return false;
244
+        }
245
+    }
246
+
247
+    public function getPermissions($path) {
248
+        $stat = $this->stat($path);
249
+
250
+        if (is_array($stat) && isset($stat['permissions'])) {
251
+            return $stat['permissions'];
252
+        }
253
+
254
+        return parent::getPermissions($path);
255
+    }
256
+
257
+    /**
258
+     * Override this method if you need a different unique resource identifier for your object storage implementation.
259
+     * The default implementations just appends the fileId to 'urn:oid:'. Make sure the URN is unique over all users.
260
+     * You may need a mapping table to store your URN if it cannot be generated from the fileid.
261
+     *
262
+     * @param int $fileId the fileid
263
+     * @return null|string the unified resource name used to identify the object
264
+     */
265
+    public function getURN($fileId) {
266
+        if (is_numeric($fileId)) {
267
+            return $this->objectPrefix . $fileId;
268
+        }
269
+        return null;
270
+    }
271
+
272
+    public function opendir($path) {
273
+        $path = $this->normalizePath($path);
274
+
275
+        try {
276
+            $files = [];
277
+            $folderContents = $this->getCache()->getFolderContents($path);
278
+            foreach ($folderContents as $file) {
279
+                $files[] = $file['name'];
280
+            }
281
+
282
+            return IteratorDirectory::wrap($files);
283
+        } catch (\Exception $e) {
284
+            $this->logger->logException($e);
285
+            return false;
286
+        }
287
+    }
288
+
289
+    public function filetype($path) {
290
+        $path = $this->normalizePath($path);
291
+        $stat = $this->stat($path);
292
+        if ($stat) {
293
+            if ($stat['mimetype'] === 'httpd/unix-directory') {
294
+                return 'dir';
295
+            }
296
+            return 'file';
297
+        } else {
298
+            return false;
299
+        }
300
+    }
301
+
302
+    public function fopen($path, $mode) {
303
+        $path = $this->normalizePath($path);
304
+
305
+        if (strrpos($path, '.') !== false) {
306
+            $ext = substr($path, strrpos($path, '.'));
307
+        } else {
308
+            $ext = '';
309
+        }
310
+
311
+        switch ($mode) {
312
+            case 'r':
313
+            case 'rb':
314
+                $stat = $this->stat($path);
315
+                if (is_array($stat)) {
316
+                    $filesize = $stat['size'] ?? 0;
317
+                    // Reading 0 sized files is a waste of time
318
+                    if ($filesize === 0) {
319
+                        return fopen('php://memory', $mode);
320
+                    }
321
+
322
+                    try {
323
+                        $handle = $this->objectStore->readObject($this->getURN($stat['fileid']));
324
+                        if ($handle === false) {
325
+                            return false; // keep backward compatibility
326
+                        }
327
+                        $streamStat = fstat($handle);
328
+                        $actualSize = $streamStat['size'] ?? -1;
329
+                        if ($actualSize > -1 && $actualSize !== $filesize) {
330
+                            $this->getCache()->update((int)$stat['fileid'], ['size' => $actualSize]);
331
+                        }
332
+                        return $handle;
333
+                    } catch (NotFoundException $e) {
334
+                        $this->logger->logException($e, [
335
+                            'app' => 'objectstore',
336
+                            'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
337
+                        ]);
338
+                        throw $e;
339
+                    } catch (\Exception $ex) {
340
+                        $this->logger->logException($ex, [
341
+                            'app' => 'objectstore',
342
+                            'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
343
+                        ]);
344
+                        return false;
345
+                    }
346
+                } else {
347
+                    return false;
348
+                }
349
+                // no break
350
+            case 'w':
351
+            case 'wb':
352
+            case 'w+':
353
+            case 'wb+':
354
+                $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
355
+                $handle = fopen($tmpFile, $mode);
356
+                return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
357
+                    $this->writeBack($tmpFile, $path);
358
+                    unlink($tmpFile);
359
+                });
360
+            case 'a':
361
+            case 'ab':
362
+            case 'r+':
363
+            case 'a+':
364
+            case 'x':
365
+            case 'x+':
366
+            case 'c':
367
+            case 'c+':
368
+                $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
369
+                if ($this->file_exists($path)) {
370
+                    $source = $this->fopen($path, 'r');
371
+                    file_put_contents($tmpFile, $source);
372
+                }
373
+                $handle = fopen($tmpFile, $mode);
374
+                return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
375
+                    $this->writeBack($tmpFile, $path);
376
+                    unlink($tmpFile);
377
+                });
378
+        }
379
+        return false;
380
+    }
381
+
382
+    public function file_exists($path) {
383
+        $path = $this->normalizePath($path);
384
+        return (bool)$this->stat($path);
385
+    }
386
+
387
+    public function rename($source, $target) {
388
+        $source = $this->normalizePath($source);
389
+        $target = $this->normalizePath($target);
390
+        $this->remove($target);
391
+        $this->getCache()->move($source, $target);
392
+        $this->touch(dirname($target));
393
+        return true;
394
+    }
395
+
396
+    public function getMimeType($path) {
397
+        $path = $this->normalizePath($path);
398
+        return parent::getMimeType($path);
399
+    }
400
+
401
+    public function touch($path, $mtime = null) {
402
+        if (is_null($mtime)) {
403
+            $mtime = time();
404
+        }
405
+
406
+        $path = $this->normalizePath($path);
407
+        $dirName = dirname($path);
408
+        $parentExists = $this->is_dir($dirName);
409
+        if (!$parentExists) {
410
+            return false;
411
+        }
412
+
413
+        $stat = $this->stat($path);
414
+        if (is_array($stat)) {
415
+            // update existing mtime in db
416
+            $stat['mtime'] = $mtime;
417
+            $this->getCache()->update($stat['fileid'], $stat);
418
+        } else {
419
+            try {
420
+                //create a empty file, need to have at least on char to make it
421
+                // work with all object storage implementations
422
+                $this->file_put_contents($path, ' ');
423
+                $mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
424
+                $stat = [
425
+                    'etag' => $this->getETag($path),
426
+                    'mimetype' => $mimeType,
427
+                    'size' => 0,
428
+                    'mtime' => $mtime,
429
+                    'storage_mtime' => $mtime,
430
+                    'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
431
+                ];
432
+                $this->getCache()->put($path, $stat);
433
+            } catch (\Exception $ex) {
434
+                $this->logger->logException($ex, [
435
+                    'app' => 'objectstore',
436
+                    'message' => 'Could not create object for ' . $path,
437
+                ]);
438
+                throw $ex;
439
+            }
440
+        }
441
+        return true;
442
+    }
443
+
444
+    public function writeBack($tmpFile, $path) {
445
+        $size = filesize($tmpFile);
446
+        $this->writeStream($path, fopen($tmpFile, 'r'), $size);
447
+    }
448
+
449
+    /**
450
+     * external changes are not supported, exclusive access to the object storage is assumed
451
+     *
452
+     * @param string $path
453
+     * @param int $time
454
+     * @return false
455
+     */
456
+    public function hasUpdated($path, $time) {
457
+        return false;
458
+    }
459
+
460
+    public function needsPartFile() {
461
+        return false;
462
+    }
463
+
464
+    public function file_put_contents($path, $data) {
465
+        $handle = $this->fopen($path, 'w+');
466
+        $result = fwrite($handle, $data);
467
+        fclose($handle);
468
+        return $result;
469
+    }
470
+
471
+    public function writeStream(string $path, $stream, int $size = null): int {
472
+        $stat = $this->stat($path);
473
+        if (empty($stat)) {
474
+            // create new file
475
+            $stat = [
476
+                'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
477
+            ];
478
+        }
479
+        // update stat with new data
480
+        $mTime = time();
481
+        $stat['size'] = (int)$size;
482
+        $stat['mtime'] = $mTime;
483
+        $stat['storage_mtime'] = $mTime;
484
+
485
+        $mimetypeDetector = \OC::$server->getMimeTypeDetector();
486
+        $mimetype = $mimetypeDetector->detectPath($path);
487
+
488
+        $stat['mimetype'] = $mimetype;
489
+        $stat['etag'] = $this->getETag($path);
490
+        $stat['checksum'] = '';
491
+
492
+        $exists = $this->getCache()->inCache($path);
493
+        $uploadPath = $exists ? $path : $path . '.part';
494
+
495
+        if ($exists) {
496
+            $fileId = $stat['fileid'];
497
+        } else {
498
+            $fileId = $this->getCache()->put($uploadPath, $stat);
499
+        }
500
+
501
+        $urn = $this->getURN($fileId);
502
+        try {
503
+            //upload to object storage
504
+            if ($size === null) {
505
+                $countStream = CountWrapper::wrap($stream, function ($writtenSize) use ($fileId, &$size) {
506
+                    $this->getCache()->update($fileId, [
507
+                        'size' => $writtenSize,
508
+                    ]);
509
+                    $size = $writtenSize;
510
+                });
511
+                $this->objectStore->writeObject($urn, $countStream, $mimetype);
512
+                if (is_resource($countStream)) {
513
+                    fclose($countStream);
514
+                }
515
+                $stat['size'] = $size;
516
+            } else {
517
+                $this->objectStore->writeObject($urn, $stream, $mimetype);
518
+                if (is_resource($stream)) {
519
+                    fclose($stream);
520
+                }
521
+            }
522
+        } catch (\Exception $ex) {
523
+            if (!$exists) {
524
+                /*
525 525
 				 * Only remove the entry if we are dealing with a new file.
526 526
 				 * Else people lose access to existing files
527 527
 				 */
528
-				$this->getCache()->remove($uploadPath);
529
-				$this->logger->logException($ex, [
530
-					'app' => 'objectstore',
531
-					'message' => 'Could not create object ' . $urn . ' for ' . $path,
532
-				]);
533
-			} else {
534
-				$this->logger->logException($ex, [
535
-					'app' => 'objectstore',
536
-					'message' => 'Could not update object ' . $urn . ' for ' . $path,
537
-				]);
538
-			}
539
-			throw $ex; // make this bubble up
540
-		}
541
-
542
-		if ($exists) {
543
-			$this->getCache()->update($fileId, $stat);
544
-		} else {
545
-			if (!$this->validateWrites || $this->objectStore->objectExists($urn)) {
546
-				$this->getCache()->move($uploadPath, $path);
547
-			} else {
548
-				$this->getCache()->remove($uploadPath);
549
-				throw new \Exception("Object not found after writing (urn: $urn, path: $path)", 404);
550
-			}
551
-		}
552
-
553
-		return $size;
554
-	}
555
-
556
-	public function getObjectStore(): IObjectStore {
557
-		return $this->objectStore;
558
-	}
559
-
560
-	public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
561
-		if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class)) {
562
-			/** @var ObjectStoreStorage $sourceStorage */
563
-			if ($sourceStorage->getObjectStore()->getStorageId() === $this->getObjectStore()->getStorageId()) {
564
-				/** @var CacheEntry $sourceEntry */
565
-				$sourceEntry = $sourceStorage->getCache()->get($sourceInternalPath);
566
-				$sourceEntryData = $sourceEntry->getData();
567
-				// $sourceEntry['permissions'] here is the permissions from the jailed storage for the current
568
-				// user. Instead we use $sourceEntryData['scan_permissions'] that are the permissions from the
569
-				// unjailed storage.
570
-				if (is_array($sourceEntryData) && array_key_exists('scan_permissions', $sourceEntryData)) {
571
-					$sourceEntry['permissions'] = $sourceEntryData['scan_permissions'];
572
-				}
573
-				$this->copyInner($sourceEntry, $targetInternalPath);
574
-				return true;
575
-			}
576
-		}
577
-
578
-		return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
579
-	}
580
-
581
-	public function copy($source, $target) {
582
-		$source = $this->normalizePath($source);
583
-		$target = $this->normalizePath($target);
584
-
585
-		$cache = $this->getCache();
586
-		$sourceEntry = $cache->get($source);
587
-		if (!$sourceEntry) {
588
-			throw new NotFoundException('Source object not found');
589
-		}
590
-
591
-		$this->copyInner($sourceEntry, $target);
592
-
593
-		return true;
594
-	}
595
-
596
-	private function copyInner(ICacheEntry $sourceEntry, string $to) {
597
-		$cache = $this->getCache();
598
-
599
-		if ($sourceEntry->getMimeType() === FileInfo::MIMETYPE_FOLDER) {
600
-			if ($cache->inCache($to)) {
601
-				$cache->remove($to);
602
-			}
603
-			$this->mkdir($to);
604
-
605
-			foreach ($cache->getFolderContentsById($sourceEntry->getId()) as $child) {
606
-				$this->copyInner($child, $to . '/' . $child->getName());
607
-			}
608
-		} else {
609
-			$this->copyFile($sourceEntry, $to);
610
-		}
611
-	}
612
-
613
-	private function copyFile(ICacheEntry $sourceEntry, string $to) {
614
-		$cache = $this->getCache();
615
-
616
-		$sourceUrn = $this->getURN($sourceEntry->getId());
617
-
618
-		if (!$cache instanceof Cache) {
619
-			throw new \Exception("Invalid source cache for object store copy");
620
-		}
621
-
622
-		$targetId = $cache->copyFromCache($cache, $sourceEntry, $to);
623
-
624
-		$targetUrn = $this->getURN($targetId);
625
-
626
-		try {
627
-			$this->objectStore->copyObject($sourceUrn, $targetUrn);
628
-		} catch (\Exception $e) {
629
-			$cache->remove($to);
630
-
631
-			throw $e;
632
-		}
633
-	}
634
-
635
-	public function startChunkedWrite(string $targetPath): string {
636
-		if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
637
-			throw new GenericFileException('Object store does not support multipart upload');
638
-		}
639
-		$cacheEntry = $this->getCache()->get($targetPath);
640
-		$urn = $this->getURN($cacheEntry->getId());
641
-		return $this->objectStore->initiateMultipartUpload($urn);
642
-	}
643
-
644
-	/**
645
-	 *
646
-	 * @throws GenericFileException
647
-	 */
648
-	public function putChunkedWritePart(string $targetPath, string $writeToken, string $chunkId, $data, $size = null): ?array {
649
-		if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
650
-			throw new GenericFileException('Object store does not support multipart upload');
651
-		}
652
-		$cacheEntry = $this->getCache()->get($targetPath);
653
-		$urn = $this->getURN($cacheEntry->getId());
654
-
655
-		$result = $this->objectStore->uploadMultipartPart($urn, $writeToken, (int)$chunkId, $data, $size);
656
-
657
-		$parts[$chunkId] = [
658
-			'PartNumber' => $chunkId,
659
-			'ETag' => trim($result->get('ETag'), '"')
660
-		];
661
-		return $parts[$chunkId];
662
-	}
663
-
664
-	public function completeChunkedWrite(string $targetPath, string $writeToken): int {
665
-		if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
666
-			throw new GenericFileException('Object store does not support multipart upload');
667
-		}
668
-		$cacheEntry = $this->getCache()->get($targetPath);
669
-		$urn = $this->getURN($cacheEntry->getId());
670
-		$parts = $this->objectStore->getMultipartUploads($urn, $writeToken);
671
-		$sortedParts = array_values($parts);
672
-		sort($sortedParts);
673
-		try {
674
-			$size = $this->objectStore->completeMultipartUpload($urn, $writeToken, $sortedParts);
675
-			$stat = $this->stat($targetPath);
676
-			$mtime = time();
677
-			if (is_array($stat)) {
678
-				$stat['size'] = $size;
679
-				$stat['mtime'] = $mtime;
680
-				$stat['mimetype'] = $this->getMimeType($targetPath);
681
-				$this->getCache()->update($stat['fileid'], $stat);
682
-			}
683
-		} catch (S3MultipartUploadException | S3Exception $e) {
684
-			$this->objectStore->abortMultipartUpload($urn, $writeToken);
685
-			$this->logger->logException($e, [
686
-				'app' => 'objectstore',
687
-				'message' => 'Could not compete multipart upload ' . $urn. ' with uploadId ' . $writeToken
688
-			]);
689
-			throw new GenericFileException('Could not write chunked file');
690
-		}
691
-		return $size;
692
-	}
693
-
694
-	public function cancelChunkedWrite(string $targetPath, string $writeToken): void {
695
-		if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
696
-			throw new GenericFileException('Object store does not support multipart upload');
697
-		}
698
-		$cacheEntry = $this->getCache()->get($targetPath);
699
-		$urn = $this->getURN($cacheEntry->getId());
700
-		$this->objectStore->abortMultipartUpload($urn, $writeToken);
701
-	}
528
+                $this->getCache()->remove($uploadPath);
529
+                $this->logger->logException($ex, [
530
+                    'app' => 'objectstore',
531
+                    'message' => 'Could not create object ' . $urn . ' for ' . $path,
532
+                ]);
533
+            } else {
534
+                $this->logger->logException($ex, [
535
+                    'app' => 'objectstore',
536
+                    'message' => 'Could not update object ' . $urn . ' for ' . $path,
537
+                ]);
538
+            }
539
+            throw $ex; // make this bubble up
540
+        }
541
+
542
+        if ($exists) {
543
+            $this->getCache()->update($fileId, $stat);
544
+        } else {
545
+            if (!$this->validateWrites || $this->objectStore->objectExists($urn)) {
546
+                $this->getCache()->move($uploadPath, $path);
547
+            } else {
548
+                $this->getCache()->remove($uploadPath);
549
+                throw new \Exception("Object not found after writing (urn: $urn, path: $path)", 404);
550
+            }
551
+        }
552
+
553
+        return $size;
554
+    }
555
+
556
+    public function getObjectStore(): IObjectStore {
557
+        return $this->objectStore;
558
+    }
559
+
560
+    public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
561
+        if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class)) {
562
+            /** @var ObjectStoreStorage $sourceStorage */
563
+            if ($sourceStorage->getObjectStore()->getStorageId() === $this->getObjectStore()->getStorageId()) {
564
+                /** @var CacheEntry $sourceEntry */
565
+                $sourceEntry = $sourceStorage->getCache()->get($sourceInternalPath);
566
+                $sourceEntryData = $sourceEntry->getData();
567
+                // $sourceEntry['permissions'] here is the permissions from the jailed storage for the current
568
+                // user. Instead we use $sourceEntryData['scan_permissions'] that are the permissions from the
569
+                // unjailed storage.
570
+                if (is_array($sourceEntryData) && array_key_exists('scan_permissions', $sourceEntryData)) {
571
+                    $sourceEntry['permissions'] = $sourceEntryData['scan_permissions'];
572
+                }
573
+                $this->copyInner($sourceEntry, $targetInternalPath);
574
+                return true;
575
+            }
576
+        }
577
+
578
+        return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
579
+    }
580
+
581
+    public function copy($source, $target) {
582
+        $source = $this->normalizePath($source);
583
+        $target = $this->normalizePath($target);
584
+
585
+        $cache = $this->getCache();
586
+        $sourceEntry = $cache->get($source);
587
+        if (!$sourceEntry) {
588
+            throw new NotFoundException('Source object not found');
589
+        }
590
+
591
+        $this->copyInner($sourceEntry, $target);
592
+
593
+        return true;
594
+    }
595
+
596
+    private function copyInner(ICacheEntry $sourceEntry, string $to) {
597
+        $cache = $this->getCache();
598
+
599
+        if ($sourceEntry->getMimeType() === FileInfo::MIMETYPE_FOLDER) {
600
+            if ($cache->inCache($to)) {
601
+                $cache->remove($to);
602
+            }
603
+            $this->mkdir($to);
604
+
605
+            foreach ($cache->getFolderContentsById($sourceEntry->getId()) as $child) {
606
+                $this->copyInner($child, $to . '/' . $child->getName());
607
+            }
608
+        } else {
609
+            $this->copyFile($sourceEntry, $to);
610
+        }
611
+    }
612
+
613
+    private function copyFile(ICacheEntry $sourceEntry, string $to) {
614
+        $cache = $this->getCache();
615
+
616
+        $sourceUrn = $this->getURN($sourceEntry->getId());
617
+
618
+        if (!$cache instanceof Cache) {
619
+            throw new \Exception("Invalid source cache for object store copy");
620
+        }
621
+
622
+        $targetId = $cache->copyFromCache($cache, $sourceEntry, $to);
623
+
624
+        $targetUrn = $this->getURN($targetId);
625
+
626
+        try {
627
+            $this->objectStore->copyObject($sourceUrn, $targetUrn);
628
+        } catch (\Exception $e) {
629
+            $cache->remove($to);
630
+
631
+            throw $e;
632
+        }
633
+    }
634
+
635
+    public function startChunkedWrite(string $targetPath): string {
636
+        if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
637
+            throw new GenericFileException('Object store does not support multipart upload');
638
+        }
639
+        $cacheEntry = $this->getCache()->get($targetPath);
640
+        $urn = $this->getURN($cacheEntry->getId());
641
+        return $this->objectStore->initiateMultipartUpload($urn);
642
+    }
643
+
644
+    /**
645
+     *
646
+     * @throws GenericFileException
647
+     */
648
+    public function putChunkedWritePart(string $targetPath, string $writeToken, string $chunkId, $data, $size = null): ?array {
649
+        if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
650
+            throw new GenericFileException('Object store does not support multipart upload');
651
+        }
652
+        $cacheEntry = $this->getCache()->get($targetPath);
653
+        $urn = $this->getURN($cacheEntry->getId());
654
+
655
+        $result = $this->objectStore->uploadMultipartPart($urn, $writeToken, (int)$chunkId, $data, $size);
656
+
657
+        $parts[$chunkId] = [
658
+            'PartNumber' => $chunkId,
659
+            'ETag' => trim($result->get('ETag'), '"')
660
+        ];
661
+        return $parts[$chunkId];
662
+    }
663
+
664
+    public function completeChunkedWrite(string $targetPath, string $writeToken): int {
665
+        if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
666
+            throw new GenericFileException('Object store does not support multipart upload');
667
+        }
668
+        $cacheEntry = $this->getCache()->get($targetPath);
669
+        $urn = $this->getURN($cacheEntry->getId());
670
+        $parts = $this->objectStore->getMultipartUploads($urn, $writeToken);
671
+        $sortedParts = array_values($parts);
672
+        sort($sortedParts);
673
+        try {
674
+            $size = $this->objectStore->completeMultipartUpload($urn, $writeToken, $sortedParts);
675
+            $stat = $this->stat($targetPath);
676
+            $mtime = time();
677
+            if (is_array($stat)) {
678
+                $stat['size'] = $size;
679
+                $stat['mtime'] = $mtime;
680
+                $stat['mimetype'] = $this->getMimeType($targetPath);
681
+                $this->getCache()->update($stat['fileid'], $stat);
682
+            }
683
+        } catch (S3MultipartUploadException | S3Exception $e) {
684
+            $this->objectStore->abortMultipartUpload($urn, $writeToken);
685
+            $this->logger->logException($e, [
686
+                'app' => 'objectstore',
687
+                'message' => 'Could not compete multipart upload ' . $urn. ' with uploadId ' . $writeToken
688
+            ]);
689
+            throw new GenericFileException('Could not write chunked file');
690
+        }
691
+        return $size;
692
+    }
693
+
694
+    public function cancelChunkedWrite(string $targetPath, string $writeToken): void {
695
+        if (!$this->objectStore instanceof IObjectStoreMultiPartUpload) {
696
+            throw new GenericFileException('Object store does not support multipart upload');
697
+        }
698
+        $cacheEntry = $this->getCache()->get($targetPath);
699
+        $urn = $this->getURN($cacheEntry->getId());
700
+        $this->objectStore->abortMultipartUpload($urn, $writeToken);
701
+    }
702 702
 }
Please login to merge, or discard this patch.
Spacing   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -76,15 +76,15 @@  discard block
 block discarded – undo
76 76
 			throw new \Exception('missing IObjectStore instance');
77 77
 		}
78 78
 		if (isset($params['storageid'])) {
79
-			$this->id = 'object::store:' . $params['storageid'];
79
+			$this->id = 'object::store:'.$params['storageid'];
80 80
 		} else {
81
-			$this->id = 'object::store:' . $this->objectStore->getStorageId();
81
+			$this->id = 'object::store:'.$this->objectStore->getStorageId();
82 82
 		}
83 83
 		if (isset($params['objectPrefix'])) {
84 84
 			$this->objectPrefix = $params['objectPrefix'];
85 85
 		}
86 86
 		if (isset($params['validateWrites'])) {
87
-			$this->validateWrites = (bool)$params['validateWrites'];
87
+			$this->validateWrites = (bool) $params['validateWrites'];
88 88
 		}
89 89
 		//initialize cache with root directory in cache
90 90
 		if (!$this->is_dir('/')) {
@@ -222,7 +222,7 @@  discard block
 block discarded – undo
222 222
 				if ($ex->getCode() !== 404) {
223 223
 					$this->logger->logException($ex, [
224 224
 						'app' => 'objectstore',
225
-						'message' => 'Could not delete object ' . $this->getURN($stat['fileid']) . ' for ' . $path,
225
+						'message' => 'Could not delete object '.$this->getURN($stat['fileid']).' for '.$path,
226 226
 					]);
227 227
 					return false;
228 228
 				}
@@ -264,7 +264,7 @@  discard block
 block discarded – undo
264 264
 	 */
265 265
 	public function getURN($fileId) {
266 266
 		if (is_numeric($fileId)) {
267
-			return $this->objectPrefix . $fileId;
267
+			return $this->objectPrefix.$fileId;
268 268
 		}
269 269
 		return null;
270 270
 	}
@@ -327,19 +327,19 @@  discard block
 block discarded – undo
327 327
 						$streamStat = fstat($handle);
328 328
 						$actualSize = $streamStat['size'] ?? -1;
329 329
 						if ($actualSize > -1 && $actualSize !== $filesize) {
330
-							$this->getCache()->update((int)$stat['fileid'], ['size' => $actualSize]);
330
+							$this->getCache()->update((int) $stat['fileid'], ['size' => $actualSize]);
331 331
 						}
332 332
 						return $handle;
333 333
 					} catch (NotFoundException $e) {
334 334
 						$this->logger->logException($e, [
335 335
 							'app' => 'objectstore',
336
-							'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
336
+							'message' => 'Could not get object '.$this->getURN($stat['fileid']).' for file '.$path,
337 337
 						]);
338 338
 						throw $e;
339 339
 					} catch (\Exception $ex) {
340 340
 						$this->logger->logException($ex, [
341 341
 							'app' => 'objectstore',
342
-							'message' => 'Could not get object ' . $this->getURN($stat['fileid']) . ' for file ' . $path,
342
+							'message' => 'Could not get object '.$this->getURN($stat['fileid']).' for file '.$path,
343 343
 						]);
344 344
 						return false;
345 345
 					}
@@ -353,7 +353,7 @@  discard block
 block discarded – undo
353 353
 			case 'wb+':
354 354
 				$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
355 355
 				$handle = fopen($tmpFile, $mode);
356
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
356
+				return CallbackWrapper::wrap($handle, null, null, function() use ($path, $tmpFile) {
357 357
 					$this->writeBack($tmpFile, $path);
358 358
 					unlink($tmpFile);
359 359
 				});
@@ -371,7 +371,7 @@  discard block
 block discarded – undo
371 371
 					file_put_contents($tmpFile, $source);
372 372
 				}
373 373
 				$handle = fopen($tmpFile, $mode);
374
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
374
+				return CallbackWrapper::wrap($handle, null, null, function() use ($path, $tmpFile) {
375 375
 					$this->writeBack($tmpFile, $path);
376 376
 					unlink($tmpFile);
377 377
 				});
@@ -381,7 +381,7 @@  discard block
 block discarded – undo
381 381
 
382 382
 	public function file_exists($path) {
383 383
 		$path = $this->normalizePath($path);
384
-		return (bool)$this->stat($path);
384
+		return (bool) $this->stat($path);
385 385
 	}
386 386
 
387 387
 	public function rename($source, $target) {
@@ -433,7 +433,7 @@  discard block
 block discarded – undo
433 433
 			} catch (\Exception $ex) {
434 434
 				$this->logger->logException($ex, [
435 435
 					'app' => 'objectstore',
436
-					'message' => 'Could not create object for ' . $path,
436
+					'message' => 'Could not create object for '.$path,
437 437
 				]);
438 438
 				throw $ex;
439 439
 			}
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
 		}
479 479
 		// update stat with new data
480 480
 		$mTime = time();
481
-		$stat['size'] = (int)$size;
481
+		$stat['size'] = (int) $size;
482 482
 		$stat['mtime'] = $mTime;
483 483
 		$stat['storage_mtime'] = $mTime;
484 484
 
@@ -490,7 +490,7 @@  discard block
 block discarded – undo
490 490
 		$stat['checksum'] = '';
491 491
 
492 492
 		$exists = $this->getCache()->inCache($path);
493
-		$uploadPath = $exists ? $path : $path . '.part';
493
+		$uploadPath = $exists ? $path : $path.'.part';
494 494
 
495 495
 		if ($exists) {
496 496
 			$fileId = $stat['fileid'];
@@ -502,7 +502,7 @@  discard block
 block discarded – undo
502 502
 		try {
503 503
 			//upload to object storage
504 504
 			if ($size === null) {
505
-				$countStream = CountWrapper::wrap($stream, function ($writtenSize) use ($fileId, &$size) {
505
+				$countStream = CountWrapper::wrap($stream, function($writtenSize) use ($fileId, &$size) {
506 506
 					$this->getCache()->update($fileId, [
507 507
 						'size' => $writtenSize,
508 508
 					]);
@@ -528,12 +528,12 @@  discard block
 block discarded – undo
528 528
 				$this->getCache()->remove($uploadPath);
529 529
 				$this->logger->logException($ex, [
530 530
 					'app' => 'objectstore',
531
-					'message' => 'Could not create object ' . $urn . ' for ' . $path,
531
+					'message' => 'Could not create object '.$urn.' for '.$path,
532 532
 				]);
533 533
 			} else {
534 534
 				$this->logger->logException($ex, [
535 535
 					'app' => 'objectstore',
536
-					'message' => 'Could not update object ' . $urn . ' for ' . $path,
536
+					'message' => 'Could not update object '.$urn.' for '.$path,
537 537
 				]);
538 538
 			}
539 539
 			throw $ex; // make this bubble up
@@ -603,7 +603,7 @@  discard block
 block discarded – undo
603 603
 			$this->mkdir($to);
604 604
 
605 605
 			foreach ($cache->getFolderContentsById($sourceEntry->getId()) as $child) {
606
-				$this->copyInner($child, $to . '/' . $child->getName());
606
+				$this->copyInner($child, $to.'/'.$child->getName());
607 607
 			}
608 608
 		} else {
609 609
 			$this->copyFile($sourceEntry, $to);
@@ -652,7 +652,7 @@  discard block
 block discarded – undo
652 652
 		$cacheEntry = $this->getCache()->get($targetPath);
653 653
 		$urn = $this->getURN($cacheEntry->getId());
654 654
 
655
-		$result = $this->objectStore->uploadMultipartPart($urn, $writeToken, (int)$chunkId, $data, $size);
655
+		$result = $this->objectStore->uploadMultipartPart($urn, $writeToken, (int) $chunkId, $data, $size);
656 656
 
657 657
 		$parts[$chunkId] = [
658 658
 			'PartNumber' => $chunkId,
@@ -684,7 +684,7 @@  discard block
 block discarded – undo
684 684
 			$this->objectStore->abortMultipartUpload($urn, $writeToken);
685 685
 			$this->logger->logException($e, [
686 686
 				'app' => 'objectstore',
687
-				'message' => 'Could not compete multipart upload ' . $urn. ' with uploadId ' . $writeToken
687
+				'message' => 'Could not compete multipart upload '.$urn.' with uploadId '.$writeToken
688 688
 			]);
689 689
 			throw new GenericFileException('Could not write chunked file');
690 690
 		}
Please login to merge, or discard this patch.
apps/dav/lib/Connector/Sabre/Node.php 1 patch
Indentation   +368 added lines, -368 removed lines patch added patch discarded remove patch
@@ -48,377 +48,377 @@
 block discarded – undo
48 48
 use OCP\Share\IManager;
49 49
 
50 50
 abstract class Node implements \Sabre\DAV\INode {
51
-	/**
52
-	 * @var View
53
-	 */
54
-	protected $fileView;
55
-
56
-	/**
57
-	 * The path to the current node
58
-	 *
59
-	 * @var string
60
-	 */
61
-	protected $path;
62
-
63
-	/**
64
-	 * node properties cache
65
-	 *
66
-	 * @var array
67
-	 */
68
-	protected $property_cache = null;
69
-
70
-	protected FileInfo $info;
71
-
72
-	/**
73
-	 * @var IManager
74
-	 */
75
-	protected $shareManager;
76
-
77
-	protected \OCP\Files\Node $node;
78
-
79
-	/**
80
-	 * Sets up the node, expects a full path name
81
-	 */
82
-	public function __construct(View $view, FileInfo $info, IManager $shareManager = null) {
83
-		$this->fileView = $view;
84
-		$this->path = $this->fileView->getRelativePath($info->getPath());
85
-		$this->info = $info;
86
-		if ($shareManager) {
87
-			$this->shareManager = $shareManager;
88
-		} else {
89
-			$this->shareManager = \OC::$server->getShareManager();
90
-		}
91
-		if ($info instanceof Folder || $info instanceof File) {
92
-			$this->node = $info;
93
-		} else {
94
-			$root = \OC::$server->get(IRootFolder::class);
95
-			if ($info->getType() === FileInfo::TYPE_FOLDER) {
96
-				$this->node = new Folder($root, $view, $this->path, $info);
97
-			} else {
98
-				$this->node = new File($root, $view, $this->path, $info);
99
-			}
100
-		}
101
-	}
102
-
103
-	protected function refreshInfo(): void {
104
-		$info = $this->fileView->getFileInfo($this->path);
105
-		if ($info === false) {
106
-			throw new \Sabre\DAV\Exception('Failed to get fileinfo for '. $this->path);
107
-		}
108
-		$this->info = $info;
109
-		$root = \OC::$server->get(IRootFolder::class);
110
-		if ($this->info->getType() === FileInfo::TYPE_FOLDER) {
111
-			$this->node = new Folder($root, $this->fileView, $this->path, $this->info);
112
-		} else {
113
-			$this->node = new File($root, $this->fileView, $this->path, $this->info);
114
-		}
115
-	}
116
-
117
-	/**
118
-	 *  Returns the name of the node
119
-	 *
120
-	 * @return string
121
-	 */
122
-	public function getName() {
123
-		return $this->info->getName();
124
-	}
125
-
126
-	/**
127
-	 * Returns the full path
128
-	 *
129
-	 * @return string
130
-	 */
131
-	public function getPath() {
132
-		return $this->path;
133
-	}
134
-
135
-	/**
136
-	 * Renames the node
137
-	 *
138
-	 * @param string $name The new name
139
-	 * @throws \Sabre\DAV\Exception\BadRequest
140
-	 * @throws \Sabre\DAV\Exception\Forbidden
141
-	 */
142
-	public function setName($name) {
143
-		// rename is only allowed if the update privilege is granted
144
-		if (!($this->info->isUpdateable() || ($this->info->getMountPoint() instanceof MoveableMount && $this->info->getInternalPath() === ''))) {
145
-			throw new \Sabre\DAV\Exception\Forbidden();
146
-		}
147
-
148
-		[$parentPath,] = \Sabre\Uri\split($this->path);
149
-		[, $newName] = \Sabre\Uri\split($name);
150
-
151
-		// verify path of the target
152
-		$this->verifyPath();
153
-
154
-		$newPath = $parentPath . '/' . $newName;
155
-
156
-		if (!$this->fileView->rename($this->path, $newPath)) {
157
-			throw new \Sabre\DAV\Exception('Failed to rename '. $this->path . ' to ' . $newPath);
158
-		}
159
-
160
-		$this->path = $newPath;
161
-
162
-		$this->refreshInfo();
163
-	}
164
-
165
-	public function setPropertyCache($property_cache) {
166
-		$this->property_cache = $property_cache;
167
-	}
168
-
169
-	/**
170
-	 * Returns the last modification time, as a unix timestamp
171
-	 *
172
-	 * @return int timestamp as integer
173
-	 */
174
-	public function getLastModified() {
175
-		$timestamp = $this->info->getMtime();
176
-		if (!empty($timestamp)) {
177
-			return (int)$timestamp;
178
-		}
179
-		return $timestamp;
180
-	}
181
-
182
-	/**
183
-	 *  sets the last modification time of the file (mtime) to the value given
184
-	 *  in the second parameter or to now if the second param is empty.
185
-	 *  Even if the modification time is set to a custom value the access time is set to now.
186
-	 */
187
-	public function touch($mtime) {
188
-		$mtime = $this->sanitizeMtime($mtime);
189
-		$this->fileView->touch($this->path, $mtime);
190
-		$this->refreshInfo();
191
-	}
192
-
193
-	/**
194
-	 * Returns the ETag for a file
195
-	 *
196
-	 * An ETag is a unique identifier representing the current version of the
197
-	 * file. If the file changes, the ETag MUST change.  The ETag is an
198
-	 * arbitrary string, but MUST be surrounded by double-quotes.
199
-	 *
200
-	 * Return null if the ETag can not effectively be determined
201
-	 *
202
-	 * @return string
203
-	 */
204
-	public function getETag() {
205
-		return '"' . $this->info->getEtag() . '"';
206
-	}
207
-
208
-	/**
209
-	 * Sets the ETag
210
-	 *
211
-	 * @param string $etag
212
-	 *
213
-	 * @return int file id of updated file or -1 on failure
214
-	 */
215
-	public function setETag($etag) {
216
-		return $this->fileView->putFileInfo($this->path, ['etag' => $etag]);
217
-	}
218
-
219
-	public function setCreationTime(int $time) {
220
-		return $this->fileView->putFileInfo($this->path, ['creation_time' => $time]);
221
-	}
222
-
223
-	public function setUploadTime(int $time) {
224
-		return $this->fileView->putFileInfo($this->path, ['upload_time' => $time]);
225
-	}
226
-
227
-	/**
228
-	 * Returns the size of the node, in bytes
229
-	 *
230
-	 * @psalm-suppress ImplementedReturnTypeMismatch \Sabre\DAV\IFile::getSize signature does not support 32bit
231
-	 * @return int|float
232
-	 */
233
-	public function getSize(): int|float {
234
-		return $this->info->getSize();
235
-	}
236
-
237
-	/**
238
-	 * Returns the cache's file id
239
-	 *
240
-	 * @return int
241
-	 */
242
-	public function getId() {
243
-		return $this->info->getId();
244
-	}
245
-
246
-	/**
247
-	 * @return string|null
248
-	 */
249
-	public function getFileId() {
250
-		if ($id = $this->info->getId()) {
251
-			return DavUtil::getDavFileId($id);
252
-		}
253
-
254
-		return null;
255
-	}
256
-
257
-	/**
258
-	 * @return integer
259
-	 */
260
-	public function getInternalFileId() {
261
-		return $this->info->getId();
262
-	}
263
-
264
-	public function getInternalPath(): string {
265
-		return $this->info->getInternalPath();
266
-	}
267
-
268
-	/**
269
-	 * @param string $user
270
-	 * @return int
271
-	 */
272
-	public function getSharePermissions($user) {
273
-		// check of we access a federated share
274
-		if ($user !== null) {
275
-			try {
276
-				$share = $this->shareManager->getShareByToken($user);
277
-				return $share->getPermissions();
278
-			} catch (ShareNotFound $e) {
279
-				// ignore
280
-			}
281
-		}
282
-
283
-		try {
284
-			$storage = $this->info->getStorage();
285
-		} catch (StorageNotAvailableException $e) {
286
-			$storage = null;
287
-		}
288
-
289
-		if ($storage && $storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) {
290
-			/** @var \OCA\Files_Sharing\SharedStorage $storage */
291
-			$permissions = (int)$storage->getShare()->getPermissions();
292
-		} else {
293
-			$permissions = $this->info->getPermissions();
294
-		}
295
-
296
-		/*
51
+    /**
52
+     * @var View
53
+     */
54
+    protected $fileView;
55
+
56
+    /**
57
+     * The path to the current node
58
+     *
59
+     * @var string
60
+     */
61
+    protected $path;
62
+
63
+    /**
64
+     * node properties cache
65
+     *
66
+     * @var array
67
+     */
68
+    protected $property_cache = null;
69
+
70
+    protected FileInfo $info;
71
+
72
+    /**
73
+     * @var IManager
74
+     */
75
+    protected $shareManager;
76
+
77
+    protected \OCP\Files\Node $node;
78
+
79
+    /**
80
+     * Sets up the node, expects a full path name
81
+     */
82
+    public function __construct(View $view, FileInfo $info, IManager $shareManager = null) {
83
+        $this->fileView = $view;
84
+        $this->path = $this->fileView->getRelativePath($info->getPath());
85
+        $this->info = $info;
86
+        if ($shareManager) {
87
+            $this->shareManager = $shareManager;
88
+        } else {
89
+            $this->shareManager = \OC::$server->getShareManager();
90
+        }
91
+        if ($info instanceof Folder || $info instanceof File) {
92
+            $this->node = $info;
93
+        } else {
94
+            $root = \OC::$server->get(IRootFolder::class);
95
+            if ($info->getType() === FileInfo::TYPE_FOLDER) {
96
+                $this->node = new Folder($root, $view, $this->path, $info);
97
+            } else {
98
+                $this->node = new File($root, $view, $this->path, $info);
99
+            }
100
+        }
101
+    }
102
+
103
+    protected function refreshInfo(): void {
104
+        $info = $this->fileView->getFileInfo($this->path);
105
+        if ($info === false) {
106
+            throw new \Sabre\DAV\Exception('Failed to get fileinfo for '. $this->path);
107
+        }
108
+        $this->info = $info;
109
+        $root = \OC::$server->get(IRootFolder::class);
110
+        if ($this->info->getType() === FileInfo::TYPE_FOLDER) {
111
+            $this->node = new Folder($root, $this->fileView, $this->path, $this->info);
112
+        } else {
113
+            $this->node = new File($root, $this->fileView, $this->path, $this->info);
114
+        }
115
+    }
116
+
117
+    /**
118
+     *  Returns the name of the node
119
+     *
120
+     * @return string
121
+     */
122
+    public function getName() {
123
+        return $this->info->getName();
124
+    }
125
+
126
+    /**
127
+     * Returns the full path
128
+     *
129
+     * @return string
130
+     */
131
+    public function getPath() {
132
+        return $this->path;
133
+    }
134
+
135
+    /**
136
+     * Renames the node
137
+     *
138
+     * @param string $name The new name
139
+     * @throws \Sabre\DAV\Exception\BadRequest
140
+     * @throws \Sabre\DAV\Exception\Forbidden
141
+     */
142
+    public function setName($name) {
143
+        // rename is only allowed if the update privilege is granted
144
+        if (!($this->info->isUpdateable() || ($this->info->getMountPoint() instanceof MoveableMount && $this->info->getInternalPath() === ''))) {
145
+            throw new \Sabre\DAV\Exception\Forbidden();
146
+        }
147
+
148
+        [$parentPath,] = \Sabre\Uri\split($this->path);
149
+        [, $newName] = \Sabre\Uri\split($name);
150
+
151
+        // verify path of the target
152
+        $this->verifyPath();
153
+
154
+        $newPath = $parentPath . '/' . $newName;
155
+
156
+        if (!$this->fileView->rename($this->path, $newPath)) {
157
+            throw new \Sabre\DAV\Exception('Failed to rename '. $this->path . ' to ' . $newPath);
158
+        }
159
+
160
+        $this->path = $newPath;
161
+
162
+        $this->refreshInfo();
163
+    }
164
+
165
+    public function setPropertyCache($property_cache) {
166
+        $this->property_cache = $property_cache;
167
+    }
168
+
169
+    /**
170
+     * Returns the last modification time, as a unix timestamp
171
+     *
172
+     * @return int timestamp as integer
173
+     */
174
+    public function getLastModified() {
175
+        $timestamp = $this->info->getMtime();
176
+        if (!empty($timestamp)) {
177
+            return (int)$timestamp;
178
+        }
179
+        return $timestamp;
180
+    }
181
+
182
+    /**
183
+     *  sets the last modification time of the file (mtime) to the value given
184
+     *  in the second parameter or to now if the second param is empty.
185
+     *  Even if the modification time is set to a custom value the access time is set to now.
186
+     */
187
+    public function touch($mtime) {
188
+        $mtime = $this->sanitizeMtime($mtime);
189
+        $this->fileView->touch($this->path, $mtime);
190
+        $this->refreshInfo();
191
+    }
192
+
193
+    /**
194
+     * Returns the ETag for a file
195
+     *
196
+     * An ETag is a unique identifier representing the current version of the
197
+     * file. If the file changes, the ETag MUST change.  The ETag is an
198
+     * arbitrary string, but MUST be surrounded by double-quotes.
199
+     *
200
+     * Return null if the ETag can not effectively be determined
201
+     *
202
+     * @return string
203
+     */
204
+    public function getETag() {
205
+        return '"' . $this->info->getEtag() . '"';
206
+    }
207
+
208
+    /**
209
+     * Sets the ETag
210
+     *
211
+     * @param string $etag
212
+     *
213
+     * @return int file id of updated file or -1 on failure
214
+     */
215
+    public function setETag($etag) {
216
+        return $this->fileView->putFileInfo($this->path, ['etag' => $etag]);
217
+    }
218
+
219
+    public function setCreationTime(int $time) {
220
+        return $this->fileView->putFileInfo($this->path, ['creation_time' => $time]);
221
+    }
222
+
223
+    public function setUploadTime(int $time) {
224
+        return $this->fileView->putFileInfo($this->path, ['upload_time' => $time]);
225
+    }
226
+
227
+    /**
228
+     * Returns the size of the node, in bytes
229
+     *
230
+     * @psalm-suppress ImplementedReturnTypeMismatch \Sabre\DAV\IFile::getSize signature does not support 32bit
231
+     * @return int|float
232
+     */
233
+    public function getSize(): int|float {
234
+        return $this->info->getSize();
235
+    }
236
+
237
+    /**
238
+     * Returns the cache's file id
239
+     *
240
+     * @return int
241
+     */
242
+    public function getId() {
243
+        return $this->info->getId();
244
+    }
245
+
246
+    /**
247
+     * @return string|null
248
+     */
249
+    public function getFileId() {
250
+        if ($id = $this->info->getId()) {
251
+            return DavUtil::getDavFileId($id);
252
+        }
253
+
254
+        return null;
255
+    }
256
+
257
+    /**
258
+     * @return integer
259
+     */
260
+    public function getInternalFileId() {
261
+        return $this->info->getId();
262
+    }
263
+
264
+    public function getInternalPath(): string {
265
+        return $this->info->getInternalPath();
266
+    }
267
+
268
+    /**
269
+     * @param string $user
270
+     * @return int
271
+     */
272
+    public function getSharePermissions($user) {
273
+        // check of we access a federated share
274
+        if ($user !== null) {
275
+            try {
276
+                $share = $this->shareManager->getShareByToken($user);
277
+                return $share->getPermissions();
278
+            } catch (ShareNotFound $e) {
279
+                // ignore
280
+            }
281
+        }
282
+
283
+        try {
284
+            $storage = $this->info->getStorage();
285
+        } catch (StorageNotAvailableException $e) {
286
+            $storage = null;
287
+        }
288
+
289
+        if ($storage && $storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) {
290
+            /** @var \OCA\Files_Sharing\SharedStorage $storage */
291
+            $permissions = (int)$storage->getShare()->getPermissions();
292
+        } else {
293
+            $permissions = $this->info->getPermissions();
294
+        }
295
+
296
+        /*
297 297
 		 * We can always share non moveable mount points with DELETE and UPDATE
298 298
 		 * Eventually we need to do this properly
299 299
 		 */
300
-		$mountpoint = $this->info->getMountPoint();
301
-		if (!($mountpoint instanceof MoveableMount)) {
302
-			$mountpointpath = $mountpoint->getMountPoint();
303
-			if (substr($mountpointpath, -1) === '/') {
304
-				$mountpointpath = substr($mountpointpath, 0, -1);
305
-			}
306
-
307
-			if (!$mountpoint->getOption('readonly', false) && $mountpointpath === $this->info->getPath()) {
308
-				$permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
309
-			}
310
-		}
311
-
312
-		/*
300
+        $mountpoint = $this->info->getMountPoint();
301
+        if (!($mountpoint instanceof MoveableMount)) {
302
+            $mountpointpath = $mountpoint->getMountPoint();
303
+            if (substr($mountpointpath, -1) === '/') {
304
+                $mountpointpath = substr($mountpointpath, 0, -1);
305
+            }
306
+
307
+            if (!$mountpoint->getOption('readonly', false) && $mountpointpath === $this->info->getPath()) {
308
+                $permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
309
+            }
310
+        }
311
+
312
+        /*
313 313
 		 * Files can't have create or delete permissions
314 314
 		 */
315
-		if ($this->info->getType() === \OCP\Files\FileInfo::TYPE_FILE) {
316
-			$permissions &= ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE);
317
-		}
318
-
319
-		return $permissions;
320
-	}
321
-
322
-	/**
323
-	 * @return array
324
-	 */
325
-	public function getShareAttributes(): array {
326
-		$attributes = [];
327
-
328
-		try {
329
-			$storage = $this->info->getStorage();
330
-		} catch (StorageNotAvailableException $e) {
331
-			$storage = null;
332
-		}
333
-
334
-		if ($storage && $storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) {
335
-			/** @var \OCA\Files_Sharing\SharedStorage $storage */
336
-			$attributes = $storage->getShare()->getAttributes();
337
-			if ($attributes === null) {
338
-				return [];
339
-			} else {
340
-				return $attributes->toArray();
341
-			}
342
-		}
343
-
344
-		return $attributes;
345
-	}
346
-
347
-	/**
348
-	 * @param string $user
349
-	 * @return string
350
-	 */
351
-	public function getNoteFromShare($user) {
352
-		if ($user === null) {
353
-			return '';
354
-		}
355
-
356
-		// Retrieve note from the share object already loaded into
357
-		// memory, to avoid additional database queries.
358
-		$storage = $this->getNode()->getStorage();
359
-		if (!$storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) {
360
-			return '';
361
-		}
362
-		/** @var \OCA\Files_Sharing\SharedStorage $storage */
363
-
364
-		$share = $storage->getShare();
365
-		$note = $share->getNote();
366
-		if ($share->getShareOwner() !== $user) {
367
-			return $note;
368
-		}
369
-		return '';
370
-	}
371
-
372
-	/**
373
-	 * @return string
374
-	 */
375
-	public function getDavPermissions() {
376
-		return DavUtil::getDavPermissions($this->info);
377
-	}
378
-
379
-	public function getOwner() {
380
-		return $this->info->getOwner();
381
-	}
382
-
383
-	protected function verifyPath() {
384
-		try {
385
-			$fileName = basename($this->info->getPath());
386
-			$this->fileView->verifyPath($this->path, $fileName);
387
-		} catch (\OCP\Files\InvalidPathException $ex) {
388
-			throw new InvalidPath($ex->getMessage());
389
-		}
390
-	}
391
-
392
-	/**
393
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
394
-	 */
395
-	public function acquireLock($type) {
396
-		$this->fileView->lockFile($this->path, $type);
397
-	}
398
-
399
-	/**
400
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
401
-	 */
402
-	public function releaseLock($type) {
403
-		$this->fileView->unlockFile($this->path, $type);
404
-	}
405
-
406
-	/**
407
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
408
-	 */
409
-	public function changeLock($type) {
410
-		$this->fileView->changeLock($this->path, $type);
411
-	}
412
-
413
-	public function getFileInfo() {
414
-		return $this->info;
415
-	}
416
-
417
-	public function getNode(): \OCP\Files\Node {
418
-		return $this->node;
419
-	}
420
-
421
-	protected function sanitizeMtime($mtimeFromRequest) {
422
-		return MtimeSanitizer::sanitizeMtime($mtimeFromRequest);
423
-	}
315
+        if ($this->info->getType() === \OCP\Files\FileInfo::TYPE_FILE) {
316
+            $permissions &= ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE);
317
+        }
318
+
319
+        return $permissions;
320
+    }
321
+
322
+    /**
323
+     * @return array
324
+     */
325
+    public function getShareAttributes(): array {
326
+        $attributes = [];
327
+
328
+        try {
329
+            $storage = $this->info->getStorage();
330
+        } catch (StorageNotAvailableException $e) {
331
+            $storage = null;
332
+        }
333
+
334
+        if ($storage && $storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) {
335
+            /** @var \OCA\Files_Sharing\SharedStorage $storage */
336
+            $attributes = $storage->getShare()->getAttributes();
337
+            if ($attributes === null) {
338
+                return [];
339
+            } else {
340
+                return $attributes->toArray();
341
+            }
342
+        }
343
+
344
+        return $attributes;
345
+    }
346
+
347
+    /**
348
+     * @param string $user
349
+     * @return string
350
+     */
351
+    public function getNoteFromShare($user) {
352
+        if ($user === null) {
353
+            return '';
354
+        }
355
+
356
+        // Retrieve note from the share object already loaded into
357
+        // memory, to avoid additional database queries.
358
+        $storage = $this->getNode()->getStorage();
359
+        if (!$storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) {
360
+            return '';
361
+        }
362
+        /** @var \OCA\Files_Sharing\SharedStorage $storage */
363
+
364
+        $share = $storage->getShare();
365
+        $note = $share->getNote();
366
+        if ($share->getShareOwner() !== $user) {
367
+            return $note;
368
+        }
369
+        return '';
370
+    }
371
+
372
+    /**
373
+     * @return string
374
+     */
375
+    public function getDavPermissions() {
376
+        return DavUtil::getDavPermissions($this->info);
377
+    }
378
+
379
+    public function getOwner() {
380
+        return $this->info->getOwner();
381
+    }
382
+
383
+    protected function verifyPath() {
384
+        try {
385
+            $fileName = basename($this->info->getPath());
386
+            $this->fileView->verifyPath($this->path, $fileName);
387
+        } catch (\OCP\Files\InvalidPathException $ex) {
388
+            throw new InvalidPath($ex->getMessage());
389
+        }
390
+    }
391
+
392
+    /**
393
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
394
+     */
395
+    public function acquireLock($type) {
396
+        $this->fileView->lockFile($this->path, $type);
397
+    }
398
+
399
+    /**
400
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
401
+     */
402
+    public function releaseLock($type) {
403
+        $this->fileView->unlockFile($this->path, $type);
404
+    }
405
+
406
+    /**
407
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
408
+     */
409
+    public function changeLock($type) {
410
+        $this->fileView->changeLock($this->path, $type);
411
+    }
412
+
413
+    public function getFileInfo() {
414
+        return $this->info;
415
+    }
416
+
417
+    public function getNode(): \OCP\Files\Node {
418
+        return $this->node;
419
+    }
420
+
421
+    protected function sanitizeMtime($mtimeFromRequest) {
422
+        return MtimeSanitizer::sanitizeMtime($mtimeFromRequest);
423
+    }
424 424
 }
Please login to merge, or discard this patch.
apps/dav/lib/Server.php 1 patch
Indentation   +295 added lines, -295 removed lines patch added patch discarded remove patch
@@ -86,299 +86,299 @@
 block discarded – undo
86 86
 use SearchDAV\DAV\SearchPlugin;
87 87
 
88 88
 class Server {
89
-	private IRequest $request;
90
-	private string $baseUri;
91
-	public Connector\Sabre\Server $server;
92
-	private IProfiler $profiler;
93
-
94
-	public function __construct(IRequest $request, string $baseUri) {
95
-		$this->profiler = \OC::$server->get(IProfiler::class);
96
-		if ($this->profiler->isEnabled()) {
97
-			/** @var IEventLogger $eventLogger */
98
-			$eventLogger = \OC::$server->get(IEventLogger::class);
99
-			$eventLogger->start('runtime', 'DAV Runtime');
100
-		}
101
-
102
-		$this->request = $request;
103
-		$this->baseUri = $baseUri;
104
-		$logger = \OC::$server->get(LoggerInterface::class);
105
-		$dispatcher = \OC::$server->getEventDispatcher();
106
-		/** @var IEventDispatcher $newDispatcher */
107
-		$newDispatcher = \OC::$server->query(IEventDispatcher::class);
108
-
109
-		$root = new RootCollection();
110
-		$this->server = new \OCA\DAV\Connector\Sabre\Server(new CachingTree($root));
111
-
112
-		// Add maintenance plugin
113
-		$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin(\OC::$server->getConfig(), \OC::$server->getL10N('dav')));
114
-
115
-		// Backends
116
-		$authBackend = new Auth(
117
-			\OC::$server->getSession(),
118
-			\OC::$server->getUserSession(),
119
-			\OC::$server->getRequest(),
120
-			\OC::$server->getTwoFactorAuthManager(),
121
-			\OC::$server->getBruteForceThrottler()
122
-		);
123
-
124
-		// Set URL explicitly due to reverse-proxy situations
125
-		$this->server->httpRequest->setUrl($this->request->getRequestUri());
126
-		$this->server->setBaseUri($this->baseUri);
127
-
128
-		$this->server->addPlugin(new ProfilerPlugin($this->request));
129
-		$this->server->addPlugin(new BlockLegacyClientPlugin(\OC::$server->getConfig()));
130
-		$this->server->addPlugin(new AnonymousOptionsPlugin());
131
-		$authPlugin = new Plugin();
132
-		$authPlugin->addBackend(new PublicAuth());
133
-		$this->server->addPlugin($authPlugin);
134
-
135
-		// allow setup of additional auth backends
136
-		$event = new SabrePluginEvent($this->server);
137
-		$dispatcher->dispatch('OCA\DAV\Connector\Sabre::authInit', $event);
138
-
139
-		$newAuthEvent = new SabrePluginAuthInitEvent($this->server);
140
-		$newDispatcher->dispatchTyped($newAuthEvent);
141
-
142
-		$bearerAuthBackend = new BearerAuth(
143
-			\OC::$server->getUserSession(),
144
-			\OC::$server->getSession(),
145
-			\OC::$server->getRequest()
146
-		);
147
-		$authPlugin->addBackend($bearerAuthBackend);
148
-		// because we are throwing exceptions this plugin has to be the last one
149
-		$authPlugin->addBackend($authBackend);
150
-
151
-		// debugging
152
-		if (\OC::$server->getConfig()->getSystemValue('debug', false)) {
153
-			$this->server->addPlugin(new \Sabre\DAV\Browser\Plugin());
154
-		} else {
155
-			$this->server->addPlugin(new DummyGetResponsePlugin());
156
-		}
157
-
158
-		$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $logger));
159
-		$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\LockPlugin());
160
-		$this->server->addPlugin(new \Sabre\DAV\Sync\Plugin());
161
-
162
-		// acl
163
-		$acl = new DavAclPlugin();
164
-		$acl->principalCollectionSet = [
165
-			'principals/users',
166
-			'principals/groups',
167
-			'principals/calendar-resources',
168
-			'principals/calendar-rooms',
169
-		];
170
-		$this->server->addPlugin($acl);
171
-
172
-		// calendar plugins
173
-		if ($this->requestIsForSubtree(['calendars', 'public-calendars', 'system-calendars', 'principals'])) {
174
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\Plugin());
175
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\ICSExportPlugin\ICSExportPlugin(\OC::$server->getConfig(), $logger));
176
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(\OC::$server->getConfig(), \OC::$server->get(LoggerInterface::class)));
177
-			if (\OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') {
178
-				$this->server->addPlugin(\OC::$server->query(\OCA\DAV\CalDAV\Schedule\IMipPlugin::class));
179
-			}
180
-
181
-			$this->server->addPlugin(\OC::$server->get(\OCA\DAV\CalDAV\Trashbin\Plugin::class));
182
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\WebcalCaching\Plugin($request));
183
-			if (\OC::$server->getConfig()->getAppValue('dav', 'allow_calendar_link_subscriptions', 'yes') === 'yes') {
184
-				$this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin());
185
-			}
186
-
187
-			$this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin());
188
-			$this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest(), \OC::$server->getConfig()));
189
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\Publishing\PublishPlugin(
190
-				\OC::$server->getConfig(),
191
-				\OC::$server->getURLGenerator()
192
-			));
193
-		}
194
-
195
-		// addressbook plugins
196
-		if ($this->requestIsForSubtree(['addressbooks', 'principals'])) {
197
-			$this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest(), \OC::$server->getConfig()));
198
-			$this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin());
199
-			$this->server->addPlugin(new VCFExportPlugin());
200
-			$this->server->addPlugin(new MultiGetExportPlugin());
201
-			$this->server->addPlugin(new HasPhotoPlugin());
202
-			$this->server->addPlugin(new ImageExportPlugin(new PhotoCache(
203
-				\OC::$server->getAppDataDir('dav-photocache'),
204
-				$logger)
205
-			));
206
-		}
207
-
208
-		// system tags plugins
209
-		$this->server->addPlugin(new SystemTagPlugin(
210
-			\OC::$server->getSystemTagManager(),
211
-			\OC::$server->getGroupManager(),
212
-			\OC::$server->getUserSession()
213
-		));
214
-
215
-		// comments plugin
216
-		$this->server->addPlugin(new CommentsPlugin(
217
-			\OC::$server->getCommentsManager(),
218
-			\OC::$server->getUserSession()
219
-		));
220
-
221
-		$this->server->addPlugin(new CopyEtagHeaderPlugin());
222
-		$this->server->addPlugin(new RequestIdHeaderPlugin(\OC::$server->get(IRequest::class)));
223
-		$this->server->addPlugin(new ChunkingV2Plugin(\OCP\Server::get(ICacheFactory::class)));
224
-		$this->server->addPlugin(new ChunkingPlugin());
225
-
226
-		// allow setup of additional plugins
227
-		$dispatcher->dispatch('OCA\DAV\Connector\Sabre::addPlugin', $event);
228
-
229
-		// Some WebDAV clients do require Class 2 WebDAV support (locking), since
230
-		// we do not provide locking we emulate it using a fake locking plugin.
231
-		if ($request->isUserAgent([
232
-			'/WebDAVFS/',
233
-			'/OneNote/',
234
-			'/^Microsoft-WebDAV/',// Microsoft-WebDAV-MiniRedir/6.1.7601
235
-		])) {
236
-			$this->server->addPlugin(new FakeLockerPlugin());
237
-		}
238
-
239
-		// Allow view-only plugin for webdav requests
240
-		$this->server->addPlugin(new ViewOnlyPlugin(
241
-			$logger
242
-		));
243
-
244
-		if (BrowserErrorPagePlugin::isBrowserRequest($request)) {
245
-			$this->server->addPlugin(new BrowserErrorPagePlugin());
246
-		}
247
-
248
-		$lazySearchBackend = new LazySearchBackend();
249
-		$this->server->addPlugin(new SearchPlugin($lazySearchBackend));
250
-
251
-		// wait with registering these until auth is handled and the filesystem is setup
252
-		$this->server->on('beforeMethod:*', function () use ($root, $lazySearchBackend, $logger) {
253
-			// custom properties plugin must be the last one
254
-			$userSession = \OC::$server->getUserSession();
255
-			$user = $userSession->getUser();
256
-			if ($user !== null) {
257
-				$view = \OC\Files\Filesystem::getView();
258
-				$this->server->addPlugin(
259
-					new FilesPlugin(
260
-						$this->server->tree,
261
-						\OC::$server->getConfig(),
262
-						$this->request,
263
-						\OC::$server->getPreviewManager(),
264
-						\OC::$server->getUserSession(),
265
-						false,
266
-						!\OC::$server->getConfig()->getSystemValue('debug', false)
267
-					)
268
-				);
269
-				$this->server->addPlugin(new ChecksumUpdatePlugin());
270
-
271
-				$this->server->addPlugin(
272
-					new \Sabre\DAV\PropertyStorage\Plugin(
273
-						new CustomPropertiesBackend(
274
-							$this->server->tree,
275
-							\OC::$server->getDatabaseConnection(),
276
-							\OC::$server->getUserSession()->getUser()
277
-						)
278
-					)
279
-				);
280
-				if ($view !== null) {
281
-					$this->server->addPlugin(
282
-						new QuotaPlugin($view));
283
-				}
284
-				$this->server->addPlugin(
285
-					new TagsPlugin(
286
-						$this->server->tree, \OC::$server->getTagManager()
287
-					)
288
-				);
289
-				// TODO: switch to LazyUserFolder
290
-				$userFolder = \OC::$server->getUserFolder();
291
-				$this->server->addPlugin(new SharesPlugin(
292
-					$this->server->tree,
293
-					$userSession,
294
-					$userFolder,
295
-					\OC::$server->getShareManager()
296
-				));
297
-				$this->server->addPlugin(new CommentPropertiesPlugin(
298
-					\OC::$server->getCommentsManager(),
299
-					$userSession
300
-				));
301
-				$this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin());
302
-				if ($view !== null) {
303
-					$this->server->addPlugin(new FilesReportPlugin(
304
-						$this->server->tree,
305
-						$view,
306
-						\OC::$server->getSystemTagManager(),
307
-						\OC::$server->getSystemTagObjectMapper(),
308
-						\OC::$server->getTagManager(),
309
-						$userSession,
310
-						\OC::$server->getGroupManager(),
311
-						$userFolder,
312
-						\OC::$server->getAppManager()
313
-					));
314
-					$lazySearchBackend->setBackend(new \OCA\DAV\Files\FileSearchBackend(
315
-						$this->server->tree,
316
-						$user,
317
-						\OC::$server->getRootFolder(),
318
-						\OC::$server->getShareManager(),
319
-						$view
320
-					));
321
-					$this->server->addPlugin(
322
-						new BulkUploadPlugin(
323
-							$userFolder,
324
-							$logger
325
-						)
326
-					);
327
-				}
328
-				$this->server->addPlugin(new \OCA\DAV\CalDAV\BirthdayCalendar\EnablePlugin(
329
-					\OC::$server->getConfig(),
330
-					\OC::$server->query(BirthdayService::class)
331
-				));
332
-				$this->server->addPlugin(new AppleProvisioningPlugin(
333
-					\OC::$server->getUserSession(),
334
-					\OC::$server->getURLGenerator(),
335
-					\OC::$server->getThemingDefaults(),
336
-					\OC::$server->getRequest(),
337
-					\OC::$server->getL10N('dav'),
338
-					function () {
339
-						return UUIDUtil::getUUID();
340
-					}
341
-				));
342
-			}
343
-
344
-			// register plugins from apps
345
-			$pluginManager = new PluginManager(
346
-				\OC::$server,
347
-				\OC::$server->getAppManager()
348
-			);
349
-			foreach ($pluginManager->getAppPlugins() as $appPlugin) {
350
-				$this->server->addPlugin($appPlugin);
351
-			}
352
-			foreach ($pluginManager->getAppCollections() as $appCollection) {
353
-				$root->addChild($appCollection);
354
-			}
355
-		});
356
-
357
-		$this->server->addPlugin(
358
-			new PropfindCompressionPlugin()
359
-		);
360
-	}
361
-
362
-	public function exec() {
363
-		/** @var IEventLogger $eventLogger */
364
-		$eventLogger = \OC::$server->get(IEventLogger::class);
365
-		$eventLogger->start('dav_server_exec', '');
366
-		$this->server->exec();
367
-		$eventLogger->end('dav_server_exec');
368
-		if ($this->profiler->isEnabled()) {
369
-			$eventLogger->end('runtime');
370
-			$profile = $this->profiler->collect(\OC::$server->get(IRequest::class), new Response());
371
-			$this->profiler->saveProfile($profile);
372
-		}
373
-	}
374
-
375
-	private function requestIsForSubtree(array $subTrees): bool {
376
-		foreach ($subTrees as $subTree) {
377
-			$subTree = trim($subTree, ' /');
378
-			if (strpos($this->server->getRequestUri(), $subTree.'/') === 0) {
379
-				return true;
380
-			}
381
-		}
382
-		return false;
383
-	}
89
+    private IRequest $request;
90
+    private string $baseUri;
91
+    public Connector\Sabre\Server $server;
92
+    private IProfiler $profiler;
93
+
94
+    public function __construct(IRequest $request, string $baseUri) {
95
+        $this->profiler = \OC::$server->get(IProfiler::class);
96
+        if ($this->profiler->isEnabled()) {
97
+            /** @var IEventLogger $eventLogger */
98
+            $eventLogger = \OC::$server->get(IEventLogger::class);
99
+            $eventLogger->start('runtime', 'DAV Runtime');
100
+        }
101
+
102
+        $this->request = $request;
103
+        $this->baseUri = $baseUri;
104
+        $logger = \OC::$server->get(LoggerInterface::class);
105
+        $dispatcher = \OC::$server->getEventDispatcher();
106
+        /** @var IEventDispatcher $newDispatcher */
107
+        $newDispatcher = \OC::$server->query(IEventDispatcher::class);
108
+
109
+        $root = new RootCollection();
110
+        $this->server = new \OCA\DAV\Connector\Sabre\Server(new CachingTree($root));
111
+
112
+        // Add maintenance plugin
113
+        $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin(\OC::$server->getConfig(), \OC::$server->getL10N('dav')));
114
+
115
+        // Backends
116
+        $authBackend = new Auth(
117
+            \OC::$server->getSession(),
118
+            \OC::$server->getUserSession(),
119
+            \OC::$server->getRequest(),
120
+            \OC::$server->getTwoFactorAuthManager(),
121
+            \OC::$server->getBruteForceThrottler()
122
+        );
123
+
124
+        // Set URL explicitly due to reverse-proxy situations
125
+        $this->server->httpRequest->setUrl($this->request->getRequestUri());
126
+        $this->server->setBaseUri($this->baseUri);
127
+
128
+        $this->server->addPlugin(new ProfilerPlugin($this->request));
129
+        $this->server->addPlugin(new BlockLegacyClientPlugin(\OC::$server->getConfig()));
130
+        $this->server->addPlugin(new AnonymousOptionsPlugin());
131
+        $authPlugin = new Plugin();
132
+        $authPlugin->addBackend(new PublicAuth());
133
+        $this->server->addPlugin($authPlugin);
134
+
135
+        // allow setup of additional auth backends
136
+        $event = new SabrePluginEvent($this->server);
137
+        $dispatcher->dispatch('OCA\DAV\Connector\Sabre::authInit', $event);
138
+
139
+        $newAuthEvent = new SabrePluginAuthInitEvent($this->server);
140
+        $newDispatcher->dispatchTyped($newAuthEvent);
141
+
142
+        $bearerAuthBackend = new BearerAuth(
143
+            \OC::$server->getUserSession(),
144
+            \OC::$server->getSession(),
145
+            \OC::$server->getRequest()
146
+        );
147
+        $authPlugin->addBackend($bearerAuthBackend);
148
+        // because we are throwing exceptions this plugin has to be the last one
149
+        $authPlugin->addBackend($authBackend);
150
+
151
+        // debugging
152
+        if (\OC::$server->getConfig()->getSystemValue('debug', false)) {
153
+            $this->server->addPlugin(new \Sabre\DAV\Browser\Plugin());
154
+        } else {
155
+            $this->server->addPlugin(new DummyGetResponsePlugin());
156
+        }
157
+
158
+        $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $logger));
159
+        $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\LockPlugin());
160
+        $this->server->addPlugin(new \Sabre\DAV\Sync\Plugin());
161
+
162
+        // acl
163
+        $acl = new DavAclPlugin();
164
+        $acl->principalCollectionSet = [
165
+            'principals/users',
166
+            'principals/groups',
167
+            'principals/calendar-resources',
168
+            'principals/calendar-rooms',
169
+        ];
170
+        $this->server->addPlugin($acl);
171
+
172
+        // calendar plugins
173
+        if ($this->requestIsForSubtree(['calendars', 'public-calendars', 'system-calendars', 'principals'])) {
174
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\Plugin());
175
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\ICSExportPlugin\ICSExportPlugin(\OC::$server->getConfig(), $logger));
176
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(\OC::$server->getConfig(), \OC::$server->get(LoggerInterface::class)));
177
+            if (\OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') {
178
+                $this->server->addPlugin(\OC::$server->query(\OCA\DAV\CalDAV\Schedule\IMipPlugin::class));
179
+            }
180
+
181
+            $this->server->addPlugin(\OC::$server->get(\OCA\DAV\CalDAV\Trashbin\Plugin::class));
182
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\WebcalCaching\Plugin($request));
183
+            if (\OC::$server->getConfig()->getAppValue('dav', 'allow_calendar_link_subscriptions', 'yes') === 'yes') {
184
+                $this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin());
185
+            }
186
+
187
+            $this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin());
188
+            $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest(), \OC::$server->getConfig()));
189
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\Publishing\PublishPlugin(
190
+                \OC::$server->getConfig(),
191
+                \OC::$server->getURLGenerator()
192
+            ));
193
+        }
194
+
195
+        // addressbook plugins
196
+        if ($this->requestIsForSubtree(['addressbooks', 'principals'])) {
197
+            $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest(), \OC::$server->getConfig()));
198
+            $this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin());
199
+            $this->server->addPlugin(new VCFExportPlugin());
200
+            $this->server->addPlugin(new MultiGetExportPlugin());
201
+            $this->server->addPlugin(new HasPhotoPlugin());
202
+            $this->server->addPlugin(new ImageExportPlugin(new PhotoCache(
203
+                \OC::$server->getAppDataDir('dav-photocache'),
204
+                $logger)
205
+            ));
206
+        }
207
+
208
+        // system tags plugins
209
+        $this->server->addPlugin(new SystemTagPlugin(
210
+            \OC::$server->getSystemTagManager(),
211
+            \OC::$server->getGroupManager(),
212
+            \OC::$server->getUserSession()
213
+        ));
214
+
215
+        // comments plugin
216
+        $this->server->addPlugin(new CommentsPlugin(
217
+            \OC::$server->getCommentsManager(),
218
+            \OC::$server->getUserSession()
219
+        ));
220
+
221
+        $this->server->addPlugin(new CopyEtagHeaderPlugin());
222
+        $this->server->addPlugin(new RequestIdHeaderPlugin(\OC::$server->get(IRequest::class)));
223
+        $this->server->addPlugin(new ChunkingV2Plugin(\OCP\Server::get(ICacheFactory::class)));
224
+        $this->server->addPlugin(new ChunkingPlugin());
225
+
226
+        // allow setup of additional plugins
227
+        $dispatcher->dispatch('OCA\DAV\Connector\Sabre::addPlugin', $event);
228
+
229
+        // Some WebDAV clients do require Class 2 WebDAV support (locking), since
230
+        // we do not provide locking we emulate it using a fake locking plugin.
231
+        if ($request->isUserAgent([
232
+            '/WebDAVFS/',
233
+            '/OneNote/',
234
+            '/^Microsoft-WebDAV/',// Microsoft-WebDAV-MiniRedir/6.1.7601
235
+        ])) {
236
+            $this->server->addPlugin(new FakeLockerPlugin());
237
+        }
238
+
239
+        // Allow view-only plugin for webdav requests
240
+        $this->server->addPlugin(new ViewOnlyPlugin(
241
+            $logger
242
+        ));
243
+
244
+        if (BrowserErrorPagePlugin::isBrowserRequest($request)) {
245
+            $this->server->addPlugin(new BrowserErrorPagePlugin());
246
+        }
247
+
248
+        $lazySearchBackend = new LazySearchBackend();
249
+        $this->server->addPlugin(new SearchPlugin($lazySearchBackend));
250
+
251
+        // wait with registering these until auth is handled and the filesystem is setup
252
+        $this->server->on('beforeMethod:*', function () use ($root, $lazySearchBackend, $logger) {
253
+            // custom properties plugin must be the last one
254
+            $userSession = \OC::$server->getUserSession();
255
+            $user = $userSession->getUser();
256
+            if ($user !== null) {
257
+                $view = \OC\Files\Filesystem::getView();
258
+                $this->server->addPlugin(
259
+                    new FilesPlugin(
260
+                        $this->server->tree,
261
+                        \OC::$server->getConfig(),
262
+                        $this->request,
263
+                        \OC::$server->getPreviewManager(),
264
+                        \OC::$server->getUserSession(),
265
+                        false,
266
+                        !\OC::$server->getConfig()->getSystemValue('debug', false)
267
+                    )
268
+                );
269
+                $this->server->addPlugin(new ChecksumUpdatePlugin());
270
+
271
+                $this->server->addPlugin(
272
+                    new \Sabre\DAV\PropertyStorage\Plugin(
273
+                        new CustomPropertiesBackend(
274
+                            $this->server->tree,
275
+                            \OC::$server->getDatabaseConnection(),
276
+                            \OC::$server->getUserSession()->getUser()
277
+                        )
278
+                    )
279
+                );
280
+                if ($view !== null) {
281
+                    $this->server->addPlugin(
282
+                        new QuotaPlugin($view));
283
+                }
284
+                $this->server->addPlugin(
285
+                    new TagsPlugin(
286
+                        $this->server->tree, \OC::$server->getTagManager()
287
+                    )
288
+                );
289
+                // TODO: switch to LazyUserFolder
290
+                $userFolder = \OC::$server->getUserFolder();
291
+                $this->server->addPlugin(new SharesPlugin(
292
+                    $this->server->tree,
293
+                    $userSession,
294
+                    $userFolder,
295
+                    \OC::$server->getShareManager()
296
+                ));
297
+                $this->server->addPlugin(new CommentPropertiesPlugin(
298
+                    \OC::$server->getCommentsManager(),
299
+                    $userSession
300
+                ));
301
+                $this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin());
302
+                if ($view !== null) {
303
+                    $this->server->addPlugin(new FilesReportPlugin(
304
+                        $this->server->tree,
305
+                        $view,
306
+                        \OC::$server->getSystemTagManager(),
307
+                        \OC::$server->getSystemTagObjectMapper(),
308
+                        \OC::$server->getTagManager(),
309
+                        $userSession,
310
+                        \OC::$server->getGroupManager(),
311
+                        $userFolder,
312
+                        \OC::$server->getAppManager()
313
+                    ));
314
+                    $lazySearchBackend->setBackend(new \OCA\DAV\Files\FileSearchBackend(
315
+                        $this->server->tree,
316
+                        $user,
317
+                        \OC::$server->getRootFolder(),
318
+                        \OC::$server->getShareManager(),
319
+                        $view
320
+                    ));
321
+                    $this->server->addPlugin(
322
+                        new BulkUploadPlugin(
323
+                            $userFolder,
324
+                            $logger
325
+                        )
326
+                    );
327
+                }
328
+                $this->server->addPlugin(new \OCA\DAV\CalDAV\BirthdayCalendar\EnablePlugin(
329
+                    \OC::$server->getConfig(),
330
+                    \OC::$server->query(BirthdayService::class)
331
+                ));
332
+                $this->server->addPlugin(new AppleProvisioningPlugin(
333
+                    \OC::$server->getUserSession(),
334
+                    \OC::$server->getURLGenerator(),
335
+                    \OC::$server->getThemingDefaults(),
336
+                    \OC::$server->getRequest(),
337
+                    \OC::$server->getL10N('dav'),
338
+                    function () {
339
+                        return UUIDUtil::getUUID();
340
+                    }
341
+                ));
342
+            }
343
+
344
+            // register plugins from apps
345
+            $pluginManager = new PluginManager(
346
+                \OC::$server,
347
+                \OC::$server->getAppManager()
348
+            );
349
+            foreach ($pluginManager->getAppPlugins() as $appPlugin) {
350
+                $this->server->addPlugin($appPlugin);
351
+            }
352
+            foreach ($pluginManager->getAppCollections() as $appCollection) {
353
+                $root->addChild($appCollection);
354
+            }
355
+        });
356
+
357
+        $this->server->addPlugin(
358
+            new PropfindCompressionPlugin()
359
+        );
360
+    }
361
+
362
+    public function exec() {
363
+        /** @var IEventLogger $eventLogger */
364
+        $eventLogger = \OC::$server->get(IEventLogger::class);
365
+        $eventLogger->start('dav_server_exec', '');
366
+        $this->server->exec();
367
+        $eventLogger->end('dav_server_exec');
368
+        if ($this->profiler->isEnabled()) {
369
+            $eventLogger->end('runtime');
370
+            $profile = $this->profiler->collect(\OC::$server->get(IRequest::class), new Response());
371
+            $this->profiler->saveProfile($profile);
372
+        }
373
+    }
374
+
375
+    private function requestIsForSubtree(array $subTrees): bool {
376
+        foreach ($subTrees as $subTree) {
377
+            $subTree = trim($subTree, ' /');
378
+            if (strpos($this->server->getRequestUri(), $subTree.'/') === 0) {
379
+                return true;
380
+            }
381
+        }
382
+        return false;
383
+    }
384 384
 }
Please login to merge, or discard this patch.
apps/dav/lib/Upload/UploadFile.php 1 patch
Indentation   +62 added lines, -62 removed lines patch added patch discarded remove patch
@@ -29,66 +29,66 @@
 block discarded – undo
29 29
 use Sabre\DAV\IFile;
30 30
 
31 31
 class UploadFile implements IFile {
32
-	/**  @var File */
33
-	private $file;
34
-
35
-	public function __construct(File $file) {
36
-		$this->file = $file;
37
-	}
38
-
39
-	public function put($data) {
40
-		return $this->file->put($data);
41
-	}
42
-
43
-	public function get() {
44
-		return $this->file->get();
45
-	}
46
-
47
-	public function getId() {
48
-		return $this->file->getId();
49
-	}
50
-
51
-	public function getContentType() {
52
-		return $this->file->getContentType();
53
-	}
54
-
55
-	public function getETag() {
56
-		return $this->file->getETag();
57
-	}
58
-
59
-	/**
60
-	 * @psalm-suppress ImplementedReturnTypeMismatch \Sabre\DAV\IFile::getSize signature does not support 32bit
61
-	 * @return int|float
62
-	 */
63
-	public function getSize() {
64
-		return $this->file->getSize();
65
-	}
66
-
67
-	public function delete() {
68
-		$this->file->delete();
69
-	}
70
-
71
-	public function getName() {
72
-		return $this->file->getName();
73
-	}
74
-
75
-	public function setName($name) {
76
-		$this->file->setName($name);
77
-	}
78
-
79
-	public function getLastModified() {
80
-		return $this->file->getLastModified();
81
-	}
82
-
83
-	public function getInternalPath(): string {
84
-		return $this->file->getInternalPath();
85
-	}
86
-
87
-	public function getFile(): File {
88
-		return $this->file;
89
-	}
90
-
91
-	public function getNode() {
92
-		return $this->file->getNode();
93
-	}
32
+    /**  @var File */
33
+    private $file;
34
+
35
+    public function __construct(File $file) {
36
+        $this->file = $file;
37
+    }
38
+
39
+    public function put($data) {
40
+        return $this->file->put($data);
41
+    }
42
+
43
+    public function get() {
44
+        return $this->file->get();
45
+    }
46
+
47
+    public function getId() {
48
+        return $this->file->getId();
49
+    }
50
+
51
+    public function getContentType() {
52
+        return $this->file->getContentType();
53
+    }
54
+
55
+    public function getETag() {
56
+        return $this->file->getETag();
57
+    }
58
+
59
+    /**
60
+     * @psalm-suppress ImplementedReturnTypeMismatch \Sabre\DAV\IFile::getSize signature does not support 32bit
61
+     * @return int|float
62
+     */
63
+    public function getSize() {
64
+        return $this->file->getSize();
65
+    }
66
+
67
+    public function delete() {
68
+        $this->file->delete();
69
+    }
70
+
71
+    public function getName() {
72
+        return $this->file->getName();
73
+    }
74
+
75
+    public function setName($name) {
76
+        $this->file->setName($name);
77
+    }
78
+
79
+    public function getLastModified() {
80
+        return $this->file->getLastModified();
81
+    }
82
+
83
+    public function getInternalPath(): string {
84
+        return $this->file->getInternalPath();
85
+    }
86
+
87
+    public function getFile(): File {
88
+        return $this->file;
89
+    }
90
+
91
+    public function getNode() {
92
+        return $this->file->getNode();
93
+    }
94 94
 }
Please login to merge, or discard this patch.
apps/dav/lib/Upload/PartFile.php 2 patches
Indentation   +65 added lines, -65 removed lines patch added patch discarded remove patch
@@ -32,80 +32,80 @@
 block discarded – undo
32 32
  * but handled directly by external storage services like S3 with Multipart Upload
33 33
  */
34 34
 class PartFile implements IFile {
35
-	/** @var Directory */
36
-	private $root;
37
-	/** @var array */
38
-	private $partInfo;
35
+    /** @var Directory */
36
+    private $root;
37
+    /** @var array */
38
+    private $partInfo;
39 39
 
40
-	public function __construct(Directory $root, array $partInfo) {
41
-		$this->root = $root;
42
-		$this->partInfo = $partInfo;
43
-	}
40
+    public function __construct(Directory $root, array $partInfo) {
41
+        $this->root = $root;
42
+        $this->partInfo = $partInfo;
43
+    }
44 44
 
45
-	/**
46
-	 * @inheritdoc
47
-	 */
48
-	public function put($data) {
49
-		throw new Forbidden('Permission denied to put into this file');
50
-	}
45
+    /**
46
+     * @inheritdoc
47
+     */
48
+    public function put($data) {
49
+        throw new Forbidden('Permission denied to put into this file');
50
+    }
51 51
 
52
-	/**
53
-	 * @inheritdoc
54
-	 */
55
-	public function get() {
56
-		throw new Forbidden('Permission denied to get this file');
57
-	}
52
+    /**
53
+     * @inheritdoc
54
+     */
55
+    public function get() {
56
+        throw new Forbidden('Permission denied to get this file');
57
+    }
58 58
 
59
-	public function getPath() {
60
-		return $this->root->getFileInfo()->getInternalPath() . '/' . $this->partInfo['PartNumber'];
61
-	}
59
+    public function getPath() {
60
+        return $this->root->getFileInfo()->getInternalPath() . '/' . $this->partInfo['PartNumber'];
61
+    }
62 62
 
63
-	/**
64
-	 * @inheritdoc
65
-	 */
66
-	public function getContentType() {
67
-		return 'application/octet-stream';
68
-	}
63
+    /**
64
+     * @inheritdoc
65
+     */
66
+    public function getContentType() {
67
+        return 'application/octet-stream';
68
+    }
69 69
 
70
-	/**
71
-	 * @inheritdoc
72
-	 */
73
-	public function getETag() {
74
-		return $this->partInfo['ETag'];
75
-	}
70
+    /**
71
+     * @inheritdoc
72
+     */
73
+    public function getETag() {
74
+        return $this->partInfo['ETag'];
75
+    }
76 76
 
77
-	/**
78
-	 * @inheritdoc
79
-	 */
80
-	public function getSize() {
81
-		return $this->partInfo['Size'];
82
-	}
77
+    /**
78
+     * @inheritdoc
79
+     */
80
+    public function getSize() {
81
+        return $this->partInfo['Size'];
82
+    }
83 83
 
84
-	/**
85
-	 * @inheritdoc
86
-	 */
87
-	public function delete() {
88
-		$this->root->delete();
89
-	}
84
+    /**
85
+     * @inheritdoc
86
+     */
87
+    public function delete() {
88
+        $this->root->delete();
89
+    }
90 90
 
91
-	/**
92
-	 * @inheritdoc
93
-	 */
94
-	public function getName() {
95
-		return $this->partInfo['PartNumber'];
96
-	}
91
+    /**
92
+     * @inheritdoc
93
+     */
94
+    public function getName() {
95
+        return $this->partInfo['PartNumber'];
96
+    }
97 97
 
98
-	/**
99
-	 * @inheritdoc
100
-	 */
101
-	public function setName($name) {
102
-		throw new Forbidden('Permission denied to rename this file');
103
-	}
98
+    /**
99
+     * @inheritdoc
100
+     */
101
+    public function setName($name) {
102
+        throw new Forbidden('Permission denied to rename this file');
103
+    }
104 104
 
105
-	/**
106
-	 * @inheritdoc
107
-	 */
108
-	public function getLastModified() {
109
-		return $this->partInfo['LastModified'];
110
-	}
105
+    /**
106
+     * @inheritdoc
107
+     */
108
+    public function getLastModified() {
109
+        return $this->partInfo['LastModified'];
110
+    }
111 111
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@
 block discarded – undo
57 57
 	}
58 58
 
59 59
 	public function getPath() {
60
-		return $this->root->getFileInfo()->getInternalPath() . '/' . $this->partInfo['PartNumber'];
60
+		return $this->root->getFileInfo()->getInternalPath().'/'.$this->partInfo['PartNumber'];
61 61
 	}
62 62
 
63 63
 	/**
Please login to merge, or discard this patch.
apps/dav/lib/Upload/FutureFile.php 2 patches
Indentation   +75 added lines, -75 removed lines patch added patch discarded remove patch
@@ -36,91 +36,91 @@
 block discarded – undo
36 36
  * @package OCA\DAV\Upload
37 37
  */
38 38
 class FutureFile implements \Sabre\DAV\IFile {
39
-	/** @var Directory */
40
-	private $root;
41
-	/** @var string */
42
-	private $name;
39
+    /** @var Directory */
40
+    private $root;
41
+    /** @var string */
42
+    private $name;
43 43
 
44
-	/**
45
-	 * @param Directory $root
46
-	 * @param string $name
47
-	 */
48
-	public function __construct(Directory $root, $name) {
49
-		$this->root = $root;
50
-		$this->name = $name;
51
-	}
44
+    /**
45
+     * @param Directory $root
46
+     * @param string $name
47
+     */
48
+    public function __construct(Directory $root, $name) {
49
+        $this->root = $root;
50
+        $this->name = $name;
51
+    }
52 52
 
53
-	/**
54
-	 * @inheritdoc
55
-	 */
56
-	public function put($data) {
57
-		throw new Forbidden('Permission denied to put into this file');
58
-	}
53
+    /**
54
+     * @inheritdoc
55
+     */
56
+    public function put($data) {
57
+        throw new Forbidden('Permission denied to put into this file');
58
+    }
59 59
 
60
-	/**
61
-	 * @inheritdoc
62
-	 */
63
-	public function get() {
64
-		$nodes = $this->root->getChildren();
65
-		return AssemblyStream::wrap($nodes);
66
-	}
60
+    /**
61
+     * @inheritdoc
62
+     */
63
+    public function get() {
64
+        $nodes = $this->root->getChildren();
65
+        return AssemblyStream::wrap($nodes);
66
+    }
67 67
 
68
-	public function getPath() {
69
-		return $this->root->getFileInfo()->getInternalPath() . '/.file';
70
-	}
68
+    public function getPath() {
69
+        return $this->root->getFileInfo()->getInternalPath() . '/.file';
70
+    }
71 71
 
72
-	/**
73
-	 * @inheritdoc
74
-	 */
75
-	public function getContentType() {
76
-		return 'application/octet-stream';
77
-	}
72
+    /**
73
+     * @inheritdoc
74
+     */
75
+    public function getContentType() {
76
+        return 'application/octet-stream';
77
+    }
78 78
 
79
-	/**
80
-	 * @inheritdoc
81
-	 */
82
-	public function getETag() {
83
-		return $this->root->getETag();
84
-	}
79
+    /**
80
+     * @inheritdoc
81
+     */
82
+    public function getETag() {
83
+        return $this->root->getETag();
84
+    }
85 85
 
86
-	/**
87
-	 * @inheritdoc
88
-	 */
89
-	public function getSize() {
90
-		$children = $this->root->getChildren();
91
-		$sizes = array_map(function ($node) {
92
-			/** @var IFile $node */
93
-			return $node->getSize();
94
-		}, $children);
86
+    /**
87
+     * @inheritdoc
88
+     */
89
+    public function getSize() {
90
+        $children = $this->root->getChildren();
91
+        $sizes = array_map(function ($node) {
92
+            /** @var IFile $node */
93
+            return $node->getSize();
94
+        }, $children);
95 95
 
96
-		return array_sum($sizes);
97
-	}
96
+        return array_sum($sizes);
97
+    }
98 98
 
99
-	/**
100
-	 * @inheritdoc
101
-	 */
102
-	public function delete() {
103
-		$this->root->delete();
104
-	}
99
+    /**
100
+     * @inheritdoc
101
+     */
102
+    public function delete() {
103
+        $this->root->delete();
104
+    }
105 105
 
106
-	/**
107
-	 * @inheritdoc
108
-	 */
109
-	public function getName() {
110
-		return $this->name;
111
-	}
106
+    /**
107
+     * @inheritdoc
108
+     */
109
+    public function getName() {
110
+        return $this->name;
111
+    }
112 112
 
113
-	/**
114
-	 * @inheritdoc
115
-	 */
116
-	public function setName($name) {
117
-		throw new Forbidden('Permission denied to rename this file');
118
-	}
113
+    /**
114
+     * @inheritdoc
115
+     */
116
+    public function setName($name) {
117
+        throw new Forbidden('Permission denied to rename this file');
118
+    }
119 119
 
120
-	/**
121
-	 * @inheritdoc
122
-	 */
123
-	public function getLastModified() {
124
-		return $this->root->getLastModified();
125
-	}
120
+    /**
121
+     * @inheritdoc
122
+     */
123
+    public function getLastModified() {
124
+        return $this->root->getLastModified();
125
+    }
126 126
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -66,7 +66,7 @@  discard block
 block discarded – undo
66 66
 	}
67 67
 
68 68
 	public function getPath() {
69
-		return $this->root->getFileInfo()->getInternalPath() . '/.file';
69
+		return $this->root->getFileInfo()->getInternalPath().'/.file';
70 70
 	}
71 71
 
72 72
 	/**
@@ -88,7 +88,7 @@  discard block
 block discarded – undo
88 88
 	 */
89 89
 	public function getSize() {
90 90
 		$children = $this->root->getChildren();
91
-		$sizes = array_map(function ($node) {
91
+		$sizes = array_map(function($node) {
92 92
 			/** @var IFile $node */
93 93
 			return $node->getSize();
94 94
 		}, $children);
Please login to merge, or discard this patch.