Passed
Push — master ( 18ff26...b73f40 )
by Christoph
12:59 queued 11s
created
apps/files_sharing/lib/Cache.php 1 patch
Indentation   +159 added lines, -159 removed lines patch added patch discarded remove patch
@@ -46,163 +46,163 @@
 block discarded – undo
46 46
  * don't use this class directly if you need to get metadata, use \OC\Files\Filesystem::getFileInfo instead
47 47
  */
48 48
 class Cache extends CacheJail {
49
-	/** @var \OCA\Files_Sharing\SharedStorage */
50
-	private $storage;
51
-	/** @var ICacheEntry */
52
-	private $sourceRootInfo;
53
-	/** @var IUserManager */
54
-	private $userManager;
55
-
56
-	private $rootUnchanged = true;
57
-
58
-	private $ownerDisplayName;
59
-
60
-	private $numericId;
61
-
62
-	/**
63
-	 * @param \OCA\Files_Sharing\SharedStorage $storage
64
-	 */
65
-	public function __construct($storage, ICacheEntry $sourceRootInfo, IUserManager $userManager) {
66
-		$this->storage = $storage;
67
-		$this->sourceRootInfo = $sourceRootInfo;
68
-		$this->userManager = $userManager;
69
-		$this->numericId = $sourceRootInfo->getStorageId();
70
-
71
-		parent::__construct(
72
-			null,
73
-			''
74
-		);
75
-	}
76
-
77
-	protected function getRoot() {
78
-		if ($this->root === '') {
79
-			$absoluteRoot = $this->sourceRootInfo->getPath();
80
-
81
-			// the sourceRootInfo path is the absolute path of the folder in the "real" storage
82
-			// in the case where a folder is shared from a Jail we need to ensure that the share Jail
83
-			// has it's root set relative to the source Jail
84
-			$currentStorage = $this->storage->getSourceStorage();
85
-			if ($currentStorage->instanceOfStorage(Jail::class)) {
86
-				/** @var Jail $currentStorage */
87
-				$absoluteRoot = $currentStorage->getJailedPath($absoluteRoot);
88
-			}
89
-			$this->root = $absoluteRoot;
90
-		}
91
-		return $this->root;
92
-	}
93
-
94
-	protected function getGetUnjailedRoot() {
95
-		return $this->sourceRootInfo->getPath();
96
-	}
97
-
98
-	public function getCache() {
99
-		if (is_null($this->cache)) {
100
-			$sourceStorage = $this->storage->getSourceStorage();
101
-			if ($sourceStorage) {
102
-				$this->cache = $sourceStorage->getCache();
103
-			} else {
104
-				// don't set $this->cache here since sourceStorage will be set later
105
-				return new FailedCache();
106
-			}
107
-		}
108
-		return $this->cache;
109
-	}
110
-
111
-	public function getNumericStorageId() {
112
-		if (isset($this->numericId)) {
113
-			return $this->numericId;
114
-		} else {
115
-			return false;
116
-		}
117
-	}
118
-
119
-	public function get($file) {
120
-		if ($this->rootUnchanged && ($file === '' || $file === $this->sourceRootInfo->getId())) {
121
-			return $this->formatCacheEntry(clone $this->sourceRootInfo, '');
122
-		}
123
-		return parent::get($file);
124
-	}
125
-
126
-	public function update($id, array $data) {
127
-		$this->rootUnchanged = false;
128
-		parent::update($id, $data);
129
-	}
130
-
131
-	public function insert($file, array $data) {
132
-		$this->rootUnchanged = false;
133
-		return parent::insert($file, $data);
134
-	}
135
-
136
-	public function remove($file) {
137
-		$this->rootUnchanged = false;
138
-		parent::remove($file);
139
-	}
140
-
141
-	public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath, $targetPath) {
142
-		$this->rootUnchanged = false;
143
-		return parent::moveFromCache($sourceCache, $sourcePath, $targetPath);
144
-	}
145
-
146
-	protected function formatCacheEntry($entry, $path = null) {
147
-		if (is_null($path)) {
148
-			$path = $entry['path'] ?? '';
149
-			$entry['path'] = $this->getJailedPath($path);
150
-		} else {
151
-			$entry['path'] = $path;
152
-		}
153
-
154
-		try {
155
-			if (isset($entry['permissions'])) {
156
-				$entry['permissions'] &= $this->storage->getShare()->getPermissions();
157
-			} else {
158
-				$entry['permissions'] = $this->storage->getPermissions($entry['path']);
159
-			}
160
-		} catch (StorageNotAvailableException $e) {
161
-			// thrown by FailedStorage e.g. when the sharer does not exist anymore
162
-			// (IDE may say the exception is never thrown – false negative)
163
-			$sharePermissions = 0;
164
-		}
165
-		$entry['uid_owner'] = $this->storage->getOwner('');
166
-		$entry['displayname_owner'] = $this->getOwnerDisplayName();
167
-		if ($path === '') {
168
-			$entry['is_share_mount_point'] = true;
169
-		}
170
-		return $entry;
171
-	}
172
-
173
-	private function getOwnerDisplayName() {
174
-		if (!$this->ownerDisplayName) {
175
-			$uid = $this->storage->getOwner('');
176
-			$user = $this->userManager->get($uid);
177
-			if ($user) {
178
-				$this->ownerDisplayName = $user->getDisplayName();
179
-			} else {
180
-				$this->ownerDisplayName = $uid;
181
-			}
182
-		}
183
-		return $this->ownerDisplayName;
184
-	}
185
-
186
-	/**
187
-	 * remove all entries for files that are stored on the storage from the cache
188
-	 */
189
-	public function clear() {
190
-		// Not a valid action for Shared Cache
191
-	}
192
-
193
-	public function getQueryFilterForStorage(): ISearchOperator {
194
-		// Do the normal jail behavior for non files
195
-		if ($this->storage->getItemType() !== 'file') {
196
-			return parent::getQueryFilterForStorage();
197
-		}
198
-
199
-		// for single file shares we don't need to do the LIKE
200
-		return new SearchBinaryOperator(
201
-			ISearchBinaryOperator::OPERATOR_AND,
202
-			[
203
-				\OC\Files\Cache\Cache::getQueryFilterForStorage(),
204
-				new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()),
205
-			]
206
-		);
207
-	}
49
+    /** @var \OCA\Files_Sharing\SharedStorage */
50
+    private $storage;
51
+    /** @var ICacheEntry */
52
+    private $sourceRootInfo;
53
+    /** @var IUserManager */
54
+    private $userManager;
55
+
56
+    private $rootUnchanged = true;
57
+
58
+    private $ownerDisplayName;
59
+
60
+    private $numericId;
61
+
62
+    /**
63
+     * @param \OCA\Files_Sharing\SharedStorage $storage
64
+     */
65
+    public function __construct($storage, ICacheEntry $sourceRootInfo, IUserManager $userManager) {
66
+        $this->storage = $storage;
67
+        $this->sourceRootInfo = $sourceRootInfo;
68
+        $this->userManager = $userManager;
69
+        $this->numericId = $sourceRootInfo->getStorageId();
70
+
71
+        parent::__construct(
72
+            null,
73
+            ''
74
+        );
75
+    }
76
+
77
+    protected function getRoot() {
78
+        if ($this->root === '') {
79
+            $absoluteRoot = $this->sourceRootInfo->getPath();
80
+
81
+            // the sourceRootInfo path is the absolute path of the folder in the "real" storage
82
+            // in the case where a folder is shared from a Jail we need to ensure that the share Jail
83
+            // has it's root set relative to the source Jail
84
+            $currentStorage = $this->storage->getSourceStorage();
85
+            if ($currentStorage->instanceOfStorage(Jail::class)) {
86
+                /** @var Jail $currentStorage */
87
+                $absoluteRoot = $currentStorage->getJailedPath($absoluteRoot);
88
+            }
89
+            $this->root = $absoluteRoot;
90
+        }
91
+        return $this->root;
92
+    }
93
+
94
+    protected function getGetUnjailedRoot() {
95
+        return $this->sourceRootInfo->getPath();
96
+    }
97
+
98
+    public function getCache() {
99
+        if (is_null($this->cache)) {
100
+            $sourceStorage = $this->storage->getSourceStorage();
101
+            if ($sourceStorage) {
102
+                $this->cache = $sourceStorage->getCache();
103
+            } else {
104
+                // don't set $this->cache here since sourceStorage will be set later
105
+                return new FailedCache();
106
+            }
107
+        }
108
+        return $this->cache;
109
+    }
110
+
111
+    public function getNumericStorageId() {
112
+        if (isset($this->numericId)) {
113
+            return $this->numericId;
114
+        } else {
115
+            return false;
116
+        }
117
+    }
118
+
119
+    public function get($file) {
120
+        if ($this->rootUnchanged && ($file === '' || $file === $this->sourceRootInfo->getId())) {
121
+            return $this->formatCacheEntry(clone $this->sourceRootInfo, '');
122
+        }
123
+        return parent::get($file);
124
+    }
125
+
126
+    public function update($id, array $data) {
127
+        $this->rootUnchanged = false;
128
+        parent::update($id, $data);
129
+    }
130
+
131
+    public function insert($file, array $data) {
132
+        $this->rootUnchanged = false;
133
+        return parent::insert($file, $data);
134
+    }
135
+
136
+    public function remove($file) {
137
+        $this->rootUnchanged = false;
138
+        parent::remove($file);
139
+    }
140
+
141
+    public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath, $targetPath) {
142
+        $this->rootUnchanged = false;
143
+        return parent::moveFromCache($sourceCache, $sourcePath, $targetPath);
144
+    }
145
+
146
+    protected function formatCacheEntry($entry, $path = null) {
147
+        if (is_null($path)) {
148
+            $path = $entry['path'] ?? '';
149
+            $entry['path'] = $this->getJailedPath($path);
150
+        } else {
151
+            $entry['path'] = $path;
152
+        }
153
+
154
+        try {
155
+            if (isset($entry['permissions'])) {
156
+                $entry['permissions'] &= $this->storage->getShare()->getPermissions();
157
+            } else {
158
+                $entry['permissions'] = $this->storage->getPermissions($entry['path']);
159
+            }
160
+        } catch (StorageNotAvailableException $e) {
161
+            // thrown by FailedStorage e.g. when the sharer does not exist anymore
162
+            // (IDE may say the exception is never thrown – false negative)
163
+            $sharePermissions = 0;
164
+        }
165
+        $entry['uid_owner'] = $this->storage->getOwner('');
166
+        $entry['displayname_owner'] = $this->getOwnerDisplayName();
167
+        if ($path === '') {
168
+            $entry['is_share_mount_point'] = true;
169
+        }
170
+        return $entry;
171
+    }
172
+
173
+    private function getOwnerDisplayName() {
174
+        if (!$this->ownerDisplayName) {
175
+            $uid = $this->storage->getOwner('');
176
+            $user = $this->userManager->get($uid);
177
+            if ($user) {
178
+                $this->ownerDisplayName = $user->getDisplayName();
179
+            } else {
180
+                $this->ownerDisplayName = $uid;
181
+            }
182
+        }
183
+        return $this->ownerDisplayName;
184
+    }
185
+
186
+    /**
187
+     * remove all entries for files that are stored on the storage from the cache
188
+     */
189
+    public function clear() {
190
+        // Not a valid action for Shared Cache
191
+    }
192
+
193
+    public function getQueryFilterForStorage(): ISearchOperator {
194
+        // Do the normal jail behavior for non files
195
+        if ($this->storage->getItemType() !== 'file') {
196
+            return parent::getQueryFilterForStorage();
197
+        }
198
+
199
+        // for single file shares we don't need to do the LIKE
200
+        return new SearchBinaryOperator(
201
+            ISearchBinaryOperator::OPERATOR_AND,
202
+            [
203
+                \OC\Files\Cache\Cache::getQueryFilterForStorage(),
204
+                new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()),
205
+            ]
206
+        );
207
+    }
208 208
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/SharedStorage.php 1 patch
Indentation   +468 added lines, -468 removed lines patch added patch discarded remove patch
@@ -52,472 +52,472 @@
 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(
390
-			$storage,
391
-			$sourceRoot,
392
-			\OC::$server->get(IUserManager::class)
393
-		);
394
-		return $this->cache;
395
-	}
396
-
397
-	public function getScanner($path = '', $storage = null) {
398
-		if (!$storage) {
399
-			$storage = $this;
400
-		}
401
-		return new \OCA\Files_Sharing\Scanner($storage);
402
-	}
403
-
404
-	public function getOwner($path): string {
405
-		return $this->superShare->getShareOwner();
406
-	}
407
-
408
-	public function getWatcher($path = '', $storage = null): NullWatcher {
409
-		// cache updating is handled by the share source
410
-		return new NullWatcher();
411
-	}
412
-
413
-	/**
414
-	 * unshare complete storage, also the grouped shares
415
-	 *
416
-	 * @return bool
417
-	 */
418
-	public function unshareStorage(): bool {
419
-		foreach ($this->groupedShares as $share) {
420
-			\OC::$server->getShareManager()->deleteFromSelf($share, $this->user);
421
-		}
422
-		return true;
423
-	}
424
-
425
-	/**
426
-	 * @param string $path
427
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
428
-	 * @param \OCP\Lock\ILockingProvider $provider
429
-	 * @throws \OCP\Lock\LockedException
430
-	 */
431
-	public function acquireLock($path, $type, ILockingProvider $provider) {
432
-		/** @var \OCP\Files\Storage $targetStorage */
433
-		[$targetStorage, $targetInternalPath] = $this->resolvePath($path);
434
-		$targetStorage->acquireLock($targetInternalPath, $type, $provider);
435
-		// lock the parent folders of the owner when locking the share as recipient
436
-		if ($path === '') {
437
-			$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
438
-			$this->ownerView->lockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
439
-		}
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
-	 */
447
-	public function releaseLock($path, $type, ILockingProvider $provider) {
448
-		/** @var \OCP\Files\Storage $targetStorage */
449
-		[$targetStorage, $targetInternalPath] = $this->resolvePath($path);
450
-		$targetStorage->releaseLock($targetInternalPath, $type, $provider);
451
-		// unlock the parent folders of the owner when unlocking the share as recipient
452
-		if ($path === '') {
453
-			$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
454
-			$this->ownerView->unlockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
455
-		}
456
-	}
457
-
458
-	/**
459
-	 * @param string $path
460
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
461
-	 * @param \OCP\Lock\ILockingProvider $provider
462
-	 */
463
-	public function changeLock($path, $type, ILockingProvider $provider) {
464
-		/** @var \OCP\Files\Storage $targetStorage */
465
-		[$targetStorage, $targetInternalPath] = $this->resolvePath($path);
466
-		$targetStorage->changeLock($targetInternalPath, $type, $provider);
467
-	}
468
-
469
-	/**
470
-	 * @return array [ available, last_checked ]
471
-	 */
472
-	public function getAvailability() {
473
-		// shares do not participate in availability logic
474
-		return [
475
-			'available' => true,
476
-			'last_checked' => 0,
477
-		];
478
-	}
479
-
480
-	/**
481
-	 * @param bool $available
482
-	 */
483
-	public function setAvailability($available) {
484
-		// shares do not participate in availability logic
485
-	}
486
-
487
-	public function getSourceStorage() {
488
-		$this->init();
489
-		return $this->nonMaskedStorage;
490
-	}
491
-
492
-	public function getWrapperStorage() {
493
-		$this->init();
494
-		return $this->storage;
495
-	}
496
-
497
-	public function file_get_contents($path) {
498
-		$info = [
499
-			'target' => $this->getMountPoint() . '/' . $path,
500
-			'source' => $this->getUnjailedPath($path),
501
-		];
502
-		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info);
503
-		return parent::file_get_contents($path);
504
-	}
505
-
506
-	public function file_put_contents($path, $data) {
507
-		$info = [
508
-			'target' => $this->getMountPoint() . '/' . $path,
509
-			'source' => $this->getUnjailedPath($path),
510
-		];
511
-		\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info);
512
-		return parent::file_put_contents($path, $data);
513
-	}
514
-
515
-	public function setMountOptions(array $options) {
516
-		$this->mountOptions = $options;
517
-	}
518
-
519
-	public function getUnjailedPath($path) {
520
-		$this->init();
521
-		return parent::getUnjailedPath($path);
522
-	}
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(
390
+            $storage,
391
+            $sourceRoot,
392
+            \OC::$server->get(IUserManager::class)
393
+        );
394
+        return $this->cache;
395
+    }
396
+
397
+    public function getScanner($path = '', $storage = null) {
398
+        if (!$storage) {
399
+            $storage = $this;
400
+        }
401
+        return new \OCA\Files_Sharing\Scanner($storage);
402
+    }
403
+
404
+    public function getOwner($path): string {
405
+        return $this->superShare->getShareOwner();
406
+    }
407
+
408
+    public function getWatcher($path = '', $storage = null): NullWatcher {
409
+        // cache updating is handled by the share source
410
+        return new NullWatcher();
411
+    }
412
+
413
+    /**
414
+     * unshare complete storage, also the grouped shares
415
+     *
416
+     * @return bool
417
+     */
418
+    public function unshareStorage(): bool {
419
+        foreach ($this->groupedShares as $share) {
420
+            \OC::$server->getShareManager()->deleteFromSelf($share, $this->user);
421
+        }
422
+        return true;
423
+    }
424
+
425
+    /**
426
+     * @param string $path
427
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
428
+     * @param \OCP\Lock\ILockingProvider $provider
429
+     * @throws \OCP\Lock\LockedException
430
+     */
431
+    public function acquireLock($path, $type, ILockingProvider $provider) {
432
+        /** @var \OCP\Files\Storage $targetStorage */
433
+        [$targetStorage, $targetInternalPath] = $this->resolvePath($path);
434
+        $targetStorage->acquireLock($targetInternalPath, $type, $provider);
435
+        // lock the parent folders of the owner when locking the share as recipient
436
+        if ($path === '') {
437
+            $sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
438
+            $this->ownerView->lockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
439
+        }
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
+     */
447
+    public function releaseLock($path, $type, ILockingProvider $provider) {
448
+        /** @var \OCP\Files\Storage $targetStorage */
449
+        [$targetStorage, $targetInternalPath] = $this->resolvePath($path);
450
+        $targetStorage->releaseLock($targetInternalPath, $type, $provider);
451
+        // unlock the parent folders of the owner when unlocking the share as recipient
452
+        if ($path === '') {
453
+            $sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
454
+            $this->ownerView->unlockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
455
+        }
456
+    }
457
+
458
+    /**
459
+     * @param string $path
460
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
461
+     * @param \OCP\Lock\ILockingProvider $provider
462
+     */
463
+    public function changeLock($path, $type, ILockingProvider $provider) {
464
+        /** @var \OCP\Files\Storage $targetStorage */
465
+        [$targetStorage, $targetInternalPath] = $this->resolvePath($path);
466
+        $targetStorage->changeLock($targetInternalPath, $type, $provider);
467
+    }
468
+
469
+    /**
470
+     * @return array [ available, last_checked ]
471
+     */
472
+    public function getAvailability() {
473
+        // shares do not participate in availability logic
474
+        return [
475
+            'available' => true,
476
+            'last_checked' => 0,
477
+        ];
478
+    }
479
+
480
+    /**
481
+     * @param bool $available
482
+     */
483
+    public function setAvailability($available) {
484
+        // shares do not participate in availability logic
485
+    }
486
+
487
+    public function getSourceStorage() {
488
+        $this->init();
489
+        return $this->nonMaskedStorage;
490
+    }
491
+
492
+    public function getWrapperStorage() {
493
+        $this->init();
494
+        return $this->storage;
495
+    }
496
+
497
+    public function file_get_contents($path) {
498
+        $info = [
499
+            'target' => $this->getMountPoint() . '/' . $path,
500
+            'source' => $this->getUnjailedPath($path),
501
+        ];
502
+        \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info);
503
+        return parent::file_get_contents($path);
504
+    }
505
+
506
+    public function file_put_contents($path, $data) {
507
+        $info = [
508
+            'target' => $this->getMountPoint() . '/' . $path,
509
+            'source' => $this->getUnjailedPath($path),
510
+        ];
511
+        \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info);
512
+        return parent::file_put_contents($path, $data);
513
+    }
514
+
515
+    public function setMountOptions(array $options) {
516
+        $this->mountOptions = $options;
517
+    }
518
+
519
+    public function getUnjailedPath($path) {
520
+        $this->init();
521
+        return parent::getUnjailedPath($path);
522
+    }
523 523
 }
