Passed
Push — master ( c3361a...cdc9a1 )
by Christoph
13:22 queued 10s
created
apps/files_sharing/lib/SharedStorage.php 2 patches
Indentation   +464 added lines, -464 removed lines patch added patch discarded remove patch
@@ -52,468 +52,468 @@
 block discarded – undo
52 52
  */
53 53
 class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage, IDisableEncryptionStorage {
54 54
 
55
-	/** @var \OCP\Share\IShare */
56
-	private $superShare;
57
-
58
-	/** @var \OCP\Share\IShare[] */
59
-	private $groupedShares;
60
-
61
-	/**
62
-	 * @var \OC\Files\View
63
-	 */
64
-	private $ownerView;
65
-
66
-	private $initialized = false;
67
-
68
-	/**
69
-	 * @var ICacheEntry
70
-	 */
71
-	private $sourceRootInfo;
72
-
73
-	/** @var string */
74
-	private $user;
75
-
76
-	/**
77
-	 * @var \OCP\ILogger
78
-	 */
79
-	private $logger;
80
-
81
-	/** @var  IStorage */
82
-	private $nonMaskedStorage;
83
-
84
-	private $options;
85
-
86
-	/** @var boolean */
87
-	private $sharingDisabledForUser;
88
-
89
-	public function __construct($arguments) {
90
-		$this->ownerView = $arguments['ownerView'];
91
-		$this->logger = \OC::$server->getLogger();
92
-
93
-		$this->superShare = $arguments['superShare'];
94
-		$this->groupedShares = $arguments['groupedShares'];
95
-
96
-		$this->user = $arguments['user'];
97
-		if (isset($arguments['sharingDisabledForUser'])) {
98
-			$this->sharingDisabledForUser = $arguments['sharingDisabledForUser'];
99
-		} else {
100
-			$this->sharingDisabledForUser = false;
101
-		}
102
-
103
-		parent::__construct([
104
-			'storage' => null,
105
-			'root' => null,
106
-		]);
107
-	}
108
-
109
-	/**
110
-	 * @return ICacheEntry
111
-	 */
112
-	private function getSourceRootInfo() {
113
-		if (is_null($this->sourceRootInfo)) {
114
-			if (is_null($this->superShare->getNodeCacheEntry())) {
115
-				$this->init();
116
-				$this->sourceRootInfo = $this->nonMaskedStorage->getCache()->get($this->rootPath);
117
-			} else {
118
-				$this->sourceRootInfo = $this->superShare->getNodeCacheEntry();
119
-			}
120
-		}
121
-		return $this->sourceRootInfo;
122
-	}
123
-
124
-	private function init() {
125
-		if ($this->initialized) {
126
-			return;
127
-		}
128
-		$this->initialized = true;
129
-		try {
130
-			Filesystem::initMountPoints($this->superShare->getShareOwner());
131
-			$storageId = $this->superShare->getNodeCacheEntry() ? $this->superShare->getNodeCacheEntry()->getStorageId() : null;
132
-			$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId(), $storageId);
133
-			[$this->nonMaskedStorage, $this->rootPath] = $this->ownerView->resolvePath($sourcePath);
134
-			$this->storage = new PermissionsMask([
135
-				'storage' => $this->nonMaskedStorage,
136
-				'mask' => $this->superShare->getPermissions(),
137
-			]);
138
-		} catch (NotFoundException $e) {
139
-			// original file not accessible or deleted, set FailedStorage
140
-			$this->storage = new FailedStorage(['exception' => $e]);
141
-			$this->cache = new FailedCache();
142
-			$this->rootPath = '';
143
-		} catch (NoUserException $e) {
144
-			// sharer user deleted, set FailedStorage
145
-			$this->storage = new FailedStorage(['exception' => $e]);
146
-			$this->cache = new FailedCache();
147
-			$this->rootPath = '';
148
-		} catch (\Exception $e) {
149
-			$this->storage = new FailedStorage(['exception' => $e]);
150
-			$this->cache = new FailedCache();
151
-			$this->rootPath = '';
152
-			$this->logger->logException($e);
153
-		}
154
-
155
-		if (!$this->nonMaskedStorage) {
156
-			$this->nonMaskedStorage = $this->storage;
157
-		}
158
-	}
159
-
160
-	/**
161
-	 * @inheritdoc
162
-	 */
163
-	public function instanceOfStorage($class): bool {
164
-		if ($class === '\OC\Files\Storage\Common') {
165
-			return true;
166
-		}
167
-		if (in_array($class, ['\OC\Files\Storage\Home', '\OC\Files\ObjectStore\HomeObjectStoreStorage', '\OCP\Files\IHomeStorage'])) {
168
-			return false;
169
-		}
170
-		return parent::instanceOfStorage($class);
171
-	}
172
-
173
-	/**
174
-	 * @return string
175
-	 */
176
-	public function getShareId() {
177
-		return $this->superShare->getId();
178
-	}
179
-
180
-	private function isValid(): bool {
181
-		return $this->getSourceRootInfo() && ($this->getSourceRootInfo()->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE;
182
-	}
183
-
184
-	/**
185
-	 * get id of the mount point
186
-	 *
187
-	 * @return string
188
-	 */
189
-	public function getId(): string {
190
-		return 'shared::' . $this->getMountPoint();
191
-	}
192
-
193
-	/**
194
-	 * Get the permissions granted for a shared file
195
-	 *
196
-	 * @param string $target Shared target file path
197
-	 * @return int CRUDS permissions granted
198
-	 */
199
-	public function getPermissions($target = ''): int {
200
-		if (!$this->isValid()) {
201
-			return 0;
202
-		}
203
-		$permissions = parent::getPermissions($target) & $this->superShare->getPermissions();
204
-
205
-		// part files and the mount point always have delete permissions
206
-		if ($target === '' || pathinfo($target, PATHINFO_EXTENSION) === 'part') {
207
-			$permissions |= \OCP\Constants::PERMISSION_DELETE;
208
-		}
209
-
210
-		if ($this->sharingDisabledForUser) {
211
-			$permissions &= ~\OCP\Constants::PERMISSION_SHARE;
212
-		}
213
-
214
-		return $permissions;
215
-	}
216
-
217
-	public function isCreatable($path): bool {
218
-		return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_CREATE);
219
-	}
220
-
221
-	public function isReadable($path): bool {
222
-		if (!$this->isValid()) {
223
-			return false;
224
-		}
225
-		if (!$this->file_exists($path)) {
226
-			return false;
227
-		}
228
-		/** @var IStorage $storage */
229
-		/** @var string $internalPath */
230
-		[$storage, $internalPath] = $this->resolvePath($path);
231
-		return $storage->isReadable($internalPath);
232
-	}
233
-
234
-	public function isUpdatable($path): bool {
235
-		return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_UPDATE);
236
-	}
237
-
238
-	public function isDeletable($path): bool {
239
-		return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_DELETE);
240
-	}
241
-
242
-	public function isSharable($path): bool {
243
-		if (\OCP\Util::isSharingDisabledForUser() || !\OC\Share\Share::isResharingAllowed()) {
244
-			return false;
245
-		}
246
-		return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_SHARE);
247
-	}
248
-
249
-	public function fopen($path, $mode) {
250
-		$source = $this->getUnjailedPath($path);
251
-		switch ($mode) {
252
-			case 'r+':
253
-			case 'rb+':
254
-			case 'w+':
255
-			case 'wb+':
256
-			case 'x+':
257
-			case 'xb+':
258
-			case 'a+':
259
-			case 'ab+':
260
-			case 'w':
261
-			case 'wb':
262
-			case 'x':
263
-			case 'xb':
264
-			case 'a':
265
-			case 'ab':
266
-				$creatable = $this->isCreatable(dirname($path));
267
-				$updatable = $this->isUpdatable($path);
268
-				// if neither permissions given, no need to continue
269
-				if (!$creatable && !$updatable) {
270
-					if (pathinfo($path, PATHINFO_EXTENSION) === 'part') {
271
-						$updatable = $this->isUpdatable(dirname($path));
272
-					}
273
-
274
-					if (!$updatable) {
275
-						return false;
276
-					}
277
-				}
278
-
279
-				$exists = $this->file_exists($path);
280
-				// if a file exists, updatable permissions are required
281
-				if ($exists && !$updatable) {
282
-					return false;
283
-				}
284
-
285
-				// part file is allowed if !$creatable but the final file is $updatable
286
-				if (pathinfo($path, PATHINFO_EXTENSION) !== 'part') {
287
-					if (!$exists && !$creatable) {
288
-						return false;
289
-					}
290
-				}
291
-		}
292
-		$info = [
293
-			'target' => $this->getMountPoint() . '/' . $path,
294
-			'source' => $source,
295
-			'mode' => $mode,
296
-		];
297
-		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info);
298
-		return $this->nonMaskedStorage->fopen($this->getUnjailedPath($path), $mode);
299
-	}
300
-
301
-	/**
302
-	 * see https://www.php.net/manual/en/function.rename.php
303
-	 *
304
-	 * @param string $path1
305
-	 * @param string $path2
306
-	 * @return bool
307
-	 */
308
-	public function rename($path1, $path2): bool {
309
-		$this->init();
310
-		$isPartFile = pathinfo($path1, PATHINFO_EXTENSION) === 'part';
311
-		$targetExists = $this->file_exists($path2);
312
-		$sameFolder = dirname($path1) === dirname($path2);
313
-
314
-		if ($targetExists || ($sameFolder && !$isPartFile)) {
315
-			if (!$this->isUpdatable('')) {
316
-				return false;
317
-			}
318
-		} else {
319
-			if (!$this->isCreatable('')) {
320
-				return false;
321
-			}
322
-		}
323
-
324
-		return $this->nonMaskedStorage->rename($this->getUnjailedPath($path1), $this->getUnjailedPath($path2));
325
-	}
326
-
327
-	/**
328
-	 * return mount point of share, relative to data/user/files
329
-	 *
330
-	 * @return string
331
-	 */
332
-	public function getMountPoint(): string {
333
-		return $this->superShare->getTarget();
334
-	}
335
-
336
-	/**
337
-	 * @param string $path
338
-	 */
339
-	public function setMountPoint($path): void {
340
-		$this->superShare->setTarget($path);
341
-
342
-		foreach ($this->groupedShares as $share) {
343
-			$share->setTarget($path);
344
-		}
345
-	}
346
-
347
-	/**
348
-	 * get the user who shared the file
349
-	 *
350
-	 * @return string
351
-	 */
352
-	public function getSharedFrom(): string {
353
-		return $this->superShare->getShareOwner();
354
-	}
355
-
356
-	/**
357
-	 * @return \OCP\Share\IShare
358
-	 */
359
-	public function getShare(): IShare {
360
-		return $this->superShare;
361
-	}
362
-
363
-	/**
364
-	 * return share type, can be "file" or "folder"
365
-	 *
366
-	 * @return string
367
-	 */
368
-	public function getItemType(): string {
369
-		return $this->superShare->getNodeType();
370
-	}
371
-
372
-	/**
373
-	 * @param string $path
374
-	 * @param null $storage
375
-	 * @return Cache
376
-	 */
377
-	public function getCache($path = '', $storage = null) {
378
-		if ($this->cache) {
379
-			return $this->cache;
380
-		}
381
-		if (!$storage) {
382
-			$storage = $this;
383
-		}
384
-		$sourceRoot = $this->getSourceRootInfo();
385
-		if ($this->storage instanceof FailedStorage) {
386
-			return new FailedCache();
387
-		}
388
-
389
-		$this->cache = new \OCA\Files_Sharing\Cache($storage, $sourceRoot, $this->superShare);
390
-		return $this->cache;
391
-	}
392
-
393
-	public function getScanner($path = '', $storage = null) {
394
-		if (!$storage) {
395
-			$storage = $this;
396
-		}
397
-		return new \OCA\Files_Sharing\Scanner($storage);
398
-	}
399
-
400
-	public function getOwner($path): string {
401
-		return $this->superShare->getShareOwner();
402
-	}
403
-
404
-	public function getWatcher($path = '', $storage = null): NullWatcher {
405
-		// cache updating is handled by the share source
406
-		return new NullWatcher();
407
-	}
408
-
409
-	/**
410
-	 * unshare complete storage, also the grouped shares
411
-	 *
412
-	 * @return bool
413
-	 */
414
-	public function unshareStorage(): bool {
415
-		foreach ($this->groupedShares as $share) {
416
-			\OC::$server->getShareManager()->deleteFromSelf($share, $this->user);
417
-		}
418
-		return true;
419
-	}
420
-
421
-	/**
422
-	 * @param string $path
423
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
424
-	 * @param \OCP\Lock\ILockingProvider $provider
425
-	 * @throws \OCP\Lock\LockedException
426
-	 */
427
-	public function acquireLock($path, $type, ILockingProvider $provider) {
428
-		/** @var \OCP\Files\Storage $targetStorage */
429
-		[$targetStorage, $targetInternalPath] = $this->resolvePath($path);
430
-		$targetStorage->acquireLock($targetInternalPath, $type, $provider);
431
-		// lock the parent folders of the owner when locking the share as recipient
432
-		if ($path === '') {
433
-			$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
434
-			$this->ownerView->lockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
435
-		}
436
-	}
437
-
438
-	/**
439
-	 * @param string $path
440
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
441
-	 * @param \OCP\Lock\ILockingProvider $provider
442
-	 */
443
-	public function releaseLock($path, $type, ILockingProvider $provider) {
444
-		/** @var \OCP\Files\Storage $targetStorage */
445
-		[$targetStorage, $targetInternalPath] = $this->resolvePath($path);
446
-		$targetStorage->releaseLock($targetInternalPath, $type, $provider);
447
-		// unlock the parent folders of the owner when unlocking the share as recipient
448
-		if ($path === '') {
449
-			$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
450
-			$this->ownerView->unlockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
451
-		}
452
-	}
453
-
454
-	/**
455
-	 * @param string $path
456
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
457
-	 * @param \OCP\Lock\ILockingProvider $provider
458
-	 */
459
-	public function changeLock($path, $type, ILockingProvider $provider) {
460
-		/** @var \OCP\Files\Storage $targetStorage */
461
-		[$targetStorage, $targetInternalPath] = $this->resolvePath($path);
462
-		$targetStorage->changeLock($targetInternalPath, $type, $provider);
463
-	}
464
-
465
-	/**
466
-	 * @return array [ available, last_checked ]
467
-	 */
468
-	public function getAvailability() {
469
-		// shares do not participate in availability logic
470
-		return [
471
-			'available' => true,
472
-			'last_checked' => 0,
473
-		];
474
-	}
475
-
476
-	/**
477
-	 * @param bool $available
478
-	 */
479
-	public function setAvailability($available) {
480
-		// shares do not participate in availability logic
481
-	}
482
-
483
-	public function getSourceStorage() {
484
-		$this->init();
485
-		return $this->nonMaskedStorage;
486
-	}
487
-
488
-	public function getWrapperStorage() {
489
-		$this->init();
490
-		return $this->storage;
491
-	}
492
-
493
-	public function file_get_contents($path) {
494
-		$info = [
495
-			'target' => $this->getMountPoint() . '/' . $path,
496
-			'source' => $this->getUnjailedPath($path),
497
-		];
498
-		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info);
499
-		return parent::file_get_contents($path);
500
-	}
501
-
502
-	public function file_put_contents($path, $data) {
503
-		$info = [
504
-			'target' => $this->getMountPoint() . '/' . $path,
505
-			'source' => $this->getUnjailedPath($path),
506
-		];
507
-		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info);
508
-		return parent::file_put_contents($path, $data);
509
-	}
510
-
511
-	public function setMountOptions(array $options) {
512
-		$this->mountOptions = $options;
513
-	}
514
-
515
-	public function getUnjailedPath($path) {
516
-		$this->init();
517
-		return parent::getUnjailedPath($path);
518
-	}
55
+    /** @var \OCP\Share\IShare */
56
+    private $superShare;
57
+
58
+    /** @var \OCP\Share\IShare[] */
59
+    private $groupedShares;
60
+
61
+    /**
62
+     * @var \OC\Files\View
63
+     */
64
+    private $ownerView;
65
+
66
+    private $initialized = false;
67
+
68
+    /**
69
+     * @var ICacheEntry
70
+     */
71
+    private $sourceRootInfo;
72
+
73
+    /** @var string */
74
+    private $user;
75
+
76
+    /**
77
+     * @var \OCP\ILogger
78
+     */
79
+    private $logger;
80
+
81
+    /** @var  IStorage */
82
+    private $nonMaskedStorage;
83
+
84
+    private $options;
85
+
86
+    /** @var boolean */
87
+    private $sharingDisabledForUser;
88
+
89
+    public function __construct($arguments) {
90
+        $this->ownerView = $arguments['ownerView'];
91
+        $this->logger = \OC::$server->getLogger();
92
+
93
+        $this->superShare = $arguments['superShare'];
94
+        $this->groupedShares = $arguments['groupedShares'];
95
+
96
+        $this->user = $arguments['user'];
97
+        if (isset($arguments['sharingDisabledForUser'])) {
98
+            $this->sharingDisabledForUser = $arguments['sharingDisabledForUser'];
99
+        } else {
100
+            $this->sharingDisabledForUser = false;
101
+        }
102
+
103
+        parent::__construct([
104
+            'storage' => null,
105
+            'root' => null,
106
+        ]);
107
+    }
108
+
109
+    /**
110
+     * @return ICacheEntry
111
+     */
112
+    private function getSourceRootInfo() {
113
+        if (is_null($this->sourceRootInfo)) {
114
+            if (is_null($this->superShare->getNodeCacheEntry())) {
115
+                $this->init();
116
+                $this->sourceRootInfo = $this->nonMaskedStorage->getCache()->get($this->rootPath);
117
+            } else {
118
+                $this->sourceRootInfo = $this->superShare->getNodeCacheEntry();
119
+            }
120
+        }
121
+        return $this->sourceRootInfo;
122
+    }
123
+
124
+    private function init() {
125
+        if ($this->initialized) {
126
+            return;
127
+        }
128
+        $this->initialized = true;
129
+        try {
130
+            Filesystem::initMountPoints($this->superShare->getShareOwner());
131
+            $storageId = $this->superShare->getNodeCacheEntry() ? $this->superShare->getNodeCacheEntry()->getStorageId() : null;
132
+            $sourcePath = $this->ownerView->getPath($this->superShare->getNodeId(), $storageId);
133
+            [$this->nonMaskedStorage, $this->rootPath] = $this->ownerView->resolvePath($sourcePath);
134
+            $this->storage = new PermissionsMask([
135
+                'storage' => $this->nonMaskedStorage,
136
+                'mask' => $this->superShare->getPermissions(),
137
+            ]);
138
+        } catch (NotFoundException $e) {
139
+            // original file not accessible or deleted, set FailedStorage
140
+            $this->storage = new FailedStorage(['exception' => $e]);
141
+            $this->cache = new FailedCache();
142
+            $this->rootPath = '';
143
+        } catch (NoUserException $e) {
144
+            // sharer user deleted, set FailedStorage
145
+            $this->storage = new FailedStorage(['exception' => $e]);
146
+            $this->cache = new FailedCache();
147
+            $this->rootPath = '';
148
+        } catch (\Exception $e) {
149
+            $this->storage = new FailedStorage(['exception' => $e]);
150
+            $this->cache = new FailedCache();
151
+            $this->rootPath = '';
152
+            $this->logger->logException($e);
153
+        }
154
+
155
+        if (!$this->nonMaskedStorage) {
156
+            $this->nonMaskedStorage = $this->storage;
157
+        }
158
+    }
159
+
160
+    /**
161
+     * @inheritdoc
162
+     */
163
+    public function instanceOfStorage($class): bool {
164
+        if ($class === '\OC\Files\Storage\Common') {
165
+            return true;
166
+        }
167
+        if (in_array($class, ['\OC\Files\Storage\Home', '\OC\Files\ObjectStore\HomeObjectStoreStorage', '\OCP\Files\IHomeStorage'])) {
168
+            return false;
169
+        }
170
+        return parent::instanceOfStorage($class);
171
+    }
172
+
173
+    /**
174
+     * @return string
175
+     */
176
+    public function getShareId() {
177
+        return $this->superShare->getId();
178
+    }
179
+
180
+    private function isValid(): bool {
181
+        return $this->getSourceRootInfo() && ($this->getSourceRootInfo()->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE;
182
+    }
183
+
184
+    /**
185
+     * get id of the mount point
186
+     *
187
+     * @return string
188
+     */
189
+    public function getId(): string {
190
+        return 'shared::' . $this->getMountPoint();
191
+    }
192
+
193
+    /**
194
+     * Get the permissions granted for a shared file
195
+     *
196
+     * @param string $target Shared target file path
197
+     * @return int CRUDS permissions granted
198
+     */
199
+    public function getPermissions($target = ''): int {
200
+        if (!$this->isValid()) {
201
+            return 0;
202
+        }
203
+        $permissions = parent::getPermissions($target) & $this->superShare->getPermissions();
204
+
205
+        // part files and the mount point always have delete permissions
206
+        if ($target === '' || pathinfo($target, PATHINFO_EXTENSION) === 'part') {
207
+            $permissions |= \OCP\Constants::PERMISSION_DELETE;
208
+        }
209
+
210
+        if ($this->sharingDisabledForUser) {
211
+            $permissions &= ~\OCP\Constants::PERMISSION_SHARE;
212
+        }
213
+
214
+        return $permissions;
215
+    }
216
+
217
+    public function isCreatable($path): bool {
218
+        return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_CREATE);
219
+    }
220
+
221
+    public function isReadable($path): bool {
222
+        if (!$this->isValid()) {
223
+            return false;
224
+        }
225
+        if (!$this->file_exists($path)) {
226
+            return false;
227
+        }
228
+        /** @var IStorage $storage */
229
+        /** @var string $internalPath */
230
+        [$storage, $internalPath] = $this->resolvePath($path);
231
+        return $storage->isReadable($internalPath);
232
+    }
233
+
234
+    public function isUpdatable($path): bool {
235
+        return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_UPDATE);
236
+    }
237
+
238
+    public function isDeletable($path): bool {
239
+        return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_DELETE);
240
+    }
241
+
242
+    public function isSharable($path): bool {
243
+        if (\OCP\Util::isSharingDisabledForUser() || !\OC\Share\Share::isResharingAllowed()) {
244
+            return false;
245
+        }
246
+        return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_SHARE);
247
+    }
248
+
249
+    public function fopen($path, $mode) {
250
+        $source = $this->getUnjailedPath($path);
251
+        switch ($mode) {
252
+            case 'r+':
253
+            case 'rb+':
254
+            case 'w+':
255
+            case 'wb+':
256
+            case 'x+':
257
+            case 'xb+':
258
+            case 'a+':
259
+            case 'ab+':
260
+            case 'w':
261
+            case 'wb':
262
+            case 'x':
263
+            case 'xb':
264
+            case 'a':
265
+            case 'ab':
266
+                $creatable = $this->isCreatable(dirname($path));
267
+                $updatable = $this->isUpdatable($path);
268
+                // if neither permissions given, no need to continue
269
+                if (!$creatable && !$updatable) {
270
+                    if (pathinfo($path, PATHINFO_EXTENSION) === 'part') {
271
+                        $updatable = $this->isUpdatable(dirname($path));
272
+                    }
273
+
274
+                    if (!$updatable) {
275
+                        return false;
276
+                    }
277
+                }
278
+
279
+                $exists = $this->file_exists($path);
280
+                // if a file exists, updatable permissions are required
281
+                if ($exists && !$updatable) {
282
+                    return false;
283
+                }
284
+
285
+                // part file is allowed if !$creatable but the final file is $updatable
286
+                if (pathinfo($path, PATHINFO_EXTENSION) !== 'part') {
287
+                    if (!$exists && !$creatable) {
288
+                        return false;
289
+                    }
290
+                }
291
+        }
292
+        $info = [
293
+            'target' => $this->getMountPoint() . '/' . $path,
294
+            'source' => $source,
295
+            'mode' => $mode,
296
+        ];
297
+        \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info);
298
+        return $this->nonMaskedStorage->fopen($this->getUnjailedPath($path), $mode);
299
+    }
300
+
301
+    /**
302
+     * see https://www.php.net/manual/en/function.rename.php
303
+     *
304
+     * @param string $path1
305
+     * @param string $path2
306
+     * @return bool
307
+     */
308
+    public function rename($path1, $path2): bool {
309
+        $this->init();
310
+        $isPartFile = pathinfo($path1, PATHINFO_EXTENSION) === 'part';
311
+        $targetExists = $this->file_exists($path2);
312
+        $sameFolder = dirname($path1) === dirname($path2);
313
+
314
+        if ($targetExists || ($sameFolder && !$isPartFile)) {
315
+            if (!$this->isUpdatable('')) {
316
+                return false;
317
+            }
318
+        } else {
319
+            if (!$this->isCreatable('')) {
320
+                return false;
321
+            }
322
+        }
323
+
324
+        return $this->nonMaskedStorage->rename($this->getUnjailedPath($path1), $this->getUnjailedPath($path2));
325
+    }
326
+
327
+    /**
328
+     * return mount point of share, relative to data/user/files
329
+     *
330
+     * @return string
331
+     */
332
+    public function getMountPoint(): string {
333
+        return $this->superShare->getTarget();
334
+    }
335
+
336
+    /**
337
+     * @param string $path
338
+     */
339
+    public function setMountPoint($path): void {
340
+        $this->superShare->setTarget($path);
341
+
342
+        foreach ($this->groupedShares as $share) {
343
+            $share->setTarget($path);
344
+        }
345
+    }
346
+
347
+    /**
348
+     * get the user who shared the file
349
+     *
350
+     * @return string
351
+     */
352
+    public function getSharedFrom(): string {
353
+        return $this->superShare->getShareOwner();
354
+    }
355
+
356
+    /**
357
+     * @return \OCP\Share\IShare
358
+     */
359
+    public function getShare(): IShare {
360
+        return $this->superShare;
361
+    }
362
+
363
+    /**
364
+     * return share type, can be "file" or "folder"
365
+     *
366
+     * @return string
367
+     */
368
+    public function getItemType(): string {
369
+        return $this->superShare->getNodeType();
370
+    }
371
+
372
+    /**
373
+     * @param string $path
374
+     * @param null $storage
375
+     * @return Cache
376
+     */
377
+    public function getCache($path = '', $storage = null) {
378
+        if ($this->cache) {
379
+            return $this->cache;
380
+        }
381
+        if (!$storage) {
382
+            $storage = $this;
383
+        }
384
+        $sourceRoot = $this->getSourceRootInfo();
385
+        if ($this->storage instanceof FailedStorage) {
386
+            return new FailedCache();
387
+        }
388
+
389
+        $this->cache = new \OCA\Files_Sharing\Cache($storage, $sourceRoot, $this->superShare);
390
+        return $this->cache;
391
+    }
392
+
393
+    public function getScanner($path = '', $storage = null) {
394
+        if (!$storage) {
395
+            $storage = $this;
396
+        }
397
+        return new \OCA\Files_Sharing\Scanner($storage);
398
+    }
399
+
400
+    public function getOwner($path): string {
401
+        return $this->superShare->getShareOwner();
402
+    }
403
+
404
+    public function getWatcher($path = '', $storage = null): NullWatcher {
405
+        // cache updating is handled by the share source
406
+        return new NullWatcher();
407
+    }
408
+
409
+    /**
410
+     * unshare complete storage, also the grouped shares
411
+     *
412
+     * @return bool
413
+     */
414
+    public function unshareStorage(): bool {
415
+        foreach ($this->groupedShares as $share) {
416
+            \OC::$server->getShareManager()->deleteFromSelf($share, $this->user);
417
+        }
418
+        return true;
419
+    }
420
+
421
+    /**
422
+     * @param string $path
423
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
424
+     * @param \OCP\Lock\ILockingProvider $provider
425
+     * @throws \OCP\Lock\LockedException
426
+     */
427
+    public function acquireLock($path, $type, ILockingProvider $provider) {
428
+        /** @var \OCP\Files\Storage $targetStorage */
429
+        [$targetStorage, $targetInternalPath] = $this->resolvePath($path);
430
+        $targetStorage->acquireLock($targetInternalPath, $type, $provider);
431
+        // lock the parent folders of the owner when locking the share as recipient
432
+        if ($path === '') {
433
+            $sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
434
+            $this->ownerView->lockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
435
+        }
436
+    }
437
+
438
+    /**
439
+     * @param string $path
440
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
441
+     * @param \OCP\Lock\ILockingProvider $provider
442
+     */
443
+    public function releaseLock($path, $type, ILockingProvider $provider) {
444
+        /** @var \OCP\Files\Storage $targetStorage */
445
+        [$targetStorage, $targetInternalPath] = $this->resolvePath($path);
446
+        $targetStorage->releaseLock($targetInternalPath, $type, $provider);
447
+        // unlock the parent folders of the owner when unlocking the share as recipient
448
+        if ($path === '') {
449
+            $sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
450
+            $this->ownerView->unlockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
451
+        }
452
+    }
453
+
454
+    /**
455
+     * @param string $path
456
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
457
+     * @param \OCP\Lock\ILockingProvider $provider
458
+     */
459
+    public function changeLock($path, $type, ILockingProvider $provider) {
460
+        /** @var \OCP\Files\Storage $targetStorage */
461
+        [$targetStorage, $targetInternalPath] = $this->resolvePath($path);
462
+        $targetStorage->changeLock($targetInternalPath, $type, $provider);
463
+    }
464
+
465
+    /**
466
+     * @return array [ available, last_checked ]
467
+     */
468
+    public function getAvailability() {
469
+        // shares do not participate in availability logic
470
+        return [
471
+            'available' => true,
472
+            'last_checked' => 0,
473
+        ];
474
+    }
475
+
476
+    /**
477
+     * @param bool $available
478
+     */
479
+    public function setAvailability($available) {
480
+        // shares do not participate in availability logic
481
+    }
482
+
483
+    public function getSourceStorage() {
484
+        $this->init();
485
+        return $this->nonMaskedStorage;
486
+    }
487
+
488
+    public function getWrapperStorage() {
489
+        $this->init();
490
+        return $this->storage;
491
+    }
492
+
493
+    public function file_get_contents($path) {
494
+        $info = [
495
+            'target' => $this->getMountPoint() . '/' . $path,
496
+            'source' => $this->getUnjailedPath($path),
497
+        ];
498
+        \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info);
499
+        return parent::file_get_contents($path);
500
+    }
501
+
502
+    public function file_put_contents($path, $data) {
503
+        $info = [
504
+            'target' => $this->getMountPoint() . '/' . $path,
505
+            'source' => $this->getUnjailedPath($path),
506
+        ];
507
+        \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info);
508
+        return parent::file_put_contents($path, $data);
509
+    }
510
+
511
+    public function setMountOptions(array $options) {
512
+        $this->mountOptions = $options;
513
+    }
514
+
515
+    public function getUnjailedPath($path) {
516
+        $this->init();
517
+        return parent::getUnjailedPath($path);
518
+    }
519 519
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -187,7 +187,7 @@  discard block
 block discarded – undo
