Completed
Push — master ( 4635cb...14f798 )
by
unknown
27:59 queued 14s
created
lib/private/Files/Cache/Wrapper/CacheJail.php 1 patch
Indentation   +304 added lines, -304 removed lines patch added patch discarded remove patch
@@ -22,308 +22,308 @@
 block discarded – undo
22 22
  */
23 23
 class CacheJail extends CacheWrapper {
24 24
 
25
-	protected string $unjailedRoot;
26
-
27
-	public function __construct(
28
-		?ICache $cache,
29
-		protected string $root,
30
-		?CacheDependencies $dependencies = null,
31
-	) {
32
-		parent::__construct($cache, $dependencies);
33
-
34
-		$this->unjailedRoot = $root;
35
-		$parent = $cache;
36
-		while ($parent instanceof CacheWrapper) {
37
-			if ($parent instanceof CacheJail) {
38
-				$this->unjailedRoot = $parent->getSourcePath($this->unjailedRoot);
39
-			}
40
-			$parent = $parent->getCache();
41
-		}
42
-	}
43
-
44
-	/**
45
-	 * @return string
46
-	 */
47
-	protected function getRoot() {
48
-		return $this->root;
49
-	}
50
-
51
-	/**
52
-	 * Get the root path with any nested jails resolved
53
-	 *
54
-	 * @return string
55
-	 */
56
-	public function getGetUnjailedRoot() {
57
-		return $this->unjailedRoot;
58
-	}
59
-
60
-	/**
61
-	 * @return string
62
-	 */
63
-	protected function getSourcePath(string $path) {
64
-		if ($path === '') {
65
-			return $this->getRoot();
66
-		} else {
67
-			return $this->getRoot() . '/' . ltrim($path, '/');
68
-		}
69
-	}
70
-
71
-	/**
72
-	 * @param string $path
73
-	 * @param null|string $root
74
-	 * @return null|string the jailed path or null if the path is outside the jail
75
-	 */
76
-	protected function getJailedPath(string $path, ?string $root = null) {
77
-		if ($root === null) {
78
-			$root = $this->getRoot();
79
-		}
80
-		if ($root === '') {
81
-			return $path;
82
-		}
83
-		$rootLength = strlen($root) + 1;
84
-		if ($path === $root) {
85
-			return '';
86
-		} elseif (substr($path, 0, $rootLength) === $root . '/') {
87
-			return substr($path, $rootLength);
88
-		} else {
89
-			return null;
90
-		}
91
-	}
92
-
93
-	protected function formatCacheEntry($entry) {
94
-		if (isset($entry['path'])) {
95
-			$entry['path'] = $this->getJailedPath($entry['path']);
96
-		}
97
-		return $entry;
98
-	}
99
-
100
-	/**
101
-	 * get the stored metadata of a file or folder
102
-	 *
103
-	 * @param string|int $file
104
-	 * @return ICacheEntry|false
105
-	 */
106
-	public function get($file) {
107
-		if (is_string($file) or $file == '') {
108
-			$file = $this->getSourcePath($file);
109
-		}
110
-		return parent::get($file);
111
-	}
112
-
113
-	/**
114
-	 * insert meta data for a new file or folder
115
-	 *
116
-	 * @param string $file
117
-	 * @param array $data
118
-	 *
119
-	 * @return int file id
120
-	 * @throws \RuntimeException
121
-	 */
122
-	public function insert($file, array $data) {
123
-		return $this->getCache()->insert($this->getSourcePath($file), $data);
124
-	}
125
-
126
-	/**
127
-	 * update the metadata in the cache
128
-	 *
129
-	 * @param int $id
130
-	 * @param array $data
131
-	 */
132
-	public function update($id, array $data) {
133
-		$this->getCache()->update($id, $data);
134
-	}
135
-
136
-	/**
137
-	 * get the file id for a file
138
-	 *
139
-	 * @param string $file
140
-	 * @return int
141
-	 */
142
-	public function getId($file) {
143
-		return $this->getCache()->getId($this->getSourcePath($file));
144
-	}
145
-
146
-	/**
147
-	 * get the id of the parent folder of a file
148
-	 *
149
-	 * @param string $file
150
-	 * @return int
151
-	 */
152
-	public function getParentId($file) {
153
-		return $this->getCache()->getParentId($this->getSourcePath($file));
154
-	}
155
-
156
-	/**
157
-	 * check if a file is available in the cache
158
-	 *
159
-	 * @param string $file
160
-	 * @return bool
161
-	 */
162
-	public function inCache($file) {
163
-		return $this->getCache()->inCache($this->getSourcePath($file));
164
-	}
165
-
166
-	/**
167
-	 * remove a file or folder from the cache
168
-	 *
169
-	 * @param string $file
170
-	 */
171
-	public function remove($file) {
172
-		$this->getCache()->remove($this->getSourcePath($file));
173
-	}
174
-
175
-	/**
176
-	 * Move a file or folder in the cache
177
-	 *
178
-	 * @param string $source
179
-	 * @param string $target
180
-	 */
181
-	public function move($source, $target) {
182
-		$this->getCache()->move($this->getSourcePath($source), $this->getSourcePath($target));
183
-	}
184
-
185
-	/**
186
-	 * Get the storage id and path needed for a move
187
-	 *
188
-	 * @param string $path
189
-	 * @return array [$storageId, $internalPath]
190
-	 */
191
-	protected function getMoveInfo($path) {
192
-		return [$this->getNumericStorageId(), $this->getSourcePath($path)];
193
-	}
194
-
195
-	/**
196
-	 * remove all entries for files that are stored on the storage from the cache
197
-	 */
198
-	public function clear() {
199
-		$this->getCache()->remove($this->getRoot());
200
-	}
201
-
202
-	/**
203
-	 * @param string $file
204
-	 *
205
-	 * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
206
-	 */
207
-	public function getStatus($file) {
208
-		return $this->getCache()->getStatus($this->getSourcePath($file));
209
-	}
210
-
211
-	/**
212
-	 * update the folder size and the size of all parent folders
213
-	 *
214
-	 * @param array|ICacheEntry|null $data (optional) meta data of the folder
215
-	 */
216
-	public function correctFolderSize(string $path, $data = null, bool $isBackgroundScan = false): void {
217
-		$cache = $this->getCache();
218
-		if ($cache instanceof Cache) {
219
-			$cache->correctFolderSize($this->getSourcePath($path), $data, $isBackgroundScan);
220
-		}
221
-	}
222
-
223
-	/**
224
-	 * get the size of a folder and set it in the cache
225
-	 *
226
-	 * @param string $path
227
-	 * @param array|null|ICacheEntry $entry (optional) meta data of the folder
228
-	 * @return int|float
229
-	 */
230
-	public function calculateFolderSize($path, $entry = null) {
231
-		$cache = $this->getCache();
232
-		if ($cache instanceof Cache) {
233
-			return $cache->calculateFolderSize($this->getSourcePath($path), $entry);
234
-		} else {
235
-			return 0;
236
-		}
237
-	}
238
-
239
-	/**
240
-	 * get all file ids on the files on the storage
241
-	 *
242
-	 * @return int[]
243
-	 */
244
-	public function getAll() {
245
-		// not supported
246
-		return [];
247
-	}
248
-
249
-	/**
250
-	 * find a folder in the cache which has not been fully scanned
251
-	 *
252
-	 * If multiply incomplete folders are in the cache, the one with the highest id will be returned,
253
-	 * use the one with the highest id gives the best result with the background scanner, since that is most
254
-	 * likely the folder where we stopped scanning previously
255
-	 *
256
-	 * @return string|false the path of the folder or false when no folder matched
257
-	 */
258
-	public function getIncomplete() {
259
-		// not supported
260
-		return false;
261
-	}
262
-
263
-	/**
264
-	 * get the path of a file on this storage by it's id
265
-	 *
266
-	 * @param int $id
267
-	 * @return string|null
268
-	 */
269
-	public function getPathById($id) {
270
-		$path = $this->getCache()->getPathById($id);
271
-		if ($path === null) {
272
-			return null;
273
-		}
274
-
275
-		return $this->getJailedPath($path);
276
-	}
277
-
278
-	/**
279
-	 * Move a file or folder in the cache
280
-	 *
281
-	 * Note that this should make sure the entries are removed from the source cache
282
-	 *
283
-	 * @param \OCP\Files\Cache\ICache $sourceCache
284
-	 * @param string $sourcePath
285
-	 * @param string $targetPath
286
-	 */
287
-	public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath, $targetPath) {
288
-		if ($sourceCache === $this) {
289
-			return $this->move($sourcePath, $targetPath);
290
-		}
291
-		return $this->getCache()->moveFromCache($sourceCache, $sourcePath, $this->getSourcePath($targetPath));
292
-	}
293
-
294
-	public function getQueryFilterForStorage(): ISearchOperator {
295
-		return $this->addJailFilterQuery($this->getCache()->getQueryFilterForStorage());
296
-	}
297
-
298
-	protected function addJailFilterQuery(ISearchOperator $filter): ISearchOperator {
299
-		if ($this->getGetUnjailedRoot() !== '' && $this->getGetUnjailedRoot() !== '/') {
300
-			return new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND,
301
-				[
302
-					$filter,
303
-					new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR,
304
-						[
305
-							new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()),
306
-							new SearchComparison(ISearchComparison::COMPARE_LIKE_CASE_SENSITIVE, 'path', SearchComparison::escapeLikeParameter($this->getGetUnjailedRoot()) . '/%'),
307
-						],
308
-					)
309
-				]
310
-			);
311
-		} else {
312
-			return $filter;
313
-		}
314
-	}
315
-
316
-	public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {
317
-		if ($this->getGetUnjailedRoot() === '' || str_starts_with($rawEntry->getPath(), $this->getGetUnjailedRoot())) {
318
-			$rawEntry = $this->getCache()->getCacheEntryFromSearchResult($rawEntry);
319
-			if ($rawEntry) {
320
-				$jailedPath = $this->getJailedPath($rawEntry->getPath());
321
-				if ($jailedPath !== null) {
322
-					return $this->formatCacheEntry(clone $rawEntry) ?: null;
323
-				}
324
-			}
325
-		}
326
-
327
-		return null;
328
-	}
25
+    protected string $unjailedRoot;
26
+
27
+    public function __construct(
28
+        ?ICache $cache,
29
+        protected string $root,
30
+        ?CacheDependencies $dependencies = null,
31
+    ) {
32
+        parent::__construct($cache, $dependencies);
33
+
34
+        $this->unjailedRoot = $root;
35
+        $parent = $cache;
36
+        while ($parent instanceof CacheWrapper) {
37
+            if ($parent instanceof CacheJail) {
38
+                $this->unjailedRoot = $parent->getSourcePath($this->unjailedRoot);
39
+            }
40
+            $parent = $parent->getCache();
41
+        }
42
+    }
43
+
44
+    /**
45
+     * @return string
46
+     */
47
+    protected function getRoot() {
48
+        return $this->root;
49
+    }
50
+
51
+    /**
52
+     * Get the root path with any nested jails resolved
53
+     *
54
+     * @return string
55
+     */
56
+    public function getGetUnjailedRoot() {
57
+        return $this->unjailedRoot;
58
+    }
59
+
60
+    /**
61
+     * @return string
62
+     */
63
+    protected function getSourcePath(string $path) {
64
+        if ($path === '') {
65
+            return $this->getRoot();
66
+        } else {
67
+            return $this->getRoot() . '/' . ltrim($path, '/');
68
+        }
69
+    }
70
+
71
+    /**
72
+     * @param string $path
73
+     * @param null|string $root
74
+     * @return null|string the jailed path or null if the path is outside the jail
75
+     */
76
+    protected function getJailedPath(string $path, ?string $root = null) {
77
+        if ($root === null) {
78
+            $root = $this->getRoot();
79
+        }
80
+        if ($root === '') {
81
+            return $path;
82
+        }
83
+        $rootLength = strlen($root) + 1;
84
+        if ($path === $root) {
85
+            return '';
86
+        } elseif (substr($path, 0, $rootLength) === $root . '/') {
87
+            return substr($path, $rootLength);
88
+        } else {
89
+            return null;
90
+        }
91
+    }
92
+
93
+    protected function formatCacheEntry($entry) {
94
+        if (isset($entry['path'])) {
95
+            $entry['path'] = $this->getJailedPath($entry['path']);
96
+        }
97
+        return $entry;
98
+    }
99
+
100
+    /**
101
+     * get the stored metadata of a file or folder
102
+     *
103
+     * @param string|int $file
104
+     * @return ICacheEntry|false
105
+     */
106
+    public function get($file) {
107
+        if (is_string($file) or $file == '') {
108
+            $file = $this->getSourcePath($file);
109
+        }
110
+        return parent::get($file);
111
+    }
112
+
113
+    /**
114
+     * insert meta data for a new file or folder
115
+     *
116
+     * @param string $file
117
+     * @param array $data
118
+     *
119
+     * @return int file id
120
+     * @throws \RuntimeException
121
+     */
122
+    public function insert($file, array $data) {
123
+        return $this->getCache()->insert($this->getSourcePath($file), $data);
124
+    }
125
+
126
+    /**
127
+     * update the metadata in the cache
128
+     *
129
+     * @param int $id
130
+     * @param array $data
131
+     */
132
+    public function update($id, array $data) {
133
+        $this->getCache()->update($id, $data);
134
+    }
135
+
136
+    /**
137
+     * get the file id for a file
138
+     *
139
+     * @param string $file
140
+     * @return int
141
+     */
142
+    public function getId($file) {
143
+        return $this->getCache()->getId($this->getSourcePath($file));
144
+    }
145
+
146
+    /**
147
+     * get the id of the parent folder of a file
148
+     *
149
+     * @param string $file
150
+     * @return int
151
+     */
152
+    public function getParentId($file) {
153
+        return $this->getCache()->getParentId($this->getSourcePath($file));
154
+    }
155
+
156
+    /**
157
+     * check if a file is available in the cache
158
+     *
159
+     * @param string $file
160
+     * @return bool
161
+     */
162
+    public function inCache($file) {
163
+        return $this->getCache()->inCache($this->getSourcePath($file));
164
+    }
165
+
166
+    /**
167
+     * remove a file or folder from the cache
168
+     *
169
+     * @param string $file
170
+     */
171
+    public function remove($file) {
172
+        $this->getCache()->remove($this->getSourcePath($file));
173
+    }
174
+
175
+    /**
176
+     * Move a file or folder in the cache
177
+     *
178
+     * @param string $source
179
+     * @param string $target
180
+     */
181
+    public function move($source, $target) {
182
+        $this->getCache()->move($this->getSourcePath($source), $this->getSourcePath($target));
183
+    }
184
+
185
+    /**
186
+     * Get the storage id and path needed for a move
187
+     *
188
+     * @param string $path
189
+     * @return array [$storageId, $internalPath]
190
+     */
191
+    protected function getMoveInfo($path) {
192
+        return [$this->getNumericStorageId(), $this->getSourcePath($path)];
193
+    }
194
+
195
+    /**
196
+     * remove all entries for files that are stored on the storage from the cache
197
+     */
198
+    public function clear() {
199
+        $this->getCache()->remove($this->getRoot());
200
+    }
201
+
202
+    /**
203
+     * @param string $file
204
+     *
205
+     * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
206
+     */
207
+    public function getStatus($file) {
208
+        return $this->getCache()->getStatus($this->getSourcePath($file));
209
+    }
210
+
211
+    /**
212
+     * update the folder size and the size of all parent folders
213
+     *
214
+     * @param array|ICacheEntry|null $data (optional) meta data of the folder
215
+     */
216
+    public function correctFolderSize(string $path, $data = null, bool $isBackgroundScan = false): void {
217
+        $cache = $this->getCache();
218
+        if ($cache instanceof Cache) {
219
+            $cache->correctFolderSize($this->getSourcePath($path), $data, $isBackgroundScan);
220
+        }
221
+    }
222
+
223
+    /**
224
+     * get the size of a folder and set it in the cache
225
+     *
226
+     * @param string $path
227
+     * @param array|null|ICacheEntry $entry (optional) meta data of the folder
228
+     * @return int|float
229
+     */
230
+    public function calculateFolderSize($path, $entry = null) {
231
+        $cache = $this->getCache();
232
+        if ($cache instanceof Cache) {
233
+            return $cache->calculateFolderSize($this->getSourcePath($path), $entry);
234
+        } else {
235
+            return 0;
236
+        }
237
+    }
238
+
239
+    /**
240
+     * get all file ids on the files on the storage
241
+     *
242
+     * @return int[]
243
+     */
244
+    public function getAll() {
245
+        // not supported
246
+        return [];
247
+    }
248
+
249
+    /**
250
+     * find a folder in the cache which has not been fully scanned
251
+     *
252
+     * If multiply incomplete folders are in the cache, the one with the highest id will be returned,
253
+     * use the one with the highest id gives the best result with the background scanner, since that is most
254
+     * likely the folder where we stopped scanning previously
255
+     *
256
+     * @return string|false the path of the folder or false when no folder matched
257
+     */
258
+    public function getIncomplete() {
259
+        // not supported
260
+        return false;
261
+    }
262
+
263
+    /**
264
+     * get the path of a file on this storage by it's id
265
+     *
266
+     * @param int $id
267
+     * @return string|null
268
+     */
269
+    public function getPathById($id) {
270
+        $path = $this->getCache()->getPathById($id);
271
+        if ($path === null) {
272
+            return null;
273
+        }
274
+
275
+        return $this->getJailedPath($path);
276
+    }
277
+
278
+    /**
279
+     * Move a file or folder in the cache
280
+     *
281
+     * Note that this should make sure the entries are removed from the source cache
282
+     *
283
+     * @param \OCP\Files\Cache\ICache $sourceCache
284
+     * @param string $sourcePath
285
+     * @param string $targetPath
286
+     */
287
+    public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath, $targetPath) {
288
+        if ($sourceCache === $this) {
289
+            return $this->move($sourcePath, $targetPath);
290
+        }
291
+        return $this->getCache()->moveFromCache($sourceCache, $sourcePath, $this->getSourcePath($targetPath));
292
+    }
293
+
294
+    public function getQueryFilterForStorage(): ISearchOperator {
295
+        return $this->addJailFilterQuery($this->getCache()->getQueryFilterForStorage());
296
+    }
297
+
298
+    protected function addJailFilterQuery(ISearchOperator $filter): ISearchOperator {
299
+        if ($this->getGetUnjailedRoot() !== '' && $this->getGetUnjailedRoot() !== '/') {
300
+            return new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND,
301
+                [
302
+                    $filter,
303
+                    new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR,
304
+                        [
305
+                            new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()),
306
+                            new SearchComparison(ISearchComparison::COMPARE_LIKE_CASE_SENSITIVE, 'path', SearchComparison::escapeLikeParameter($this->getGetUnjailedRoot()) . '/%'),
307
+                        ],
308
+                    )
309
+                ]
310
+            );
311
+        } else {
312
+            return $filter;
313
+        }
314
+    }
315
+
316
+    public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {
317
+        if ($this->getGetUnjailedRoot() === '' || str_starts_with($rawEntry->getPath(), $this->getGetUnjailedRoot())) {
318
+            $rawEntry = $this->getCache()->getCacheEntryFromSearchResult($rawEntry);
319
+            if ($rawEntry) {
320
+                $jailedPath = $this->getJailedPath($rawEntry->getPath());
321
+                if ($jailedPath !== null) {
322
+                    return $this->formatCacheEntry(clone $rawEntry) ?: null;
323
+                }
324
+            }
325
+        }
326
+
327
+        return null;
328
+    }
329 329
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Cache.php 1 patch
Indentation   +168 added lines, -168 removed lines patch added patch discarded remove patch
@@ -27,172 +27,172 @@
 block discarded – undo
