Passed
Push — master ( 023d18...e0d767 )
by Roeland
12:40 queued 12s
created
lib/private/Files/Storage/Wrapper/Jail.php 2 patches
Indentation   +500 added lines, -500 removed lines patch added patch discarded remove patch
@@ -39,504 +39,504 @@
 block discarded – undo
39 39
  * This restricts access to a subfolder of the wrapped storage with the subfolder becoming the root folder new storage
40 40
  */
41 41
 class Jail extends Wrapper {
42
-	/**
43
-	 * @var string
44
-	 */
45
-	protected $rootPath;
46
-
47
-	/**
48
-	 * @param array $arguments ['storage' => $storage, 'mask' => $root]
49
-	 *
50
-	 * $storage: The storage that will be wrapper
51
-	 * $root: The folder in the wrapped storage that will become the root folder of the wrapped storage
52
-	 */
53
-	public function __construct($arguments) {
54
-		parent::__construct($arguments);
55
-		$this->rootPath = $arguments['root'];
56
-	}
57
-
58
-	public function getUnjailedPath($path) {
59
-		return trim(Filesystem::normalizePath($this->rootPath . '/' . $path), '/');
60
-	}
61
-
62
-	/**
63
-	 * This is separate from Wrapper::getWrapperStorage so we can get the jailed storage consistently even if the jail is inside another wrapper
64
-	 */
65
-	public function getUnjailedStorage() {
66
-		return $this->storage;
67
-	}
68
-
69
-
70
-	public function getJailedPath($path) {
71
-		$root = rtrim($this->rootPath, '/') . '/';
72
-
73
-		if ($path !== $this->rootPath && strpos($path, $root) !== 0) {
74
-			return null;
75
-		} else {
76
-			$path = substr($path, strlen($this->rootPath));
77
-			return trim($path, '/');
78
-		}
79
-	}
80
-
81
-	public function getId() {
82
-		return parent::getId();
83
-	}
84
-
85
-	/**
86
-	 * see http://php.net/manual/en/function.mkdir.php
87
-	 *
88
-	 * @param string $path
89
-	 * @return bool
90
-	 */
91
-	public function mkdir($path) {
92
-		return $this->getWrapperStorage()->mkdir($this->getUnjailedPath($path));
93
-	}
94
-
95
-	/**
96
-	 * see http://php.net/manual/en/function.rmdir.php
97
-	 *
98
-	 * @param string $path
99
-	 * @return bool
100
-	 */
101
-	public function rmdir($path) {
102
-		return $this->getWrapperStorage()->rmdir($this->getUnjailedPath($path));
103
-	}
104
-
105
-	/**
106
-	 * see http://php.net/manual/en/function.opendir.php
107
-	 *
108
-	 * @param string $path
109
-	 * @return resource
110
-	 */
111
-	public function opendir($path) {
112
-		return $this->getWrapperStorage()->opendir($this->getUnjailedPath($path));
113
-	}
114
-
115
-	/**
116
-	 * see http://php.net/manual/en/function.is_dir.php
117
-	 *
118
-	 * @param string $path
119
-	 * @return bool
120
-	 */
121
-	public function is_dir($path) {
122
-		return $this->getWrapperStorage()->is_dir($this->getUnjailedPath($path));
123
-	}
124
-
125
-	/**
126
-	 * see http://php.net/manual/en/function.is_file.php
127
-	 *
128
-	 * @param string $path
129
-	 * @return bool
130
-	 */
131
-	public function is_file($path) {
132
-		return $this->getWrapperStorage()->is_file($this->getUnjailedPath($path));
133
-	}
134
-
135
-	/**
136
-	 * see http://php.net/manual/en/function.stat.php
137
-	 * only the following keys are required in the result: size and mtime
138
-	 *
139
-	 * @param string $path
140
-	 * @return array
141
-	 */
142
-	public function stat($path) {
143
-		return $this->getWrapperStorage()->stat($this->getUnjailedPath($path));
144
-	}
145
-
146
-	/**
147
-	 * see http://php.net/manual/en/function.filetype.php
148
-	 *
149
-	 * @param string $path
150
-	 * @return bool
151
-	 */
152
-	public function filetype($path) {
153
-		return $this->getWrapperStorage()->filetype($this->getUnjailedPath($path));
154
-	}
155
-
156
-	/**
157
-	 * see http://php.net/manual/en/function.filesize.php
158
-	 * The result for filesize when called on a folder is required to be 0
159
-	 *
160
-	 * @param string $path
161
-	 * @return int
162
-	 */
163
-	public function filesize($path) {
164
-		return $this->getWrapperStorage()->filesize($this->getUnjailedPath($path));
165
-	}
166
-
167
-	/**
168
-	 * check if a file can be created in $path
169
-	 *
170
-	 * @param string $path
171
-	 * @return bool
172
-	 */
173
-	public function isCreatable($path) {
174
-		return $this->getWrapperStorage()->isCreatable($this->getUnjailedPath($path));
175
-	}
176
-
177
-	/**
178
-	 * check if a file can be read
179
-	 *
180
-	 * @param string $path
181
-	 * @return bool
182
-	 */
183
-	public function isReadable($path) {
184
-		return $this->getWrapperStorage()->isReadable($this->getUnjailedPath($path));
185
-	}
186
-
187
-	/**
188
-	 * check if a file can be written to
189
-	 *
190
-	 * @param string $path
191
-	 * @return bool
192
-	 */
193
-	public function isUpdatable($path) {
194
-		return $this->getWrapperStorage()->isUpdatable($this->getUnjailedPath($path));
195
-	}
196
-
197
-	/**
198
-	 * check if a file can be deleted
199
-	 *
200
-	 * @param string $path
201
-	 * @return bool
202
-	 */
203
-	public function isDeletable($path) {
204
-		return $this->getWrapperStorage()->isDeletable($this->getUnjailedPath($path));
205
-	}
206
-
207
-	/**
208
-	 * check if a file can be shared
209
-	 *
210
-	 * @param string $path
211
-	 * @return bool
212
-	 */
213
-	public function isSharable($path) {
214
-		return $this->getWrapperStorage()->isSharable($this->getUnjailedPath($path));
215
-	}
216
-
217
-	/**
218
-	 * get the full permissions of a path.
219
-	 * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
220
-	 *
221
-	 * @param string $path
222
-	 * @return int
223
-	 */
224
-	public function getPermissions($path) {
225
-		return $this->getWrapperStorage()->getPermissions($this->getUnjailedPath($path));
226
-	}
227
-
228
-	/**
229
-	 * see http://php.net/manual/en/function.file_exists.php
230
-	 *
231
-	 * @param string $path
232
-	 * @return bool
233
-	 */
234
-	public function file_exists($path) {
235
-		return $this->getWrapperStorage()->file_exists($this->getUnjailedPath($path));
236
-	}
237
-
238
-	/**
239
-	 * see http://php.net/manual/en/function.filemtime.php
240
-	 *
241
-	 * @param string $path
242
-	 * @return int
243
-	 */
244
-	public function filemtime($path) {
245
-		return $this->getWrapperStorage()->filemtime($this->getUnjailedPath($path));
246
-	}
247
-
248
-	/**
249
-	 * see http://php.net/manual/en/function.file_get_contents.php
250
-	 *
251
-	 * @param string $path
252
-	 * @return string
253
-	 */
254
-	public function file_get_contents($path) {
255
-		return $this->getWrapperStorage()->file_get_contents($this->getUnjailedPath($path));
256
-	}
257
-
258
-	/**
259
-	 * see http://php.net/manual/en/function.file_put_contents.php
260
-	 *
261
-	 * @param string $path
262
-	 * @param string $data
263
-	 * @return bool
264
-	 */
265
-	public function file_put_contents($path, $data) {
266
-		return $this->getWrapperStorage()->file_put_contents($this->getUnjailedPath($path), $data);
267
-	}
268
-
269
-	/**
270
-	 * see http://php.net/manual/en/function.unlink.php
271
-	 *
272
-	 * @param string $path
273
-	 * @return bool
274
-	 */
275
-	public function unlink($path) {
276
-		return $this->getWrapperStorage()->unlink($this->getUnjailedPath($path));
277
-	}
278
-
279
-	/**
280
-	 * see http://php.net/manual/en/function.rename.php
281
-	 *
282
-	 * @param string $path1
283
-	 * @param string $path2
284
-	 * @return bool
285
-	 */
286
-	public function rename($path1, $path2) {
287
-		return $this->getWrapperStorage()->rename($this->getUnjailedPath($path1), $this->getUnjailedPath($path2));
288
-	}
289
-
290
-	/**
291
-	 * see http://php.net/manual/en/function.copy.php
292
-	 *
293
-	 * @param string $path1
294
-	 * @param string $path2
295
-	 * @return bool
296
-	 */
297
-	public function copy($path1, $path2) {
298
-		return $this->getWrapperStorage()->copy($this->getUnjailedPath($path1), $this->getUnjailedPath($path2));
299
-	}
300
-
301
-	/**
302
-	 * see http://php.net/manual/en/function.fopen.php
303
-	 *
304
-	 * @param string $path
305
-	 * @param string $mode
306
-	 * @return resource
307
-	 */
308
-	public function fopen($path, $mode) {
309
-		return $this->getWrapperStorage()->fopen($this->getUnjailedPath($path), $mode);
310
-	}
311
-
312
-	/**
313
-	 * get the mimetype for a file or folder
314
-	 * The mimetype for a folder is required to be "httpd/unix-directory"
315
-	 *
316
-	 * @param string $path
317
-	 * @return string
318
-	 */
319
-	public function getMimeType($path) {
320
-		return $this->getWrapperStorage()->getMimeType($this->getUnjailedPath($path));
321
-	}
322
-
323
-	/**
324
-	 * see http://php.net/manual/en/function.hash.php
325
-	 *
326
-	 * @param string $type
327
-	 * @param string $path
328
-	 * @param bool $raw
329
-	 * @return string
330
-	 */
331
-	public function hash($type, $path, $raw = false) {
332
-		return $this->getWrapperStorage()->hash($type, $this->getUnjailedPath($path), $raw);
333
-	}
334
-
335
-	/**
336
-	 * see http://php.net/manual/en/function.free_space.php
337
-	 *
338
-	 * @param string $path
339
-	 * @return int
340
-	 */
341
-	public function free_space($path) {
342
-		return $this->getWrapperStorage()->free_space($this->getUnjailedPath($path));
343
-	}
344
-
345
-	/**
346
-	 * search for occurrences of $query in file names
347
-	 *
348
-	 * @param string $query
349
-	 * @return array
350
-	 */
351
-	public function search($query) {
352
-		return $this->getWrapperStorage()->search($query);
353
-	}
354
-
355
-	/**
356
-	 * see http://php.net/manual/en/function.touch.php
357
-	 * If the backend does not support the operation, false should be returned
358
-	 *
359
-	 * @param string $path
360
-	 * @param int $mtime
361
-	 * @return bool
362
-	 */
363
-	public function touch($path, $mtime = null) {
364
-		return $this->getWrapperStorage()->touch($this->getUnjailedPath($path), $mtime);
365
-	}
366
-
367
-	/**
368
-	 * get the path to a local version of the file.
369
-	 * The local version of the file can be temporary and doesn't have to be persistent across requests
370
-	 *
371
-	 * @param string $path
372
-	 * @return string
373
-	 */
374
-	public function getLocalFile($path) {
375
-		return $this->getWrapperStorage()->getLocalFile($this->getUnjailedPath($path));
376
-	}
377
-
378
-	/**
379
-	 * check if a file or folder has been updated since $time
380
-	 *
381
-	 * @param string $path
382
-	 * @param int $time
383
-	 * @return bool
384
-	 *
385
-	 * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
386
-	 * returning true for other changes in the folder is optional
387
-	 */
388
-	public function hasUpdated($path, $time) {
389
-		return $this->getWrapperStorage()->hasUpdated($this->getUnjailedPath($path), $time);
390
-	}
391
-
392
-	/**
393
-	 * get a cache instance for the storage
394
-	 *
395
-	 * @param string $path
396
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
397
-	 * @return \OC\Files\Cache\Cache
398
-	 */
399
-	public function getCache($path = '', $storage = null) {
400
-		if (!$storage) {
401
-			$storage = $this->getWrapperStorage();
402
-		}
403
-		$sourceCache = $this->getWrapperStorage()->getCache($this->getUnjailedPath($path), $storage);
404
-		return new CacheJail($sourceCache, $this->rootPath);
405
-	}
406
-
407
-	/**
408
-	 * get the user id of the owner of a file or folder
409
-	 *
410
-	 * @param string $path
411
-	 * @return string
412
-	 */
413
-	public function getOwner($path) {
414
-		return $this->getWrapperStorage()->getOwner($this->getUnjailedPath($path));
415
-	}
416
-
417
-	/**
418
-	 * get a watcher instance for the cache
419
-	 *
420
-	 * @param string $path
421
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
422
-	 * @return \OC\Files\Cache\Watcher
423
-	 */
424
-	public function getWatcher($path = '', $storage = null) {
425
-		if (!$storage) {
426
-			$storage = $this;
427
-		}
428
-		return $this->getWrapperStorage()->getWatcher($this->getUnjailedPath($path), $storage);
429
-	}
430
-
431
-	/**
432
-	 * get the ETag for a file or folder
433
-	 *
434
-	 * @param string $path
435
-	 * @return string
436
-	 */
437
-	public function getETag($path) {
438
-		return $this->getWrapperStorage()->getETag($this->getUnjailedPath($path));
439
-	}
440
-
441
-	/**
442
-	 * @param string $path
443
-	 * @return array
444
-	 */
445
-	public function getMetaData($path) {
446
-		return $this->getWrapperStorage()->getMetaData($this->getUnjailedPath($path));
447
-	}
448
-
449
-	/**
450
-	 * @param string $path
451
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
452
-	 * @param \OCP\Lock\ILockingProvider $provider
453
-	 * @throws \OCP\Lock\LockedException
454
-	 */
455
-	public function acquireLock($path, $type, ILockingProvider $provider) {
456
-		$this->getWrapperStorage()->acquireLock($this->getUnjailedPath($path), $type, $provider);
457
-	}
458
-
459
-	/**
460
-	 * @param string $path
461
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
462
-	 * @param \OCP\Lock\ILockingProvider $provider
463
-	 */
464
-	public function releaseLock($path, $type, ILockingProvider $provider) {
465
-		$this->getWrapperStorage()->releaseLock($this->getUnjailedPath($path), $type, $provider);
466
-	}
467
-
468
-	/**
469
-	 * @param string $path
470
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
471
-	 * @param \OCP\Lock\ILockingProvider $provider
472
-	 */
473
-	public function changeLock($path, $type, ILockingProvider $provider) {
474
-		$this->getWrapperStorage()->changeLock($this->getUnjailedPath($path), $type, $provider);
475
-	}
476
-
477
-	/**
478
-	 * Resolve the path for the source of the share
479
-	 *
480
-	 * @param string $path
481
-	 * @return array
482
-	 */
483
-	public function resolvePath($path) {
484
-		return [$this->getWrapperStorage(), $this->getUnjailedPath($path)];
485
-	}
486
-
487
-	/**
488
-	 * @param IStorage $sourceStorage
489
-	 * @param string $sourceInternalPath
490
-	 * @param string $targetInternalPath
491
-	 * @return bool
492
-	 */
493
-	public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
494
-		if ($sourceStorage === $this) {
495
-			return $this->copy($sourceInternalPath, $targetInternalPath);
496
-		}
497
-		return $this->getWrapperStorage()->copyFromStorage($sourceStorage, $sourceInternalPath, $this->getUnjailedPath($targetInternalPath));
498
-	}
499
-
500
-	/**
501
-	 * @param IStorage $sourceStorage
502
-	 * @param string $sourceInternalPath
503
-	 * @param string $targetInternalPath
504
-	 * @return bool
505
-	 */
506
-	public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
507
-		if ($sourceStorage === $this) {
508
-			return $this->rename($sourceInternalPath, $targetInternalPath);
509
-		}
510
-		return $this->getWrapperStorage()->moveFromStorage($sourceStorage, $sourceInternalPath, $this->getUnjailedPath($targetInternalPath));
511
-	}
512
-
513
-	public function getPropagator($storage = null) {
514
-		if (isset($this->propagator)) {
515
-			return $this->propagator;
516
-		}
517
-
518
-		if (!$storage) {
519
-			$storage = $this;
520
-		}
521
-		$this->propagator = new JailPropagator($storage, \OC::$server->getDatabaseConnection());
522
-		return $this->propagator;
523
-	}
524
-
525
-	public function writeStream(string $path, $stream, int $size = null): int {
526
-		$storage = $this->getWrapperStorage();
527
-		if ($storage->instanceOfStorage(IWriteStreamStorage::class)) {
528
-			/** @var IWriteStreamStorage $storage */
529
-			return $storage->writeStream($this->getUnjailedPath($path), $stream, $size);
530
-		} else {
531
-			$target = $this->fopen($path, 'w');
532
-			list($count, $result) = \OC_Helper::streamCopy($stream, $target);
533
-			fclose($stream);
534
-			fclose($target);
535
-			return $count;
536
-		}
537
-	}
538
-
539
-	public function getDirectoryContent($directory): \Traversable {
540
-		return $this->getWrapperStorage()->getDirectoryContent($this->getUnjailedPath($directory));
541
-	}
42
+    /**
43
+     * @var string
44
+     */
45
+    protected $rootPath;
46
+
47
+    /**
48
+     * @param array $arguments ['storage' => $storage, 'mask' => $root]
49
+     *
50
+     * $storage: The storage that will be wrapper
51
+     * $root: The folder in the wrapped storage that will become the root folder of the wrapped storage
52
+     */
53
+    public function __construct($arguments) {
54
+        parent::__construct($arguments);
55
+        $this->rootPath = $arguments['root'];
56
+    }
57
+
58
+    public function getUnjailedPath($path) {
59
+        return trim(Filesystem::normalizePath($this->rootPath . '/' . $path), '/');
60
+    }
61
+
62
+    /**
63
+     * This is separate from Wrapper::getWrapperStorage so we can get the jailed storage consistently even if the jail is inside another wrapper
64
+     */
65
+    public function getUnjailedStorage() {
66
+        return $this->storage;
67
+    }
68
+
69
+
70
+    public function getJailedPath($path) {
71
+        $root = rtrim($this->rootPath, '/') . '/';
72
+
73
+        if ($path !== $this->rootPath && strpos($path, $root) !== 0) {
74
+            return null;
75
+        } else {
76
+            $path = substr($path, strlen($this->rootPath));
77
+            return trim($path, '/');
78
+        }
79
+    }
80
+
81
+    public function getId() {
82
+        return parent::getId();
83
+    }
84
+
85
+    /**
86
+     * see http://php.net/manual/en/function.mkdir.php
87
+     *
88
+     * @param string $path
89
+     * @return bool
90
+     */
91
+    public function mkdir($path) {
92
+        return $this->getWrapperStorage()->mkdir($this->getUnjailedPath($path));
93
+    }
94
+
95
+    /**
96
+     * see http://php.net/manual/en/function.rmdir.php
97
+     *
98
+     * @param string $path
99
+     * @return bool
100
+     */
101
+    public function rmdir($path) {
102
+        return $this->getWrapperStorage()->rmdir($this->getUnjailedPath($path));
103
+    }
104
+
105
+    /**
106
+     * see http://php.net/manual/en/function.opendir.php
107
+     *
108
+     * @param string $path
109
+     * @return resource
110
+     */
111
+    public function opendir($path) {
112
+        return $this->getWrapperStorage()->opendir($this->getUnjailedPath($path));
113
+    }
114
+
115
+    /**
116
+     * see http://php.net/manual/en/function.is_dir.php
117
+     *
118
+     * @param string $path
119
+     * @return bool
120
+     */
121
+    public function is_dir($path) {
122
+        return $this->getWrapperStorage()->is_dir($this->getUnjailedPath($path));
123
+    }
124
+
125
+    /**
126
+     * see http://php.net/manual/en/function.is_file.php
127
+     *
128
+     * @param string $path
129
+     * @return bool
130
+     */
131
+    public function is_file($path) {
132
+        return $this->getWrapperStorage()->is_file($this->getUnjailedPath($path));
133
+    }
134
+
135
+    /**
136
+     * see http://php.net/manual/en/function.stat.php
137
+     * only the following keys are required in the result: size and mtime
138
+     *
139
+     * @param string $path
140
+     * @return array
141
+     */
142
+    public function stat($path) {
143
+        return $this->getWrapperStorage()->stat($this->getUnjailedPath($path));
144
+    }
145
+
146
+    /**
147
+     * see http://php.net/manual/en/function.filetype.php
148
+     *
149
+     * @param string $path
150
+     * @return bool
151
+     */
152
+    public function filetype($path) {
153
+        return $this->getWrapperStorage()->filetype($this->getUnjailedPath($path));
154
+    }
155
+
156
+    /**
157
+     * see http://php.net/manual/en/function.filesize.php
158
+     * The result for filesize when called on a folder is required to be 0
159
+     *
160
+     * @param string $path
161
+     * @return int
162
+     */
163
+    public function filesize($path) {
164
+        return $this->getWrapperStorage()->filesize($this->getUnjailedPath($path));
165
+    }
166
+
167
+    /**
168
+     * check if a file can be created in $path
169
+     *
170
+     * @param string $path
171
+     * @return bool
172
+     */
173
+    public function isCreatable($path) {
174
+        return $this->getWrapperStorage()->isCreatable($this->getUnjailedPath($path));
175
+    }
176
+
177
+    /**
178
+     * check if a file can be read
179
+     *
180
+     * @param string $path
181
+     * @return bool
182
+     */
183
+    public function isReadable($path) {
184
+        return $this->getWrapperStorage()->isReadable($this->getUnjailedPath($path));
185
+    }
186
+
187
+    /**
188
+     * check if a file can be written to
189
+     *
190
+     * @param string $path
191
+     * @return bool
192
+     */
193
+    public function isUpdatable($path) {
194
+        return $this->getWrapperStorage()->isUpdatable($this->getUnjailedPath($path));
195
+    }
196
+
197
+    /**
198
+     * check if a file can be deleted
199
+     *
200
+     * @param string $path
201
+     * @return bool
202
+     */
203
+    public function isDeletable($path) {
204
+        return $this->getWrapperStorage()->isDeletable($this->getUnjailedPath($path));
205
+    }
206
+
207
+    /**
208
+     * check if a file can be shared
209
+     *
210
+     * @param string $path
211
+     * @return bool
212
+     */
213
+    public function isSharable($path) {
214
+        return $this->getWrapperStorage()->isSharable($this->getUnjailedPath($path));
215
+    }
216
+
217
+    /**
218
+     * get the full permissions of a path.
219
+     * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
220
+     *
221
+     * @param string $path
222
+     * @return int
223
+     */
224
+    public function getPermissions($path) {
225
+        return $this->getWrapperStorage()->getPermissions($this->getUnjailedPath($path));
226
+    }
227
+
228
+    /**
229
+     * see http://php.net/manual/en/function.file_exists.php
230
+     *
231
+     * @param string $path
232
+     * @return bool
233
+     */
234
+    public function file_exists($path) {
235
+        return $this->getWrapperStorage()->file_exists($this->getUnjailedPath($path));
236
+    }
237
+
238
+    /**
239
+     * see http://php.net/manual/en/function.filemtime.php
240
+     *
241
+     * @param string $path
242
+     * @return int
243
+     */
244
+    public function filemtime($path) {
245
+        return $this->getWrapperStorage()->filemtime($this->getUnjailedPath($path));
246
+    }
247
+
248
+    /**
249
+     * see http://php.net/manual/en/function.file_get_contents.php
250
+     *
251
+     * @param string $path
252
+     * @return string
253
+     */
254
+    public function file_get_contents($path) {
255
+        return $this->getWrapperStorage()->file_get_contents($this->getUnjailedPath($path));
256
+    }
257
+
258
+    /**
259
+     * see http://php.net/manual/en/function.file_put_contents.php
260
+     *
261
+     * @param string $path
262
+     * @param string $data
263
+     * @return bool
264
+     */
265
+    public function file_put_contents($path, $data) {
266
+        return $this->getWrapperStorage()->file_put_contents($this->getUnjailedPath($path), $data);
267
+    }
268
+
269
+    /**
270
+     * see http://php.net/manual/en/function.unlink.php
271
+     *
272
+     * @param string $path
273
+     * @return bool
274
+     */
275
+    public function unlink($path) {
276
+        return $this->getWrapperStorage()->unlink($this->getUnjailedPath($path));
277
+    }
278
+
279
+    /**
280
+     * see http://php.net/manual/en/function.rename.php
281
+     *
282
+     * @param string $path1
283
+     * @param string $path2
284
+     * @return bool
285
+     */
286
+    public function rename($path1, $path2) {
287
+        return $this->getWrapperStorage()->rename($this->getUnjailedPath($path1), $this->getUnjailedPath($path2));
288
+    }
289
+
290
+    /**
291
+     * see http://php.net/manual/en/function.copy.php
292
+     *
293
+     * @param string $path1
294
+     * @param string $path2
295
+     * @return bool
296
+     */
297
+    public function copy($path1, $path2) {
298
+        return $this->getWrapperStorage()->copy($this->getUnjailedPath($path1), $this->getUnjailedPath($path2));
299
+    }
300
+
301
+    /**
302
+     * see http://php.net/manual/en/function.fopen.php
303
+     *
304
+     * @param string $path
305
+     * @param string $mode
306
+     * @return resource
307
+     */
308
+    public function fopen($path, $mode) {
309
+        return $this->getWrapperStorage()->fopen($this->getUnjailedPath($path), $mode);
310
+    }
311
+
312
+    /**
313
+     * get the mimetype for a file or folder
314
+     * The mimetype for a folder is required to be "httpd/unix-directory"
315
+     *
316
+     * @param string $path
317
+     * @return string
318
+     */
319
+    public function getMimeType($path) {
320
+        return $this->getWrapperStorage()->getMimeType($this->getUnjailedPath($path));
321
+    }
322
+
323
+    /**
324
+     * see http://php.net/manual/en/function.hash.php
325
+     *
326
+     * @param string $type
327
+     * @param string $path
328
+     * @param bool $raw
329
+     * @return string
330
+     */
331
+    public function hash($type, $path, $raw = false) {
332
+        return $this->getWrapperStorage()->hash($type, $this->getUnjailedPath($path), $raw);
333
+    }
334
+
335
+    /**
336
+     * see http://php.net/manual/en/function.free_space.php
337
+     *
338
+     * @param string $path
339
+     * @return int
340
+     */
341
+    public function free_space($path) {
342
+        return $this->getWrapperStorage()->free_space($this->getUnjailedPath($path));
343
+    }
344
+
345
+    /**
346
+     * search for occurrences of $query in file names
347
+     *
348
+     * @param string $query
349
+     * @return array
350
+     */
351
+    public function search($query) {
352
+        return $this->getWrapperStorage()->search($query);
353
+    }
354
+
355
+    /**
356
+     * see http://php.net/manual/en/function.touch.php
357
+     * If the backend does not support the operation, false should be returned
358
+     *
359
+     * @param string $path
360
+     * @param int $mtime
361
+     * @return bool
362
+     */
363
+    public function touch($path, $mtime = null) {
364
+        return $this->getWrapperStorage()->touch($this->getUnjailedPath($path), $mtime);
365
+    }
366
+
367
+    /**
368
+     * get the path to a local version of the file.
369
+     * The local version of the file can be temporary and doesn't have to be persistent across requests
370
+     *
371
+     * @param string $path
372
+     * @return string
373
+     */
374
+    public function getLocalFile($path) {
375
+        return $this->getWrapperStorage()->getLocalFile($this->getUnjailedPath($path));
376
+    }
377
+
378
+    /**
379
+     * check if a file or folder has been updated since $time
380
+     *
381
+     * @param string $path
382
+     * @param int $time
383
+     * @return bool
384
+     *
385
+     * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
386
+     * returning true for other changes in the folder is optional
387
+     */
388
+    public function hasUpdated($path, $time) {
389
+        return $this->getWrapperStorage()->hasUpdated($this->getUnjailedPath($path), $time);
390
+    }
391
+
392
+    /**
393
+     * get a cache instance for the storage
394
+     *
395
+     * @param string $path
396
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
397
+     * @return \OC\Files\Cache\Cache
398
+     */
399
+    public function getCache($path = '', $storage = null) {
400
+        if (!$storage) {
401
+            $storage = $this->getWrapperStorage();
402
+        }
403
+        $sourceCache = $this->getWrapperStorage()->getCache($this->getUnjailedPath($path), $storage);
404
+        return new CacheJail($sourceCache, $this->rootPath);
405
+    }
406
+
407
+    /**
408
+     * get the user id of the owner of a file or folder
409
+     *
410
+     * @param string $path
411
+     * @return string
412
+     */
413
+    public function getOwner($path) {
414
+        return $this->getWrapperStorage()->getOwner($this->getUnjailedPath($path));
415
+    }
416
+
417
+    /**
418
+     * get a watcher instance for the cache
419
+     *
420
+     * @param string $path
421
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
422
+     * @return \OC\Files\Cache\Watcher
423
+     */
424
+    public function getWatcher($path = '', $storage = null) {
425
+        if (!$storage) {
426
+            $storage = $this;
427
+        }
428
+        return $this->getWrapperStorage()->getWatcher($this->getUnjailedPath($path), $storage);
429
+    }
430
+
431
+    /**
432
+     * get the ETag for a file or folder
433
+     *
434
+     * @param string $path
435
+     * @return string
436
+     */
437
+    public function getETag($path) {
438
+        return $this->getWrapperStorage()->getETag($this->getUnjailedPath($path));
439
+    }
440
+
441
+    /**
442
+     * @param string $path
443
+     * @return array
444
+     */
445
+    public function getMetaData($path) {
446
+        return $this->getWrapperStorage()->getMetaData($this->getUnjailedPath($path));
447
+    }
448
+
449
+    /**
450
+     * @param string $path
451
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
452
+     * @param \OCP\Lock\ILockingProvider $provider
453
+     * @throws \OCP\Lock\LockedException
454
+     */
455
+    public function acquireLock($path, $type, ILockingProvider $provider) {
456
+        $this->getWrapperStorage()->acquireLock($this->getUnjailedPath($path), $type, $provider);
457
+    }
458
+
459
+    /**
460
+     * @param string $path
461
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
462
+     * @param \OCP\Lock\ILockingProvider $provider
463
+     */
464
+    public function releaseLock($path, $type, ILockingProvider $provider) {
465
+        $this->getWrapperStorage()->releaseLock($this->getUnjailedPath($path), $type, $provider);
466
+    }
467
+
468
+    /**
469
+     * @param string $path
470
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
471
+     * @param \OCP\Lock\ILockingProvider $provider
472
+     */
473
+    public function changeLock($path, $type, ILockingProvider $provider) {
474
+        $this->getWrapperStorage()->changeLock($this->getUnjailedPath($path), $type, $provider);
475
+    }
476
+
477
+    /**
478
+     * Resolve the path for the source of the share
479
+     *
480
+     * @param string $path
481
+     * @return array
482
+     */
483
+    public function resolvePath($path) {
484
+        return [$this->getWrapperStorage(), $this->getUnjailedPath($path)];
485
+    }
486
+
487
+    /**
488
+     * @param IStorage $sourceStorage
489
+     * @param string $sourceInternalPath
490
+     * @param string $targetInternalPath
491
+     * @return bool
492
+     */
493
+    public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
494
+        if ($sourceStorage === $this) {
495
+            return $this->copy($sourceInternalPath, $targetInternalPath);
496
+        }
497
+        return $this->getWrapperStorage()->copyFromStorage($sourceStorage, $sourceInternalPath, $this->getUnjailedPath($targetInternalPath));
498
+    }
499
+
500
+    /**
501
+     * @param IStorage $sourceStorage
502
+     * @param string $sourceInternalPath
503
+     * @param string $targetInternalPath
504
+     * @return bool
505
+     */
506
+    public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
507
+        if ($sourceStorage === $this) {
508
+            return $this->rename($sourceInternalPath, $targetInternalPath);
509
+        }
510
+        return $this->getWrapperStorage()->moveFromStorage($sourceStorage, $sourceInternalPath, $this->getUnjailedPath($targetInternalPath));
511
+    }
512
+
513
+    public function getPropagator($storage = null) {
514
+        if (isset($this->propagator)) {
515
+            return $this->propagator;
516
+        }
517
+
518
+        if (!$storage) {
519
+            $storage = $this;
520
+        }
521
+        $this->propagator = new JailPropagator($storage, \OC::$server->getDatabaseConnection());
522
+        return $this->propagator;
523
+    }
524
+
525
+    public function writeStream(string $path, $stream, int $size = null): int {
526
+        $storage = $this->getWrapperStorage();
527
+        if ($storage->instanceOfStorage(IWriteStreamStorage::class)) {
528
+            /** @var IWriteStreamStorage $storage */
529
+            return $storage->writeStream($this->getUnjailedPath($path), $stream, $size);
530
+        } else {
531
+            $target = $this->fopen($path, 'w');
532
+            list($count, $result) = \OC_Helper::streamCopy($stream, $target);
533
+            fclose($stream);
534
+            fclose($target);
535
+            return $count;
536
+        }
537
+    }
538
+
539
+    public function getDirectoryContent($directory): \Traversable {
540
+        return $this->getWrapperStorage()->getDirectoryContent($this->getUnjailedPath($directory));
541
+    }
542 542
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -56,7 +56,7 @@  discard block
 block discarded – undo
