Completed
Push — master ( b6a39b...106d93 )
by Morris
15:45
created

Jail::getJailedPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 6
Ratio 60 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
nc 2
nop 1
dl 6
loc 10
rs 9.4285
c 1
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Lukas Reschke <[email protected]>
6
 * @author Morris Jobke <[email protected]>
7
 * @author Robin Appelman <[email protected]>
8
 * @author Roeland Jago Douma <[email protected]>
9
 *
10
 * @license AGPL-3.0
11
 *
12
 * This code is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License, version 3,
14
 * as published by the Free Software Foundation.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License, version 3,
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
23
 *
24
 */
25
26
namespace OC\Files\Storage\Wrapper;
27
28
use OC\Files\Cache\Wrapper\CacheJail;
29
use OC\Files\Cache\Wrapper\JailPropagator;
30
use OCP\Files\Storage\IStorage;
31
use OCP\Lock\ILockingProvider;
32
33
/**
34
 * Jail to a subdirectory of the wrapped storage
35
 *
36
 * This restricts access to a subfolder of the wrapped storage with the subfolder becoming the root folder new storage
37
 */
38
class Jail extends Wrapper {
39
	/**
40
	 * @var string
41
	 */
42
	protected $rootPath;
43
44
	/**
45
	 * @param array $arguments ['storage' => $storage, 'mask' => $root]
46
	 *
47
	 * $storage: The storage that will be wrapper
48
	 * $root: The folder in the wrapped storage that will become the root folder of the wrapped storage
49
	 */
50
	public function __construct($arguments) {
51
		parent::__construct($arguments);
52
		$this->rootPath = $arguments['root'];
53
	}
54
55
	public function getUnjailedPath($path) {
56
		if ($path === '') {
57
			return $this->rootPath;
58
		} else {
59
			return $this->rootPath . '/' . $path;
60
		}
61
	}
62
63
	public function getJailedPath($path) {
64
		$root = rtrim($this->rootPath, '/') . '/';
65
66 View Code Duplication
		if (strpos($path, $root) !== 0) {
67
			return null;
68
		} else {
69
			$path = substr($path, strlen($this->rootPath));
70
			return trim($path, '/');
71
		}
72
	}
73
74
	public function getId() {
75
		return parent::getId();
76
	}
77
78
	/**
79
	 * see http://php.net/manual/en/function.mkdir.php
80
	 *
81
	 * @param string $path
82
	 * @return bool
83
	 */
84
	public function mkdir($path) {
85
		return $this->getWrapperStorage()->mkdir($this->getUnjailedPath($path));
86
	}
87
88
	/**
89
	 * see http://php.net/manual/en/function.rmdir.php
90
	 *
91
	 * @param string $path
92
	 * @return bool
93
	 */
94
	public function rmdir($path) {
95
		return $this->getWrapperStorage()->rmdir($this->getUnjailedPath($path));
96
	}
97
98
	/**
99
	 * see http://php.net/manual/en/function.opendir.php
100
	 *
101
	 * @param string $path
102
	 * @return resource
103
	 */
104
	public function opendir($path) {
105
		return $this->getWrapperStorage()->opendir($this->getUnjailedPath($path));
106
	}
107
108
	/**
109
	 * see http://php.net/manual/en/function.is_dir.php
110
	 *
111
	 * @param string $path
112
	 * @return bool
113
	 */
114
	public function is_dir($path) {
115
		return $this->getWrapperStorage()->is_dir($this->getUnjailedPath($path));
116
	}
117
118
	/**
119
	 * see http://php.net/manual/en/function.is_file.php
120
	 *
121
	 * @param string $path
122
	 * @return bool
123
	 */
124
	public function is_file($path) {
125
		return $this->getWrapperStorage()->is_file($this->getUnjailedPath($path));
126
	}
127
128
	/**
129
	 * see http://php.net/manual/en/function.stat.php
130
	 * only the following keys are required in the result: size and mtime
131
	 *
132
	 * @param string $path
133
	 * @return array
134
	 */
135
	public function stat($path) {
136
		return $this->getWrapperStorage()->stat($this->getUnjailedPath($path));
137
	}
138
139
	/**
140
	 * see http://php.net/manual/en/function.filetype.php
141
	 *
142
	 * @param string $path
143
	 * @return bool
144
	 */
145
	public function filetype($path) {
146
		return $this->getWrapperStorage()->filetype($this->getUnjailedPath($path));
147
	}
148
149
	/**
150
	 * see http://php.net/manual/en/function.filesize.php
151
	 * The result for filesize when called on a folder is required to be 0
152
	 *
153
	 * @param string $path
154
	 * @return int
155
	 */
156
	public function filesize($path) {
157
		return $this->getWrapperStorage()->filesize($this->getUnjailedPath($path));
158
	}
159
160
	/**
161
	 * check if a file can be created in $path
162
	 *
163
	 * @param string $path
164
	 * @return bool
165
	 */
166
	public function isCreatable($path) {
167
		return $this->getWrapperStorage()->isCreatable($this->getUnjailedPath($path));
168
	}
169
170
	/**
171
	 * check if a file can be read
172
	 *
173
	 * @param string $path
174
	 * @return bool
175
	 */
176
	public function isReadable($path) {
177
		return $this->getWrapperStorage()->isReadable($this->getUnjailedPath($path));
178
	}
179
180
	/**
181
	 * check if a file can be written to
182
	 *
183
	 * @param string $path
184
	 * @return bool
185
	 */
186
	public function isUpdatable($path) {
187
		return $this->getWrapperStorage()->isUpdatable($this->getUnjailedPath($path));
188
	}
189
190
	/**
191
	 * check if a file can be deleted
192
	 *
193
	 * @param string $path
194
	 * @return bool
195
	 */
196
	public function isDeletable($path) {
197
		return $this->getWrapperStorage()->isDeletable($this->getUnjailedPath($path));
198
	}
199
200
	/**
201
	 * check if a file can be shared
202
	 *
203
	 * @param string $path
204
	 * @return bool
205
	 */
206
	public function isSharable($path) {
207
		return $this->getWrapperStorage()->isSharable($this->getUnjailedPath($path));
208
	}
209
210
	/**
211
	 * get the full permissions of a path.
212
	 * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
213
	 *
214
	 * @param string $path
215
	 * @return int
216
	 */
217
	public function getPermissions($path) {
218
		return $this->getWrapperStorage()->getPermissions($this->getUnjailedPath($path));
219
	}
220
221
	/**
222
	 * see http://php.net/manual/en/function.file_exists.php
223
	 *
224
	 * @param string $path
225
	 * @return bool
226
	 */
227
	public function file_exists($path) {
228
		return $this->getWrapperStorage()->file_exists($this->getUnjailedPath($path));
229
	}
230
231
	/**
232
	 * see http://php.net/manual/en/function.filemtime.php
233
	 *
234
	 * @param string $path
235
	 * @return int
236
	 */
237
	public function filemtime($path) {
238
		return $this->getWrapperStorage()->filemtime($this->getUnjailedPath($path));
239
	}
240
241
	/**
242
	 * see http://php.net/manual/en/function.file_get_contents.php
243
	 *
244
	 * @param string $path
245
	 * @return string
246
	 */
247
	public function file_get_contents($path) {
248
		return $this->getWrapperStorage()->file_get_contents($this->getUnjailedPath($path));
249
	}
250
251
	/**
252
	 * see http://php.net/manual/en/function.file_put_contents.php
253
	 *
254
	 * @param string $path
255
	 * @param string $data
256
	 * @return bool
257
	 */
258
	public function file_put_contents($path, $data) {
259
		return $this->getWrapperStorage()->file_put_contents($this->getUnjailedPath($path), $data);
260
	}
261
262
	/**
263
	 * see http://php.net/manual/en/function.unlink.php
264
	 *
265
	 * @param string $path
266
	 * @return bool
267
	 */
268
	public function unlink($path) {
269
		return $this->getWrapperStorage()->unlink($this->getUnjailedPath($path));
270
	}
271
272
	/**
273
	 * see http://php.net/manual/en/function.rename.php
274
	 *
275
	 * @param string $path1
276
	 * @param string $path2
277
	 * @return bool
278
	 */
279
	public function rename($path1, $path2) {
280
		return $this->getWrapperStorage()->rename($this->getUnjailedPath($path1), $this->getUnjailedPath($path2));
281
	}
282
283
	/**
284
	 * see http://php.net/manual/en/function.copy.php
285
	 *
286
	 * @param string $path1
287
	 * @param string $path2
288
	 * @return bool
289
	 */
290
	public function copy($path1, $path2) {
291
		return $this->getWrapperStorage()->copy($this->getUnjailedPath($path1), $this->getUnjailedPath($path2));
292
	}
293
294
	/**
295
	 * see http://php.net/manual/en/function.fopen.php
296
	 *
297
	 * @param string $path
298
	 * @param string $mode
299
	 * @return resource
300
	 */
301
	public function fopen($path, $mode) {
302
		return $this->getWrapperStorage()->fopen($this->getUnjailedPath($path), $mode);
303
	}
304
305
	/**
306
	 * get the mimetype for a file or folder
307
	 * The mimetype for a folder is required to be "httpd/unix-directory"
308
	 *
309
	 * @param string $path
310
	 * @return string
311
	 */
312
	public function getMimeType($path) {
313
		return $this->getWrapperStorage()->getMimeType($this->getUnjailedPath($path));
314
	}
315
316
	/**
317
	 * see http://php.net/manual/en/function.hash.php
318
	 *
319
	 * @param string $type
320
	 * @param string $path
321
	 * @param bool $raw
322
	 * @return string
323
	 */
324
	public function hash($type, $path, $raw = false) {
325
		return $this->getWrapperStorage()->hash($type, $this->getUnjailedPath($path), $raw);
326
	}
327
328
	/**
329
	 * see http://php.net/manual/en/function.free_space.php
330
	 *
331
	 * @param string $path
332
	 * @return int
333
	 */
334
	public function free_space($path) {
335
		return $this->getWrapperStorage()->free_space($this->getUnjailedPath($path));
336
	}
337
338
	/**
339
	 * search for occurrences of $query in file names
340
	 *
341
	 * @param string $query
342
	 * @return array
343
	 */
344
	public function search($query) {
345
		return $this->getWrapperStorage()->search($query);
346
	}
347
348
	/**
349
	 * see http://php.net/manual/en/function.touch.php
350
	 * If the backend does not support the operation, false should be returned
351
	 *
352
	 * @param string $path
353
	 * @param int $mtime
354
	 * @return bool
355
	 */
356
	public function touch($path, $mtime = null) {
357
		return $this->getWrapperStorage()->touch($this->getUnjailedPath($path), $mtime);
358
	}
359
360
	/**
361
	 * get the path to a local version of the file.
362
	 * The local version of the file can be temporary and doesn't have to be persistent across requests
363
	 *
364
	 * @param string $path
365
	 * @return string
366
	 */
367
	public function getLocalFile($path) {
368
		return $this->getWrapperStorage()->getLocalFile($this->getUnjailedPath($path));
369
	}
370
371
	/**
372
	 * check if a file or folder has been updated since $time
373
	 *
374
	 * @param string $path
375
	 * @param int $time
376
	 * @return bool
377
	 *
378
	 * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
379
	 * returning true for other changes in the folder is optional
380
	 */
381
	public function hasUpdated($path, $time) {
382
		return $this->getWrapperStorage()->hasUpdated($this->getUnjailedPath($path), $time);
383
	}
384
385
	/**
386
	 * get a cache instance for the storage
387
	 *
388
	 * @param string $path
389
	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
390
	 * @return \OC\Files\Cache\Cache
391
	 */
392
	public function getCache($path = '', $storage = null) {
393
		if (!$storage) {
394
			$storage = $this->getWrapperStorage();
395
		}
396
		$sourceCache = $this->getWrapperStorage()->getCache($this->getUnjailedPath($path), $storage);
397
		return new CacheJail($sourceCache, $this->rootPath);
398
	}
399
400
	/**
401
	 * get the user id of the owner of a file or folder
402
	 *
403
	 * @param string $path
404
	 * @return string
405
	 */
406
	public function getOwner($path) {
407
		return $this->getWrapperStorage()->getOwner($this->getUnjailedPath($path));
408
	}
409
410
	/**
411
	 * get a watcher instance for the cache
412
	 *
413
	 * @param string $path
414
	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
415
	 * @return \OC\Files\Cache\Watcher
416
	 */
417
	public function getWatcher($path = '', $storage = null) {
418
		if (!$storage) {
419
			$storage = $this;
420
		}
421
		return $this->getWrapperStorage()->getWatcher($this->getUnjailedPath($path), $storage);
422
	}
423
424
	/**
425
	 * get the ETag for a file or folder
426
	 *
427
	 * @param string $path
428
	 * @return string
429
	 */
430
	public function getETag($path) {
431
		return $this->getWrapperStorage()->getETag($this->getUnjailedPath($path));
432
	}
433
434
	/**
435
	 * @param string $path
436
	 * @return array
437
	 */
438
	public function getMetaData($path) {
439
		return $this->getWrapperStorage()->getMetaData($this->getUnjailedPath($path));
440
	}
441
442
	/**
443
	 * @param string $path
444
	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
445
	 * @param \OCP\Lock\ILockingProvider $provider
446
	 * @throws \OCP\Lock\LockedException
447
	 */
448
	public function acquireLock($path, $type, ILockingProvider $provider) {
449
		$this->getWrapperStorage()->acquireLock($this->getUnjailedPath($path), $type, $provider);
450
	}
451
452
	/**
453
	 * @param string $path
454
	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
455
	 * @param \OCP\Lock\ILockingProvider $provider
456
	 */
457
	public function releaseLock($path, $type, ILockingProvider $provider) {
458
		$this->getWrapperStorage()->releaseLock($this->getUnjailedPath($path), $type, $provider);
459
	}
460
461
	/**
462
	 * @param string $path
463
	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
464
	 * @param \OCP\Lock\ILockingProvider $provider
465
	 */
466
	public function changeLock($path, $type, ILockingProvider $provider) {
467
		$this->getWrapperStorage()->changeLock($this->getUnjailedPath($path), $type, $provider);
468
	}
469
470
	/**
471
	 * Resolve the path for the source of the share
472
	 *
473
	 * @param string $path
474
	 * @return array
475
	 */
476
	public function resolvePath($path) {
477
		return [$this->getWrapperStorage(), $this->getUnjailedPath($path)];
478
	}
479
480
	/**
481
	 * @param IStorage $sourceStorage
482
	 * @param string $sourceInternalPath
483
	 * @param string $targetInternalPath
484
	 * @return bool
485
	 */
486
	public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
487
		if ($sourceStorage === $this) {
488
			return $this->copy($sourceInternalPath, $targetInternalPath);
489
		}
490
		return $this->getWrapperStorage()->copyFromStorage($sourceStorage, $sourceInternalPath, $this->getUnjailedPath($targetInternalPath));
491
	}
492
493
	/**
494
	 * @param IStorage $sourceStorage
495
	 * @param string $sourceInternalPath
496
	 * @param string $targetInternalPath
497
	 * @return bool
498
	 */
499
	public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
500
		if ($sourceStorage === $this) {
501
			return $this->rename($sourceInternalPath, $targetInternalPath);
502
		}
503
		return $this->getWrapperStorage()->moveFromStorage($sourceStorage, $sourceInternalPath, $this->getUnjailedPath($targetInternalPath));
504
	}
505
506 View Code Duplication
	public function getPropagator($storage = null) {
507
		if (isset($this->propagator)) {
508
			return $this->propagator;
509
		}
510
511
		if (!$storage) {
512
			$storage = $this;
513
		}
514
		$this->propagator = new JailPropagator($storage, \OC::$server->getDatabaseConnection());
515
		return $this->propagator;
516
	}
517
}
518