Please login to merge, or discard this patch.
lib/private/TemplateLayout.php 1 patch
Indentation   +332 added lines, -332 removed lines patch added patch discarded remove patch
@@ -57,336 +57,336 @@
 block discarded – undo
57 57
 use OCP\Util;
58 58
 
59 59
 class TemplateLayout extends \OC_Template {
60
-	private static $versionHash = '';
61
-
62
-	/** @var IConfig */
63
-	private $config;
64
-
65
-	/** @var IInitialStateService */
66
-	private $initialState;
67
-
68
-	/** @var INavigationManager */
69
-	private $navigationManager;
70
-
71
-	/**
72
-	 * @param string $renderAs
73
-	 * @param string $appId application id
74
-	 */
75
-	public function __construct($renderAs, $appId = '') {
76
-
77
-		/** @var IConfig */
78
-		$this->config = \OC::$server->get(IConfig::class);
79
-
80
-		/** @var IInitialStateService */
81
-		$this->initialState = \OC::$server->get(IInitialStateService::class);
82
-
83
-		if (\OC_Util::isIe()) {
84
-			Util::addStyle('ie');
85
-		}
86
-
87
-		// Decide which page we show
88
-		if ($renderAs === TemplateResponse::RENDER_AS_USER) {
89
-			/** @var INavigationManager */
90
-			$this->navigationManager = \OC::$server->get(INavigationManager::class);
91
-
92
-			parent::__construct('core', 'layout.user');
93
-			if (in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) {
94
-				$this->assign('bodyid', 'body-settings');
95
-			} else {
96
-				$this->assign('bodyid', 'body-user');
97
-			}
98
-
99
-			$this->initialState->provideInitialState('core', 'active-app', $this->navigationManager->getActiveEntry());
100
-			$this->initialState->provideInitialState('unified-search', 'limit-default', SearchQuery::LIMIT_DEFAULT);
101
-			Util::addScript('dist/unified-search', null, true);
102
-
103
-			// Add navigation entry
104
-			$this->assign('application', '');
105
-			$this->assign('appid', $appId);
106
-
107
-			$navigation = $this->navigationManager->getAll();
108
-			$this->assign('navigation', $navigation);
109
-			$settingsNavigation = $this->navigationManager->getAll('settings');
110
-			$this->assign('settingsnavigation', $settingsNavigation);
111
-
112
-			foreach ($navigation as $entry) {
113
-				if ($entry['active']) {
114
-					$this->assign('application', $entry['name']);
115
-					break;
116
-				}
117
-			}
118
-
119
-			foreach ($settingsNavigation as $entry) {
120
-				if ($entry['active']) {
121
-					$this->assign('application', $entry['name']);
122
-					break;
123
-				}
124
-			}
125
-
126
-			$userDisplayName = false;
127
-			$user = \OC::$server->get(IUserSession::class)->getUser();
128
-			if ($user) {
129
-				$userDisplayName = $user->getDisplayName();
130
-			}
131
-			$this->assign('user_displayname', $userDisplayName);
132
-			$this->assign('user_uid', \OC_User::getUser());
133
-
134
-			if (\OC_User::getUser() === false) {
135
-				$this->assign('userAvatarSet', false);
136
-			} else {
137
-				$this->assign('userAvatarSet', true);
138
-				$this->assign('userAvatarVersion', $this->config->getUserValue(\OC_User::getUser(), 'avatar', 'version', 0));
139
-			}
140
-
141
-			// check if app menu icons should be inverted
142
-			try {
143
-				/** @var \OCA\Theming\Util $util */
144
-				$util = \OC::$server->query(\OCA\Theming\Util::class);
145
-				$this->assign('themingInvertMenu', $util->invertTextColor(\OC::$server->getThemingDefaults()->getColorPrimary()));
146
-			} catch (\OCP\AppFramework\QueryException $e) {
147
-				$this->assign('themingInvertMenu', false);
148
-			} catch (\OCP\AutoloadNotAllowedException $e) {
149
-				$this->assign('themingInvertMenu', false);
150
-			}
151
-		} elseif ($renderAs === TemplateResponse::RENDER_AS_ERROR) {
152
-			parent::__construct('core', 'layout.guest', '', false);
153
-			$this->assign('bodyid', 'body-login');
154
-			$this->assign('user_displayname', '');
155
-			$this->assign('user_uid', '');
156
-		} elseif ($renderAs === TemplateResponse::RENDER_AS_GUEST) {
157
-			parent::__construct('core', 'layout.guest');
158
-			\OC_Util::addStyle('guest');
159
-			$this->assign('bodyid', 'body-login');
160
-
161
-			$userDisplayName = false;
162
-			$user = \OC::$server->get(IUserSession::class)->getUser();
163
-			if ($user) {
164
-				$userDisplayName = $user->getDisplayName();
165
-			}
166
-			$this->assign('user_displayname', $userDisplayName);
167
-			$this->assign('user_uid', \OC_User::getUser());
168
-		} elseif ($renderAs === TemplateResponse::RENDER_AS_PUBLIC) {
169
-			parent::__construct('core', 'layout.public');
170
-			$this->assign('appid', $appId);
171
-			$this->assign('bodyid', 'body-public');
172
-
173
-			/** @var IRegistry $subscription */
174
-			$subscription = \OC::$server->query(IRegistry::class);
175
-			$showSimpleSignup = $this->config->getSystemValueBool('simpleSignUpLink.shown', true);
176
-			if ($showSimpleSignup && $subscription->delegateHasValidSubscription()) {
177
-				$showSimpleSignup = false;
178
-			}
179
-			$this->assign('showSimpleSignUpLink', $showSimpleSignup);
180
-		} else {
181
-			parent::__construct('core', 'layout.base');
182
-		}
183
-		// Send the language and the locale to our layouts
184
-		$lang = \OC::$server->getL10NFactory()->findLanguage();
185
-		$locale = \OC::$server->getL10NFactory()->findLocale($lang);
186
-
187
-		$lang = str_replace('_', '-', $lang);
188
-		$this->assign('language', $lang);
189
-		$this->assign('locale', $locale);
190
-
191
-		if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
192
-			if (empty(self::$versionHash)) {
193
-				$v = \OC_App::getAppVersions();
194
-				$v['core'] = implode('.', \OCP\Util::getVersion());
195
-				self::$versionHash = substr(md5(implode(',', $v)), 0, 8);
196
-			}
197
-		} else {
198
-			self::$versionHash = md5('not installed');
199
-		}
200
-
201
-		// Add the js files
202
-		$jsFiles = self::findJavascriptFiles(\OC_Util::$scripts);
203
-		$this->assign('jsfiles', []);
204
-		if ($this->config->getSystemValue('installed', false) && $renderAs != TemplateResponse::RENDER_AS_ERROR) {
205
-			// this is on purpose outside of the if statement below so that the initial state is prefilled (done in the getConfig() call)
206
-			// see https://github.com/nextcloud/server/pull/22636 for details
207
-			$jsConfigHelper = new JSConfigHelper(
208
-				\OC::$server->getL10N('lib'),
209
-				\OC::$server->query(Defaults::class),
210
-				\OC::$server->getAppManager(),
211
-				\OC::$server->getSession(),
212
-				\OC::$server->getUserSession()->getUser(),
213
-				$this->config,
214
-				\OC::$server->getGroupManager(),
215
-				\OC::$server->get(IniGetWrapper::class),
216
-				\OC::$server->getURLGenerator(),
217
-				\OC::$server->getCapabilitiesManager(),
218
-				\OC::$server->query(IInitialStateService::class)
219
-			);
220
-			$config = $jsConfigHelper->getConfig();
221
-			if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) {
222
-				$this->assign('inline_ocjs', $config);
223
-			} else {
224
-				$this->append('jsfiles', \OC::$server->getURLGenerator()->linkToRoute('core.OCJS.getConfig', ['v' => self::$versionHash]));
225
-			}
226
-		}
227
-		foreach ($jsFiles as $info) {
228
-			$web = $info[1];
229
-			$file = $info[2];
230
-			$this->append('jsfiles', $web.'/'.$file . $this->getVersionHashSuffix());
231
-		}
232
-
233
-		try {
234
-			$pathInfo = \OC::$server->getRequest()->getPathInfo();
235
-		} catch (\Exception $e) {
236
-			$pathInfo = '';
237
-		}
238
-
239
-		// Do not initialise scss appdata until we have a fully installed instance
240
-		// Do not load scss for update, errors, installation or login page
241
-		if (\OC::$server->getSystemConfig()->getValue('installed', false)
242
-			&& !\OCP\Util::needUpgrade()
243
-			&& $pathInfo !== ''
244
-			&& !preg_match('/^\/login/', $pathInfo)
245
-			&& $renderAs !== TemplateResponse::RENDER_AS_ERROR
246
-		) {
247
-			$cssFiles = self::findStylesheetFiles(\OC_Util::$styles);
248
-		} else {
249
-			// If we ignore the scss compiler,
250
-			// we need to load the guest css fallback
251
-			\OC_Util::addStyle('guest');
252
-			$cssFiles = self::findStylesheetFiles(\OC_Util::$styles, false);
253
-		}
254
-
255
-		$this->assign('cssfiles', []);
256
-		$this->assign('printcssfiles', []);
257
-		$this->assign('versionHash', self::$versionHash);
258
-		foreach ($cssFiles as $info) {
259
-			$web = $info[1];
260
-			$file = $info[2];
261
-
262
-			if (substr($file, -strlen('print.css')) === 'print.css') {
263
-				$this->append('printcssfiles', $web.'/'.$file . $this->getVersionHashSuffix());
264
-			} else {
265
-				$suffix = $this->getVersionHashSuffix($web, $file);
266
-
267
-				if (strpos($file, '?v=') == false) {
268
-					$this->append('cssfiles', $web.'/'.$file . $suffix);
269
-				} else {
270
-					$this->append('cssfiles', $web.'/'.$file . '-' . substr($suffix, 3));
271
-				}
272
-			}
273
-		}
274
-
275
-		$this->assign('initialStates', $this->initialState->getInitialStates());
276
-	}
277
-
278
-	/**
279
-	 * @param string $path
280
-	 * @param string $file
281
-	 * @return string
282
-	 */
283
-	protected function getVersionHashSuffix($path = false, $file = false) {
284
-		if ($this->config->getSystemValue('debug', false)) {
285
-			// allows chrome workspace mapping in debug mode
286
-			return "";
287
-		}
288
-		$themingSuffix = '';
289
-		$v = [];
290
-
291
-		if ($this->config->getSystemValue('installed', false)) {
292
-			if (\OC::$server->getAppManager()->isInstalled('theming')) {
293
-				$themingSuffix = '-' . $this->config->getAppValue('theming', 'cachebuster', '0');
294
-			}
295
-			$v = \OC_App::getAppVersions();
296
-		}
297
-
298
-		// Try the webroot path for a match
299
-		if ($path !== false && $path !== '') {
300
-			$appName = $this->getAppNamefromPath($path);
301
-			if (array_key_exists($appName, $v)) {
302
-				$appVersion = $v[$appName];
303
-				return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
304
-			}
305
-		}
306
-		// fallback to the file path instead
307
-		if ($file !== false && $file !== '') {
308
-			$appName = $this->getAppNamefromPath($file);
309
-			if (array_key_exists($appName, $v)) {
310
-				$appVersion = $v[$appName];
311
-				return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
312
-			}
313
-		}
314
-
315
-		return '?v=' . self::$versionHash . $themingSuffix;
316
-	}
317
-
318
-	/**
319
-	 * @param array $styles
320
-	 * @return array
321
-	 */
322
-	public static function findStylesheetFiles($styles, $compileScss = true) {
323
-		// Read the selected theme from the config file
324
-		$theme = \OC_Util::getTheme();
325
-
326
-		if ($compileScss) {
327
-			$SCSSCacher = \OC::$server->query(SCSSCacher::class);
328
-		} else {
329
-			$SCSSCacher = null;
330
-		}
331
-
332
-		$locator = new \OC\Template\CSSResourceLocator(
333
-			\OC::$server->getLogger(),
334
-			$theme,
335
-			[ \OC::$SERVERROOT => \OC::$WEBROOT ],
336
-			[ \OC::$SERVERROOT => \OC::$WEBROOT ],
337
-			$SCSSCacher
338
-		);
339
-		$locator->find($styles);
340
-		return $locator->getResources();
341
-	}
342
-
343
-	/**
344
-	 * @param string $path
345
-	 * @return string|boolean
346
-	 */
347
-	public function getAppNamefromPath($path) {
348
-		if ($path !== '' && is_string($path)) {
349
-			$pathParts = explode('/', $path);
350
-			if ($pathParts[0] === 'css') {
351
-				// This is a scss request
352
-				return $pathParts[1];
353
-			}
354
-			return end($pathParts);
355
-		}
356
-		return false;
357
-	}
358
-
359
-	/**
360
-	 * @param array $scripts
361
-	 * @return array
362
-	 */
363
-	public static function findJavascriptFiles($scripts) {
364
-		// Read the selected theme from the config file
365
-		$theme = \OC_Util::getTheme();
366
-
367
-		$locator = new \OC\Template\JSResourceLocator(
368
-			\OC::$server->getLogger(),
369
-			$theme,
370
-			[ \OC::$SERVERROOT => \OC::$WEBROOT ],
371
-			[ \OC::$SERVERROOT => \OC::$WEBROOT ],
372
-			\OC::$server->query(JSCombiner::class)
373
-			);
374
-		$locator->find($scripts);
375
-		return $locator->getResources();
376
-	}
377
-
378
-	/**
379
-	 * Converts the absolute file path to a relative path from \OC::$SERVERROOT
380
-	 * @param string $filePath Absolute path
381
-	 * @return string Relative path
382
-	 * @throws \Exception If $filePath is not under \OC::$SERVERROOT
383
-	 */
384
-	public static function convertToRelativePath($filePath) {
385
-		$relativePath = explode(\OC::$SERVERROOT, $filePath);
386
-		if (count($relativePath) !== 2) {
387
-			throw new \Exception('$filePath is not under the \OC::$SERVERROOT');
388
-		}
389
-
390
-		return $relativePath[1];
391
-	}
60
+    private static $versionHash = '';
61
+
62
+    /** @var IConfig */
63
+    private $config;
64
+
65
+    /** @var IInitialStateService */
66
+    private $initialState;
67
+
68
+    /** @var INavigationManager */
69
+    private $navigationManager;
70
+
71
+    /**
72
+     * @param string $renderAs
73
+     * @param string $appId application id
74
+     */
75
+    public function __construct($renderAs, $appId = '') {
76
+
77
+        /** @var IConfig */
78
+        $this->config = \OC::$server->get(IConfig::class);
79
+
80
+        /** @var IInitialStateService */
81
+        $this->initialState = \OC::$server->get(IInitialStateService::class);
82
+
83
+        if (\OC_Util::isIe()) {
84
+            Util::addStyle('ie');
85
+        }
86
+
87
+        // Decide which page we show
88
+        if ($renderAs === TemplateResponse::RENDER_AS_USER) {
89
+            /** @var INavigationManager */
90
+            $this->navigationManager = \OC::$server->get(INavigationManager::class);
91
+
92
+            parent::__construct('core', 'layout.user');
93
+            if (in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) {
94
+                $this->assign('bodyid', 'body-settings');
95
+            } else {
96
+                $this->assign('bodyid', 'body-user');
97
+            }
98
+
99
+            $this->initialState->provideInitialState('core', 'active-app', $this->navigationManager->getActiveEntry());
100
+            $this->initialState->provideInitialState('unified-search', 'limit-default', SearchQuery::LIMIT_DEFAULT);
101
+            Util::addScript('dist/unified-search', null, true);
102
+
103
+            // Add navigation entry
104
+            $this->assign('application', '');
105
+            $this->assign('appid', $appId);
106
+
107
+            $navigation = $this->navigationManager->getAll();
108
+            $this->assign('navigation', $navigation);
109
+            $settingsNavigation = $this->navigationManager->getAll('settings');
110
+            $this->assign('settingsnavigation', $settingsNavigation);
111
+
112
+            foreach ($navigation as $entry) {
113
+                if ($entry['active']) {
114
+                    $this->assign('application', $entry['name']);
115
+                    break;
116
+                }
117
+            }
118
+
119
+            foreach ($settingsNavigation as $entry) {
120
+                if ($entry['active']) {
121
+                    $this->assign('application', $entry['name']);
122
+                    break;
123
+                }
124
+            }
125
+
126
+            $userDisplayName = false;
127
+            $user = \OC::$server->get(IUserSession::class)->getUser();
128
+            if ($user) {
129
+                $userDisplayName = $user->getDisplayName();
130
+            }
131
+            $this->assign('user_displayname', $userDisplayName);
132
+            $this->assign('user_uid', \OC_User::getUser());
133
+
134
+            if (\OC_User::getUser() === false) {
135
+                $this->assign('userAvatarSet', false);
136
+            } else {
137
+                $this->assign('userAvatarSet', true);
138
+                $this->assign('userAvatarVersion', $this->config->getUserValue(\OC_User::getUser(), 'avatar', 'version', 0));
139
+            }
140
+
141
+            // check if app menu icons should be inverted
142
+            try {
143
+                /** @var \OCA\Theming\Util $util */
144
+                $util = \OC::$server->query(\OCA\Theming\Util::class);
145
+                $this->assign('themingInvertMenu', $util->invertTextColor(\OC::$server->getThemingDefaults()->getColorPrimary()));
146
+            } catch (\OCP\AppFramework\QueryException $e) {
147
+                $this->assign('themingInvertMenu', false);
148
+            } catch (\OCP\AutoloadNotAllowedException $e) {
149
+                $this->assign('themingInvertMenu', false);
150
+            }
151
+        } elseif ($renderAs === TemplateResponse::RENDER_AS_ERROR) {
152
+            parent::__construct('core', 'layout.guest', '', false);
153
+            $this->assign('bodyid', 'body-login');
154
+            $this->assign('user_displayname', '');
155
+            $this->assign('user_uid', '');
156
+        } elseif ($renderAs === TemplateResponse::RENDER_AS_GUEST) {
157
+            parent::__construct('core', 'layout.guest');
158
+            \OC_Util::addStyle('guest');
159
+            $this->assign('bodyid', 'body-login');
160
+
161
+            $userDisplayName = false;
162
+            $user = \OC::$server->get(IUserSession::class)->getUser();
163
+            if ($user) {
164
+                $userDisplayName = $user->getDisplayName();
165
+            }
166
+            $this->assign('user_displayname', $userDisplayName);
167
+            $this->assign('user_uid', \OC_User::getUser());
168
+        } elseif ($renderAs === TemplateResponse::RENDER_AS_PUBLIC) {
169
+            parent::__construct('core', 'layout.public');
170
+            $this->assign('appid', $appId);
171
+            $this->assign('bodyid', 'body-public');
172
+
173
+            /** @var IRegistry $subscription */
174
+            $subscription = \OC::$server->query(IRegistry::class);
175
+            $showSimpleSignup = $this->config->getSystemValueBool('simpleSignUpLink.shown', true);
176
+            if ($showSimpleSignup && $subscription->delegateHasValidSubscription()) {
177
+                $showSimpleSignup = false;
178
+            }
179
+            $this->assign('showSimpleSignUpLink', $showSimpleSignup);
180
+        } else {
181
+            parent::__construct('core', 'layout.base');
182
+        }
183
+        // Send the language and the locale to our layouts
184
+        $lang = \OC::$server->getL10NFactory()->findLanguage();
185
+        $locale = \OC::$server->getL10NFactory()->findLocale($lang);
186
+
187
+        $lang = str_replace('_', '-', $lang);
188
+        $this->assign('language', $lang);
189
+        $this->assign('locale', $locale);
190
+
191
+        if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
192
+            if (empty(self::$versionHash)) {
193
+                $v = \OC_App::getAppVersions();
194
+                $v['core'] = implode('.', \OCP\Util::getVersion());
195
+                self::$versionHash = substr(md5(implode(',', $v)), 0, 8);
196
+            }
197
+        } else {
198
+            self::$versionHash = md5('not installed');
199
+        }
200
+
201
+        // Add the js files
202
+        $jsFiles = self::findJavascriptFiles(\OC_Util::$scripts);
203
+        $this->assign('jsfiles', []);
204
+        if ($this->config->getSystemValue('installed', false) && $renderAs != TemplateResponse::RENDER_AS_ERROR) {
205
+            // this is on purpose outside of the if statement below so that the initial state is prefilled (done in the getConfig() call)
206
+            // see https://github.com/nextcloud/server/pull/22636 for details
207
+            $jsConfigHelper = new JSConfigHelper(
208
+                \OC::$server->getL10N('lib'),
209
+                \OC::$server->query(Defaults::class),
210
+                \OC::$server->getAppManager(),
211
+                \OC::$server->getSession(),
212
+                \OC::$server->getUserSession()->getUser(),
213
+                $this->config,
214
+                \OC::$server->getGroupManager(),
215
+                \OC::$server->get(IniGetWrapper::class),
216
+                \OC::$server->getURLGenerator(),
217
+                \OC::$server->getCapabilitiesManager(),
218
+                \OC::$server->query(IInitialStateService::class)
219
+            );
220
+            $config = $jsConfigHelper->getConfig();
221
+            if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) {
222
+                $this->assign('inline_ocjs', $config);
223
+            } else {
224
+                $this->append('jsfiles', \OC::$server->getURLGenerator()->linkToRoute('core.OCJS.getConfig', ['v' => self::$versionHash]));
225
+            }
226
+        }
227
+        foreach ($jsFiles as $info) {
228
+            $web = $info[1];
229
+            $file = $info[2];
230
+            $this->append('jsfiles', $web.'/'.$file . $this->getVersionHashSuffix());
231
+        }
232
+
233
+        try {
234
+            $pathInfo = \OC::$server->getRequest()->getPathInfo();
235
+        } catch (\Exception $e) {
236
+            $pathInfo = '';
237
+        }
238
+
239
+        // Do not initialise scss appdata until we have a fully installed instance
240
+        // Do not load scss for update, errors, installation or login page
241
+        if (\OC::$server->getSystemConfig()->getValue('installed', false)
242
+            && !\OCP\Util::needUpgrade()
243
+            && $pathInfo !== ''
244
+            && !preg_match('/^\/login/', $pathInfo)
245
+            && $renderAs !== TemplateResponse::RENDER_AS_ERROR
246
+        ) {
247
+            $cssFiles = self::findStylesheetFiles(\OC_Util::$styles);
248
+        } else {
249
+            // If we ignore the scss compiler,
250
+            // we need to load the guest css fallback
251
+            \OC_Util::addStyle('guest');
252
+            $cssFiles = self::findStylesheetFiles(\OC_Util::$styles, false);
253
+        }
254
+
255
+        $this->assign('cssfiles', []);
256
+        $this->assign('printcssfiles', []);
257
+        $this->assign('versionHash', self::$versionHash);
258
+        foreach ($cssFiles as $info) {
259
+            $web = $info[1];
260
+            $file = $info[2];
261
+
262
+            if (substr($file, -strlen('print.css')) === 'print.css') {
263
+                $this->append('printcssfiles', $web.'/'.$file . $this->getVersionHashSuffix());
264
+            } else {
265
+                $suffix = $this->getVersionHashSuffix($web, $file);
266
+
267
+                if (strpos($file, '?v=') == false) {
268
+                    $this->append('cssfiles', $web.'/'.$file . $suffix);
269
+                } else {
270
+                    $this->append('cssfiles', $web.'/'.$file . '-' . substr($suffix, 3));
271
+                }
272
+            }
273
+        }
274
+
275
+        $this->assign('initialStates', $this->initialState->getInitialStates());
276
+    }
277
+
278
+    /**
279
+     * @param string $path
280
+     * @param string $file
281
+     * @return string
282
+     */
283
+    protected function getVersionHashSuffix($path = false, $file = false) {
284
+        if ($this->config->getSystemValue('debug', false)) {
285
+            // allows chrome workspace mapping in debug mode
286
+            return "";
287
+        }
288
+        $themingSuffix = '';
289
+        $v = [];
290
+
291
+        if ($this->config->getSystemValue('installed', false)) {
292
+            if (\OC::$server->getAppManager()->isInstalled('theming')) {
293
+                $themingSuffix = '-' . $this->config->getAppValue('theming', 'cachebuster', '0');
294
+            }
295
+            $v = \OC_App::getAppVersions();
296
+        }
297
+
298
+        // Try the webroot path for a match
299
+        if ($path !== false && $path !== '') {
300
+            $appName = $this->getAppNamefromPath($path);
301
+            if (array_key_exists($appName, $v)) {
302
+                $appVersion = $v[$appName];
303
+                return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
304
+            }
305
+        }
306
+        // fallback to the file path instead
307
+        if ($file !== false && $file !== '') {
308
+            $appName = $this->getAppNamefromPath($file);
309
+            if (array_key_exists($appName, $v)) {
310
+                $appVersion = $v[$appName];
311
+                return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
312
+            }
313
+        }
314
+
315
+        return '?v=' . self::$versionHash . $themingSuffix;
316
+    }
317
+
318
+    /**
319
+     * @param array $styles
320
+     * @return array
321
+     */
322
+    public static function findStylesheetFiles($styles, $compileScss = true) {
323
+        // Read the selected theme from the config file
324
+        $theme = \OC_Util::getTheme();
325
+
326
+        if ($compileScss) {
327
+            $SCSSCacher = \OC::$server->query(SCSSCacher::class);
328
+        } else {
329
+            $SCSSCacher = null;
330
+        }
331
+
332
+        $locator = new \OC\Template\CSSResourceLocator(
333
+            \OC::$server->getLogger(),
334
+            $theme,
335
+            [ \OC::$SERVERROOT => \OC::$WEBROOT ],
336
+            [ \OC::$SERVERROOT => \OC::$WEBROOT ],
337
+            $SCSSCacher
338
+        );
339
+        $locator->find($styles);
340
+        return $locator->getResources();
341
+    }
342
+
343
+    /**
344
+     * @param string $path
345
+     * @return string|boolean
346
+     */
347
+    public function getAppNamefromPath($path) {
348
+        if ($path !== '' && is_string($path)) {
349
+            $pathParts = explode('/', $path);
350
+            if ($pathParts[0] === 'css') {
351
+                // This is a scss request
352
+                return $pathParts[1];
353
+            }
354
+            return end($pathParts);
355
+        }
356
+        return false;
357
+    }
358
+
359
+    /**
360
+     * @param array $scripts
361
+     * @return array
362
+     */
363
+    public static function findJavascriptFiles($scripts) {
364
+        // Read the selected theme from the config file
365
+        $theme = \OC_Util::getTheme();
366
+
367
+        $locator = new \OC\Template\JSResourceLocator(
368
+            \OC::$server->getLogger(),
369
+            $theme,
370
+            [ \OC::$SERVERROOT => \OC::$WEBROOT ],
371
+            [ \OC::$SERVERROOT => \OC::$WEBROOT ],
372
+            \OC::$server->query(JSCombiner::class)
373
+            );
374
+        $locator->find($scripts);
375
+        return $locator->getResources();
376
+    }
377
+
378
+    /**
379
+     * Converts the absolute file path to a relative path from \OC::$SERVERROOT
380
+     * @param string $filePath Absolute path
381
+     * @return string Relative path
382
+     * @throws \Exception If $filePath is not under \OC::$SERVERROOT
383
+     */
384
+    public static function convertToRelativePath($filePath) {
385
+        $relativePath = explode(\OC::$SERVERROOT, $filePath);
386
+        if (count($relativePath) !== 2) {
387
+            throw new \Exception('$filePath is not under the \OC::$SERVERROOT');
388
+        }
389
+
390
+        return $relativePath[1];
391
+    }
392 392
 }