187 187
 	 * @return string
188 188
 	 */
189 189
 	public function getId(): string {
190
-		return 'shared::' . $this->getMountPoint();
190
+		return 'shared::'.$this->getMountPoint();
191 191
 	}
192 192
 
193 193
 	/**
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
 	}
216 216
 
217 217
 	public function isCreatable($path): bool {
218
-		return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_CREATE);
218
+		return (bool) ($this->getPermissions($path) & \OCP\Constants::PERMISSION_CREATE);
219 219
 	}
220 220
 
221 221
 	public function isReadable($path): bool {
@@ -232,18 +232,18 @@  discard block
 block discarded – undo
232 232
 	}
233 233
 
234 234
 	public function isUpdatable($path): bool {
235
-		return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_UPDATE);
235
+		return (bool) ($this->getPermissions($path) & \OCP\Constants::PERMISSION_UPDATE);
236 236
 	}
237 237
 
238 238
 	public function isDeletable($path): bool {
239
-		return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_DELETE);
239
+		return (bool) ($this->getPermissions($path) & \OCP\Constants::PERMISSION_DELETE);
240 240
 	}
241 241
 
242 242
 	public function isSharable($path): bool {
243 243
 		if (\OCP\Util::isSharingDisabledForUser() || !\OC\Share\Share::isResharingAllowed()) {
244 244
 			return false;
245 245
 		}
246
-		return (bool)($this->getPermissions($path) & \OCP\Constants::PERMISSION_SHARE);
246
+		return (bool) ($this->getPermissions($path) & \OCP\Constants::PERMISSION_SHARE);
247 247
 	}
248 248
 
249 249
 	public function fopen($path, $mode) {
@@ -290,7 +290,7 @@  discard block
 block discarded – undo
290 290
 				}
291 291
 		}
292 292
 		$info = [
293
-			'target' => $this->getMountPoint() . '/' . $path,
293
+			'target' => $this->getMountPoint().'/'.$path,
294 294
 			'source' => $source,
295 295
 			'mode' => $mode,
296 296
 		];
@@ -492,7 +492,7 @@  discard block
 block discarded – undo
492 492
 
493 493
 	public function file_get_contents($path) {
494 494
 		$info = [
495
-			'target' => $this->getMountPoint() . '/' . $path,
495
+			'target' => $this->getMountPoint().'/'.$path,
496 496
 			'source' => $this->getUnjailedPath($path),
497 497
 		];
498 498
 		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info);
@@ -501,7 +501,7 @@  discard block
 block discarded – undo
501 501
 
502 502
 	public function file_put_contents($path, $data) {
503 503
 		$info = [
504
-			'target' => $this->getMountPoint() . '/' . $path,
504
+			'target' => $this->getMountPoint().'/'.$path,
505 505
 			'source' => $this->getUnjailedPath($path),
506 506
 		];
507 507
 		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info);
Please login to merge, or discard this patch.