27 27
  * don't use this class directly if you need to get metadata, use \OC\Files\Filesystem::getFileInfo instead
28 28
  */
29 29
 class Cache extends CacheJail {
30
-	private bool $rootUnchanged = true;
31
-	private ?string $ownerDisplayName = null;
32
-	private $numericId;
33
-	private DisplayNameCache $displayNameCache;
34
-
35
-	/**
36
-	 * @param SharedStorage $storage
37
-	 */
38
-	public function __construct(
39
-		private $storage,
40
-		private ICacheEntry $sourceRootInfo,
41
-		CacheDependencies $dependencies,
42
-		private IShare $share,
43
-	) {
44
-		$this->numericId = $this->sourceRootInfo->getStorageId();
45
-		$this->displayNameCache = $dependencies->getDisplayNameCache();
46
-
47
-		parent::__construct(
48
-			null,
49
-			'',
50
-			$dependencies,
51
-		);
52
-	}
53
-
54
-	protected function getRoot() {
55
-		if ($this->root === '') {
56
-			$absoluteRoot = $this->sourceRootInfo->getPath();
57
-
58
-			// the sourceRootInfo path is the absolute path of the folder in the "real" storage
59
-			// in the case where a folder is shared from a Jail we need to ensure that the share Jail
60
-			// has its root set relative to the source Jail
61
-			$currentStorage = $this->storage->getSourceStorage();
62
-			if ($currentStorage->instanceOfStorage(Jail::class)) {
63
-				/** @var Jail $currentStorage */
64
-				$absoluteRoot = $currentStorage->getJailedPath($absoluteRoot);
65
-			}
66
-			$this->root = $absoluteRoot ?? '';
67
-		}
68
-		return $this->root;
69
-	}
70
-
71
-	public function getGetUnjailedRoot(): string {
72
-		return $this->sourceRootInfo->getPath();
73
-	}
74
-
75
-	public function getCache(): ICache {
76
-		if (is_null($this->cache)) {
77
-			$sourceStorage = $this->storage->getSourceStorage();
78
-			if ($sourceStorage) {
79
-				$this->cache = $sourceStorage->getCache();
80
-			} else {
81
-				// don't set $this->cache here since sourceStorage will be set later
82
-				return new FailedCache();
83
-			}
84
-		}
85
-		return $this->cache;
86
-	}
87
-
88
-	public function getNumericStorageId() {
89
-		if (isset($this->numericId)) {
90
-			return $this->numericId;
91
-		} else {
92
-			return -1;
93
-		}
94
-	}
95
-
96
-	public function get($file) {
97
-		if ($this->rootUnchanged && ($file === '' || $file === $this->sourceRootInfo->getId())) {
98
-			return $this->formatCacheEntry(clone $this->sourceRootInfo, '');
99
-		}
100
-		return parent::get($file);
101
-	}
102
-
103
-	public function update($id, array $data) {
104
-		$this->rootUnchanged = false;
105
-		parent::update($id, $data);
106
-	}
107
-
108
-	public function insert($file, array $data) {
109
-		$this->rootUnchanged = false;
110
-		return parent::insert($file, $data);
111
-	}
112
-
113
-	public function remove($file) {
114
-		$this->rootUnchanged = false;
115
-		parent::remove($file);
116
-	}
117
-
118
-	public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
119
-		$this->rootUnchanged = false;
120
-		return parent::moveFromCache($sourceCache, $sourcePath, $targetPath);
121
-	}
122
-
123
-	protected function formatCacheEntry($entry, $path = null) {
124
-		if (is_null($path)) {
125
-			$path = $entry['path'] ?? '';
126
-			$entry['path'] = $this->getJailedPath($path);
127
-		} else {
128
-			$entry['path'] = $path;
129
-		}
130
-
131
-		try {
132
-			if (isset($entry['permissions'])) {
133
-				$entry['permissions'] &= $this->share->getPermissions();
134
-			} else {
135
-				$entry['permissions'] = $this->storage->getPermissions($entry['path']);
136
-			}
137
-
138
-			if ($this->share->getNodeId() === $entry['fileid']) {
139
-				$entry['name'] = basename($this->share->getTarget());
140
-			}
141
-		} catch (StorageNotAvailableException $e) {
142
-			// thrown by FailedStorage e.g. when the sharer does not exist anymore
143
-			// (IDE may say the exception is never thrown – false negative)
144
-			$sharePermissions = 0;
145
-		}
146
-		$entry['uid_owner'] = $this->share->getShareOwner();
147
-		$entry['displayname_owner'] = $this->getOwnerDisplayName();
148
-		if ($path === '') {
149
-			$entry['is_share_mount_point'] = true;
150
-		}
151
-		return $entry;
152
-	}
153
-
154
-	private function getOwnerDisplayName() {
155
-		if (!$this->ownerDisplayName) {
156
-			$uid = $this->share->getShareOwner();
157
-			$this->ownerDisplayName = $this->displayNameCache->getDisplayName($uid) ?? $uid;
158
-		}
159
-		return $this->ownerDisplayName;
160
-	}
161
-
162
-	/**
163
-	 * remove all entries for files that are stored on the storage from the cache
164
-	 */
165
-	public function clear() {
166
-		// Not a valid action for Shared Cache
167
-	}
168
-
169
-	public function getQueryFilterForStorage(): ISearchOperator {
170
-		$storageFilter = \OC\Files\Cache\Cache::getQueryFilterForStorage();
171
-
172
-		// Do the normal jail behavior for non files
173
-		if ($this->storage->getItemType() !== 'file') {
174
-			return $this->addJailFilterQuery($storageFilter);
175
-		}
176
-
177
-		// for single file shares we don't need to do the LIKE
178
-		return new SearchBinaryOperator(
179
-			ISearchBinaryOperator::OPERATOR_AND,
180
-			[
181
-				$storageFilter,
182
-				new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()),
183
-			]
184
-		);
185
-	}
186
-
187
-	public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {
188
-		if ($rawEntry->getStorageId() === $this->getNumericStorageId()) {
189
-			return parent::getCacheEntryFromSearchResult($rawEntry);
190
-		} else {
191
-			return null;
192
-		}
193
-	}
194
-
195
-	public function markRootChanged(): void {
196
-		$this->rootUnchanged = false;
197
-	}
30
+    private bool $rootUnchanged = true;
31
+    private ?string $ownerDisplayName = null;
32
+    private $numericId;
33
+    private DisplayNameCache $displayNameCache;
34
+
35
+    /**
36
+     * @param SharedStorage $storage
37
+     */
38
+    public function __construct(
39
+        private $storage,
40
+        private ICacheEntry $sourceRootInfo,
41
+        CacheDependencies $dependencies,
42
+        private IShare $share,
43
+    ) {
44
+        $this->numericId = $this->sourceRootInfo->getStorageId();
45
+        $this->displayNameCache = $dependencies->getDisplayNameCache();
46
+
47
+        parent::__construct(
48
+            null,
49
+            '',
50
+            $dependencies,
51
+        );
52
+    }
53
+
54
+    protected function getRoot() {
55
+        if ($this->root === '') {
56
+            $absoluteRoot = $this->sourceRootInfo->getPath();
57
+
58
+            // the sourceRootInfo path is the absolute path of the folder in the "real" storage
59
+            // in the case where a folder is shared from a Jail we need to ensure that the share Jail
60
+            // has its root set relative to the source Jail
61
+            $currentStorage = $this->storage->getSourceStorage();
62
+            if ($currentStorage->instanceOfStorage(Jail::class)) {
63
+                /** @var Jail $currentStorage */
64
+                $absoluteRoot = $currentStorage->getJailedPath($absoluteRoot);
65
+            }
66
+            $this->root = $absoluteRoot ?? '';
67
+        }
68
+        return $this->root;
69
+    }
70
+
71
+    public function getGetUnjailedRoot(): string {
72
+        return $this->sourceRootInfo->getPath();
73
+    }
74
+
75
+    public function getCache(): ICache {
76
+        if (is_null($this->cache)) {
77
+            $sourceStorage = $this->storage->getSourceStorage();
78
+            if ($sourceStorage) {
79
+                $this->cache = $sourceStorage->getCache();
80
+            } else {
81
+                // don't set $this->cache here since sourceStorage will be set later
82
+                return new FailedCache();
83
+            }
84
+        }
85
+        return $this->cache;
86
+    }
87
+
88
+    public function getNumericStorageId() {
89
+        if (isset($this->numericId)) {
90
+            return $this->numericId;
91
+        } else {
92
+            return -1;
93
+        }
94
+    }
95
+
96
+    public function get($file) {
97
+        if ($this->rootUnchanged && ($file === '' || $file === $this->sourceRootInfo->getId())) {
98
+            return $this->formatCacheEntry(clone $this->sourceRootInfo, '');
99
+        }
100
+        return parent::get($file);
101
+    }
102
+
103
+    public function update($id, array $data) {
104
+        $this->rootUnchanged = false;
105
+        parent::update($id, $data);
106
+    }
107
+
108
+    public function insert($file, array $data) {
109
+        $this->rootUnchanged = false;
110
+        return parent::insert($file, $data);
111
+    }
112
+
113
+    public function remove($file) {
114
+        $this->rootUnchanged = false;
115
+        parent::remove($file);
116
+    }
117
+
118
+    public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
119
+        $this->rootUnchanged = false;
120
+        return parent::moveFromCache($sourceCache, $sourcePath, $targetPath);
121
+    }
122
+
123
+    protected function formatCacheEntry($entry, $path = null) {
124
+        if (is_null($path)) {
125
+            $path = $entry['path'] ?? '';
126
+            $entry['path'] = $this->getJailedPath($path);
127
+        } else {
128
+            $entry['path'] = $path;
129
+        }
130
+
131
+        try {
132
+            if (isset($entry['permissions'])) {
133
+                $entry['permissions'] &= $this->share->getPermissions();
134
+            } else {
135
+                $entry['permissions'] = $this->storage->getPermissions($entry['path']);
136
+            }
137
+
138
+            if ($this->share->getNodeId() === $entry['fileid']) {
139
+                $entry['name'] = basename($this->share->getTarget());
140
+            }
141
+        } catch (StorageNotAvailableException $e) {
142
+            // thrown by FailedStorage e.g. when the sharer does not exist anymore
143
+            // (IDE may say the exception is never thrown – false negative)
144
+            $sharePermissions = 0;
145
+        }
146
+        $entry['uid_owner'] = $this->share->getShareOwner();
147
+        $entry['displayname_owner'] = $this->getOwnerDisplayName();
148
+        if ($path === '') {
149
+            $entry['is_share_mount_point'] = true;
150
+        }
151
+        return $entry;
152
+    }
153
+
154
+    private function getOwnerDisplayName() {
155
+        if (!$this->ownerDisplayName) {
156
+            $uid = $this->share->getShareOwner();
157
+            $this->ownerDisplayName = $this->displayNameCache->getDisplayName($uid) ?? $uid;
158
+        }
159
+        return $this->ownerDisplayName;
160
+    }
161
+
162
+    /**
163
+     * remove all entries for files that are stored on the storage from the cache
164
+     */
165
+    public function clear() {
166
+        // Not a valid action for Shared Cache
167
+    }
168
+
169
+    public function getQueryFilterForStorage(): ISearchOperator {
170
+        $storageFilter = \OC\Files\Cache\Cache::getQueryFilterForStorage();
171
+
172
+        // Do the normal jail behavior for non files
173
+        if ($this->storage->getItemType() !== 'file') {
174
+            return $this->addJailFilterQuery($storageFilter);
175
+        }
176
+
177
+        // for single file shares we don't need to do the LIKE
178
+        return new SearchBinaryOperator(
179
+            ISearchBinaryOperator::OPERATOR_AND,
180
+            [
181
+                $storageFilter,
182
+                new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()),
183
+            ]
184
+        );
185
+    }
186
+
187
+    public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {
188
+        if ($rawEntry->getStorageId() === $this->getNumericStorageId()) {
189
+            return parent::getCacheEntryFromSearchResult($rawEntry);
190
+        } else {
191
+            return null;
192
+        }
193
+    }
194
+
195
+    public function markRootChanged(): void {
196
+        $this->rootUnchanged = false;
197
+    }
198 198
 }