Please login to merge, or discard this patch.
lib/private/legacy/OC_User.php 1 patch
Indentation   +340 added lines, -340 removed lines patch added patch discarded remove patch
@@ -59,344 +59,344 @@
 block discarded – undo
59 59
  *   logout()
60 60
  */
61 61
 class OC_User {
62
-	private static $_usedBackends = [];
63
-
64
-	private static $_setupedBackends = [];
65
-
66
-	// bool, stores if a user want to access a resource anonymously, e.g if they open a public link
67
-	private static $incognitoMode = false;
68
-
69
-	/**
70
-	 * Adds the backend to the list of used backends
71
-	 *
72
-	 * @param string|\OCP\UserInterface $backend default: database The backend to use for user management
73
-	 * @return bool
74
-	 *
75
-	 * Set the User Authentication Module
76
-	 * @suppress PhanDeprecatedFunction
77
-	 */
78
-	public static function useBackend($backend = 'database') {
79
-		if ($backend instanceof \OCP\UserInterface) {
80
-			self::$_usedBackends[get_class($backend)] = $backend;
81
-			\OC::$server->getUserManager()->registerBackend($backend);
82
-		} else {
83
-			// You'll never know what happens
84
-			if (null === $backend or !is_string($backend)) {
85
-				$backend = 'database';
86
-			}
87
-
88
-			// Load backend
89
-			switch ($backend) {
90
-				case 'database':
91
-				case 'mysql':
92
-				case 'sqlite':
93
-					\OCP\Util::writeLog('core', 'Adding user backend ' . $backend . '.', ILogger::DEBUG);
94
-					self::$_usedBackends[$backend] = new \OC\User\Database();
95
-					\OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
96
-					break;
97
-				case 'dummy':
98
-					self::$_usedBackends[$backend] = new \Test\Util\User\Dummy();
99
-					\OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
100
-					break;
101
-				default:
102
-					\OCP\Util::writeLog('core', 'Adding default user backend ' . $backend . '.', ILogger::DEBUG);
103
-					$className = 'OC_USER_' . strtoupper($backend);
104
-					self::$_usedBackends[$backend] = new $className();
105
-					\OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
106
-					break;
107
-			}
108
-		}
109
-		return true;
110
-	}
111
-
112
-	/**
113
-	 * remove all used backends
114
-	 */
115
-	public static function clearBackends() {
116
-		self::$_usedBackends = [];
117
-		\OC::$server->getUserManager()->clearBackends();
118
-	}
119
-
120
-	/**
121
-	 * setup the configured backends in config.php
122
-	 * @suppress PhanDeprecatedFunction
123
-	 */
124
-	public static function setupBackends() {
125
-		OC_App::loadApps(['prelogin']);
126
-		$backends = \OC::$server->getSystemConfig()->getValue('user_backends', []);
127
-		if (isset($backends['default']) && !$backends['default']) {
128
-			// clear default backends
129
-			self::clearBackends();
130
-		}
131
-		foreach ($backends as $i => $config) {
132
-			if (!is_array($config)) {
133
-				continue;
134
-			}
135
-			$class = $config['class'];
136
-			$arguments = $config['arguments'];
137
-			if (class_exists($class)) {
138
-				if (array_search($i, self::$_setupedBackends) === false) {
139
-					// make a reflection object
140
-					$reflectionObj = new ReflectionClass($class);
141
-
142
-					// use Reflection to create a new instance, using the $args
143
-					$backend = $reflectionObj->newInstanceArgs($arguments);
144
-					self::useBackend($backend);
145
-					self::$_setupedBackends[] = $i;
146
-				} else {
147
-					\OCP\Util::writeLog('core', 'User backend ' . $class . ' already initialized.', ILogger::DEBUG);
148
-				}
149
-			} else {
150
-				\OCP\Util::writeLog('core', 'User backend ' . $class . ' not found.', ILogger::ERROR);
151
-			}
152
-		}
153
-	}
154
-
155
-	/**
156
-	 * Try to login a user, assuming authentication
157
-	 * has already happened (e.g. via Single Sign On).
158
-	 *
159
-	 * Log in a user and regenerate a new session.
160
-	 *
161
-	 * @param \OCP\Authentication\IApacheBackend $backend
162
-	 * @return bool
163
-	 */
164
-	public static function loginWithApache(\OCP\Authentication\IApacheBackend $backend) {
165
-		$uid = $backend->getCurrentUserId();
166
-		$run = true;
167
-		OC_Hook::emit("OC_User", "pre_login", ["run" => &$run, "uid" => $uid, 'backend' => $backend]);
168
-
169
-		if ($uid) {
170
-			if (self::getUser() !== $uid) {
171
-				self::setUserId($uid);
172
-				$userSession = \OC::$server->getUserSession();
173
-				$userSession->setLoginName($uid);
174
-				$request = OC::$server->getRequest();
175
-				$userSession->createSessionToken($request, $uid, $uid);
176
-				// setup the filesystem
177
-				OC_Util::setupFS($uid);
178
-				// first call the post_login hooks, the login-process needs to be
179
-				// completed before we can safely create the users folder.
180
-				// For example encryption needs to initialize the users keys first
181
-				// before we can create the user folder with the skeleton files
182
-				OC_Hook::emit(
183
-					'OC_User',
184
-					'post_login',
185
-					[
186
-						'uid' => $uid,
187
-						'password' => '',
188
-						'isTokenLogin' => false,
189
-					]
190
-				);
191
-				/** @var IEventDispatcher $dispatcher */
192
-				$dispatcher = \OC::$server->get(IEventDispatcher::class);
193
-				$dispatcher->dispatchTyped(new UserLoggedInEvent(
194
-						\OC::$server->get(IUserManager::class)->get($uid),
195
-						$uid,
196
-						'',
197
-						false)
198
-				);
199
-
200
-				//trigger creation of user home and /files folder
201
-				\OC::$server->getUserFolder($uid);
202
-			}
203
-			return true;
204
-		}
205
-		return false;
206
-	}
207
-
208
-	/**
209
-	 * Verify with Apache whether user is authenticated.
210
-	 *
211
-	 * @return boolean|null
212
-	 *          true: authenticated
213
-	 *          false: not authenticated
214
-	 *          null: not handled / no backend available
215
-	 */
216
-	public static function handleApacheAuth() {
217
-		$backend = self::findFirstActiveUsedBackend();
218
-		if ($backend) {
219
-			OC_App::loadApps();
220
-
221
-			//setup extra user backends
222
-			self::setupBackends();
223
-			\OC::$server->getUserSession()->unsetMagicInCookie();
224
-
225
-			return self::loginWithApache($backend);
226
-		}
227
-
228
-		return null;
229
-	}
230
-
231
-
232
-	/**
233
-	 * Sets user id for session and triggers emit
234
-	 *
235
-	 * @param string $uid
236
-	 */
237
-	public static function setUserId($uid) {
238
-		$userSession = \OC::$server->getUserSession();
239
-		$userManager = \OC::$server->getUserManager();
240
-		if ($user = $userManager->get($uid)) {
241
-			$userSession->setUser($user);
242
-		} else {
243
-			\OC::$server->getSession()->set('user_id', $uid);
244
-		}
245
-	}
246
-
247
-	/**
248
-	 * Check if the user is logged in, considers also the HTTP basic credentials
249
-	 *
250
-	 * @deprecated use \OC::$server->getUserSession()->isLoggedIn()
251
-	 * @return bool
252
-	 */
253
-	public static function isLoggedIn() {
254
-		return \OC::$server->getUserSession()->isLoggedIn();
255
-	}
256
-
257
-	/**
258
-	 * set incognito mode, e.g. if a user wants to open a public link
259
-	 *
260
-	 * @param bool $status
261
-	 */
262
-	public static function setIncognitoMode($status) {
263
-		self::$incognitoMode = $status;
264
-	}
265
-
266
-	/**
267
-	 * get incognito mode status
268
-	 *
269
-	 * @return bool
270
-	 */
271
-	public static function isIncognitoMode() {
272
-		return self::$incognitoMode;
273
-	}
274
-
275
-	/**
276
-	 * Returns the current logout URL valid for the currently logged-in user
277
-	 *
278
-	 * @param \OCP\IURLGenerator $urlGenerator
279
-	 * @return string
280
-	 */
281
-	public static function getLogoutUrl(\OCP\IURLGenerator $urlGenerator) {
282
-		$backend = self::findFirstActiveUsedBackend();
283
-		if ($backend) {
284
-			return $backend->getLogoutUrl();
285
-		}
286
-
287
-		$user = \OC::$server->getUserSession()->getUser();
288
-		if ($user instanceof \OCP\IUser) {
289
-			$backend = $user->getBackend();
290
-			if ($backend instanceof \OCP\User\Backend\ICustomLogout) {
291
-				return $backend->getLogoutUrl();
292
-			}
293
-		}
294
-
295
-		$logoutUrl = $urlGenerator->linkToRoute('core.login.logout');
296
-		$logoutUrl .= '?requesttoken=' . urlencode(\OCP\Util::callRegister());
297
-
298
-		return $logoutUrl;
299
-	}
300
-
301
-	/**
302
-	 * Check if the user is an admin user
303
-	 *
304
-	 * @param string $uid uid of the admin
305
-	 * @return bool
306
-	 */
307
-	public static function isAdminUser($uid) {
308
-		$group = \OC::$server->getGroupManager()->get('admin');
309
-		$user = \OC::$server->getUserManager()->get($uid);
310
-		if ($group && $user && $group->inGroup($user) && self::$incognitoMode === false) {
311
-			return true;
312
-		}
313
-		return false;
314
-	}
315
-
316
-
317
-	/**
318
-	 * get the user id of the user currently logged in.
319
-	 *
320
-	 * @return string|bool uid or false
321
-	 */
322
-	public static function getUser() {
323
-		$uid = \OC::$server->getSession() ? \OC::$server->getSession()->get('user_id') : null;
324
-		if (!is_null($uid) && self::$incognitoMode === false) {
325
-			return $uid;
326
-		} else {
327
-			return false;
328
-		}
329
-	}
330
-
331
-	/**
332
-	 * Set password
333
-	 *
334
-	 * @param string $uid The username
335
-	 * @param string $password The new password
336
-	 * @param string $recoveryPassword for the encryption app to reset encryption keys
337
-	 * @return bool
338
-	 *
339
-	 * Change the password of a user
340
-	 */
341
-	public static function setPassword($uid, $password, $recoveryPassword = null) {
342
-		$user = \OC::$server->getUserManager()->get($uid);
343
-		if ($user) {
344
-			return $user->setPassword($password, $recoveryPassword);
345
-		} else {
346
-			return false;
347
-		}
348
-	}
349
-
350
-	/**
351
-	 * @param string $uid The username
352
-	 * @return string
353
-	 *
354
-	 * returns the path to the users home directory
355
-	 * @deprecated Use \OC::$server->getUserManager->getHome()
356
-	 */
357
-	public static function getHome($uid) {
358
-		$user = \OC::$server->getUserManager()->get($uid);
359
-		if ($user) {
360
-			return $user->getHome();
361
-		} else {
362
-			return \OC::$server->getSystemConfig()->getValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $uid;
363
-		}
364
-	}
365
-
366
-	/**
367
-	 * Get a list of all users display name
368
-	 *
369
-	 * @param string $search
370
-	 * @param int $limit
371
-	 * @param int $offset
372
-	 * @return array associative array with all display names (value) and corresponding uids (key)
373
-	 *
374
-	 * Get a list of all display names and user ids.
375
-	 * @deprecated Use \OC::$server->getUserManager->searchDisplayName($search, $limit, $offset) instead.
376
-	 */
377
-	public static function getDisplayNames($search = '', $limit = null, $offset = null) {
378
-		$displayNames = [];
379
-		$users = \OC::$server->getUserManager()->searchDisplayName($search, $limit, $offset);
380
-		foreach ($users as $user) {
381
-			$displayNames[$user->getUID()] = $user->getDisplayName();
382
-		}
383
-		return $displayNames;
384
-	}
385
-
386
-	/**
387
-	 * Returns the first active backend from self::$_usedBackends.
388
-	 *
389
-	 * @return OCP\Authentication\IApacheBackend|null if no backend active, otherwise OCP\Authentication\IApacheBackend
390
-	 */
391
-	private static function findFirstActiveUsedBackend() {
392
-		foreach (self::$_usedBackends as $backend) {
393
-			if ($backend instanceof OCP\Authentication\IApacheBackend) {
394
-				if ($backend->isSessionActive()) {
395
-					return $backend;
396
-				}
397
-			}
398
-		}
399
-
400
-		return null;
401
-	}
62
+    private static $_usedBackends = [];
63
+
64
+    private static $_setupedBackends = [];
65
+
66
+    // bool, stores if a user want to access a resource anonymously, e.g if they open a public link
67
+    private static $incognitoMode = false;
68
+
69
+    /**
70
+     * Adds the backend to the list of used backends
71
+     *
72
+     * @param string|\OCP\UserInterface $backend default: database The backend to use for user management
73
+     * @return bool
74
+     *
75
+     * Set the User Authentication Module
76
+     * @suppress PhanDeprecatedFunction
77
+     */
78
+    public static function useBackend($backend = 'database') {
79
+        if ($backend instanceof \OCP\UserInterface) {
80
+            self::$_usedBackends[get_class($backend)] = $backend;
81
+            \OC::$server->getUserManager()->registerBackend($backend);
82
+        } else {
83
+            // You'll never know what happens
84
+            if (null === $backend or !is_string($backend)) {
85
+                $backend = 'database';
86
+            }
87
+
88
+            // Load backend
89
+            switch ($backend) {
90
+                case 'database':
91
+                case 'mysql':
92
+                case 'sqlite':
93
+                    \OCP\Util::writeLog('core', 'Adding user backend ' . $backend . '.', ILogger::DEBUG);
94
+                    self::$_usedBackends[$backend] = new \OC\User\Database();
95
+                    \OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
96
+                    break;
97
+                case 'dummy':
98
+                    self::$_usedBackends[$backend] = new \Test\Util\User\Dummy();
99
+                    \OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
100
+                    break;
101
+                default:
102
+                    \OCP\Util::writeLog('core', 'Adding default user backend ' . $backend . '.', ILogger::DEBUG);
103
+                    $className = 'OC_USER_' . strtoupper($backend);
104
+                    self::$_usedBackends[$backend] = new $className();
105
+                    \OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
106
+                    break;
107
+            }
108
+        }
109
+        return true;
110
+    }
111
+
112
+    /**
113
+     * remove all used backends
114
+     */
115
+    public static function clearBackends() {
116
+        self::$_usedBackends = [];
117
+        \OC::$server->getUserManager()->clearBackends();
118
+    }
119
+
120
+    /**
121
+     * setup the configured backends in config.php
122
+     * @suppress PhanDeprecatedFunction
123
+     */
124
+    public static function setupBackends() {
125
+        OC_App::loadApps(['prelogin']);
126
+        $backends = \OC::$server->getSystemConfig()->getValue('user_backends', []);
127
+        if (isset($backends['default']) && !$backends['default']) {
128
+            // clear default backends
129
+            self::clearBackends();
130
+        }
131
+        foreach ($backends as $i => $config) {
132
+            if (!is_array($config)) {
133
+                continue;
134
+            }
135
+            $class = $config['class'];
136
+            $arguments = $config['arguments'];
137
+            if (class_exists($class)) {
138
+                if (array_search($i, self::$_setupedBackends) === false) {
139
+                    // make a reflection object
140
+                    $reflectionObj = new ReflectionClass($class);
141
+
142
+                    // use Reflection to create a new instance, using the $args
143
+                    $backend = $reflectionObj->newInstanceArgs($arguments);
144
+                    self::useBackend($backend);
145
+                    self::$_setupedBackends[] = $i;
146
+                } else {
147
+                    \OCP\Util::writeLog('core', 'User backend ' . $class . ' already initialized.', ILogger::DEBUG);
148
+                }
149
+            } else {
150
+                \OCP\Util::writeLog('core', 'User backend ' . $class . ' not found.', ILogger::ERROR);
151
+            }
152
+        }
153
+    }
154
+
155
+    /**
156
+     * Try to login a user, assuming authentication
157
+     * has already happened (e.g. via Single Sign On).
158
+     *
159
+     * Log in a user and regenerate a new session.
160
+     *
161
+     * @param \OCP\Authentication\IApacheBackend $backend
162
+     * @return bool
163
+     */
164
+    public static function loginWithApache(\OCP\Authentication\IApacheBackend $backend) {
165
+        $uid = $backend->getCurrentUserId();
166
+        $run = true;
167
+        OC_Hook::emit("OC_User", "pre_login", ["run" => &$run, "uid" => $uid, 'backend' => $backend]);
168
+
169
+        if ($uid) {
170
+            if (self::getUser() !== $uid) {
171
+                self::setUserId($uid);
172
+                $userSession = \OC::$server->getUserSession();
173
+                $userSession->setLoginName($uid);
174
+                $request = OC::$server->getRequest();
175
+                $userSession->createSessionToken($request, $uid, $uid);
176
+                // setup the filesystem
177
+                OC_Util::setupFS($uid);
178
+                // first call the post_login hooks, the login-process needs to be
179
+                // completed before we can safely create the users folder.
180
+                // For example encryption needs to initialize the users keys first
181
+                // before we can create the user folder with the skeleton files
182
+                OC_Hook::emit(
183
+                    'OC_User',
184
+                    'post_login',
185
+                    [
186
+                        'uid' => $uid,
187
+                        'password' => '',
188
+                        'isTokenLogin' => false,
189
+                    ]
190
+                );
191
+                /** @var IEventDispatcher $dispatcher */
192
+                $dispatcher = \OC::$server->get(IEventDispatcher::class);
193
+                $dispatcher->dispatchTyped(new UserLoggedInEvent(
194
+                        \OC::$server->get(IUserManager::class)->get($uid),
195
+                        $uid,
196
+                        '',
197
+                        false)
198
+                );
199
+
200
+                //trigger creation of user home and /files folder
201
+                \OC::$server->getUserFolder($uid);
202
+            }
203
+            return true;
204
+        }
205
+        return false;
206
+    }
207
+
208
+    /**
209
+     * Verify with Apache whether user is authenticated.
210
+     *
211
+     * @return boolean|null
212
+     *          true: authenticated
213
+     *          false: not authenticated
214
+     *          null: not handled / no backend available
215
+     */
216
+    public static function handleApacheAuth() {
217
+        $backend = self::findFirstActiveUsedBackend();
218
+        if ($backend) {
219
+            OC_App::loadApps();
220
+
221
+            //setup extra user backends
222
+            self::setupBackends();
223
+            \OC::$server->getUserSession()->unsetMagicInCookie();
224
+
225
+            return self::loginWithApache($backend);
226
+        }
227
+
228
+        return null;
229
+    }
230
+
231
+
232
+    /**
233
+     * Sets user id for session and triggers emit
234
+     *
235
+     * @param string $uid
236
+     */
237
+    public static function setUserId($uid) {
238
+        $userSession = \OC::$server->getUserSession();
239
+        $userManager = \OC::$server->getUserManager();
240
+        if ($user = $userManager->get($uid)) {
241
+            $userSession->setUser($user);
242
+        } else {
243
+            \OC::$server->getSession()->set('user_id', $uid);
244
+        }
245
+    }
246
+
247
+    /**
248
+     * Check if the user is logged in, considers also the HTTP basic credentials
249
+     *
250
+     * @deprecated use \OC::$server->getUserSession()->isLoggedIn()
251
+     * @return bool
252
+     */
253
+    public static function isLoggedIn() {
254
+        return \OC::$server->getUserSession()->isLoggedIn();
255
+    }
256
+
257
+    /**
258
+     * set incognito mode, e.g. if a user wants to open a public link
259
+     *
260
+     * @param bool $status
261
+     */
262
+    public static function setIncognitoMode($status) {
263
+        self::$incognitoMode = $status;
264
+    }
265
+
266
+    /**
267
+     * get incognito mode status
268
+     *
269
+     * @return bool
270
+     */
271
+    public static function isIncognitoMode() {
272
+        return self::$incognitoMode;
273
+    }
274
+
275
+    /**
276
+     * Returns the current logout URL valid for the currently logged-in user
277
+     *
278
+     * @param \OCP\IURLGenerator $urlGenerator
279
+     * @return string
280
+     */
281
+    public static function getLogoutUrl(\OCP\IURLGenerator $urlGenerator) {
282
+        $backend = self::findFirstActiveUsedBackend();
283
+        if ($backend) {
284
+            return $backend->getLogoutUrl();
285
+        }
286
+
287
+        $user = \OC::$server->getUserSession()->getUser();
288
+        if ($user instanceof \OCP\IUser) {
289
+            $backend = $user->getBackend();
290
+            if ($backend instanceof \OCP\User\Backend\ICustomLogout) {
291
+                return $backend->getLogoutUrl();
292
+            }
293
+        }
294
+
295
+        $logoutUrl = $urlGenerator->linkToRoute('core.login.logout');
296
+        $logoutUrl .= '?requesttoken=' . urlencode(\OCP\Util::callRegister());
297
+
298
+        return $logoutUrl;
299
+    }
300
+
301
+    /**
302
+     * Check if the user is an admin user
303
+     *
304
+     * @param string $uid uid of the admin
305
+     * @return bool
306
+     */
307
+    public static function isAdminUser($uid) {
308
+        $group = \OC::$server->getGroupManager()->get('admin');
309
+        $user = \OC::$server->getUserManager()->get($uid);
310
+        if ($group && $user && $group->inGroup($user) && self::$incognitoMode === false) {
311
+            return true;
312
+        }
313
+        return false;
314
+    }
315
+
316
+
317
+    /**
318
+     * get the user id of the user currently logged in.
319
+     *
320
+     * @return string|bool uid or false
321
+     */
322
+    public static function getUser() {
323
+        $uid = \OC::$server->getSession() ? \OC::$server->getSession()->get('user_id') : null;
324
+        if (!is_null($uid) && self::$incognitoMode === false) {
325
+            return $uid;
326
+        } else {
327
+            return false;
328
+        }
329
+    }
330
+
331
+    /**
332
+     * Set password
333
+     *
334
+     * @param string $uid The username
335
+     * @param string $password The new password
336
+     * @param string $recoveryPassword for the encryption app to reset encryption keys
337
+     * @return bool
338
+     *
339
+     * Change the password of a user
340
+     */
341
+    public static function setPassword($uid, $password, $recoveryPassword = null) {
342
+        $user = \OC::$server->getUserManager()->get($uid);
343
+        if ($user) {
344
+            return $user->setPassword($password, $recoveryPassword);
345
+        } else {
346
+            return false;
347
+        }
348
+    }
349
+
350
+    /**
351
+     * @param string $uid The username
352
+     * @return string
353
+     *
354
+     * returns the path to the users home directory
355
+     * @deprecated Use \OC::$server->getUserManager->getHome()
356
+     */
357
+    public static function getHome($uid) {
358
+        $user = \OC::$server->getUserManager()->get($uid);
359
+        if ($user) {
360
+            return $user->getHome();
361
+        } else {
362
+            return \OC::$server->getSystemConfig()->getValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $uid;
363
+        }
364
+    }
365
+
366
+    /**
367
+     * Get a list of all users display name
368
+     *
369
+     * @param string $search
370
+     * @param int $limit
371
+     * @param int $offset
372
+     * @return array associative array with all display names (value) and corresponding uids (key)
373
+     *
374
+     * Get a list of all display names and user ids.
375
+     * @deprecated Use \OC::$server->getUserManager->searchDisplayName($search, $limit, $offset) instead.
376
+     */
377
+    public static function getDisplayNames($search = '', $limit = null, $offset = null) {
378
+        $displayNames = [];
379
+        $users = \OC::$server->getUserManager()->searchDisplayName($search, $limit, $offset);
380
+        foreach ($users as $user) {
381
+            $displayNames[$user->getUID()] = $user->getDisplayName();
382
+        }
383
+        return $displayNames;
384
+    }
385
+
386
+    /**
387
+     * Returns the first active backend from self::$_usedBackends.
388
+     *
389
+     * @return OCP\Authentication\IApacheBackend|null if no backend active, otherwise OCP\Authentication\IApacheBackend
390
+     */
391
+    private static function findFirstActiveUsedBackend() {
392
+        foreach (self::$_usedBackends as $backend) {
393
+            if ($backend instanceof OCP\Authentication\IApacheBackend) {
394
+                if ($backend->isSessionActive()) {
395
+                    return $backend;
396
+                }
397
+            }
398
+        }
399
+
400
+        return null;
401
+    }
402 402
 }
Please login to merge, or discard this patch.