Completed
Pull Request — master (#10031)
by Blizzz
18:14 queued 01:24
created
lib/private/Encryption/Util.php 2 patches
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
 		$this->config = $config;
97 97
 
98 98
 		$this->excludedPaths[] = 'files_encryption';
99
-		$this->excludedPaths[] = 'appdata_' . $config->getSystemValue('instanceid', null);
99
+		$this->excludedPaths[] = 'appdata_'.$config->getSystemValue('instanceid', null);
100 100
 		$this->excludedPaths[] = 'files_external';
101 101
 	}
102 102
 
@@ -136,12 +136,12 @@  discard block
 block discarded – undo
136 136
 	 * @throws EncryptionHeaderKeyExistsException if header key is already in use
137 137
 	 */
138 138
 	public function createHeader(array $headerData, IEncryptionModule $encryptionModule) {
139
-		$header = self::HEADER_START . ':' . self::HEADER_ENCRYPTION_MODULE_KEY . ':' . $encryptionModule->getId() . ':';
139
+		$header = self::HEADER_START.':'.self::HEADER_ENCRYPTION_MODULE_KEY.':'.$encryptionModule->getId().':';
140 140
 		foreach ($headerData as $key => $value) {
141 141
 			if (in_array($key, $this->ocHeaderKeys)) {
142 142
 				throw new EncryptionHeaderKeyExistsException($key);
143 143
 			}
144
-			$header .= $key . ':' . $value . ':';
144
+			$header .= $key.':'.$value.':';
145 145
 		}
146 146
 		$header .= self::HEADER_END;
147 147
 
@@ -172,7 +172,7 @@  discard block
 block discarded – undo
172 172
 				if ($c->getType() === 'dir') {
173 173
 					$dirList[] = $c->getPath();
174 174
 				} else {
175
-					$result[] =  $c->getPath();
175
+					$result[] = $c->getPath();
176 176
 				}
177 177
 			}
178 178
 
@@ -249,15 +249,15 @@  discard block
 block discarded – undo