Please login to merge, or discard this patch.
tests/lib/Files/Cache/Wrapper/CacheJailTest.php 1 patch
Indentation   +237 added lines, -237 removed lines patch added patch discarded remove patch
@@ -26,241 +26,241 @@
 block discarded – undo
26 26
  * @package Test\Files\Cache\Wrapper
27 27
  */
28 28
 class CacheJailTest extends CacheTest {
29
-	/**
30
-	 * @var \OC\Files\Cache\Cache $sourceCache
31
-	 */
32
-	protected $sourceCache;
33
-
34
-	protected function setUp(): void {
35
-		parent::setUp();
36
-		$this->storage->mkdir('jail');
37
-		$this->sourceCache = $this->cache;
38
-		$this->cache = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, 'jail');
39
-		$this->cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
40
-	}
41
-
42
-	public function testSearchOutsideJail(): void {
43
-		$this->storage->getScanner()->scan('');
44
-		$file1 = 'jail/foobar';
45
-		$file2 = 'folder/foobar';
46
-		$data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
47
-
48
-		$this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
49
-		$this->sourceCache->put($file1, $data1);
50
-		$this->sourceCache->put($file2, $data1);
51
-
52
-		$this->assertCount(2, $this->sourceCache->search('%foobar'));
53
-
54
-		$result = $this->cache->search('%foobar%');
55
-		$this->assertCount(1, $result);
56
-		$this->assertEquals('foobar', $result[0]['path']);
57
-
58
-		$result = $this->cache->search('%foo%');
59
-		$this->assertCount(1, $result);
60
-		usort($result, function ($a, $b) {
61
-			return $a['path'] <=> $b['path'];
62
-		});
63
-		$this->assertEquals('foobar', $result[0]['path']);
64
-	}
65
-
66
-	public function testSearchMimeOutsideJail(): void {
67
-		$this->storage->getScanner()->scan('');
68
-		$file1 = 'jail/foobar';
69
-		$file2 = 'folder/foobar';
70
-		$data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
71
-
72
-		$this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
73
-		$this->sourceCache->put($file1, $data1);
74
-		$this->sourceCache->put($file2, $data1);
75
-
76
-		$this->assertCount(2, $this->sourceCache->searchByMime('foo/folder'));
77
-
78
-		$result = $this->cache->search('%foobar%');
79
-		$this->assertCount(1, $result);
80
-		$this->assertEquals('foobar', $result[0]['path']);
81
-	}
82
-
83
-	public function testSearchQueryOutsideJail(): void {
84
-		$this->storage->getScanner()->scan('');
85
-		$file1 = 'jail/foobar';
86
-		$file2 = 'folder/foobar';
87
-		$data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
88
-
89
-
90
-		$this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
91
-		$this->sourceCache->put($file1, $data1);
92
-		$this->sourceCache->put($file2, $data1);
93
-
94
-		$user = new User('foo', null, $this->createMock(IEventDispatcher::class));
95
-		$query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foobar'), 10, 0, [], $user);
96
-		$result = $this->cache->searchQuery($query);
97
-
98
-		$this->assertCount(1, $result);
99
-		$this->assertEquals('foobar', $result[0]['path']);
100
-
101
-		$query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'jail'), 10, 0, [], $user);
102
-		$result = $this->cache->searchQuery($query);
103
-		$this->assertCount(1, $result);
104
-		$this->assertEquals('', $result[0]['path']);
105
-	}
106
-
107
-	public function testClearKeepEntriesOutsideJail(): void {
108
-		$file1 = 'jail/foobar';
109
-		$file2 = 'jail/foobar/asd';
110
-		$file3 = 'folder/foobar';
111
-		$data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
112
-
113
-		$this->sourceCache->put('folder', $data1);
114
-		$this->sourceCache->put($file1, $data1);
115
-		$this->sourceCache->put($file2, $data1);
116
-		$this->sourceCache->put($file3, $data1);
117
-
118
-		$this->cache->clear();
119
-
120
-		$this->assertFalse($this->cache->inCache('foobar'));
121
-		$this->assertTrue($this->sourceCache->inCache('folder/foobar'));
122
-	}
123
-
124
-	public function testGetById(): void {
125
-		$data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
126
-		$id = $this->sourceCache->put('jail/bar', $data1);
127
-
128
-		// path from jailed foo of foo/bar is bar
129
-		$path = $this->cache->getPathById($id);
130
-		$this->assertEquals('bar', $path);
131
-
132
-		// path from jailed '' of foo/bar is foo/bar
133
-		$this->cache = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, '');
134
-		$path = $this->cache->getPathById($id);
135
-		$this->assertEquals('jail/bar', $path);
136
-	}
137
-
138
-	public function testGetIncomplete(): void {
139
-		//not supported
140
-		$this->addToAssertionCount(1);
141
-	}
142
-
143
-	public function testMoveFromJail(): void {
144
-		$folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
145
-
146
-		$this->sourceCache->put('source', $folderData);
147
-		$this->sourceCache->put('source/foo', $folderData);
148
-		$this->sourceCache->put('source/foo/bar', $folderData);
149
-		$this->sourceCache->put('target', $folderData);
150
-
151
-		$jail = new CacheJail($this->sourceCache, 'source');
152
-
153
-		$this->sourceCache->moveFromCache($jail, 'foo', 'target/foo');
154
-
155
-		$this->assertTrue($this->sourceCache->inCache('target/foo'));
156
-		$this->assertTrue($this->sourceCache->inCache('target/foo/bar'));
157
-	}
158
-
159
-	public function testMoveToJail(): void {
160
-		$folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
161
-
162
-		$this->sourceCache->put('source', $folderData);
163
-		$this->sourceCache->put('source/foo', $folderData);
164
-		$this->sourceCache->put('source/foo/bar', $folderData);
165
-		$this->sourceCache->put('target', $folderData);
166
-
167
-		$jail = new CacheJail($this->sourceCache, 'target');
168
-
169
-		$jail->moveFromCache($this->sourceCache, 'source/foo', 'foo');
170
-
171
-		$this->assertTrue($this->sourceCache->inCache('target/foo'));
172
-		$this->assertTrue($this->sourceCache->inCache('target/foo/bar'));
173
-	}
174
-
175
-	public function testMoveBetweenJail(): void {
176
-		$folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
177
-
178
-		$this->sourceCache->put('source', $folderData);
179
-		$this->sourceCache->put('source/foo', $folderData);
180
-		$this->sourceCache->put('source/foo/bar', $folderData);
181
-		$this->sourceCache->put('target', $folderData);
182
-
183
-		$jail = new CacheJail($this->sourceCache, 'target');
184
-		$sourceJail = new CacheJail($this->sourceCache, 'source');
185
-
186
-		$jail->moveFromCache($sourceJail, 'foo', 'foo');
187
-
188
-		$this->assertTrue($this->sourceCache->inCache('target/foo'));
189
-		$this->assertTrue($this->sourceCache->inCache('target/foo/bar'));
190
-	}
191
-
192
-	public function testSearchNested(): void {
193
-		$this->storage->getScanner()->scan('');
194
-		$file1 = 'jail';
195
-		$file2 = 'jail/bar';
196
-		$file3 = 'jail/bar/asd';
197
-		$data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
198
-
199
-		$this->sourceCache->put($file1, $data1);
200
-		$this->sourceCache->put($file2, $data1);
201
-		$this->sourceCache->put($file3, $data1);
202
-
203
-		$nested = new \OC\Files\Cache\Wrapper\CacheJail($this->cache, 'bar');
204
-
205
-		$result = $nested->search('%asd%');
206
-		$this->assertCount(1, $result);
207
-		$this->assertEquals('asd', $result[0]['path']);
208
-	}
209
-
210
-	public function testRootJail(): void {
211
-		$this->storage->getScanner()->scan('');
212
-		$file1 = 'jail';
213
-		$file2 = 'jail/bar';
214
-		$file3 = 'jail/bar/asd';
215
-		$data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
216
-
217
-		$this->sourceCache->put($file1, $data1);
218
-		$this->sourceCache->put($file2, $data1);
219
-		$this->sourceCache->put($file3, $data1);
220
-
221
-		$nested = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, '');
222
-
223
-		$result = $nested->search('%asd%');
224
-		$this->assertCount(1, $result);
225
-		$this->assertEquals('jail/bar/asd', $result[0]['path']);
226
-	}
227
-
228
-	public function testWatcher(): void {
229
-		$storage = new Jail([
230
-			'storage' => $this->storage,
231
-			'root' => 'jail'
232
-		]);
233
-		$storage->getScanner()->scan('');
234
-		$storage->file_put_contents('bar', 'asd');
235
-
236
-		$this->assertFalse($this->cache->inCache('bar'));
237
-		$storage->getWatcher()->update('bar', ['mimetype' => 'text/plain']);
238
-		$this->assertTrue($this->cache->inCache('bar'));
239
-	}
240
-
241
-	public function testWatcherAfterInnerWatcher(): void {
242
-		$storage = new Jail([
243
-			'storage' => $this->storage,
244
-			'root' => 'jail'
245
-		]);
246
-		$storage->getScanner()->scan('');
247
-		$storage->file_put_contents('bar', 'asd');
248
-
249
-		// let the underlying storage create it's watcher first
250
-		$this->storage->getWatcher();
251
-
252
-		$this->assertFalse($this->cache->inCache('bar'));
253
-		$storage->getWatcher()->update('bar', ['mimetype' => 'text/plain']);
254
-		$this->assertTrue($this->cache->inCache('bar'));
255
-	}
256
-
257
-	public function testUnJailedRoot(): void {
258
-		$jail1 = new CacheJail($this->sourceCache, 'foo');
259
-		$jail2 = new CacheJail($jail1, 'bar');
260
-		$this->assertEquals('foo/bar', $jail2->getGetUnjailedRoot());
261
-
262
-		$middleWrapper = new CacheWrapper($jail1);
263
-		$jail3 = new CacheJail($middleWrapper, 'bar');
264
-		$this->assertEquals('foo/bar', $jail3->getGetUnjailedRoot());
265
-	}
29
+    /**
30
+     * @var \OC\Files\Cache\Cache $sourceCache
31
+     */
32
+    protected $sourceCache;
33
+
34
+    protected function setUp(): void {
35
+        parent::setUp();
36
+        $this->storage->mkdir('jail');
37
+        $this->sourceCache = $this->cache;
38
+        $this->cache = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, 'jail');
39
+        $this->cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
40
+    }
41
+
42
+    public function testSearchOutsideJail(): void {
43
+        $this->storage->getScanner()->scan('');
44
+        $file1 = 'jail/foobar';
45
+        $file2 = 'folder/foobar';
46
+        $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
47
+
48
+        $this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
49
+        $this->sourceCache->put($file1, $data1);
50
+        $this->sourceCache->put($file2, $data1);
51
+
52
+        $this->assertCount(2, $this->sourceCache->search('%foobar'));
53
+
54
+        $result = $this->cache->search('%foobar%');
55
+        $this->assertCount(1, $result);
56
+        $this->assertEquals('foobar', $result[0]['path']);
57
+
58
+        $result = $this->cache->search('%foo%');
59
+        $this->assertCount(1, $result);
60
+        usort($result, function ($a, $b) {
61
+            return $a['path'] <=> $b['path'];
62
+        });
63
+        $this->assertEquals('foobar', $result[0]['path']);
64
+    }
65
+
66
+    public function testSearchMimeOutsideJail(): void {
67
+        $this->storage->getScanner()->scan('');
68
+        $file1 = 'jail/foobar';
69
+        $file2 = 'folder/foobar';
70
+        $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
71
+
72
+        $this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
73
+        $this->sourceCache->put($file1, $data1);
74
+        $this->sourceCache->put($file2, $data1);
75
+
76
+        $this->assertCount(2, $this->sourceCache->searchByMime('foo/folder'));
77
+
78
+        $result = $this->cache->search('%foobar%');
79
+        $this->assertCount(1, $result);
80
+        $this->assertEquals('foobar', $result[0]['path']);
81
+    }
82
+
83
+    public function testSearchQueryOutsideJail(): void {
84
+        $this->storage->getScanner()->scan('');
85
+        $file1 = 'jail/foobar';
86
+        $file2 = 'folder/foobar';
87
+        $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
88
+
89
+
90
+        $this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]);
91
+        $this->sourceCache->put($file1, $data1);
92
+        $this->sourceCache->put($file2, $data1);
93
+
94
+        $user = new User('foo', null, $this->createMock(IEventDispatcher::class));
95
+        $query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foobar'), 10, 0, [], $user);
96
+        $result = $this->cache->searchQuery($query);
97
+
98
+        $this->assertCount(1, $result);
99
+        $this->assertEquals('foobar', $result[0]['path']);
100
+
101
+        $query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'jail'), 10, 0, [], $user);
102
+        $result = $this->cache->searchQuery($query);
103
+        $this->assertCount(1, $result);
104
+        $this->assertEquals('', $result[0]['path']);
105
+    }
106
+
107
+    public function testClearKeepEntriesOutsideJail(): void {
108
+        $file1 = 'jail/foobar';
109
+        $file2 = 'jail/foobar/asd';
110
+        $file3 = 'folder/foobar';
111
+        $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
112
+
113
+        $this->sourceCache->put('folder', $data1);
114
+        $this->sourceCache->put($file1, $data1);
115
+        $this->sourceCache->put($file2, $data1);
116
+        $this->sourceCache->put($file3, $data1);
117
+
118
+        $this->cache->clear();
119
+
120
+        $this->assertFalse($this->cache->inCache('foobar'));
121
+        $this->assertTrue($this->sourceCache->inCache('folder/foobar'));
122
+    }
123
+
124
+    public function testGetById(): void {
125
+        $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
126
+        $id = $this->sourceCache->put('jail/bar', $data1);
127
+
128
+        // path from jailed foo of foo/bar is bar
129
+        $path = $this->cache->getPathById($id);
130
+        $this->assertEquals('bar', $path);
131
+
132
+        // path from jailed '' of foo/bar is foo/bar
133
+        $this->cache = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, '');
134
+        $path = $this->cache->getPathById($id);
135
+        $this->assertEquals('jail/bar', $path);
136
+    }
137
+
138
+    public function testGetIncomplete(): void {
139
+        //not supported
140
+        $this->addToAssertionCount(1);
141
+    }
142
+
143
+    public function testMoveFromJail(): void {
144
+        $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
145
+
146
+        $this->sourceCache->put('source', $folderData);
147
+        $this->sourceCache->put('source/foo', $folderData);
148
+        $this->sourceCache->put('source/foo/bar', $folderData);
149
+        $this->sourceCache->put('target', $folderData);
150
+
151
+        $jail = new CacheJail($this->sourceCache, 'source');
152
+
153
+        $this->sourceCache->moveFromCache($jail, 'foo', 'target/foo');
154
+
155
+        $this->assertTrue($this->sourceCache->inCache('target/foo'));
156
+        $this->assertTrue($this->sourceCache->inCache('target/foo/bar'));
157
+    }
158
+
159
+    public function testMoveToJail(): void {
160
+        $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
161
+
162
+        $this->sourceCache->put('source', $folderData);
163
+        $this->sourceCache->put('source/foo', $folderData);
164
+        $this->sourceCache->put('source/foo/bar', $folderData);
165
+        $this->sourceCache->put('target', $folderData);
166
+
167
+        $jail = new CacheJail($this->sourceCache, 'target');
168
+
169
+        $jail->moveFromCache($this->sourceCache, 'source/foo', 'foo');
170
+
171
+        $this->assertTrue($this->sourceCache->inCache('target/foo'));
172
+        $this->assertTrue($this->sourceCache->inCache('target/foo/bar'));
173
+    }
174
+
175
+    public function testMoveBetweenJail(): void {
176
+        $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE];
177
+
178
+        $this->sourceCache->put('source', $folderData);
179
+        $this->sourceCache->put('source/foo', $folderData);
180
+        $this->sourceCache->put('source/foo/bar', $folderData);
181
+        $this->sourceCache->put('target', $folderData);
182
+
183
+        $jail = new CacheJail($this->sourceCache, 'target');
184
+        $sourceJail = new CacheJail($this->sourceCache, 'source');
185
+
186
+        $jail->moveFromCache($sourceJail, 'foo', 'foo');
187
+
188
+        $this->assertTrue($this->sourceCache->inCache('target/foo'));
189
+        $this->assertTrue($this->sourceCache->inCache('target/foo/bar'));
190
+    }
191
+
192
+    public function testSearchNested(): void {
193
+        $this->storage->getScanner()->scan('');
194
+        $file1 = 'jail';
195
+        $file2 = 'jail/bar';
196
+        $file3 = 'jail/bar/asd';
197
+        $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
198
+
199
+        $this->sourceCache->put($file1, $data1);
200
+        $this->sourceCache->put($file2, $data1);
201
+        $this->sourceCache->put($file3, $data1);
202
+
203
+        $nested = new \OC\Files\Cache\Wrapper\CacheJail($this->cache, 'bar');
204
+
205
+        $result = $nested->search('%asd%');
206
+        $this->assertCount(1, $result);
207
+        $this->assertEquals('asd', $result[0]['path']);
208
+    }
209
+
210
+    public function testRootJail(): void {
211
+        $this->storage->getScanner()->scan('');
212
+        $file1 = 'jail';
213
+        $file2 = 'jail/bar';
214
+        $file3 = 'jail/bar/asd';
215
+        $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'];
216
+
217
+        $this->sourceCache->put($file1, $data1);
218
+        $this->sourceCache->put($file2, $data1);
219
+        $this->sourceCache->put($file3, $data1);
220
+
221
+        $nested = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, '');
222
+
223
+        $result = $nested->search('%asd%');
224
+        $this->assertCount(1, $result);
225
+        $this->assertEquals('jail/bar/asd', $result[0]['path']);
226
+    }
227
+
228
+    public function testWatcher(): void {
229
+        $storage = new Jail([
230
+            'storage' => $this->storage,
231
+            'root' => 'jail'
232
+        ]);
233
+        $storage->getScanner()->scan('');
234
+        $storage->file_put_contents('bar', 'asd');
235
+
236
+        $this->assertFalse($this->cache->inCache('bar'));
237
+        $storage->getWatcher()->update('bar', ['mimetype' => 'text/plain']);
238
+        $this->assertTrue($this->cache->inCache('bar'));
239
+    }
240
+
241
+    public function testWatcherAfterInnerWatcher(): void {
242
+        $storage = new Jail([
243
+            'storage' => $this->storage,
244
+            'root' => 'jail'
245
+        ]);
246
+        $storage->getScanner()->scan('');
247
+        $storage->file_put_contents('bar', 'asd');
248
+
249
+        // let the underlying storage create it's watcher first
250
+        $this->storage->getWatcher();
251
+
252
+        $this->assertFalse($this->cache->inCache('bar'));
253
+        $storage->getWatcher()->update('bar', ['mimetype' => 'text/plain']);
254
+        $this->assertTrue($this->cache->inCache('bar'));
255
+    }
256
+
257
+    public function testUnJailedRoot(): void {
258
+        $jail1 = new CacheJail($this->sourceCache, 'foo');
259
+        $jail2 = new CacheJail($jail1, 'bar');
260
+        $this->assertEquals('foo/bar', $jail2->getGetUnjailedRoot());
261
+
262
+        $middleWrapper = new CacheWrapper($jail1);
263
+        $jail3 = new CacheJail($middleWrapper, 'bar');
264
+        $this->assertEquals('foo/bar', $jail3->getGetUnjailedRoot());
265
+    }
266 266
 }
Please login to merge, or discard this patch.