56 56
 	}
57 57
 
58 58
 	public function getUnjailedPath($path) {
59
-		return trim(Filesystem::normalizePath($this->rootPath . '/' . $path), '/');
59
+		return trim(Filesystem::normalizePath($this->rootPath.'/'.$path), '/');
60 60
 	}
61 61
 
62 62
 	/**
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
 
69 69
 
70 70
 	public function getJailedPath($path) {
71
-		$root = rtrim($this->rootPath, '/') . '/';
71
+		$root = rtrim($this->rootPath, '/').'/';
72 72
 
73 73
 		if ($path !== $this->rootPath && strpos($path, $root) !== 0) {
74 74
 			return null;
Please login to merge, or discard this patch.
apps/files_sharing/lib/SharedStorage.php 2 patches
Indentation   +458 added lines, -458 removed lines patch added patch discarded remove patch
@@ -50,462 +50,462 @@
 block discarded – undo
50 50
  */
51 51
 class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage, IDisableEncryptionStorage {
52 52
 
53
-	/** @var \OCP\Share\IShare */
54
-	private $superShare;
55
-
56
-	/** @var \OCP\Share\IShare[] */
57
-	private $groupedShares;
58
-
59
-	/**
60
-	 * @var \OC\Files\View
61
-	 */
62
-	private $ownerView;
63
-
64
-	private $initialized = false;
65
-
66
-	/**
67
-	 * @var ICacheEntry
68
-	 */
69
-	private $sourceRootInfo;
70
-
71
-	/** @var string */
72
-	private $user;
73
-
74
-	/**
75
-	 * @var \OCP\ILogger
76
-	 */
77
-	private $logger;
78
-
79
-	/** @var  IStorage */
80
-	private $nonMaskedStorage;
81
-
82
-	private $options;
83
-
84
-	/** @var boolean */
85
-	private $sharingDisabledForUser;
86
-
87
-	public function __construct($arguments) {
88
-		$this->ownerView = $arguments['ownerView'];
89
-		$this->logger = \OC::$server->getLogger();
90
-
91
-		$this->superShare = $arguments['superShare'];
92
-		$this->groupedShares = $arguments['groupedShares'];
93
-
94
-		$this->user = $arguments['user'];
95
-		if (isset($arguments['sharingDisabledForUser'])) {
96
-			$this->sharingDisabledForUser = $arguments['sharingDisabledForUser'];
97
-		} else {
98
-			$this->sharingDisabledForUser = false;
99
-		}
100
-
101
-		parent::__construct([
102
-			'storage' => null,
103
-			'root' => null,
104
-		]);
105
-	}
106
-
107
-	/**
108
-	 * @return ICacheEntry
109
-	 */
110
-	private function getSourceRootInfo() {
111
-		if (is_null($this->sourceRootInfo)) {
112
-			if (is_null($this->superShare->getNodeCacheEntry())) {
113
-				$this->init();
114
-				$this->sourceRootInfo = $this->nonMaskedStorage->getCache()->get($this->rootPath);
115
-			} else {
116
-				$this->sourceRootInfo = $this->superShare->getNodeCacheEntry();
117
-			}
118
-		}
119
-		return $this->sourceRootInfo;
120
-	}
121
-
122
-	private function init() {
123
-		if ($this->initialized) {
124
-			return;
125
-		}
126
-		$this->initialized = true;
127
-		try {
128
-			Filesystem::initMountPoints($this->superShare->getShareOwner());
129
-			$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
130
-			list($this->nonMaskedStorage, $this->rootPath) = $this->ownerView->resolvePath($sourcePath);
131
-			$this->storage = new PermissionsMask([
132
-				'storage' => $this->nonMaskedStorage,
133
-				'mask' => $this->superShare->getPermissions()
134
-			]);
135
-		} catch (NotFoundException $e) {
136
-			// original file not accessible or deleted, set FailedStorage
137
-			$this->storage = new FailedStorage(['exception' => $e]);
138
-			$this->cache = new FailedCache();
139
-			$this->rootPath = '';
140
-		} catch (NoUserException $e) {
141
-			// sharer user deleted, set FailedStorage
142
-			$this->storage = new FailedStorage(['exception' => $e]);
143
-			$this->cache = new FailedCache();
144
-			$this->rootPath = '';
145
-		} catch (\Exception $e) {
146
-			$this->storage = new FailedStorage(['exception' => $e]);
147
-			$this->cache = new FailedCache();
148
-			$this->rootPath = '';
149
-			$this->logger->logException($e);
150
-		}
151
-
152
-		if (!$this->nonMaskedStorage) {
153
-			$this->nonMaskedStorage = $this->storage;
154
-		}
155
-	}
156
-
157
-	/**
158
-	 * @inheritdoc
159
-	 */
160
-	public function instanceOfStorage($class) {
161
-		if ($class === '\OC\Files\Storage\Common') {
162
-			return true;
163
-		}
164
-		if (in_array($class, ['\OC\Files\Storage\Home', '\OC\Files\ObjectStore\HomeObjectStoreStorage'])) {
165
-			return false;
166
-		}
167
-		return parent::instanceOfStorage($class);
168
-	}
169
-
170
-	/**
171
-	 * @return string
172
-	 */
173
-	public function getShareId() {
174
-		return $this->superShare->getId();
175
-	}
176
-
177
-	private function isValid() {
178
-		return $this->getSourceRootInfo() && ($this->getSourceRootInfo()->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE;
179
-	}
180
-
181
-	/**
182
-	 * get id of the mount point
183
-	 *
184
-	 * @return string
185
-	 */
186
-	public function getId() {
187
-		return 'shared::' . $this->getMountPoint();
188
-	}
189
-
190
-	/**
191
-	 * Get the permissions granted for a shared file
192
-	 *
193
-	 * @param string $target Shared target file path
194
-	 * @return int CRUDS permissions granted
195
-	 */
196
-	public function getPermissions($target = '') {
197
-		if (!$this->isValid()) {
198
-			return 0;
199
-		}
200
-		$permissions = parent::getPermissions($target) & $this->superShare->getPermissions();
201
-
202
-		// part files and the mount point always have delete permissions
203
-		if ($target === '' || pathinfo($target, PATHINFO_EXTENSION) === 'part') {
204
-			$permissions |= \OCP\Constants::PERMISSION_DELETE;
205
-		}
206
-
207
-		if ($this->sharingDisabledForUser) {
208
-			$permissions &= ~\OCP\Constants::PERMISSION_SHARE;
209
-		}
210
-
211
-		return $permissions;
212
-	}
213
-
214
-	public function isCreatable($path) {
215
-		return ($this->getPermissions($path) & \OCP\Constants::PERMISSION_CREATE);
216
-	}
217
-
218
-	public function isReadable($path) {
219
-		if (!$this->isValid()) {
220
-			return false;
221
-		}
222
-		if (!$this->file_exists($path)) {
223
-			return false;
224
-		}
225
-		/** @var IStorage $storage */
226
-		/** @var string $internalPath */
227
-		list($storage, $internalPath) = $this->resolvePath($path);
228
-		return $storage->isReadable($internalPath);
229
-	}
230
-
231
-	public function isUpdatable($path) {
232
-		return ($this->getPermissions($path) & \OCP\Constants::PERMISSION_UPDATE);
233
-	}
234
-
235
-	public function isDeletable($path) {
236
-		return ($this->getPermissions($path) & \OCP\Constants::PERMISSION_DELETE);
237
-	}
238
-
239
-	public function isSharable($path) {
240
-		if (\OCP\Util::isSharingDisabledForUser() || !\OC\Share\Share::isResharingAllowed()) {
241
-			return false;
242
-		}
243
-		return ($this->getPermissions($path) & \OCP\Constants::PERMISSION_SHARE);
244
-	}
245
-
246
-	public function fopen($path, $mode) {
247
-		$source = $this->getUnjailedPath($path);
248
-		switch ($mode) {
249
-			case 'r+':
250
-			case 'rb+':
251
-			case 'w+':
252
-			case 'wb+':
253
-			case 'x+':
254
-			case 'xb+':
255
-			case 'a+':
256
-			case 'ab+':
257
-			case 'w':
258
-			case 'wb':
259
-			case 'x':
260
-			case 'xb':
261
-			case 'a':
262
-			case 'ab':
263
-				$creatable = $this->isCreatable(dirname($path));
264
-				$updatable = $this->isUpdatable($path);
265
-				// if neither permissions given, no need to continue
266
-				if (!$creatable && !$updatable) {
267
-					if (pathinfo($path, PATHINFO_EXTENSION) === 'part') {
268
-						$updatable = $this->isUpdatable(dirname($path));
269
-					}
270
-
271
-					if (!$updatable) {
272
-						return false;
273
-					}
274
-				}
275
-
276
-				$exists = $this->file_exists($path);
277
-				// if a file exists, updatable permissions are required
278
-				if ($exists && !$updatable) {
279
-					return false;
280
-				}
281
-
282
-				// part file is allowed if !$creatable but the final file is $updatable
283
-				if (pathinfo($path, PATHINFO_EXTENSION) !== 'part') {
284
-					if (!$exists && !$creatable) {
285
-						return false;
286
-					}
287
-				}
288
-		}
289
-		$info = [
290
-			'target' => $this->getMountPoint() . $path,
291
-			'source' => $source,
292
-			'mode' => $mode,
293
-		];
294
-		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info);
295
-		return $this->nonMaskedStorage->fopen($this->getUnjailedPath($path), $mode);
296
-	}
297
-
298
-	/**
299
-	 * see http://php.net/manual/en/function.rename.php
300
-	 *
301
-	 * @param string $path1
302
-	 * @param string $path2
303
-	 * @return bool
304
-	 */
305
-	public function rename($path1, $path2) {
306
-		$this->init();
307
-		$isPartFile = pathinfo($path1, PATHINFO_EXTENSION) === 'part';
308
-		$targetExists = $this->file_exists($path2);
309
-		$sameFodler = dirname($path1) === dirname($path2);
310
-
311
-		if ($targetExists || ($sameFodler && !$isPartFile)) {
312
-			if (!$this->isUpdatable('')) {
313
-				return false;
314
-			}
315
-		} else {
316
-			if (!$this->isCreatable('')) {
317
-				return false;
318
-			}
319
-		}
320
-
321
-		return $this->nonMaskedStorage->rename($this->getUnjailedPath($path1), $this->getUnjailedPath($path2));
322
-	}
323
-
324
-	/**
325
-	 * return mount point of share, relative to data/user/files
326
-	 *
327
-	 * @return string
328
-	 */
329
-	public function getMountPoint() {
330
-		return $this->superShare->getTarget();
331
-	}
332
-
333
-	/**
334
-	 * @param string $path
335
-	 */
336
-	public function setMountPoint($path) {
337
-		$this->superShare->setTarget($path);
338
-
339
-		foreach ($this->groupedShares as $share) {
340
-			$share->setTarget($path);
341
-		}
342
-	}
343
-
344
-	/**
345
-	 * get the user who shared the file
346
-	 *
347
-	 * @return string
348
-	 */
349
-	public function getSharedFrom() {
350
-		return $this->superShare->getShareOwner();
351
-	}
352
-
353
-	/**
354
-	 * @return \OCP\Share\IShare
355
-	 */
356
-	public function getShare() {
357
-		return $this->superShare;
358
-	}
359
-
360
-	/**
361
-	 * return share type, can be "file" or "folder"
362
-	 *
363
-	 * @return string
364
-	 */
365
-	public function getItemType() {
366
-		return $this->superShare->getNodeType();
367
-	}
368
-
369
-	/**
370
-	 * @param string $path
371
-	 * @param null $storage
372
-	 * @return Cache
373
-	 */
374
-	public function getCache($path = '', $storage = null) {
375
-		if ($this->cache) {
376
-			return $this->cache;
377
-		}
378
-		if (!$storage) {
379
-			$storage = $this;
380
-		}
381
-		$sourceRoot  = $this->getSourceRootInfo();
382
-		if ($this->storage instanceof FailedStorage) {
383
-			return new FailedCache();
384
-		}
385
-
386
-		$this->cache = new \OCA\Files_Sharing\Cache($storage, $sourceRoot, $this->superShare);
387
-		return $this->cache;
388
-	}
389
-
390
-	public function getScanner($path = '', $storage = null) {
391
-		if (!$storage) {
392
-			$storage = $this;
393
-		}
394
-		return new \OCA\Files_Sharing\Scanner($storage);
395
-	}
396
-
397
-	public function getOwner($path) {
398
-		return $this->superShare->getShareOwner();
399
-	}
400
-
401
-	/**
402
-	 * unshare complete storage, also the grouped shares
403
-	 *
404
-	 * @return bool
405
-	 */
406
-	public function unshareStorage() {
407
-		foreach ($this->groupedShares as $share) {
408
-			\OC::$server->getShareManager()->deleteFromSelf($share, $this->user);
409
-		}
410
-		return true;
411
-	}
412
-
413
-	/**
414
-	 * @param string $path
415
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
416
-	 * @param \OCP\Lock\ILockingProvider $provider
417
-	 * @throws \OCP\Lock\LockedException
418
-	 */
419
-	public function acquireLock($path, $type, ILockingProvider $provider) {
420
-		/** @var \OCP\Files\Storage $targetStorage */
421
-		list($targetStorage, $targetInternalPath) = $this->resolvePath($path);
422
-		$targetStorage->acquireLock($targetInternalPath, $type, $provider);
423
-		// lock the parent folders of the owner when locking the share as recipient
424
-		if ($path === '') {
425
-			$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
426
-			$this->ownerView->lockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
427
-		}
428
-	}
429
-
430
-	/**
431
-	 * @param string $path
432
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
433
-	 * @param \OCP\Lock\ILockingProvider $provider
434
-	 */
435
-	public function releaseLock($path, $type, ILockingProvider $provider) {
436
-		/** @var \OCP\Files\Storage $targetStorage */
437
-		list($targetStorage, $targetInternalPath) = $this->resolvePath($path);
438
-		$targetStorage->releaseLock($targetInternalPath, $type, $provider);
439
-		// unlock the parent folders of the owner when unlocking the share as recipient
440
-		if ($path === '') {
441
-			$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
442
-			$this->ownerView->unlockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
443
-		}
444
-	}
445
-
446
-	/**
447
-	 * @param string $path
448
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
449
-	 * @param \OCP\Lock\ILockingProvider $provider
450
-	 */
451
-	public function changeLock($path, $type, ILockingProvider $provider) {
452
-		/** @var \OCP\Files\Storage $targetStorage */
453
-		list($targetStorage, $targetInternalPath) = $this->resolvePath($path);
454
-		$targetStorage->changeLock($targetInternalPath, $type, $provider);
455
-	}
456
-
457
-	/**
458
-	 * @return array [ available, last_checked ]
459
-	 */
460
-	public function getAvailability() {
461
-		// shares do not participate in availability logic
462
-		return [
463
-			'available' => true,
464
-			'last_checked' => 0
465
-		];
466
-	}
467
-
468
-	/**
469
-	 * @param bool $available
470
-	 */
471
-	public function setAvailability($available) {
472
-		// shares do not participate in availability logic
473
-	}
474
-
475
-	public function getSourceStorage() {
476
-		$this->init();
477
-		return $this->nonMaskedStorage;
478
-	}
479
-
480
-	public function getWrapperStorage() {
481
-		$this->init();
482
-		return $this->storage;
483
-	}
484
-
485
-	public function file_get_contents($path) {
486
-		$info = [
487
-			'target' => $this->getMountPoint() . '/' . $path,
488
-			'source' => $this->getUnjailedPath($path),
489
-		];
490
-		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info);
491
-		return parent::file_get_contents($path);
492
-	}
493
-
494
-	public function file_put_contents($path, $data) {
495
-		$info = [
496
-			'target' => $this->getMountPoint() . '/' . $path,
497
-			'source' => $this->getUnjailedPath($path),
498
-		];
499
-		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info);
500
-		return parent::file_put_contents($path, $data);
501
-	}
502
-
503
-	public function setMountOptions(array $options) {
504
-		$this->mountOptions = $options;
505
-	}
506
-
507
-	public function getUnjailedPath($path) {
508
-		$this->init();
509
-		return parent::getUnjailedPath($path);
510
-	}
53
+    /** @var \OCP\Share\IShare */
54
+    private $superShare;
55
+
56
+    /** @var \OCP\Share\IShare[] */
57
+    private $groupedShares;
58
+
59
+    /**
60
+     * @var \OC\Files\View
61
+     */
62
+    private $ownerView;
63
+
64
+    private $initialized = false;
65
+
66
+    /**
67
+     * @var ICacheEntry
68
+     */
69
+    private $sourceRootInfo;
70
+
71
+    /** @var string */
72
+    private $user;
73
+
74
+    /**
75
+     * @var \OCP\ILogger
76
+     */
77
+    private $logger;
78
+
79
+    /** @var  IStorage */
80
+    private $nonMaskedStorage;
81
+
82
+    private $options;
83
+
84
+    /** @var boolean */
85
+    private $sharingDisabledForUser;
86
+
87
+    public function __construct($arguments) {
88
+        $this->ownerView = $arguments['ownerView'];
89
+        $this->logger = \OC::$server->getLogger();
90
+
91
+        $this->superShare = $arguments['superShare'];
92
+        $this->groupedShares = $arguments['groupedShares'];
93
+
94
+        $this->user = $arguments['user'];
95
+        if (isset($arguments['sharingDisabledForUser'])) {
96
+            $this->sharingDisabledForUser = $arguments['sharingDisabledForUser'];
97
+        } else {
98
+            $this->sharingDisabledForUser = false;
99
+        }
100
+
101
+        parent::__construct([
102
+            'storage' => null,
103
+            'root' => null,
104
+        ]);
105
+    }
106
+
107
+    /**
108
+     * @return ICacheEntry
109
+     */
110
+    private function getSourceRootInfo() {
111
+        if (is_null($this->sourceRootInfo)) {
112
+            if (is_null($this->superShare->getNodeCacheEntry())) {
113
+                $this->init();
114
+                $this->sourceRootInfo = $this->nonMaskedStorage->getCache()->get($this->rootPath);
115
+            } else {
116
+                $this->sourceRootInfo = $this->superShare->getNodeCacheEntry();
117
+            }
118
+        }
119
+        return $this->sourceRootInfo;
120
+    }
121
+
122
+    private function init() {
123
+        if ($this->initialized) {
124
+            return;
125
+        }
126
+        $this->initialized = true;
127
+        try {
128
+            Filesystem::initMountPoints($this->superShare->getShareOwner());
129
+            $sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
130
+            list($this->nonMaskedStorage, $this->rootPath) = $this->ownerView->resolvePath($sourcePath);
131
+            $this->storage = new PermissionsMask([
132
+                'storage' => $this->nonMaskedStorage,
133
+                'mask' => $this->superShare->getPermissions()
134
+            ]);
135
+        } catch (NotFoundException $e) {
136
+            // original file not accessible or deleted, set FailedStorage
137
+            $this->storage = new FailedStorage(['exception' => $e]);
138
+            $this->cache = new FailedCache();
139
+            $this->rootPath = '';
140
+        } catch (NoUserException $e) {
141
+            // sharer user deleted, set FailedStorage
142
+            $this->storage = new FailedStorage(['exception' => $e]);
143
+            $this->cache = new FailedCache();
144
+            $this->rootPath = '';
145
+        } catch (\Exception $e) {
146
+            $this->storage = new FailedStorage(['exception' => $e]);
147
+            $this->cache = new FailedCache();
148
+            $this->rootPath = '';
149
+            $this->logger->logException($e);
150
+        }
151
+
152
+        if (!$this->nonMaskedStorage) {
153
+            $this->nonMaskedStorage = $this->storage;
154
+        }
155
+    }
156
+
157
+    /**
158
+     * @inheritdoc
159
+     */
160
+    public function instanceOfStorage($class) {
161
+        if ($class === '\OC\Files\Storage\Common') {
162
+            return true;
163
+        }
164
+        if (in_array($class, ['\OC\Files\Storage\Home', '\OC\Files\ObjectStore\HomeObjectStoreStorage'])) {
165
+            return false;
166
+        }
167
+        return parent::instanceOfStorage($class);
168
+    }
169
+
170
+    /**
171
+     * @return string
172
+     */
173
+    public function getShareId() {
174
+        return $this->superShare->getId();
175
+    }
176
+
177
+    private function isValid() {
178
+        return $this->getSourceRootInfo() && ($this->getSourceRootInfo()->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE;
179
+    }
180
+
181
+    /**
182
+     * get id of the mount point
183
+     *
184
+     * @return string
185
+     */
186
+    public function getId() {
187
+        return 'shared::' . $this->getMountPoint();
188
+    }
189
+
190
+    /**
191
+     * Get the permissions granted for a shared file
192
+     *
193
+     * @param string $target Shared target file path
194
+     * @return int CRUDS permissions granted
195
+     */
196
+    public function getPermissions($target = '') {
197
+        if (!$this->isValid()) {
198
+            return 0;
199
+        }
200
+        $permissions = parent::getPermissions($target) & $this->superShare->getPermissions();
201
+
202
+        // part files and the mount point always have delete permissions
203
+        if ($target === '' || pathinfo($target, PATHINFO_EXTENSION) === 'part') {
204
+            $permissions |= \OCP\Constants::PERMISSION_DELETE;
205
+        }
206
+
207
+        if ($this->sharingDisabledForUser) {
208
+            $permissions &= ~\OCP\Constants::PERMISSION_SHARE;
209
+        }
210
+
211
+        return $permissions;
212
+    }
213
+
214
+    public function isCreatable($path) {
215
+        return ($this->getPermissions($path) & \OCP\Constants::PERMISSION_CREATE);
216
+    }
217
+
218
+    public function isReadable($path) {
219
+        if (!$this->isValid()) {
220
+            return false;
221
+        }
222
+        if (!$this->file_exists($path)) {
223
+            return false;
224
+        }
225
+        /** @var IStorage $storage */
226
+        /** @var string $internalPath */
227
+        list($storage, $internalPath) = $this->resolvePath($path);
228
+        return $storage->isReadable($internalPath);
229
+    }
230
+
231
+    public function isUpdatable($path) {
232
+        return ($this->getPermissions($path) & \OCP\Constants::PERMISSION_UPDATE);
233
+    }
234
+
235
+    public function isDeletable($path) {
236
+        return ($this->getPermissions($path) & \OCP\Constants::PERMISSION_DELETE);
237
+    }
238
+
239
+    public function isSharable($path) {
240
+        if (\OCP\Util::isSharingDisabledForUser() || !\OC\Share\Share::isResharingAllowed()) {
241
+            return false;
242
+        }
243
+        return ($this->getPermissions($path) & \OCP\Constants::PERMISSION_SHARE);
244
+    }
245
+
246
+    public function fopen($path, $mode) {
247
+        $source = $this->getUnjailedPath($path);
248
+        switch ($mode) {
249
+            case 'r+':
250
+            case 'rb+':
251
+            case 'w+':
252
+            case 'wb+':
253
+            case 'x+':
254
+            case 'xb+':
255
+            case 'a+':
256
+            case 'ab+':
257
+            case 'w':
258
+            case 'wb':
259
+            case 'x':
260
+            case 'xb':
261
+            case 'a':
262
+            case 'ab':
263
+                $creatable = $this->isCreatable(dirname($path));
264
+                $updatable = $this->isUpdatable($path);
265
+                // if neither permissions given, no need to continue
266
+                if (!$creatable && !$updatable) {
267
+                    if (pathinfo($path, PATHINFO_EXTENSION) === 'part') {
268
+                        $updatable = $this->isUpdatable(dirname($path));
269
+                    }
270
+
271
+                    if (!$updatable) {
272
+                        return false;
273
+                    }
274
+                }
275
+
276
+                $exists = $this->file_exists($path);
277
+                // if a file exists, updatable permissions are required
278
+                if ($exists && !$updatable) {
279
+                    return false;
280
+                }
281
+
282
+                // part file is allowed if !$creatable but the final file is $updatable
283
+                if (pathinfo($path, PATHINFO_EXTENSION) !== 'part') {
284
+                    if (!$exists && !$creatable) {
285
+                        return false;
286
+                    }
287
+                }
288
+        }
289
+        $info = [
290
+            'target' => $this->getMountPoint() . $path,
291
+            'source' => $source,
292
+            'mode' => $mode,
293
+        ];
294
+        \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info);
295
+        return $this->nonMaskedStorage->fopen($this->getUnjailedPath($path), $mode);
296
+    }
297
+
298
+    /**
299
+     * see http://php.net/manual/en/function.rename.php
300
+     *
301
+     * @param string $path1
302
+     * @param string $path2
303
+     * @return bool
304
+     */
305
+    public function rename($path1, $path2) {
306
+        $this->init();
307
+        $isPartFile = pathinfo($path1, PATHINFO_EXTENSION) === 'part';
308
+        $targetExists = $this->file_exists($path2);
309
+        $sameFodler = dirname($path1) === dirname($path2);
310
+
311
+        if ($targetExists || ($sameFodler && !$isPartFile)) {
312
+            if (!$this->isUpdatable('')) {
313
+                return false;
314
+            }
315
+        } else {
316
+            if (!$this->isCreatable('')) {
317
+                return false;
318
+            }
319
+        }
320
+
321
+        return $this->nonMaskedStorage->rename($this->getUnjailedPath($path1), $this->getUnjailedPath($path2));
322
+    }
323
+
324
+    /**
325
+     * return mount point of share, relative to data/user/files
326
+     *
327
+     * @return string
328
+     */
329
+    public function getMountPoint() {
330
+        return $this->superShare->getTarget();
331
+    }
332
+
333
+    /**
334
+     * @param string $path
335
+     */
336
+    public function setMountPoint($path) {
337
+        $this->superShare->setTarget($path);
338
+
339
+        foreach ($this->groupedShares as $share) {
340
+            $share->setTarget($path);
341
+        }
342
+    }
343
+
344
+    /**
345
+     * get the user who shared the file
346
+     *
347
+     * @return string
348
+     */
349
+    public function getSharedFrom() {
350
+        return $this->superShare->getShareOwner();
351
+    }
352
+
353
+    /**
354
+     * @return \OCP\Share\IShare
355
+     */
356
+    public function getShare() {
357
+        return $this->superShare;
358
+    }
359
+
360
+    /**
361
+     * return share type, can be "file" or "folder"
362
+     *
363
+     * @return string
364
+     */
365
+    public function getItemType() {
366
+        return $this->superShare->getNodeType();
367
+    }
368
+
369
+    /**
370
+     * @param string $path
371
+     * @param null $storage
372
+     * @return Cache
373
+     */
374
+    public function getCache($path = '', $storage = null) {
375
+        if ($this->cache) {
376
+            return $this->cache;
377
+        }
378
+        if (!$storage) {
379
+            $storage = $this;
380
+        }
381
+        $sourceRoot  = $this->getSourceRootInfo();
382
+        if ($this->storage instanceof FailedStorage) {
383
+            return new FailedCache();
384
+        }
385
+
386
+        $this->cache = new \OCA\Files_Sharing\Cache($storage, $sourceRoot, $this->superShare);
387
+        return $this->cache;
388
+    }
389
+
390
+    public function getScanner($path = '', $storage = null) {
391
+        if (!$storage) {
392
+            $storage = $this;
393
+        }
394
+        return new \OCA\Files_Sharing\Scanner($storage);
395
+    }
396
+
397
+    public function getOwner($path) {
398
+        return $this->superShare->getShareOwner();
399
+    }
400
+
401
+    /**
402
+     * unshare complete storage, also the grouped shares
403
+     *
404
+     * @return bool
405
+     */
406
+    public function unshareStorage() {
407
+        foreach ($this->groupedShares as $share) {
408
+            \OC::$server->getShareManager()->deleteFromSelf($share, $this->user);
409
+        }
410
+        return true;
411
+    }
412
+
413
+    /**
414
+     * @param string $path
415
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
416
+     * @param \OCP\Lock\ILockingProvider $provider
417
+     * @throws \OCP\Lock\LockedException
418
+     */
419
+    public function acquireLock($path, $type, ILockingProvider $provider) {
420
+        /** @var \OCP\Files\Storage $targetStorage */
421
+        list($targetStorage, $targetInternalPath) = $this->resolvePath($path);
422
+        $targetStorage->acquireLock($targetInternalPath, $type, $provider);
423
+        // lock the parent folders of the owner when locking the share as recipient
424
+        if ($path === '') {
425
+            $sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
426
+            $this->ownerView->lockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
427
+        }
428
+    }
429
+
430
+    /**
431
+     * @param string $path
432
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
433
+     * @param \OCP\Lock\ILockingProvider $provider
434
+     */
435
+    public function releaseLock($path, $type, ILockingProvider $provider) {
436
+        /** @var \OCP\Files\Storage $targetStorage */
437
+        list($targetStorage, $targetInternalPath) = $this->resolvePath($path);
438
+        $targetStorage->releaseLock($targetInternalPath, $type, $provider);
439
+        // unlock the parent folders of the owner when unlocking the share as recipient
440
+        if ($path === '') {
441
+            $sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
442
+            $this->ownerView->unlockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
443
+        }
444
+    }
445
+
446
+    /**
447
+     * @param string $path
448
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
449
+     * @param \OCP\Lock\ILockingProvider $provider
450
+     */
451
+    public function changeLock($path, $type, ILockingProvider $provider) {
452
+        /** @var \OCP\Files\Storage $targetStorage */
453
+        list($targetStorage, $targetInternalPath) = $this->resolvePath($path);
454
+        $targetStorage->changeLock($targetInternalPath, $type, $provider);
455
+    }
456
+
457
+    /**
458
+     * @return array [ available, last_checked ]
459
+     */
460
+    public function getAvailability() {
461
+        // shares do not participate in availability logic
462
+        return [
463
+            'available' => true,
464
+            'last_checked' => 0
465
+        ];
466
+    }
467
+
468
+    /**
469
+     * @param bool $available
470
+     */
471
+    public function setAvailability($available) {
472
+        // shares do not participate in availability logic
473
+    }
474
+
475
+    public function getSourceStorage() {
476
+        $this->init();
477
+        return $this->nonMaskedStorage;
478
+    }
479
+
480
+    public function getWrapperStorage() {
481
+        $this->init();
482
+        return $this->storage;
483
+    }
484
+
485
+    public function file_get_contents($path) {
486
+        $info = [
487
+            'target' => $this->getMountPoint() . '/' . $path,
488
+            'source' => $this->getUnjailedPath($path),
489
+        ];
490
+        \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info);
491
+        return parent::file_get_contents($path);
492
+    }
493
+
494
+    public function file_put_contents($path, $data) {
495
+        $info = [
496
+            'target' => $this->getMountPoint() . '/' . $path,
497
+            'source' => $this->getUnjailedPath($path),
498
+        ];
499
+        \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info);
500
+        return parent::file_put_contents($path, $data);
501
+    }
502
+
503
+    public function setMountOptions(array $options) {
504
+        $this->mountOptions = $options;
505
+    }
506
+
507
+    public function getUnjailedPath($path) {
508
+        $this->init();
509
+        return parent::getUnjailedPath($path);
510
+    }
511 511
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -184,7 +184,7 @@  discard block
 block discarded – undo