249 249
 	public function stripPartialFileExtension($path) {
250 250
 		$extension = pathinfo($path, PATHINFO_EXTENSION);
251 251
 
252
-		if ( $extension === 'part') {
252
+		if ($extension === 'part') {
253 253
 
254 254
 			$newLength = strlen($path) - 5; // 5 = strlen(".part")
255 255
 			$fPath = substr($path, 0, $newLength);
256 256
 
257 257
 			// if path also contains a transaction id, we remove it too
258 258
 			$extension = pathinfo($fPath, PATHINFO_EXTENSION);
259
-			if(substr($extension, 0, 12) === 'ocTransferId') { // 12 = strlen("ocTransferId")
260
-				$newLength = strlen($fPath) - strlen($extension) -1;
259
+			if (substr($extension, 0, 12) === 'ocTransferId') { // 12 = strlen("ocTransferId")
260
+				$newLength = strlen($fPath) - strlen($extension) - 1;
261 261
 				$fPath = substr($fPath, 0, $newLength);
262 262
 			}
263 263
 			return $fPath;
@@ -301,7 +301,7 @@  discard block
 block discarded – undo
301 301
 		if (\OCP\App::isEnabled("files_external")) {
302 302
 			$mounts = \OC_Mount_Config::getSystemMountPoints();
303 303
 			foreach ($mounts as $mount) {
304
-				if (strpos($path, '/files/' . $mount['mountpoint']) === 0) {
304
+				if (strpos($path, '/files/'.$mount['mountpoint']) === 0) {
305 305
 					if ($this->isMountPointApplicableToUser($mount, $uid)) {
306 306
 						return true;
307 307
 					}
Please login to merge, or discard this patch.
Indentation   +369 added lines, -369 removed lines patch added patch discarded remove patch
@@ -39,374 +39,374 @@
 block discarded – undo
39 39
 
40 40
 class Util {
41 41
 
42
-	const HEADER_START = 'HBEGIN';
43
-	const HEADER_END = 'HEND';
44
-	const HEADER_PADDING_CHAR = '-';
45
-
46
-	const HEADER_ENCRYPTION_MODULE_KEY = 'oc_encryption_module';
47
-
48
-	/**
49
-	 * block size will always be 8192 for a PHP stream
50
-	 * @see https://bugs.php.net/bug.php?id=21641
51
-	 * @var integer
52
-	 */
53
-	protected $headerSize = 8192;
54
-
55
-	/**
56
-	 * block size will always be 8192 for a PHP stream
57
-	 * @see https://bugs.php.net/bug.php?id=21641
58
-	 * @var integer
59
-	 */
60
-	protected $blockSize = 8192;
61
-
62
-	/** @var View */
63
-	protected $rootView;
64
-
65
-	/** @var array */
66
-	protected $ocHeaderKeys;
67
-
68
-	/** @var \OC\User\Manager */
69
-	protected $userManager;
70
-
71
-	/** @var IConfig */
72
-	protected $config;
73
-
74
-	/** @var array paths excluded from encryption */
75
-	protected $excludedPaths;
76
-
77
-	/** @var \OC\Group\Manager $manager */
78
-	protected $groupManager;
79
-
80
-	/**
81
-	 *
82
-	 * @param View $rootView
83
-	 * @param \OC\User\Manager $userManager
84
-	 * @param \OC\Group\Manager $groupManager
85
-	 * @param IConfig $config
86
-	 */
87
-	public function __construct(
88
-		View $rootView,
89
-		\OC\User\Manager $userManager,
90
-		\OC\Group\Manager $groupManager,
91
-		IConfig $config) {
92
-
93
-		$this->ocHeaderKeys = [
94
-			self::HEADER_ENCRYPTION_MODULE_KEY
95
-		];
96
-
97
-		$this->rootView = $rootView;
98
-		$this->userManager = $userManager;
99
-		$this->groupManager = $groupManager;
100
-		$this->config = $config;
101
-
102
-		$this->excludedPaths[] = 'files_encryption';
103
-		$this->excludedPaths[] = 'appdata_' . $config->getSystemValue('instanceid', null);
104
-		$this->excludedPaths[] = 'files_external';
105
-	}
106
-
107
-	/**
108
-	 * read encryption module ID from header
109
-	 *
110
-	 * @param array $header
111
-	 * @return string
112
-	 * @throws ModuleDoesNotExistsException
113
-	 */
114
-	public function getEncryptionModuleId(array $header = null) {
115
-		$id = '';
116
-		$encryptionModuleKey = self::HEADER_ENCRYPTION_MODULE_KEY;
117
-
118
-		if (isset($header[$encryptionModuleKey])) {
119
-			$id = $header[$encryptionModuleKey];
120
-		} elseif (isset($header['cipher'])) {
121
-			if (class_exists('\OCA\Encryption\Crypto\Encryption')) {
122
-				// fall back to default encryption if the user migrated from
123
-				// ownCloud <= 8.0 with the old encryption
124
-				$id = \OCA\Encryption\Crypto\Encryption::ID;
125
-			} else {
126
-				throw new ModuleDoesNotExistsException('Default encryption module missing');
127
-			}
128
-		}
129
-
130
-		return $id;
131
-	}
132
-
133
-	/**
134
-	 * create header for encrypted file
135
-	 *
136
-	 * @param array $headerData
137
-	 * @param IEncryptionModule $encryptionModule
138
-	 * @return string
139
-	 * @throws EncryptionHeaderToLargeException if header has to many arguments
140
-	 * @throws EncryptionHeaderKeyExistsException if header key is already in use
141
-	 */
142
-	public function createHeader(array $headerData, IEncryptionModule $encryptionModule) {
143
-		$header = self::HEADER_START . ':' . self::HEADER_ENCRYPTION_MODULE_KEY . ':' . $encryptionModule->getId() . ':';
144
-		foreach ($headerData as $key => $value) {
145
-			if (in_array($key, $this->ocHeaderKeys)) {
146
-				throw new EncryptionHeaderKeyExistsException($key);
147
-			}
148
-			$header .= $key . ':' . $value . ':';
149
-		}
150
-		$header .= self::HEADER_END;
151
-
152
-		if (strlen($header) > $this->getHeaderSize()) {
153
-			throw new EncryptionHeaderToLargeException();
154
-		}
155
-
156
-		$paddedHeader = str_pad($header, $this->headerSize, self::HEADER_PADDING_CHAR, STR_PAD_RIGHT);
157
-
158
-		return $paddedHeader;
159
-	}
160
-
161
-	/**
162
-	 * go recursively through a dir and collect all files and sub files.
163
-	 *
164
-	 * @param string $dir relative to the users files folder
165
-	 * @return array with list of files relative to the users files folder
166
-	 */
167
-	public function getAllFiles($dir) {
168
-		$result = array();
169
-		$dirList = array($dir);
170
-
171
-		while ($dirList) {
172
-			$dir = array_pop($dirList);
173
-			$content = $this->rootView->getDirectoryContent($dir);
174
-
175
-			foreach ($content as $c) {
176
-				if ($c->getType() === 'dir') {
177
-					$dirList[] = $c->getPath();
178
-				} else {
179
-					$result[] =  $c->getPath();
180
-				}
181
-			}
182
-
183
-		}
184
-
185
-		return $result;
186
-	}
187
-
188
-	/**
189
-	 * check if it is a file uploaded by the user stored in data/user/files
190
-	 * or a metadata file
191
-	 *
192
-	 * @param string $path relative to the data/ folder
193
-	 * @return boolean
194
-	 */
195
-	public function isFile($path) {
196
-		$parts = explode('/', Filesystem::normalizePath($path), 4);
197
-		if (isset($parts[2]) && $parts[2] === 'files') {
198
-			return true;
199
-		}
200
-		return false;
201
-	}
202
-
203
-	/**
204
-	 * return size of encryption header
205
-	 *
206
-	 * @return integer
207
-	 */
208
-	public function getHeaderSize() {
209
-		return $this->headerSize;
210
-	}
211
-
212
-	/**
213
-	 * return size of block read by a PHP stream
214
-	 *
215
-	 * @return integer
216
-	 */
217
-	public function getBlockSize() {
218
-		return $this->blockSize;
219
-	}
220
-
221
-	/**
222
-	 * get the owner and the path for the file relative to the owners files folder
223
-	 *
224
-	 * @param string $path
225
-	 * @return array
226
-	 * @throws \BadMethodCallException
227
-	 */
228
-	public function getUidAndFilename($path) {
229
-
230
-		$parts = explode('/', $path);
231
-		$uid = '';
232
-		if (count($parts) > 2) {
233
-			$uid = $parts[1];
234
-		}
235
-		if (!$this->userManager->userExists($uid)) {
236
-			throw new \BadMethodCallException(
237
-				'path needs to be relative to the system wide data folder and point to a user specific file'
238
-			);
239
-		}
240
-
241
-		$ownerPath = implode('/', array_slice($parts, 2));
242
-
243
-		return array($uid, Filesystem::normalizePath($ownerPath));
244
-
245
-	}
246
-
247
-	/**
248
-	 * Remove .path extension from a file path
249
-	 * @param string $path Path that may identify a .part file
250
-	 * @return string File path without .part extension
251
-	 * @note this is needed for reusing keys
252
-	 */
253
-	public function stripPartialFileExtension($path) {
254
-		$extension = pathinfo($path, PATHINFO_EXTENSION);
255
-
256
-		if ( $extension === 'part') {
257
-
258
-			$newLength = strlen($path) - 5; // 5 = strlen(".part")
259
-			$fPath = substr($path, 0, $newLength);
260
-
261
-			// if path also contains a transaction id, we remove it too
262
-			$extension = pathinfo($fPath, PATHINFO_EXTENSION);
263
-			if(substr($extension, 0, 12) === 'ocTransferId') { // 12 = strlen("ocTransferId")
264
-				$newLength = strlen($fPath) - strlen($extension) -1;
265
-				$fPath = substr($fPath, 0, $newLength);
266
-			}
267
-			return $fPath;
268
-
269
-		} else {
270
-			return $path;
271
-		}
272
-	}
273
-
274
-	public function getUserWithAccessToMountPoint($users, $groups) {
275
-		$result = [];
276
-		if (in_array('all', $users)) {
277
-			$users = $this->userManager->search('', null, null);
278
-			$result = array_map(function(IUser $user) {
279
-				return $user->getUID();
280
-			}, $users);
281
-		} else {
282
-			$result = array_merge($result, $users);
283
-
284
-			$groupManager = \OC::$server->getGroupManager();
285
-			foreach ($groups as $group) {
286
-				$groupObject = $groupManager->get($group);
287
-				if ($groupObject) {
288
-					$foundUsers = $groupObject->searchUsers('', -1, 0);
289
-					$userIds = [];
290
-					foreach ($foundUsers as $user) {
291
-						$userIds[] = $user->getUID();
292
-					}
293
-					$result = array_merge($result, $userIds);
294
-				}
295
-			}
296
-		}
297
-
298
-		return $result;
299
-	}
300
-
301
-	/**
302
-	 * check if the file is stored on a system wide mount point
303
-	 * @param string $path relative to /data/user with leading '/'
304
-	 * @param string $uid
305
-	 * @return boolean
306
-	 */
307
-	public function isSystemWideMountPoint($path, $uid) {
308
-		if (\OCP\App::isEnabled("files_external")) {
309
-			$mounts = \OC_Mount_Config::getSystemMountPoints();
310
-			foreach ($mounts as $mount) {
311
-				if (strpos($path, '/files/' . $mount['mountpoint']) === 0) {
312
-					if ($this->isMountPointApplicableToUser($mount, $uid)) {
313
-						return true;
314
-					}
315
-				}
316
-			}
317
-		}
318
-		return false;
319
-	}
320
-
321
-	/**
322
-	 * check if mount point is applicable to user
323
-	 *
324
-	 * @param array $mount contains $mount['applicable']['users'], $mount['applicable']['groups']
325
-	 * @param string $uid
326
-	 * @return boolean
327
-	 */
328
-	private function isMountPointApplicableToUser($mount, $uid) {
329
-		$acceptedUids = array('all', $uid);
330
-		// check if mount point is applicable for the user
331
-		$intersection = array_intersect($acceptedUids, $mount['applicable']['users']);
332
-		if (!empty($intersection)) {
333
-			return true;
334
-		}
335
-		// check if mount point is applicable for group where the user is a member
336
-		foreach ($mount['applicable']['groups'] as $gid) {
337
-			if ($this->groupManager->isInGroup($uid, $gid)) {
338
-				return true;
339
-			}
340
-		}
341
-		return false;
342
-	}
343
-
344
-	/**
345
-	 * check if it is a path which is excluded by ownCloud from encryption
346
-	 *
347
-	 * @param string $path
348
-	 * @return boolean
349
-	 */
350
-	public function isExcluded($path) {
351
-		$normalizedPath = Filesystem::normalizePath($path);
352
-		$root = explode('/', $normalizedPath, 4);
353
-		if (count($root) > 1) {
354
-
355
-			// detect alternative key storage root
356
-			$rootDir = $this->getKeyStorageRoot();
357
-			if ($rootDir !== '' &&
358
-				0 === strpos(
359
-					Filesystem::normalizePath($path),
360
-					Filesystem::normalizePath($rootDir)
361
-				)
362
-			) {
363
-				return true;
364
-			}
365
-
366
-
367
-			//detect system wide folders
368
-			if (in_array($root[1], $this->excludedPaths)) {
369
-				return true;
370
-			}
371
-
372
-			// detect user specific folders
373
-			if ($this->userManager->userExists($root[1])
374
-				&& in_array($root[2], $this->excludedPaths)) {
375
-
376
-				return true;
377
-			}
378
-		}
379
-		return false;
380
-	}
381
-
382
-	/**
383
-	 * check if recovery key is enabled for user
384
-	 *
385
-	 * @param string $uid
386
-	 * @return boolean
387
-	 */
388
-	public function recoveryEnabled($uid) {
389
-		$enabled = $this->config->getUserValue($uid, 'encryption', 'recovery_enabled', '0');
390
-
391
-		return $enabled === '1';
392
-	}
393
-
394
-	/**
395
-	 * set new key storage root
396
-	 *
397
-	 * @param string $root new key store root relative to the data folder
398
-	 */
399
-	public function setKeyStorageRoot($root) {
400
-		$this->config->setAppValue('core', 'encryption_key_storage_root', $root);
401
-	}
402
-
403
-	/**
404
-	 * get key storage root
405
-	 *
406
-	 * @return string key storage root
407
-	 */
408
-	public function getKeyStorageRoot() {
409
-		return $this->config->getAppValue('core', 'encryption_key_storage_root', '');
410
-	}
42
+    const HEADER_START = 'HBEGIN';
43
+    const HEADER_END = 'HEND';
44
+    const HEADER_PADDING_CHAR = '-';
45
+
46
+    const HEADER_ENCRYPTION_MODULE_KEY = 'oc_encryption_module';
47
+
48
+    /**
49
+     * block size will always be 8192 for a PHP stream
50
+     * @see https://bugs.php.net/bug.php?id=21641
51
+     * @var integer
52
+     */
53
+    protected $headerSize = 8192;
54
+
55
+    /**
56
+     * block size will always be 8192 for a PHP stream
57
+     * @see https://bugs.php.net/bug.php?id=21641
58
+     * @var integer
59
+     */
60
+    protected $blockSize = 8192;
61
+
62
+    /** @var View */
63
+    protected $rootView;
64
+
65
+    /** @var array */
66
+    protected $ocHeaderKeys;
67
+
68
+    /** @var \OC\User\Manager */
69
+    protected $userManager;
70
+
71
+    /** @var IConfig */
72
+    protected $config;
73
+
74
+    /** @var array paths excluded from encryption */
75
+    protected $excludedPaths;
76
+
77
+    /** @var \OC\Group\Manager $manager */
78
+    protected $groupManager;
79
+
80
+    /**
81
+     *
82
+     * @param View $rootView
83
+     * @param \OC\User\Manager $userManager
84
+     * @param \OC\Group\Manager $groupManager
85
+     * @param IConfig $config
86
+     */
87
+    public function __construct(
88
+        View $rootView,
89
+        \OC\User\Manager $userManager,
90
+        \OC\Group\Manager $groupManager,
91
+        IConfig $config) {
92
+
93
+        $this->ocHeaderKeys = [
94
+            self::HEADER_ENCRYPTION_MODULE_KEY
95
+        ];
96
+
97
+        $this->rootView = $rootView;
98
+        $this->userManager = $userManager;
99
+        $this->groupManager = $groupManager;
100
+        $this->config = $config;
101
+
102
+        $this->excludedPaths[] = 'files_encryption';
103
+        $this->excludedPaths[] = 'appdata_' . $config->getSystemValue('instanceid', null);
104
+        $this->excludedPaths[] = 'files_external';
105
+    }
106
+
107
+    /**
108
+     * read encryption module ID from header
109
+     *
110
+     * @param array $header
111
+     * @return string
112
+     * @throws ModuleDoesNotExistsException
113
+     */
114
+    public function getEncryptionModuleId(array $header = null) {
115
+        $id = '';
116
+        $encryptionModuleKey = self::HEADER_ENCRYPTION_MODULE_KEY;
117
+
118
+        if (isset($header[$encryptionModuleKey])) {
119
+            $id = $header[$encryptionModuleKey];
120
+        } elseif (isset($header['cipher'])) {
121
+            if (class_exists('\OCA\Encryption\Crypto\Encryption')) {
122
+                // fall back to default encryption if the user migrated from
123
+                // ownCloud <= 8.0 with the old encryption
124
+                $id = \OCA\Encryption\Crypto\Encryption::ID;
125
+            } else {
126
+                throw new ModuleDoesNotExistsException('Default encryption module missing');
127
+            }
128
+        }
129
+
130
+        return $id;
131
+    }
132
+
133
+    /**
134
+     * create header for encrypted file
135
+     *
136
+     * @param array $headerData
137
+     * @param IEncryptionModule $encryptionModule
138
+     * @return string
139
+     * @throws EncryptionHeaderToLargeException if header has to many arguments
140
+     * @throws EncryptionHeaderKeyExistsException if header key is already in use
141
+     */
142
+    public function createHeader(array $headerData, IEncryptionModule $encryptionModule) {
143
+        $header = self::HEADER_START . ':' . self::HEADER_ENCRYPTION_MODULE_KEY . ':' . $encryptionModule->getId() . ':';
144
+        foreach ($headerData as $key => $value) {
145
+            if (in_array($key, $this->ocHeaderKeys)) {
146
+                throw new EncryptionHeaderKeyExistsException($key);
147
+            }
148
+            $header .= $key . ':' . $value . ':';
149
+        }
150
+        $header .= self::HEADER_END;
151
+
152
+        if (strlen($header) > $this->getHeaderSize()) {
153
+            throw new EncryptionHeaderToLargeException();
154
+        }
155
+
156
+        $paddedHeader = str_pad($header, $this->headerSize, self::HEADER_PADDING_CHAR, STR_PAD_RIGHT);
157
+
158
+        return $paddedHeader;
159
+    }
160
+
161
+    /**
162
+     * go recursively through a dir and collect all files and sub files.
163
+     *
164
+     * @param string $dir relative to the users files folder
165
+     * @return array with list of files relative to the users files folder
166
+     */
167
+    public function getAllFiles($dir) {
168
+        $result = array();
169
+        $dirList = array($dir);
170
+
171
+        while ($dirList) {
172
+            $dir = array_pop($dirList);
173
+            $content = $this->rootView->getDirectoryContent($dir);
174
+
175
+            foreach ($content as $c) {
176
+                if ($c->getType() === 'dir') {
177
+                    $dirList[] = $c->getPath();
178
+                } else {
179
+                    $result[] =  $c->getPath();
180
+                }
181
+            }
182
+
183
+        }
184
+
185
+        return $result;
186
+    }
187
+
188
+    /**
189
+     * check if it is a file uploaded by the user stored in data/user/files
190
+     * or a metadata file
191
+     *
192
+     * @param string $path relative to the data/ folder
193
+     * @return boolean
194
+     */
195
+    public function isFile($path) {
196
+        $parts = explode('/', Filesystem::normalizePath($path), 4);
197
+        if (isset($parts[2]) && $parts[2] === 'files') {
198
+            return true;
199
+        }
200
+        return false;
201
+    }
202
+
203
+    /**
204
+     * return size of encryption header
205
+     *
206
+     * @return integer
207
+     */
208
+    public function getHeaderSize() {
209
+        return $this->headerSize;
210
+    }
211
+
212
+    /**
213
+     * return size of block read by a PHP stream
214
+     *
215
+     * @return integer
216
+     */
217
+    public function getBlockSize() {
218
+        return $this->blockSize;
219
+    }
220
+
221
+    /**
222
+     * get the owner and the path for the file relative to the owners files folder
223
+     *
224
+     * @param string $path
225
+     * @return array
226
+     * @throws \BadMethodCallException
227
+     */
228
+    public function getUidAndFilename($path) {
229
+
230
+        $parts = explode('/', $path);
231
+        $uid = '';
232
+        if (count($parts) > 2) {
233
+            $uid = $parts[1];
234
+        }
235
+        if (!$this->userManager->userExists($uid)) {
236
+            throw new \BadMethodCallException(
237
+                'path needs to be relative to the system wide data folder and point to a user specific file'
238
+            );
239
+        }
240
+
241
+        $ownerPath = implode('/', array_slice($parts, 2));
242
+
243
+        return array($uid, Filesystem::normalizePath($ownerPath));
244
+
245
+    }
246
+
247
+    /**
248
+     * Remove .path extension from a file path
249
+     * @param string $path Path that may identify a .part file
250
+     * @return string File path without .part extension
251
+     * @note this is needed for reusing keys
252
+     */
253
+    public function stripPartialFileExtension($path) {
254
+        $extension = pathinfo($path, PATHINFO_EXTENSION);
255
+
256
+        if ( $extension === 'part') {
257
+
258
+            $newLength = strlen($path) - 5; // 5 = strlen(".part")
259
+            $fPath = substr($path, 0, $newLength);
260
+
261
+            // if path also contains a transaction id, we remove it too
262
+            $extension = pathinfo($fPath, PATHINFO_EXTENSION);
263
+            if(substr($extension, 0, 12) === 'ocTransferId') { // 12 = strlen("ocTransferId")
264
+                $newLength = strlen($fPath) - strlen($extension) -1;
265
+                $fPath = substr($fPath, 0, $newLength);
266
+            }
267
+            return $fPath;
268
+
269
+        } else {
270
+            return $path;
271
+        }
272
+    }
273
+
274
+    public function getUserWithAccessToMountPoint($users, $groups) {
275
+        $result = [];
276
+        if (in_array('all', $users)) {
277
+            $users = $this->userManager->search('', null, null);
278
+            $result = array_map(function(IUser $user) {
279
+                return $user->getUID();
280
+            }, $users);
281
+        } else {
282
+            $result = array_merge($result, $users);
283
+
284
+            $groupManager = \OC::$server->getGroupManager();
285
+            foreach ($groups as $group) {
286
+                $groupObject = $groupManager->get($group);
287
+                if ($groupObject) {
288
+                    $foundUsers = $groupObject->searchUsers('', -1, 0);
289
+                    $userIds = [];
290
+                    foreach ($foundUsers as $user) {
291
+                        $userIds[] = $user->getUID();
292
+                    }
293
+                    $result = array_merge($result, $userIds);
294
+                }
295
+            }
296
+        }
297
+
298
+        return $result;
299
+    }
300
+
301
+    /**
302
+     * check if the file is stored on a system wide mount point
303
+     * @param string $path relative to /data/user with leading '/'
304
+     * @param string $uid
305
+     * @return boolean
306
+     */
307
+    public function isSystemWideMountPoint($path, $uid) {
308
+        if (\OCP\App::isEnabled("files_external")) {
309
+            $mounts = \OC_Mount_Config::getSystemMountPoints();
310
+            foreach ($mounts as $mount) {
311
+                if (strpos($path, '/files/' . $mount['mountpoint']) === 0) {
312
+                    if ($this->isMountPointApplicableToUser($mount, $uid)) {
313
+                        return true;
314
+                    }
315
+                }
316
+            }
317
+        }
318
+        return false;
319
+    }
320
+
321
+    /**
322
+     * check if mount point is applicable to user
323
+     *
324
+     * @param array $mount contains $mount['applicable']['users'], $mount['applicable']['groups']
325
+     * @param string $uid
326
+     * @return boolean
327
+     */
328
+    private function isMountPointApplicableToUser($mount, $uid) {
329
+        $acceptedUids = array('all', $uid);
330
+        // check if mount point is applicable for the user
331
+        $intersection = array_intersect($acceptedUids, $mount['applicable']['users']);
332
+        if (!empty($intersection)) {
333
+            return true;
334
+        }
335
+        // check if mount point is applicable for group where the user is a member
336
+        foreach ($mount['applicable']['groups'] as $gid) {
337
+            if ($this->groupManager->isInGroup($uid, $gid)) {
338
+                return true;
339
+            }
340
+        }
341
+        return false;
342
+    }
343
+
344
+    /**
345
+     * check if it is a path which is excluded by ownCloud from encryption
346
+     *
347
+     * @param string $path
348
+     * @return boolean
349
+     */
350
+    public function isExcluded($path) {
351
+        $normalizedPath = Filesystem::normalizePath($path);
352
+        $root = explode('/', $normalizedPath, 4);
353
+        if (count($root) > 1) {
354
+
355
+            // detect alternative key storage root
356
+            $rootDir = $this->getKeyStorageRoot();
357
+            if ($rootDir !== '' &&
358
+                0 === strpos(
359
+                    Filesystem::normalizePath($path),
360
+                    Filesystem::normalizePath($rootDir)
361
+                )
362
+            ) {
363
+                return true;
364
+            }
365
+
366
+
367
+            //detect system wide folders
368
+            if (in_array($root[1], $this->excludedPaths)) {
369
+                return true;
370
+            }
371
+
372
+            // detect user specific folders
373
+            if ($this->userManager->userExists($root[1])
374
+                && in_array($root[2], $this->excludedPaths)) {
375
+
376
+                return true;
377
+            }
378
+        }
379
+        return false;
380
+    }
381
+
382
+    /**
383
+     * check if recovery key is enabled for user
384
+     *
385
+     * @param string $uid
386
+     * @return boolean
387
+     */
388
+    public function recoveryEnabled($uid) {
389
+        $enabled = $this->config->getUserValue($uid, 'encryption', 'recovery_enabled', '0');
390
+
391
+        return $enabled === '1';
392
+    }
393
+
394
+    /**
395
+     * set new key storage root
396
+     *
397
+     * @param string $root new key store root relative to the data folder
398
+     */
399
+    public function setKeyStorageRoot($root) {
400
+        $this->config->setAppValue('core', 'encryption_key_storage_root', $root);
401
+    }
402
+
403
+    /**
404
+     * get key storage root
405
+     *
406
+     * @return string key storage root
407
+     */
408
+    public function getKeyStorageRoot() {
409
+        return $this->config->getAppValue('core', 'encryption_key_storage_root', '');
410
+    }
411 411
 
412 412
 }
Please login to merge, or discard this patch.
apps/federatedfilesharing/templates/settings-admin.php 2 patches
Braces   +16 added lines, -4 removed lines patch added patch discarded remove patch
@@ -15,7 +15,10 @@  discard block
 block discarded – undo
15 15
 
16 16
 	<p>
17 17
 		<input type="checkbox" name="outgoing_server2server_share_enabled" id="outgoingServer2serverShareEnabled" class="checkbox"
18
-			   value="1" <?php if ($_['outgoingServer2serverShareEnabled']) print_unescaped('checked="checked"'); ?> />
18
+			   value="1" <?php if ($_['outgoingServer2serverShareEnabled']) {
19
+    print_unescaped('checked="checked"');
20
+}
21
+?> />
19 22
 		<label for="outgoingServer2serverShareEnabled">
20 23
 			<?php p($l->t('Allow users on this server to send shares to other servers'));?>
21 24
 		</label>
@@ -23,21 +26,30 @@  discard block
 block discarded – undo
23 26
 
24 27
 	<p>
25 28
 		<input type="checkbox" name="incoming_server2server_share_enabled" id="incomingServer2serverShareEnabled" class="checkbox"
26
-			   value="1" <?php if ($_['incomingServer2serverShareEnabled']) print_unescaped('checked="checked"'); ?> />
29
+			   value="1" <?php if ($_['incomingServer2serverShareEnabled']) {
30
+    print_unescaped('checked="checked"');
31
+}
32
+?> />
27 33
 		<label for="incomingServer2serverShareEnabled">
28 34
 			<?php p($l->t('Allow users on this server to receive shares from other servers'));?>
29 35
 		</label><br/>
30 36
 	</p>
31 37
 	<p>
32 38
 		<input type="checkbox" name="lookupServerEnabled" id="lookupServerEnabled" class="checkbox"
33
-			   value="1" <?php if ($_['lookupServerEnabled']) print_unescaped('checked="checked"'); ?> />
39
+			   value="1" <?php if ($_['lookupServerEnabled']) {
40
+    print_unescaped('checked="checked"');
41
+}
42
+?> />
34 43
 		<label for="lookupServerEnabled">
35 44
 			<?php p($l->t('Search global and public address book for users'));?>
36 45
 		</label><br/>
37 46
 	</p>
38 47
 	<p>
39 48
 		<input type="checkbox" name="lookupServerUploadEnabled" id="lookupServerUploadEnabled" class="checkbox"
40
-			   value="1" <?php if ($_['lookupServerUploadEnabled']) print_unescaped('checked="checked"'); ?> />
49
+			   value="1" <?php if ($_['lookupServerUploadEnabled']) {
50
+    print_unescaped('checked="checked"');
51
+}
52
+?> />
41 53
 		<label for="lookupServerUploadEnabled">
42 54
 			<?php p($l->t('Allow users to publish their data to a global and public address book'));?>
43 55
 		</label><br/>
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -4,13 +4,13 @@  discard block
 block discarded – undo
4 4
 script('federatedfilesharing', 'settings-admin');
5 5
 ?>
6 6
 
7
-<?php if($_['internalOnly'] === false): ?>
7
+<?php if ($_['internalOnly'] === false): ?>
8 8
 
9 9
 <div id="fileSharingSettings" class="section">
10 10
 	<h2>
11
-		<?php p($l->t('Federated Cloud Sharing'));?>
11
+		<?php p($l->t('Federated Cloud Sharing')); ?>
12 12
 		<a target="_blank" rel="noreferrer noopener" class="icon-info svg"
13
-		   title="<?php p($l->t('Open documentation'));?>"
13
+		   title="<?php p($l->t('Open documentation')); ?>"
14 14
 		   href="<?php p(link_to_docs('admin-sharing-federated')); ?>"></a>
15 15
 	</h2>
16 16
 
@@ -20,7 +20,7 @@  discard block
 block discarded – undo
20 20
 		<input type="checkbox" name="outgoing_server2server_share_enabled" id="outgoingServer2serverShareEnabled" class="checkbox"
21 21
 			   value="1" <?php if ($_['outgoingServer2serverShareEnabled']) print_unescaped('checked="checked"'); ?> />
22 22
 		<label for="outgoingServer2serverShareEnabled">
23
-			<?php p($l->t('Allow users on this server to send shares to other servers'));?>
23
+			<?php p($l->t('Allow users on this server to send shares to other servers')); ?>
24 24
 		</label>
25 25
 	</p>
26 26
 
@@ -28,21 +28,21 @@  discard block
 block discarded – undo
28 28
 		<input type="checkbox" name="incoming_server2server_share_enabled" id="incomingServer2serverShareEnabled" class="checkbox"
29 29
 			   value="1" <?php if ($_['incomingServer2serverShareEnabled']) print_unescaped('checked="checked"'); ?> />
30 30
 		<label for="incomingServer2serverShareEnabled">
31
-			<?php p($l->t('Allow users on this server to receive shares from other servers'));?>
31
+			<?php p($l->t('Allow users on this server to receive shares from other servers')); ?>
32 32
 		</label><br/>
33 33
 	</p>
34 34
 	<p>
35 35
 		<input type="checkbox" name="lookupServerEnabled" id="lookupServerEnabled" class="checkbox"
36 36
 			   value="1" <?php if ($_['lookupServerEnabled']) print_unescaped('checked="checked"'); ?> />
37 37
 		<label for="lookupServerEnabled">
38
-			<?php p($l->t('Search global and public address book for users'));?>
38
+			<?php p($l->t('Search global and public address book for users')); ?>
39 39
 		</label><br/>
40 40
 	</p>
41 41
 	<p>
42 42
 		<input type="checkbox" name="lookupServerUploadEnabled" id="lookupServerUploadEnabled" class="checkbox"
43 43
 			   value="1" <?php if ($_['lookupServerUploadEnabled']) print_unescaped('checked="checked"'); ?> />
44 44
 		<label for="lookupServerUploadEnabled">
45
-			<?php p($l->t('Allow users to publish their data to a global and public address book'));?>
45
+			<?php p($l->t('Allow users to publish their data to a global and public address book')); ?>
46 46
 		</label><br/>
47 47
 	</p>
48 48
 
Please login to merge, or discard this patch.
lib/private/Comments/ManagerFactory.php 1 patch
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -30,33 +30,33 @@
 block discarded – undo
30 30
 
31 31
 class ManagerFactory implements ICommentsManagerFactory {
32 32
 
33
-	/**
34
-	 * Server container
35
-	 *
36
-	 * @var IServerContainer
37
-	 */
38
-	private $serverContainer;
33
+    /**
34
+     * Server container
35
+     *
36
+     * @var IServerContainer
37
+     */
38
+    private $serverContainer;
39 39
 
40
-	/**
41
-	 * Constructor for the comments manager factory
42
-	 *
43
-	 * @param IServerContainer $serverContainer server container
44
-	 */
45
-	public function __construct(IServerContainer $serverContainer) {
46
-		$this->serverContainer = $serverContainer;
47
-	}
40
+    /**
41
+     * Constructor for the comments manager factory
42
+     *
43
+     * @param IServerContainer $serverContainer server container
44
+     */
45
+    public function __construct(IServerContainer $serverContainer) {
46
+        $this->serverContainer = $serverContainer;
47
+    }
48 48
 
49
-	/**
50
-	 * creates and returns an instance of the ICommentsManager
51
-	 *
52
-	 * @return ICommentsManager
53
-	 * @since 9.0.0
54
-	 */
55
-	public function getManager() {
56
-		return new Manager(
57
-			$this->serverContainer->getDatabaseConnection(),
58
-			$this->serverContainer->getLogger(),
59
-			$this->serverContainer->getConfig()
60
-		);
61
-	}
49
+    /**
50
+     * creates and returns an instance of the ICommentsManager
51
+     *
52
+     * @return ICommentsManager
53
+     * @since 9.0.0
54
+     */
55
+    public function getManager() {
56
+        return new Manager(
57
+            $this->serverContainer->getDatabaseConnection(),
58
+            $this->serverContainer->getLogger(),
59
+            $this->serverContainer->getConfig()
60
+        );
61
+    }
62 62
 }
Please login to merge, or discard this patch.
apps/dav/lib/Connector/Sabre/CachingTree.php 1 patch
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -24,16 +24,16 @@
 block discarded – undo
24 24
 use Sabre\DAV\Tree;
25 25
 
26 26
 class CachingTree extends Tree {
27
-	/**
28
-	 * Store a node in the cache
29
-	 *
30
-	 * @param Node $node
31
-	 * @param null|string $path
32
-	 */
33
-	public function cacheNode(Node $node, $path = null) {
34
-		if (is_null($path)) {
35
-			$path = $node->getPath();
36
-		}
37
-		$this->cache[trim($path, '/')] = $node;
38
-	}
27
+    /**
28
+     * Store a node in the cache
29
+     *
30
+     * @param Node $node
31
+     * @param null|string $path
32
+     */
33
+    public function cacheNode(Node $node, $path = null) {
34
+        if (is_null($path)) {
35
+            $path = $node->getPath();
36
+        }
37
+        $this->cache[trim($path, '/')] = $node;
38
+    }
39 39
 }
Please login to merge, or discard this patch.
apps/dav/lib/Connector/Sabre/Server.php 1 patch
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -33,14 +33,14 @@
 block discarded – undo
33 33
  * @see \Sabre\DAV\Server
34 34
  */
35 35
 class Server extends \Sabre\DAV\Server {
36
-	/** @var CachingTree $tree */
36
+    /** @var CachingTree $tree */
37 37
 
38
-	/**
39
-	 * @see \Sabre\DAV\Server
40
-	 */
41
-	public function __construct($treeOrNode = null) {
42
-		parent::__construct($treeOrNode);
43
-		self::$exposeVersion = false;
44
-		$this->enablePropfindDepthInfinity = true;
45
-	}
38
+    /**
39
+     * @see \Sabre\DAV\Server
40
+     */
41
+    public function __construct($treeOrNode = null) {
42
+        parent::__construct($treeOrNode);
43
+        self::$exposeVersion = false;
44
+        $this->enablePropfindDepthInfinity = true;
45
+    }
46 46
 }
Please login to merge, or discard this patch.
settings/templates/settings/personal/security.php 2 patches
Indentation   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -22,10 +22,10 @@
 block discarded – undo
22 22
  */
23 23
 
24 24
 script('settings', [
25
-	'authtoken',
26
-	'authtoken_collection',
27
-	'authtoken_view',
28
-	'settings/authtoken-init'
25
+    'authtoken',
26
+    'authtoken_collection',
27
+    'authtoken_view',
28
+    'settings/authtoken-init'
29 29
 ]);
30 30
 
31 31
 ?>
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -32,14 +32,14 @@
 block discarded – undo
32 32
 
33 33
 
34 34
 <div id="security" class="section">
35
-	<h2><?php p($l->t('Devices & sessions'));?></h2>
36
-	<p class="settings-hint hidden-when-empty"><?php p($l->t('Web, desktop and mobile clients currently logged in to your account.'));?></p>
35
+	<h2><?php p($l->t('Devices & sessions')); ?></h2>
36
+	<p class="settings-hint hidden-when-empty"><?php p($l->t('Web, desktop and mobile clients currently logged in to your account.')); ?></p>
37 37
 	<table class="icon-loading">
38 38
 		<thead class="token-list-header">
39 39
 			<tr>
40 40
 				<th></th>
41
-				<th><?php p($l->t('Device'));?></th>
42
-				<th><?php p($l->t('Last activity'));?></th>
41
+				<th><?php p($l->t('Device')); ?></th>
42
+				<th><?php p($l->t('Last activity')); ?></th>
43 43
 				<th></th>
44 44
 			</tr>
45 45
 		</thead>
Please login to merge, or discard this patch.
lib/private/Settings/Personal/Security.php 1 patch
Indentation   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -29,31 +29,31 @@
 block discarded – undo
29 29
 
30 30
 class Security implements ISettings {
31 31
 
32
-	/**
33
-	 * @return TemplateResponse returns the instance with all parameters set, ready to be rendered
34
-	 * @since 9.1
35
-	 */
36
-	public function getForm() {
37
-		return new TemplateResponse('settings', 'settings/personal/security');
38
-	}
32
+    /**
33
+     * @return TemplateResponse returns the instance with all parameters set, ready to be rendered
34
+     * @since 9.1
35
+     */
36
+    public function getForm() {
37
+        return new TemplateResponse('settings', 'settings/personal/security');
38
+    }
39 39
 
40
-	/**
41
-	 * @return string the section ID, e.g. 'sharing'
42
-	 * @since 9.1
43
-	 */
44
-	public function getSection() {
45
-		return 'security';
46
-	}
40
+    /**
41
+     * @return string the section ID, e.g. 'sharing'
42
+     * @since 9.1
43
+     */
44
+    public function getSection() {
45
+        return 'security';
46
+    }
47 47
 
48
-	/**
49
-	 * @return int whether the form should be rather on the top or bottom of
50
-	 * the admin section. The forms are arranged in ascending order of the
51
-	 * priority values. It is required to return a value between 0 and 100.
52
-	 *
53
-	 * E.g.: 70
54
-	 * @since 9.1
55
-	 */
56
-	public function getPriority() {
57
-		return 10;
58
-	}
48
+    /**
49
+     * @return int whether the form should be rather on the top or bottom of
50
+     * the admin section. The forms are arranged in ascending order of the
51
+     * priority values. It is required to return a value between 0 and 100.
52
+     *
53
+     * E.g.: 70
54
+     * @since 9.1
55
+     */
56
+    public function getPriority() {
57
+        return 10;
58
+    }
59 59
 }
Please login to merge, or discard this patch.
lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php 2 patches
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -362,77 +362,77 @@
 block discarded – undo
362 362
 		$policy .= "base-uri 'none';";
363 363
 		$policy .= "manifest-src 'self';";
364 364
 
365
-		if(!empty($this->allowedScriptDomains) || $this->inlineScriptAllowed || $this->evalScriptAllowed) {
365
+		if (!empty($this->allowedScriptDomains) || $this->inlineScriptAllowed || $this->evalScriptAllowed) {
366 366
 			$policy .= 'script-src ';
367
-			if(is_string($this->useJsNonce)) {
367
+			if (is_string($this->useJsNonce)) {
368 368
 				$policy .= '\'nonce-'.base64_encode($this->useJsNonce).'\'';
369 369
 				$allowedScriptDomains = array_flip($this->allowedScriptDomains);
370 370
 				unset($allowedScriptDomains['\'self\'']);
371 371
 				$this->allowedScriptDomains = array_flip($allowedScriptDomains);
372
-				if(count($allowedScriptDomains) !== 0) {
372
+				if (count($allowedScriptDomains) !== 0) {
373 373
 					$policy .= ' ';
374 374
 				}
375 375
 			}
376
-			if(is_array($this->allowedScriptDomains)) {
376
+			if (is_array($this->allowedScriptDomains)) {
377 377
 				$policy .= implode(' ', $this->allowedScriptDomains);
378 378
 			}
379
-			if($this->inlineScriptAllowed) {
379
+			if ($this->inlineScriptAllowed) {
380 380
 				$policy .= ' \'unsafe-inline\'';
381 381
 			}
382
-			if($this->evalScriptAllowed) {
382
+			if ($this->evalScriptAllowed) {
383 383
 				$policy .= ' \'unsafe-eval\'';
384 384
 			}
385 385
 			$policy .= ';';
386 386
 		}
387 387
 
388
-		if(!empty($this->allowedStyleDomains) || $this->inlineStyleAllowed) {
388
+		if (!empty($this->allowedStyleDomains) || $this->inlineStyleAllowed) {
389 389
 			$policy .= 'style-src ';
390
-			if(is_array($this->allowedStyleDomains)) {
390
+			if (is_array($this->allowedStyleDomains)) {
391 391
 				$policy .= implode(' ', $this->allowedStyleDomains);
392 392
 			}
393
-			if($this->inlineStyleAllowed) {
393
+			if ($this->inlineStyleAllowed) {
394 394
 				$policy .= ' \'unsafe-inline\'';
395 395
 			}
396 396
 			$policy .= ';';
397 397
 		}
398 398
 
399
-		if(!empty($this->allowedImageDomains)) {
400
-			$policy .= 'img-src ' . implode(' ', $this->allowedImageDomains);
399
+		if (!empty($this->allowedImageDomains)) {
400
+			$policy .= 'img-src '.implode(' ', $this->allowedImageDomains);
401 401
 			$policy .= ';';
402 402
 		}
403 403
 
404
-		if(!empty($this->allowedFontDomains)) {
405
-			$policy .= 'font-src ' . implode(' ', $this->allowedFontDomains);
404
+		if (!empty($this->allowedFontDomains)) {
405
+			$policy .= 'font-src '.implode(' ', $this->allowedFontDomains);
406 406
 			$policy .= ';';
407 407
 		}
408 408
 
409
-		if(!empty($this->allowedConnectDomains)) {
410
-			$policy .= 'connect-src ' . implode(' ', $this->allowedConnectDomains);
409
+		if (!empty($this->allowedConnectDomains)) {
410
+			$policy .= 'connect-src '.implode(' ', $this->allowedConnectDomains);
411 411
 			$policy .= ';';
412 412
 		}
413 413
 
414
-		if(!empty($this->allowedMediaDomains)) {
415
-			$policy .= 'media-src ' . implode(' ', $this->allowedMediaDomains);
414
+		if (!empty($this->allowedMediaDomains)) {
415
+			$policy .= 'media-src '.implode(' ', $this->allowedMediaDomains);
416 416
 			$policy .= ';';
417 417
 		}
418 418
 
419
-		if(!empty($this->allowedObjectDomains)) {
420
-			$policy .= 'object-src ' . implode(' ', $this->allowedObjectDomains);
419
+		if (!empty($this->allowedObjectDomains)) {
420
+			$policy .= 'object-src '.implode(' ', $this->allowedObjectDomains);
421 421
 			$policy .= ';';
422 422
 		}
423 423
 
424
-		if(!empty($this->allowedFrameDomains)) {
425
-			$policy .= 'frame-src ' . implode(' ', $this->allowedFrameDomains);
424
+		if (!empty($this->allowedFrameDomains)) {
425
+			$policy .= 'frame-src '.implode(' ', $this->allowedFrameDomains);
426 426
 			$policy .= ';';
427 427
 		}
428 428
 
429
-		if(!empty($this->allowedChildSrcDomains)) {
430
-			$policy .= 'child-src ' . implode(' ', $this->allowedChildSrcDomains);
429
+		if (!empty($this->allowedChildSrcDomains)) {
430
+			$policy .= 'child-src '.implode(' ', $this->allowedChildSrcDomains);
431 431
 			$policy .= ';';
432 432
 		}
433 433
 
434
-		if(!empty($this->allowedFrameAncestors)) {
435
-			$policy .= 'frame-ancestors ' . implode(' ', $this->allowedFrameAncestors);
434
+		if (!empty($this->allowedFrameAncestors)) {
435
+			$policy .= 'frame-ancestors '.implode(' ', $this->allowedFrameAncestors);
436 436
 			$policy .= ';';
437 437
 		}
438 438
 
Please login to merge, or discard this patch.
Indentation   +404 added lines, -404 removed lines patch added patch discarded remove patch
@@ -34,408 +34,408 @@
 block discarded – undo
34 34
  * @since 9.0.0
35 35
  */
36 36
 class EmptyContentSecurityPolicy {
37
-	/** @var bool Whether inline JS snippets are allowed */
38
-	protected $inlineScriptAllowed = null;
39
-	/** @var string Whether JS nonces should be used */
40
-	protected $useJsNonce = null;
41
-	/**
42
-	 * @var bool Whether eval in JS scripts is allowed
43
-	 * TODO: Disallow per default
44
-	 * @link https://github.com/owncloud/core/issues/11925
45
-	 */
46
-	protected $evalScriptAllowed = null;
47
-	/** @var array Domains from which scripts can get loaded */
48
-	protected $allowedScriptDomains = null;
49
-	/**
50
-	 * @var bool Whether inline CSS is allowed
51
-	 * TODO: Disallow per default
52
-	 * @link https://github.com/owncloud/core/issues/13458
53
-	 */
54
-	protected $inlineStyleAllowed = null;
55
-	/** @var array Domains from which CSS can get loaded */
56
-	protected $allowedStyleDomains = null;
57
-	/** @var array Domains from which images can get loaded */
58
-	protected $allowedImageDomains = null;
59
-	/** @var array Domains to which connections can be done */
60
-	protected $allowedConnectDomains = null;
61
-	/** @var array Domains from which media elements can be loaded */
62
-	protected $allowedMediaDomains = null;
63
-	/** @var array Domains from which object elements can be loaded */
64
-	protected $allowedObjectDomains = null;
65
-	/** @var array Domains from which iframes can be loaded */
66
-	protected $allowedFrameDomains = null;
67
-	/** @var array Domains from which fonts can be loaded */
68
-	protected $allowedFontDomains = null;
69
-	/** @var array Domains from which web-workers and nested browsing content can load elements */
70
-	protected $allowedChildSrcDomains = null;
71
-	/** @var array Domains which can embed this Nextcloud instance */
72
-	protected $allowedFrameAncestors = null;
73
-
74
-	/**
75
-	 * Whether inline JavaScript snippets are allowed or forbidden
76
-	 * @param bool $state
77
-	 * @return $this
78
-	 * @since 8.1.0
79
-	 * @deprecated 10.0 CSP tokens are now used
80
-	 */
81
-	public function allowInlineScript($state = false) {
82
-		$this->inlineScriptAllowed = $state;
83
-		return $this;
84
-	}
85
-
86
-	/**
87
-	 * Use the according JS nonce
88
-	 *
89
-	 * @param string $nonce
90
-	 * @return $this
91
-	 * @since 11.0.0
92
-	 */
93
-	public function useJsNonce($nonce) {
94
-		$this->useJsNonce = $nonce;
95
-		return $this;
96
-	}
97
-
98
-	/**
99
-	 * Whether eval in JavaScript is allowed or forbidden
100
-	 * @param bool $state
101
-	 * @return $this
102
-	 * @since 8.1.0
103
-	 */
104
-	public function allowEvalScript($state = true) {
105
-		$this->evalScriptAllowed = $state;
106
-		return $this;
107
-	}
108
-
109
-	/**
110
-	 * Allows to execute JavaScript files from a specific domain. Use * to
111
-	 * allow JavaScript from all domains.
112
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
113
-	 * @return $this
114
-	 * @since 8.1.0
115
-	 */
116
-	public function addAllowedScriptDomain($domain) {
117
-		$this->allowedScriptDomains[] = $domain;
118
-		return $this;
119
-	}
120
-
121
-	/**
122
-	 * Remove the specified allowed script domain from the allowed domains.
123
-	 *
124
-	 * @param string $domain
125
-	 * @return $this
126
-	 * @since 8.1.0
127
-	 */
128
-	public function disallowScriptDomain($domain) {
129
-		$this->allowedScriptDomains = array_diff($this->allowedScriptDomains, [$domain]);
130
-		return $this;
131
-	}
132
-
133
-	/**
134
-	 * Whether inline CSS snippets are allowed or forbidden
135
-	 * @param bool $state
136
-	 * @return $this
137
-	 * @since 8.1.0
138
-	 */
139
-	public function allowInlineStyle($state = true) {
140
-		$this->inlineStyleAllowed = $state;
141
-		return $this;
142
-	}
143
-
144
-	/**
145
-	 * Allows to execute CSS files from a specific domain. Use * to allow
146
-	 * CSS from all domains.
147
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
148
-	 * @return $this
149
-	 * @since 8.1.0
150
-	 */
151
-	public function addAllowedStyleDomain($domain) {
152
-		$this->allowedStyleDomains[] = $domain;
153
-		return $this;
154
-	}
155
-
156
-	/**
157
-	 * Remove the specified allowed style domain from the allowed domains.
158
-	 *
159
-	 * @param string $domain
160
-	 * @return $this
161
-	 * @since 8.1.0
162
-	 */
163
-	public function disallowStyleDomain($domain) {
164
-		$this->allowedStyleDomains = array_diff($this->allowedStyleDomains, [$domain]);
165
-		return $this;
166
-	}
167
-
168
-	/**
169
-	 * Allows using fonts from a specific domain. Use * to allow
170
-	 * fonts from all domains.
171
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
172
-	 * @return $this
173
-	 * @since 8.1.0
174
-	 */
175
-	public function addAllowedFontDomain($domain) {
176
-		$this->allowedFontDomains[] = $domain;
177
-		return $this;
178
-	}
179
-
180
-	/**
181
-	 * Remove the specified allowed font domain from the allowed domains.
182
-	 *
183
-	 * @param string $domain
184
-	 * @return $this
185
-	 * @since 8.1.0
186
-	 */
187
-	public function disallowFontDomain($domain) {
188
-		$this->allowedFontDomains = array_diff($this->allowedFontDomains, [$domain]);
189
-		return $this;
190
-	}
191
-
192
-	/**
193
-	 * Allows embedding images from a specific domain. Use * to allow
194
-	 * images from all domains.
195
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
196
-	 * @return $this
197
-	 * @since 8.1.0
198
-	 */
199
-	public function addAllowedImageDomain($domain) {
200
-		$this->allowedImageDomains[] = $domain;
201
-		return $this;
202
-	}
203
-
204
-	/**
205
-	 * Remove the specified allowed image domain from the allowed domains.
206
-	 *
207
-	 * @param string $domain
208
-	 * @return $this
209
-	 * @since 8.1.0
210
-	 */
211
-	public function disallowImageDomain($domain) {
212
-		$this->allowedImageDomains = array_diff($this->allowedImageDomains, [$domain]);
213
-		return $this;
214
-	}
215
-
216
-	/**
217
-	 * To which remote domains the JS connect to.
218
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
219
-	 * @return $this
220
-	 * @since 8.1.0
221
-	 */
222
-	public function addAllowedConnectDomain($domain) {
223
-		$this->allowedConnectDomains[] = $domain;
224
-		return $this;
225
-	}
226
-
227
-	/**
228
-	 * Remove the specified allowed connect domain from the allowed domains.
229
-	 *
230
-	 * @param string $domain
231
-	 * @return $this
232
-	 * @since 8.1.0
233
-	 */
234
-	public function disallowConnectDomain($domain) {
235
-		$this->allowedConnectDomains = array_diff($this->allowedConnectDomains, [$domain]);
236
-		return $this;
237
-	}
238
-
239
-	/**
240
-	 * From which domains media elements can be embedded.
241
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
242
-	 * @return $this
243
-	 * @since 8.1.0
244
-	 */
245
-	public function addAllowedMediaDomain($domain) {
246
-		$this->allowedMediaDomains[] = $domain;
247
-		return $this;
248
-	}
249
-
250
-	/**
251
-	 * Remove the specified allowed media domain from the allowed domains.
252
-	 *
253
-	 * @param string $domain
254
-	 * @return $this
255
-	 * @since 8.1.0
256
-	 */
257
-	public function disallowMediaDomain($domain) {
258
-		$this->allowedMediaDomains = array_diff($this->allowedMediaDomains, [$domain]);
259
-		return $this;
260
-	}
261
-
262
-	/**
263
-	 * From which domains objects such as <object>, <embed> or <applet> are executed
264
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
265
-	 * @return $this
266
-	 * @since 8.1.0
267
-	 */
268
-	public function addAllowedObjectDomain($domain) {
269
-		$this->allowedObjectDomains[] = $domain;
270
-		return $this;
271
-	}
272
-
273
-	/**
274
-	 * Remove the specified allowed object domain from the allowed domains.
275
-	 *
276
-	 * @param string $domain
277
-	 * @return $this
278
-	 * @since 8.1.0
279
-	 */
280
-	public function disallowObjectDomain($domain) {
281
-		$this->allowedObjectDomains = array_diff($this->allowedObjectDomains, [$domain]);
282
-		return $this;
283
-	}
284
-
285
-	/**
286
-	 * Which domains can be embedded in an iframe
287
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
288
-	 * @return $this
289
-	 * @since 8.1.0
290
-	 */
291
-	public function addAllowedFrameDomain($domain) {
292
-		$this->allowedFrameDomains[] = $domain;
293
-		return $this;
294
-	}
295
-
296
-	/**
297
-	 * Remove the specified allowed frame domain from the allowed domains.
298
-	 *
299
-	 * @param string $domain
300
-	 * @return $this
301
-	 * @since 8.1.0
302
-	 */
303
-	public function disallowFrameDomain($domain) {
304
-		$this->allowedFrameDomains = array_diff($this->allowedFrameDomains, [$domain]);
305
-		return $this;
306
-	}
307
-
308
-	/**
309
-	 * Domains from which web-workers and nested browsing content can load elements
310
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
311
-	 * @return $this
312
-	 * @since 8.1.0
313
-	 */
314
-	public function addAllowedChildSrcDomain($domain) {
315
-		$this->allowedChildSrcDomains[] = $domain;
316
-		return $this;
317
-	}
318
-
319
-	/**
320
-	 * Remove the specified allowed child src domain from the allowed domains.
321
-	 *
322
-	 * @param string $domain
323
-	 * @return $this
324
-	 * @since 8.1.0
325
-	 */
326
-	public function disallowChildSrcDomain($domain) {
327
-		$this->allowedChildSrcDomains = array_diff($this->allowedChildSrcDomains, [$domain]);
328
-		return $this;
329
-	}
330
-
331
-	/**
332
-	 * Domains which can embed an iFrame of the Nextcloud instance
333
-	 *
334
-	 * @param string $domain
335
-	 * @return $this
336
-	 * @since 13.0.0
337
-	 */
338
-	public function addAllowedFrameAncestorDomain($domain) {
339
-		$this->allowedFrameAncestors[] = $domain;
340
-		return $this;
341
-	}
342
-
343
-	/**
344
-	 * Domains which can embed an iFrame of the Nextcloud instance
345
-	 *
346
-	 * @param string $domain
347
-	 * @return $this
348
-	 * @since 13.0.0
349
-	 */
350
-	public function disallowFrameAncestorDomain($domain) {
351
-		$this->allowedFrameAncestors = array_diff($this->allowedFrameAncestors, [$domain]);
352
-		return $this;
353
-	}
354
-
355
-	/**
356
-	 * Get the generated Content-Security-Policy as a string
357
-	 * @return string
358
-	 * @since 8.1.0
359
-	 */
360
-	public function buildPolicy() {
361
-		$policy = "default-src 'none';";
362
-		$policy .= "base-uri 'none';";
363
-		$policy .= "manifest-src 'self';";
364
-
365
-		if(!empty($this->allowedScriptDomains) || $this->inlineScriptAllowed || $this->evalScriptAllowed) {
366
-			$policy .= 'script-src ';
367
-			if(is_string($this->useJsNonce)) {
368
-				$policy .= '\'nonce-'.base64_encode($this->useJsNonce).'\'';
369
-				$allowedScriptDomains = array_flip($this->allowedScriptDomains);
370
-				unset($allowedScriptDomains['\'self\'']);
371
-				$this->allowedScriptDomains = array_flip($allowedScriptDomains);
372
-				if(count($allowedScriptDomains) !== 0) {
373
-					$policy .= ' ';
374
-				}
375
-			}
376
-			if(is_array($this->allowedScriptDomains)) {
377
-				$policy .= implode(' ', $this->allowedScriptDomains);
378
-			}
379
-			if($this->inlineScriptAllowed) {
380
-				$policy .= ' \'unsafe-inline\'';
381
-			}
382
-			if($this->evalScriptAllowed) {
383
-				$policy .= ' \'unsafe-eval\'';
384
-			}
385
-			$policy .= ';';
386
-		}
387
-
388
-		if(!empty($this->allowedStyleDomains) || $this->inlineStyleAllowed) {
389
-			$policy .= 'style-src ';
390
-			if(is_array($this->allowedStyleDomains)) {
391
-				$policy .= implode(' ', $this->allowedStyleDomains);
392
-			}
393
-			if($this->inlineStyleAllowed) {
394
-				$policy .= ' \'unsafe-inline\'';
395
-			}
396
-			$policy .= ';';
397
-		}
398
-
399
-		if(!empty($this->allowedImageDomains)) {
400
-			$policy .= 'img-src ' . implode(' ', $this->allowedImageDomains);
401
-			$policy .= ';';
402
-		}
403
-
404
-		if(!empty($this->allowedFontDomains)) {
405
-			$policy .= 'font-src ' . implode(' ', $this->allowedFontDomains);
406
-			$policy .= ';';
407
-		}
408
-
409
-		if(!empty($this->allowedConnectDomains)) {
410
-			$policy .= 'connect-src ' . implode(' ', $this->allowedConnectDomains);
411
-			$policy .= ';';
412
-		}
413
-
414
-		if(!empty($this->allowedMediaDomains)) {
415
-			$policy .= 'media-src ' . implode(' ', $this->allowedMediaDomains);
416
-			$policy .= ';';
417
-		}
418
-
419
-		if(!empty($this->allowedObjectDomains)) {
420
-			$policy .= 'object-src ' . implode(' ', $this->allowedObjectDomains);
421
-			$policy .= ';';
422
-		}
423
-
424
-		if(!empty($this->allowedFrameDomains)) {
425
-			$policy .= 'frame-src ' . implode(' ', $this->allowedFrameDomains);
426
-			$policy .= ';';
427
-		}
428
-
429
-		if(!empty($this->allowedChildSrcDomains)) {
430
-			$policy .= 'child-src ' . implode(' ', $this->allowedChildSrcDomains);
431
-			$policy .= ';';
432
-		}
433
-
434
-		if(!empty($this->allowedFrameAncestors)) {
435
-			$policy .= 'frame-ancestors ' . implode(' ', $this->allowedFrameAncestors);
436
-			$policy .= ';';
437
-		}
438
-
439
-		return rtrim($policy, ';');
440
-	}
37
+    /** @var bool Whether inline JS snippets are allowed */
38
+    protected $inlineScriptAllowed = null;
39
+    /** @var string Whether JS nonces should be used */
40
+    protected $useJsNonce = null;
41
+    /**
42
+     * @var bool Whether eval in JS scripts is allowed
43
+     * TODO: Disallow per default
44
+     * @link https://github.com/owncloud/core/issues/11925
45
+     */
46
+    protected $evalScriptAllowed = null;
47
+    /** @var array Domains from which scripts can get loaded */
48
+    protected $allowedScriptDomains = null;
49
+    /**
50
+     * @var bool Whether inline CSS is allowed
51
+     * TODO: Disallow per default
52
+     * @link https://github.com/owncloud/core/issues/13458
53
+     */
54
+    protected $inlineStyleAllowed = null;
55
+    /** @var array Domains from which CSS can get loaded */
56
+    protected $allowedStyleDomains = null;
57
+    /** @var array Domains from which images can get loaded */
58
+    protected $allowedImageDomains = null;
59
+    /** @var array Domains to which connections can be done */
60
+    protected $allowedConnectDomains = null;
61
+    /** @var array Domains from which media elements can be loaded */
62
+    protected $allowedMediaDomains = null;
63
+    /** @var array Domains from which object elements can be loaded */
64
+    protected $allowedObjectDomains = null;
65
+    /** @var array Domains from which iframes can be loaded */
66
+    protected $allowedFrameDomains = null;
67
+    /** @var array Domains from which fonts can be loaded */
68
+    protected $allowedFontDomains = null;
69
+    /** @var array Domains from which web-workers and nested browsing content can load elements */
70
+    protected $allowedChildSrcDomains = null;
71
+    /** @var array Domains which can embed this Nextcloud instance */
72
+    protected $allowedFrameAncestors = null;
73
+
74
+    /**
75
+     * Whether inline JavaScript snippets are allowed or forbidden
76
+     * @param bool $state
77
+     * @return $this
78
+     * @since 8.1.0
79
+     * @deprecated 10.0 CSP tokens are now used
80
+     */
81
+    public function allowInlineScript($state = false) {
82
+        $this->inlineScriptAllowed = $state;
83
+        return $this;
84
+    }
85
+
86
+    /**
87
+     * Use the according JS nonce
88
+     *
89
+     * @param string $nonce
90
+     * @return $this
91
+     * @since 11.0.0
92
+     */
93
+    public function useJsNonce($nonce) {
94
+        $this->useJsNonce = $nonce;
95
+        return $this;
96
+    }
97
+
98
+    /**
99
+     * Whether eval in JavaScript is allowed or forbidden
100
+     * @param bool $state
101
+     * @return $this
102
+     * @since 8.1.0
103
+     */
104
+    public function allowEvalScript($state = true) {
105
+        $this->evalScriptAllowed = $state;
106
+        return $this;
107
+    }
108
+
109
+    /**
110
+     * Allows to execute JavaScript files from a specific domain. Use * to
111
+     * allow JavaScript from all domains.
112
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
113
+     * @return $this
114
+     * @since 8.1.0
115
+     */
116
+    public function addAllowedScriptDomain($domain) {
117
+        $this->allowedScriptDomains[] = $domain;
118
+        return $this;
119
+    }
120
+
121
+    /**
122
+     * Remove the specified allowed script domain from the allowed domains.
123
+     *
124
+     * @param string $domain
125
+     * @return $this
126
+     * @since 8.1.0
127
+     */
128
+    public function disallowScriptDomain($domain) {
129
+        $this->allowedScriptDomains = array_diff($this->allowedScriptDomains, [$domain]);
130
+        return $this;
131
+    }
132
+
133
+    /**
134
+     * Whether inline CSS snippets are allowed or forbidden
135
+     * @param bool $state
136
+     * @return $this
137
+     * @since 8.1.0
138
+     */
139
+    public function allowInlineStyle($state = true) {
140
+        $this->inlineStyleAllowed = $state;
141
+        return $this;
142
+    }
143
+
144
+    /**
145
+     * Allows to execute CSS files from a specific domain. Use * to allow
146
+     * CSS from all domains.
147
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
148
+     * @return $this
149
+     * @since 8.1.0
150
+     */
151
+    public function addAllowedStyleDomain($domain) {
152
+        $this->allowedStyleDomains[] = $domain;
153
+        return $this;
154
+    }
155
+
156
+    /**
157
+     * Remove the specified allowed style domain from the allowed domains.
158
+     *
159
+     * @param string $domain
160
+     * @return $this
161
+     * @since 8.1.0
162
+     */
163
+    public function disallowStyleDomain($domain) {
164
+        $this->allowedStyleDomains = array_diff($this->allowedStyleDomains, [$domain]);
165
+        return $this;
166
+    }
167
+
168
+    /**
169
+     * Allows using fonts from a specific domain. Use * to allow
170
+     * fonts from all domains.
171
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
172
+     * @return $this
173
+     * @since 8.1.0
174
+     */
175
+    public function addAllowedFontDomain($domain) {
176
+        $this->allowedFontDomains[] = $domain;
177
+        return $this;
178
+    }
179
+
180
+    /**
181
+     * Remove the specified allowed font domain from the allowed domains.
182
+     *
183
+     * @param string $domain
184
+     * @return $this
185
+     * @since 8.1.0
186
+     */
187
+    public function disallowFontDomain($domain) {
188
+        $this->allowedFontDomains = array_diff($this->allowedFontDomains, [$domain]);
189
+        return $this;
190
+    }
191
+
192
+    /**
193
+     * Allows embedding images from a specific domain. Use * to allow
194
+     * images from all domains.
195
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
196
+     * @return $this
197
+     * @since 8.1.0
198
+     */
199
+    public function addAllowedImageDomain($domain) {
200
+        $this->allowedImageDomains[] = $domain;
201
+        return $this;
202
+    }
203
+
204
+    /**
205
+     * Remove the specified allowed image domain from the allowed domains.
206
+     *
207
+     * @param string $domain
208
+     * @return $this
209
+     * @since 8.1.0
210
+     */
211
+    public function disallowImageDomain($domain) {
212
+        $this->allowedImageDomains = array_diff($this->allowedImageDomains, [$domain]);
213
+        return $this;
214
+    }
215
+
216
+    /**
217
+     * To which remote domains the JS connect to.
218
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
219
+     * @return $this
220
+     * @since 8.1.0
221
+     */
222
+    public function addAllowedConnectDomain($domain) {
223
+        $this->allowedConnectDomains[] = $domain;
224
+        return $this;
225
+    }
226
+
227
+    /**
228
+     * Remove the specified allowed connect domain from the allowed domains.
229
+     *
230
+     * @param string $domain
231
+     * @return $this
232
+     * @since 8.1.0
233
+     */
234
+    public function disallowConnectDomain($domain) {
235
+        $this->allowedConnectDomains = array_diff($this->allowedConnectDomains, [$domain]);
236
+        return $this;
237
+    }
238
+
239
+    /**
240
+     * From which domains media elements can be embedded.
241
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
242
+     * @return $this
243
+     * @since 8.1.0
244
+     */
245
+    public function addAllowedMediaDomain($domain) {
246
+        $this->allowedMediaDomains[] = $domain;
247
+        return $this;
248
+    }
249
+
250
+    /**
251
+     * Remove the specified allowed media domain from the allowed domains.
252
+     *
253
+     * @param string $domain
254
+     * @return $this
255
+     * @since 8.1.0
256
+     */
257
+    public function disallowMediaDomain($domain) {
258
+        $this->allowedMediaDomains = array_diff($this->allowedMediaDomains, [$domain]);
259
+        return $this;
260
+    }
261
+
262
+    /**
263
+     * From which domains objects such as <object>, <embed> or <applet> are executed
264
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
265
+     * @return $this
266
+     * @since 8.1.0
267
+     */
268
+    public function addAllowedObjectDomain($domain) {
269
+        $this->allowedObjectDomains[] = $domain;
270
+        return $this;
271
+    }
272
+
273
+    /**
274
+     * Remove the specified allowed object domain from the allowed domains.
275
+     *
276
+     * @param string $domain
277
+     * @return $this
278
+     * @since 8.1.0
279
+     */
280
+    public function disallowObjectDomain($domain) {
281
+        $this->allowedObjectDomains = array_diff($this->allowedObjectDomains, [$domain]);
282
+        return $this;
283
+    }
284
+
285
+    /**
286
+     * Which domains can be embedded in an iframe
287
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
288
+     * @return $this
289
+     * @since 8.1.0
290
+     */
291
+    public function addAllowedFrameDomain($domain) {
292
+        $this->allowedFrameDomains[] = $domain;
293
+        return $this;
294
+    }
295
+
296
+    /**
297
+     * Remove the specified allowed frame domain from the allowed domains.
298
+     *
299
+     * @param string $domain
300
+     * @return $this
301
+     * @since 8.1.0
302
+     */
303
+    public function disallowFrameDomain($domain) {
304
+        $this->allowedFrameDomains = array_diff($this->allowedFrameDomains, [$domain]);
305
+        return $this;
306
+    }
307
+
308
+    /**
309
+     * Domains from which web-workers and nested browsing content can load elements
310
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
311
+     * @return $this
312
+     * @since 8.1.0
313
+     */
314
+    public function addAllowedChildSrcDomain($domain) {
315
+        $this->allowedChildSrcDomains[] = $domain;
316
+        return $this;
317
+    }
318
+
319
+    /**
320
+     * Remove the specified allowed child src domain from the allowed domains.
321
+     *
322
+     * @param string $domain
323
+     * @return $this
324
+     * @since 8.1.0
325
+     */
326
+    public function disallowChildSrcDomain($domain) {
327
+        $this->allowedChildSrcDomains = array_diff($this->allowedChildSrcDomains, [$domain]);
328
+        return $this;
329
+    }
330
+
331
+    /**
332
+     * Domains which can embed an iFrame of the Nextcloud instance
333
+     *
334
+     * @param string $domain
335
+     * @return $this
336
+     * @since 13.0.0
337
+     */
338
+    public function addAllowedFrameAncestorDomain($domain) {
339
+        $this->allowedFrameAncestors[] = $domain;
340
+        return $this;
341
+    }
342
+
343
+    /**
344
+     * Domains which can embed an iFrame of the Nextcloud instance
345
+     *
346
+     * @param string $domain
347
+     * @return $this
348
+     * @since 13.0.0
349
+     */
350
+    public function disallowFrameAncestorDomain($domain) {
351
+        $this->allowedFrameAncestors = array_diff($this->allowedFrameAncestors, [$domain]);
352
+        return $this;
353
+    }
354
+
355
+    /**
356
+     * Get the generated Content-Security-Policy as a string
357
+     * @return string
358
+     * @since 8.1.0
359
+     */
360
+    public function buildPolicy() {
361
+        $policy = "default-src 'none';";
362
+        $policy .= "base-uri 'none';";
363
+        $policy .= "manifest-src 'self';";
364
+
365
+        if(!empty($this->allowedScriptDomains) || $this->inlineScriptAllowed || $this->evalScriptAllowed) {
366
+            $policy .= 'script-src ';
367
+            if(is_string($this->useJsNonce)) {
368
+                $policy .= '\'nonce-'.base64_encode($this->useJsNonce).'\'';
369
+                $allowedScriptDomains = array_flip($this->allowedScriptDomains);
370
+                unset($allowedScriptDomains['\'self\'']);
371
+                $this->allowedScriptDomains = array_flip($allowedScriptDomains);
372
+                if(count($allowedScriptDomains) !== 0) {
373
+                    $policy .= ' ';
374
+                }
375
+            }
376
+            if(is_array($this->allowedScriptDomains)) {
377
+                $policy .= implode(' ', $this->allowedScriptDomains);
378
+            }
379
+            if($this->inlineScriptAllowed) {
380
+                $policy .= ' \'unsafe-inline\'';
381
+            }
382
+            if($this->evalScriptAllowed) {
383
+                $policy .= ' \'unsafe-eval\'';
384
+            }
385
+            $policy .= ';';
386
+        }
387
+
388
+        if(!empty($this->allowedStyleDomains) || $this->inlineStyleAllowed) {
389
+            $policy .= 'style-src ';
390
+            if(is_array($this->allowedStyleDomains)) {
391
+                $policy .= implode(' ', $this->allowedStyleDomains);
392
+            }
393
+            if($this->inlineStyleAllowed) {
394
+                $policy .= ' \'unsafe-inline\'';
395
+            }
396
+            $policy .= ';';
397
+        }
398
+
399
+        if(!empty($this->allowedImageDomains)) {
400
+            $policy .= 'img-src ' . implode(' ', $this->allowedImageDomains);
401
+            $policy .= ';';
402
+        }
403
+
404
+        if(!empty($this->allowedFontDomains)) {
405
+            $policy .= 'font-src ' . implode(' ', $this->allowedFontDomains);
406
+            $policy .= ';';
407
+        }
408
+
409
+        if(!empty($this->allowedConnectDomains)) {
410
+            $policy .= 'connect-src ' . implode(' ', $this->allowedConnectDomains);
411
+            $policy .= ';';
412
+        }
413
+
414
+        if(!empty($this->allowedMediaDomains)) {
415
+            $policy .= 'media-src ' . implode(' ', $this->allowedMediaDomains);
416
+            $policy .= ';';
417
+        }
418
+
419
+        if(!empty($this->allowedObjectDomains)) {
420
+            $policy .= 'object-src ' . implode(' ', $this->allowedObjectDomains);
421
+            $policy .= ';';
422
+        }
423
+
424
+        if(!empty($this->allowedFrameDomains)) {
425
+            $policy .= 'frame-src ' . implode(' ', $this->allowedFrameDomains);
426
+            $policy .= ';';
427
+        }
428
+
429
+        if(!empty($this->allowedChildSrcDomains)) {
430
+            $policy .= 'child-src ' . implode(' ', $this->allowedChildSrcDomains);
431
+            $policy .= ';';
432
+        }
433
+
434
+        if(!empty($this->allowedFrameAncestors)) {
435
+            $policy .= 'frame-ancestors ' . implode(' ', $this->allowedFrameAncestors);
436
+            $policy .= ';';
437
+        }
438
+
439
+        return rtrim($policy, ';');
440
+    }
441 441
 }
Please login to merge, or discard this patch.
core/templates/error.php 1 patch
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -1,12 +1,12 @@
 block discarded – undo
1 1
 <div class="error">
2 2
 	<h2><?php p($l->t('Error')) ?></h2>
3 3
 	<ul>
4
-	<?php foreach($_["errors"] as $error):?>
4
+	<?php foreach ($_["errors"] as $error):?>
5 5
 		<li>
6 6
 			<p><?php p($error['error']) ?></p>
7
-			<?php if(isset($error['hint']) && $error['hint']): ?>
7
+			<?php if (isset($error['hint']) && $error['hint']): ?>
8 8
 				<p class='hint'><?php p($error['hint']) ?></p>
9
-			<?php endif;?>
9
+			<?php endif; ?>
10 10
 		</li>
11 11
 	<?php endforeach ?>
12 12
 	</ul>
Please login to merge, or discard this patch.