184 184
 	 * @return string
185 185
 	 */
186 186
 	public function getId() {
187
-		return 'shared::' . $this->getMountPoint();
187
+		return 'shared::'.$this->getMountPoint();
188 188
 	}
189 189
 
190 190
 	/**
@@ -287,7 +287,7 @@  discard block
 block discarded – undo
287 287
 				}
288 288
 		}
289 289
 		$info = [
290
-			'target' => $this->getMountPoint() . $path,
290
+			'target' => $this->getMountPoint().$path,
291 291
 			'source' => $source,
292 292
 			'mode' => $mode,
293 293
 		];
@@ -378,7 +378,7 @@  discard block
 block discarded – undo
378 378
 		if (!$storage) {
379 379
 			$storage = $this;
380 380
 		}
381
-		$sourceRoot  = $this->getSourceRootInfo();
381
+		$sourceRoot = $this->getSourceRootInfo();
382 382
 		if ($this->storage instanceof FailedStorage) {
383 383
 			return new FailedCache();
384 384
 		}
@@ -484,7 +484,7 @@  discard block
 block discarded – undo
484 484
 
485 485
 	public function file_get_contents($path) {
486 486
 		$info = [
487
-			'target' => $this->getMountPoint() . '/' . $path,
487
+			'target' => $this->getMountPoint().'/'.$path,
488 488
 			'source' => $this->getUnjailedPath($path),
489 489
 		];
490 490
 		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info);
@@ -493,7 +493,7 @@  discard block
 block discarded – undo
493 493
 
494 494
 	public function file_put_contents($path, $data) {
495 495
 		$info = [
496
-			'target' => $this->getMountPoint() . '/' . $path,
496
+			'target' => $this->getMountPoint().'/'.$path,
497 497
 			'source' => $this->getUnjailedPath($path),
498 498
 		];
499 499
 		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info);
Please login to merge, or discard this patch.