Passed
Push — master ( 62403d...0c3e2f )
by Joas
14:50 queued 14s
created
apps/files_trashbin/lib/Helper.php 1 patch
Indentation   +85 added lines, -85 removed lines patch added patch discarded remove patch
@@ -35,96 +35,96 @@
 block discarded – undo
35 35
 use OCP\Files\Cache\ICacheEntry;
36 36
 
37 37
 class Helper {
38
-	/**
39
-	 * Retrieves the contents of a trash bin directory.
40
-	 *
41
-	 * @param string $dir path to the directory inside the trashbin
42
-	 * or empty to retrieve the root of the trashbin
43
-	 * @param string $user
44
-	 * @param string $sortAttribute attribute to sort on or empty to disable sorting
45
-	 * @param bool $sortDescending true for descending sort, false otherwise
46
-	 * @return \OCP\Files\FileInfo[]
47
-	 */
48
-	public static function getTrashFiles($dir, $user, $sortAttribute = '', $sortDescending = false) {
49
-		$result = [];
50
-		$timestamp = null;
38
+    /**
39
+     * Retrieves the contents of a trash bin directory.
40
+     *
41
+     * @param string $dir path to the directory inside the trashbin
42
+     * or empty to retrieve the root of the trashbin
43
+     * @param string $user
44
+     * @param string $sortAttribute attribute to sort on or empty to disable sorting
45
+     * @param bool $sortDescending true for descending sort, false otherwise
46
+     * @return \OCP\Files\FileInfo[]
47
+     */
48
+    public static function getTrashFiles($dir, $user, $sortAttribute = '', $sortDescending = false) {
49
+        $result = [];
50
+        $timestamp = null;
51 51
 
52
-		$view = new \OC\Files\View('/' . $user . '/files_trashbin/files');
52
+        $view = new \OC\Files\View('/' . $user . '/files_trashbin/files');
53 53
 
54
-		if (ltrim($dir, '/') !== '' && !$view->is_dir($dir)) {
55
-			throw new \Exception('Directory does not exists');
56
-		}
54
+        if (ltrim($dir, '/') !== '' && !$view->is_dir($dir)) {
55
+            throw new \Exception('Directory does not exists');
56
+        }
57 57
 
58
-		$mount = $view->getMount($dir);
59
-		$storage = $mount->getStorage();
60
-		$absoluteDir = $view->getAbsolutePath($dir);
61
-		$internalPath = $mount->getInternalPath($absoluteDir);
58
+        $mount = $view->getMount($dir);
59
+        $storage = $mount->getStorage();
60
+        $absoluteDir = $view->getAbsolutePath($dir);
61
+        $internalPath = $mount->getInternalPath($absoluteDir);
62 62
 
63
-		$originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($user);
64
-		$dirContent = $storage->getCache()->getFolderContents($mount->getInternalPath($view->getAbsolutePath($dir)));
65
-		foreach ($dirContent as $entry) {
66
-			$entryName = $entry->getName();
67
-			$name = $entryName;
68
-			if ($dir === '' || $dir === '/') {
69
-				$pathparts = pathinfo($entryName);
70
-				$timestamp = substr($pathparts['extension'], 1);
71
-				$name = $pathparts['filename'];
63
+        $originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($user);
64
+        $dirContent = $storage->getCache()->getFolderContents($mount->getInternalPath($view->getAbsolutePath($dir)));
65
+        foreach ($dirContent as $entry) {
66
+            $entryName = $entry->getName();
67
+            $name = $entryName;
68
+            if ($dir === '' || $dir === '/') {
69
+                $pathparts = pathinfo($entryName);
70
+                $timestamp = substr($pathparts['extension'], 1);
71
+                $name = $pathparts['filename'];
72 72
 
73
-			} else if ($timestamp === null) {
74
-				// for subfolders we need to calculate the timestamp only once
75
-				$parts = explode('/', ltrim($dir, '/'));
76
-				$timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1);
77
-			}
78
-			$originalPath = '';
79
-			$originalName = substr($entryName, 0, -strlen($timestamp)-2);
80
-			if (isset($originalLocations[$originalName][$timestamp])) {
81
-				$originalPath = $originalLocations[$originalName][$timestamp];
82
-				if (substr($originalPath, -1) === '/') {
83
-					$originalPath = substr($originalPath, 0, -1);
84
-				}
85
-			}
86
-			$type = $entry->getMimeType() === ICacheEntry::DIRECTORY_MIMETYPE ? 'dir' : 'file';
87
-			$i = [
88
-				'name' => $name,
89
-				'mtime' => $timestamp,
90
-				'mimetype' => $type === 'dir' ? 'httpd/unix-directory' : \OC::$server->getMimeTypeDetector()->detectPath($name),
91
-				'type' => $type,
92
-				'directory' => ($dir === '/') ? '' : $dir,
93
-				'size' => $entry->getSize(),
94
-				'etag' => '',
95
-				'permissions' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE,
96
-				'fileid' => $entry->getId(),
97
-			];
98
-			if ($originalPath) {
99
-				if ($originalPath !== '.') {
100
-					$i['extraData'] = $originalPath . '/' . $originalName;
101
-				} else {
102
-					$i['extraData'] = $originalName;
103
-				}
104
-			}
105
-			$result[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i, $mount);
106
-		}
73
+            } else if ($timestamp === null) {
74
+                // for subfolders we need to calculate the timestamp only once
75
+                $parts = explode('/', ltrim($dir, '/'));
76
+                $timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1);
77
+            }
78
+            $originalPath = '';
79
+            $originalName = substr($entryName, 0, -strlen($timestamp)-2);
80
+            if (isset($originalLocations[$originalName][$timestamp])) {
81
+                $originalPath = $originalLocations[$originalName][$timestamp];
82
+                if (substr($originalPath, -1) === '/') {
83
+                    $originalPath = substr($originalPath, 0, -1);
84
+                }
85
+            }
86
+            $type = $entry->getMimeType() === ICacheEntry::DIRECTORY_MIMETYPE ? 'dir' : 'file';
87
+            $i = [
88
+                'name' => $name,
89
+                'mtime' => $timestamp,
90
+                'mimetype' => $type === 'dir' ? 'httpd/unix-directory' : \OC::$server->getMimeTypeDetector()->detectPath($name),
91
+                'type' => $type,
92
+                'directory' => ($dir === '/') ? '' : $dir,
93
+                'size' => $entry->getSize(),
94
+                'etag' => '',
95
+                'permissions' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE,
96
+                'fileid' => $entry->getId(),
97
+            ];
98
+            if ($originalPath) {
99
+                if ($originalPath !== '.') {
100
+                    $i['extraData'] = $originalPath . '/' . $originalName;
101
+                } else {
102
+                    $i['extraData'] = $originalName;
103
+                }
104
+            }
105
+            $result[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i, $mount);
106
+        }
107 107
 
108
-		if ($sortAttribute !== '') {
109
-			return \OCA\Files\Helper::sortFiles($result, $sortAttribute, $sortDescending);
110
-		}
111
-		return $result;
112
-	}
108
+        if ($sortAttribute !== '') {
109
+            return \OCA\Files\Helper::sortFiles($result, $sortAttribute, $sortDescending);
110
+        }
111
+        return $result;
112
+    }
113 113
 
114
-	/**
115
-	 * Format file infos for JSON
116
-	 *
117
-	 * @param \OCP\Files\FileInfo[] $fileInfos file infos
118
-	 */
119
-	public static function formatFileInfos($fileInfos) {
120
-		$files = [];
121
-		foreach ($fileInfos as $i) {
122
-			$entry = \OCA\Files\Helper::formatFileInfo($i);
123
-			$entry['id'] = $i->getId();
124
-			$entry['etag'] = $entry['mtime']; // add fake etag, it is only needed to identify the preview image
125
-			$entry['permissions'] = \OCP\Constants::PERMISSION_READ;
126
-			$files[] = $entry;
127
-		}
128
-		return $files;
129
-	}
114
+    /**
115
+     * Format file infos for JSON
116
+     *
117
+     * @param \OCP\Files\FileInfo[] $fileInfos file infos
118
+     */
119
+    public static function formatFileInfos($fileInfos) {
120
+        $files = [];
121
+        foreach ($fileInfos as $i) {
122
+            $entry = \OCA\Files\Helper::formatFileInfo($i);
123
+            $entry['id'] = $i->getId();
124
+            $entry['etag'] = $entry['mtime']; // add fake etag, it is only needed to identify the preview image
125
+            $entry['permissions'] = \OCP\Constants::PERMISSION_READ;
126
+            $files[] = $entry;
127
+        }
128
+        return $files;
129
+    }
130 130
 }
Please login to merge, or discard this patch.
apps/settings/lib/Settings/Personal/PersonalInfo.php 1 patch
Indentation   +242 added lines, -242 removed lines patch added patch discarded remove patch
@@ -47,247 +47,247 @@
 block discarded – undo
47 47
 
48 48
 class PersonalInfo implements ISettings {
49 49
 
50
-	/** @var IConfig */
51
-	private $config;
52
-	/** @var IUserManager */
53
-	private $userManager;
54
-	/** @var AccountManager */
55
-	private $accountManager;
56
-	/** @var IGroupManager */
57
-	private $groupManager;
58
-	/** @var IAppManager */
59
-	private $appManager;
60
-	/** @var IFactory */
61
-	private $l10nFactory;
62
-	/** @var IL10N */
63
-	private $l;
64
-
65
-	/**
66
-	 * @param IConfig $config
67
-	 * @param IUserManager $userManager
68
-	 * @param IGroupManager $groupManager
69
-	 * @param AccountManager $accountManager
70
-	 * @param IFactory $l10nFactory
71
-	 * @param IL10N $l
72
-	 */
73
-	public function __construct(
74
-		IConfig $config,
75
-		IUserManager $userManager,
76
-		IGroupManager $groupManager,
77
-		AccountManager $accountManager,
78
-		IAppManager $appManager,
79
-		IFactory $l10nFactory,
80
-		IL10N $l
81
-	) {
82
-		$this->config = $config;
83
-		$this->userManager = $userManager;
84
-		$this->accountManager = $accountManager;
85
-		$this->groupManager = $groupManager;
86
-		$this->appManager = $appManager;
87
-		$this->l10nFactory = $l10nFactory;
88
-		$this->l = $l;
89
-	}
90
-
91
-	/**
92
-	 * @return TemplateResponse returns the instance with all parameters set, ready to be rendered
93
-	 * @since 9.1
94
-	 */
95
-	public function getForm() {
96
-		$federatedFileSharingEnabled = $this->appManager->isEnabledForUser('federatedfilesharing');
97
-		$lookupServerUploadEnabled = false;
98
-		if($federatedFileSharingEnabled) {
99
-			$federatedFileSharing = \OC::$server->query(Application::class);
100
-			$shareProvider = $federatedFileSharing->getFederatedShareProvider();
101
-			$lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled();
102
-		}
103
-
104
-		$uid = \OC_User::getUser();
105
-		$user = $this->userManager->get($uid);
106
-		$userData = $this->accountManager->getUser($user);
107
-
108
-		$storageInfo = \OC_Helper::getStorageInfo('/');
109
-		if ($storageInfo['quota'] === FileInfo::SPACE_UNLIMITED) {
110
-			$totalSpace = $this->l->t('Unlimited');
111
-		} else {
112
-			$totalSpace = \OC_Helper::humanFileSize($storageInfo['total']);
113
-		}
114
-
115
-		$languageParameters = $this->getLanguages($user);
116
-		$localeParameters = $this->getLocales($user);
117
-		$messageParameters = $this->getMessageParameters($userData);
118
-
119
-		$parameters = [
120
-			'total_space' => $totalSpace,
121
-			'usage' => \OC_Helper::humanFileSize($storageInfo['used']),
122
-			'usage_relative' => round($storageInfo['relative']),
123
-			'quota' => $storageInfo['quota'],
124
-			'avatarChangeSupported' => $user->canChangeAvatar(),
125
-			'lookupServerUploadEnabled' => $lookupServerUploadEnabled,
126
-			'avatarScope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'],
127
-			'displayNameChangeSupported' => $user->canChangeDisplayName(),
128
-			'displayName' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'],
129
-			'displayNameScope' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
130
-			'email' => $userData[AccountManager::PROPERTY_EMAIL]['value'],
131
-			'emailScope' => $userData[AccountManager::PROPERTY_EMAIL]['scope'],
132
-			'emailVerification' => $userData[AccountManager::PROPERTY_EMAIL]['verified'],
133
-			'phone' => $userData[AccountManager::PROPERTY_PHONE]['value'],
134
-			'phoneScope' => $userData[AccountManager::PROPERTY_PHONE]['scope'],
135
-			'address' => $userData[AccountManager::PROPERTY_ADDRESS]['value'],
136
-			'addressScope' => $userData[AccountManager::PROPERTY_ADDRESS]['scope'],
137
-			'website' =>  $userData[AccountManager::PROPERTY_WEBSITE]['value'],
138
-			'websiteScope' =>  $userData[AccountManager::PROPERTY_WEBSITE]['scope'],
139
-			'websiteVerification' => $userData[AccountManager::PROPERTY_WEBSITE]['verified'],
140
-			'twitter' => $userData[AccountManager::PROPERTY_TWITTER]['value'],
141
-			'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'],
142
-			'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'],
143
-			'groups' => $this->getGroups($user),
144
-		] + $messageParameters + $languageParameters + $localeParameters;
145
-
146
-
147
-		return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, '');
148
-	}
149
-
150
-	/**
151
-	 * @return string the section ID, e.g. 'sharing'
152
-	 * @since 9.1
153
-	 */
154
-	public function getSection() {
155
-		return 'personal-info';
156
-	}
157
-
158
-	/**
159
-	 * @return int whether the form should be rather on the top or bottom of
160
-	 * the admin section. The forms are arranged in ascending order of the
161
-	 * priority values. It is required to return a value between 0 and 100.
162
-	 *
163
-	 * E.g.: 70
164
-	 * @since 9.1
165
-	 */
166
-	public function getPriority() {
167
-		return 10;
168
-	}
169
-
170
-	/**
171
-	 * returns a sorted list of the user's group GIDs
172
-	 *
173
-	 * @param IUser $user
174
-	 * @return array
175
-	 */
176
-	private function getGroups(IUser $user) {
177
-		$groups = array_map(
178
-			function(IGroup $group) {
179
-				return $group->getDisplayName();
180
-			},
181
-			$this->groupManager->getUserGroups($user)
182
-		);
183
-		sort($groups);
184
-
185
-		return $groups;
186
-	}
187
-
188
-	/**
189
-	 * returns the user language, common language and other languages in an
190
-	 * associative array
191
-	 *
192
-	 * @param IUser $user
193
-	 * @return array
194
-	 */
195
-	private function getLanguages(IUser $user) {
196
-		$forceLanguage = $this->config->getSystemValue('force_language', false);
197
-		if($forceLanguage !== false) {
198
-			return [];
199
-		}
200
-
201
-		$uid = $user->getUID();
202
-
203
-		$userConfLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
204
-		$languages = $this->l10nFactory->getLanguages();
205
-
206
-		// associate the user language with the proper array
207
-		$userLangIndex = array_search($userConfLang, array_column($languages['commonlanguages'], 'code'));
208
-		$userLang = $languages['commonlanguages'][$userLangIndex];
209
-		// search in the other languages
210
-		if ($userLangIndex === false) {
211
-			$userLangIndex = array_search($userConfLang, array_column($languages['languages'], 'code'));
212
-			$userLang = $languages['languages'][$userLangIndex];
213
-		}
214
-		// if user language is not available but set somehow: show the actual code as name
215
-		if (!is_array($userLang)) {
216
-			$userLang = [
217
-				'code' => $userConfLang,
218
-				'name' => $userConfLang,
219
-			];
220
-		}
221
-
222
-		return array_merge(
223
-			['activelanguage' => $userLang],
224
-			$languages
225
-		);
226
-	}
227
-
228
-	private function getLocales(IUser $user) {
229
-		$forceLanguage = $this->config->getSystemValue('force_locale', false);
230
-		if($forceLanguage !== false) {
231
-			return [];
232
-		}
233
-
234
-		$uid = $user->getUID();
235
-
236
-		$userLocaleString = $this->config->getUserValue($uid, 'core', 'locale', $this->l10nFactory->findLocale());
237
-
238
-		$userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
239
-
240
-		$localeCodes = $this->l10nFactory->findAvailableLocales();
241
-
242
-		$userLocale = array_filter($localeCodes, function($value) use ($userLocaleString) {
243
-			return $userLocaleString === $value['code'];
244
-		});
245
-
246
-		if (!empty($userLocale))
247
-		{
248
-			$userLocale = reset($userLocale);
249
-		}
250
-
251
-		$localesForLanguage = array_filter($localeCodes, function($localeCode) use ($userLang) {
252
-			return 0 === strpos($localeCode['code'], $userLang);
253
-		});
254
-
255
-		if (!$userLocale) {
256
-			$userLocale = [
257
-				'code' => 'en',
258
-				'name' => 'English'
259
-			];
260
-		}
261
-
262
-		return [
263
-			'activelocaleLang' => $userLocaleString,
264
-			'activelocale' => $userLocale,
265
-			'locales' => $localeCodes,
266
-			'localesForLanguage' => $localesForLanguage,
267
-		];
268
-	}
269
-
270
-	/**
271
-	 * @param array $userData
272
-	 * @return array
273
-	 */
274
-	private function getMessageParameters(array $userData) {
275
-		$needVerifyMessage = [AccountManager::PROPERTY_EMAIL, AccountManager::PROPERTY_WEBSITE, AccountManager::PROPERTY_TWITTER];
276
-		$messageParameters = [];
277
-		foreach ($needVerifyMessage as $property) {
278
-			switch ($userData[$property]['verified']) {
279
-				case AccountManager::VERIFIED:
280
-					$message = $this->l->t('Verifying');
281
-					break;
282
-				case AccountManager::VERIFICATION_IN_PROGRESS:
283
-					$message = $this->l->t('Verifying …');
284
-					break;
285
-				default:
286
-					$message = $this->l->t('Verify');
287
-			}
288
-			$messageParameters[$property . 'Message'] = $message;
289
-		}
290
-		return $messageParameters;
291
-	}
50
+    /** @var IConfig */
51
+    private $config;
52
+    /** @var IUserManager */
53
+    private $userManager;
54
+    /** @var AccountManager */
55
+    private $accountManager;
56
+    /** @var IGroupManager */
57
+    private $groupManager;
58
+    /** @var IAppManager */
59
+    private $appManager;
60
+    /** @var IFactory */
61
+    private $l10nFactory;
62
+    /** @var IL10N */
63
+    private $l;
64
+
65
+    /**
66
+     * @param IConfig $config
67
+     * @param IUserManager $userManager
68
+     * @param IGroupManager $groupManager
69
+     * @param AccountManager $accountManager
70
+     * @param IFactory $l10nFactory
71
+     * @param IL10N $l
72
+     */
73
+    public function __construct(
74
+        IConfig $config,
75
+        IUserManager $userManager,
76
+        IGroupManager $groupManager,
77
+        AccountManager $accountManager,
78
+        IAppManager $appManager,
79
+        IFactory $l10nFactory,
80
+        IL10N $l
81
+    ) {
82
+        $this->config = $config;
83
+        $this->userManager = $userManager;
84
+        $this->accountManager = $accountManager;
85
+        $this->groupManager = $groupManager;
86
+        $this->appManager = $appManager;
87
+        $this->l10nFactory = $l10nFactory;
88
+        $this->l = $l;
89
+    }
90
+
91
+    /**
92
+     * @return TemplateResponse returns the instance with all parameters set, ready to be rendered
93
+     * @since 9.1
94
+     */
95
+    public function getForm() {
96
+        $federatedFileSharingEnabled = $this->appManager->isEnabledForUser('federatedfilesharing');
97
+        $lookupServerUploadEnabled = false;
98
+        if($federatedFileSharingEnabled) {
99
+            $federatedFileSharing = \OC::$server->query(Application::class);
100
+            $shareProvider = $federatedFileSharing->getFederatedShareProvider();
101
+            $lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled();
102
+        }
103
+
104
+        $uid = \OC_User::getUser();
105
+        $user = $this->userManager->get($uid);
106
+        $userData = $this->accountManager->getUser($user);
107
+
108
+        $storageInfo = \OC_Helper::getStorageInfo('/');
109
+        if ($storageInfo['quota'] === FileInfo::SPACE_UNLIMITED) {
110
+            $totalSpace = $this->l->t('Unlimited');
111
+        } else {
112
+            $totalSpace = \OC_Helper::humanFileSize($storageInfo['total']);
113
+        }
114
+
115
+        $languageParameters = $this->getLanguages($user);
116
+        $localeParameters = $this->getLocales($user);
117
+        $messageParameters = $this->getMessageParameters($userData);
118
+
119
+        $parameters = [
120
+            'total_space' => $totalSpace,
121
+            'usage' => \OC_Helper::humanFileSize($storageInfo['used']),
122
+            'usage_relative' => round($storageInfo['relative']),
123
+            'quota' => $storageInfo['quota'],
124
+            'avatarChangeSupported' => $user->canChangeAvatar(),
125
+            'lookupServerUploadEnabled' => $lookupServerUploadEnabled,
126
+            'avatarScope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'],
127
+            'displayNameChangeSupported' => $user->canChangeDisplayName(),
128
+            'displayName' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'],
129
+            'displayNameScope' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
130
+            'email' => $userData[AccountManager::PROPERTY_EMAIL]['value'],
131
+            'emailScope' => $userData[AccountManager::PROPERTY_EMAIL]['scope'],
132
+            'emailVerification' => $userData[AccountManager::PROPERTY_EMAIL]['verified'],
133
+            'phone' => $userData[AccountManager::PROPERTY_PHONE]['value'],
134
+            'phoneScope' => $userData[AccountManager::PROPERTY_PHONE]['scope'],
135
+            'address' => $userData[AccountManager::PROPERTY_ADDRESS]['value'],
136
+            'addressScope' => $userData[AccountManager::PROPERTY_ADDRESS]['scope'],
137
+            'website' =>  $userData[AccountManager::PROPERTY_WEBSITE]['value'],
138
+            'websiteScope' =>  $userData[AccountManager::PROPERTY_WEBSITE]['scope'],
139
+            'websiteVerification' => $userData[AccountManager::PROPERTY_WEBSITE]['verified'],
140
+            'twitter' => $userData[AccountManager::PROPERTY_TWITTER]['value'],
141
+            'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'],
142
+            'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'],
143
+            'groups' => $this->getGroups($user),
144
+        ] + $messageParameters + $languageParameters + $localeParameters;
145
+
146
+
147
+        return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, '');
148
+    }
149
+
150
+    /**
151
+     * @return string the section ID, e.g. 'sharing'
152
+     * @since 9.1
153
+     */
154
+    public function getSection() {
155
+        return 'personal-info';
156
+    }
157
+
158
+    /**
159
+     * @return int whether the form should be rather on the top or bottom of
160
+     * the admin section. The forms are arranged in ascending order of the
161
+     * priority values. It is required to return a value between 0 and 100.
162
+     *
163
+     * E.g.: 70
164
+     * @since 9.1
165
+     */
166
+    public function getPriority() {
167
+        return 10;
168
+    }
169
+
170
+    /**
171
+     * returns a sorted list of the user's group GIDs
172
+     *
173
+     * @param IUser $user
174
+     * @return array
175
+     */
176
+    private function getGroups(IUser $user) {
177
+        $groups = array_map(
178
+            function(IGroup $group) {
179
+                return $group->getDisplayName();
180
+            },
181
+            $this->groupManager->getUserGroups($user)
182
+        );
183
+        sort($groups);
184
+
185
+        return $groups;
186
+    }
187
+
188
+    /**
189
+     * returns the user language, common language and other languages in an
190
+     * associative array
191
+     *
192
+     * @param IUser $user
193
+     * @return array
194
+     */
195
+    private function getLanguages(IUser $user) {
196
+        $forceLanguage = $this->config->getSystemValue('force_language', false);
197
+        if($forceLanguage !== false) {
198
+            return [];
199
+        }
200
+
201
+        $uid = $user->getUID();
202
+
203
+        $userConfLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
204
+        $languages = $this->l10nFactory->getLanguages();
205
+
206
+        // associate the user language with the proper array
207
+        $userLangIndex = array_search($userConfLang, array_column($languages['commonlanguages'], 'code'));
208
+        $userLang = $languages['commonlanguages'][$userLangIndex];
209
+        // search in the other languages
210
+        if ($userLangIndex === false) {
211
+            $userLangIndex = array_search($userConfLang, array_column($languages['languages'], 'code'));
212
+            $userLang = $languages['languages'][$userLangIndex];
213
+        }
214
+        // if user language is not available but set somehow: show the actual code as name
215
+        if (!is_array($userLang)) {
216
+            $userLang = [
217
+                'code' => $userConfLang,
218
+                'name' => $userConfLang,
219
+            ];
220
+        }
221
+
222
+        return array_merge(
223
+            ['activelanguage' => $userLang],
224
+            $languages
225
+        );
226
+    }
227
+
228
+    private function getLocales(IUser $user) {
229
+        $forceLanguage = $this->config->getSystemValue('force_locale', false);
230
+        if($forceLanguage !== false) {
231
+            return [];
232
+        }
233
+
234
+        $uid = $user->getUID();
235
+
236
+        $userLocaleString = $this->config->getUserValue($uid, 'core', 'locale', $this->l10nFactory->findLocale());
237
+
238
+        $userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
239
+
240
+        $localeCodes = $this->l10nFactory->findAvailableLocales();
241
+
242
+        $userLocale = array_filter($localeCodes, function($value) use ($userLocaleString) {
243
+            return $userLocaleString === $value['code'];
244
+        });
245
+
246
+        if (!empty($userLocale))
247
+        {
248
+            $userLocale = reset($userLocale);
249
+        }
250
+
251
+        $localesForLanguage = array_filter($localeCodes, function($localeCode) use ($userLang) {
252
+            return 0 === strpos($localeCode['code'], $userLang);
253
+        });
254
+
255
+        if (!$userLocale) {
256
+            $userLocale = [
257
+                'code' => 'en',
258
+                'name' => 'English'
259
+            ];
260
+        }
261
+
262
+        return [
263
+            'activelocaleLang' => $userLocaleString,
264
+            'activelocale' => $userLocale,
265
+            'locales' => $localeCodes,
266
+            'localesForLanguage' => $localesForLanguage,
267
+        ];
268
+    }
269
+
270
+    /**
271
+     * @param array $userData
272
+     * @return array
273
+     */
274
+    private function getMessageParameters(array $userData) {
275
+        $needVerifyMessage = [AccountManager::PROPERTY_EMAIL, AccountManager::PROPERTY_WEBSITE, AccountManager::PROPERTY_TWITTER];
276
+        $messageParameters = [];
277
+        foreach ($needVerifyMessage as $property) {
278
+            switch ($userData[$property]['verified']) {
279
+                case AccountManager::VERIFIED:
280
+                    $message = $this->l->t('Verifying');
281
+                    break;
282
+                case AccountManager::VERIFICATION_IN_PROGRESS:
283
+                    $message = $this->l->t('Verifying …');
284
+                    break;
285
+                default:
286
+                    $message = $this->l->t('Verify');
287
+            }
288
+            $messageParameters[$property . 'Message'] = $message;
289
+        }
290
+        return $messageParameters;
291
+    }
292 292
 
293 293
 }
Please login to merge, or discard this patch.
apps/settings/lib/Middleware/SubadminMiddleware.php 1 patch
Indentation   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -38,56 +38,56 @@
 block discarded – undo
38 38
  * To bypass use the `@NoSubadminRequired` annotation
39 39
  */
40 40
 class SubadminMiddleware extends Middleware {
41
-	/** @var bool */
42
-	protected $isSubAdmin;
43
-	/** @var ControllerMethodReflector */
44
-	protected $reflector;
45
-	/** @var IL10N */
46
-	private $l10n;
41
+    /** @var bool */
42
+    protected $isSubAdmin;
43
+    /** @var ControllerMethodReflector */
44
+    protected $reflector;
45
+    /** @var IL10N */
46
+    private $l10n;
47 47
 
48
-	/**
49
-	 * @param ControllerMethodReflector $reflector
50
-	 * @param bool $isSubAdmin
51
-	 * @param IL10N $l10n
52
-	 */
53
-	public function __construct(ControllerMethodReflector $reflector,
54
-								$isSubAdmin,
55
-								IL10N $l10n) {
56
-		$this->reflector = $reflector;
57
-		$this->isSubAdmin = $isSubAdmin;
58
-		$this->l10n = $l10n;
59
-	}
48
+    /**
49
+     * @param ControllerMethodReflector $reflector
50
+     * @param bool $isSubAdmin
51
+     * @param IL10N $l10n
52
+     */
53
+    public function __construct(ControllerMethodReflector $reflector,
54
+                                $isSubAdmin,
55
+                                IL10N $l10n) {
56
+        $this->reflector = $reflector;
57
+        $this->isSubAdmin = $isSubAdmin;
58
+        $this->l10n = $l10n;
59
+    }
60 60
 
61
-	/**
62
-	 * Check if sharing is enabled before the controllers is executed
63
-	 * @param Controller $controller
64
-	 * @param string $methodName
65
-	 * @throws \Exception
66
-	 */
67
-	public function beforeController($controller, $methodName) {
68
-		if(!$this->reflector->hasAnnotation('NoSubadminRequired')) {
69
-			if(!$this->isSubAdmin) {
70
-				throw new NotAdminException($this->l10n->t('Logged in user must be a subadmin'));
71
-			}
72
-		}
73
-	}
61
+    /**
62
+     * Check if sharing is enabled before the controllers is executed
63
+     * @param Controller $controller
64
+     * @param string $methodName
65
+     * @throws \Exception
66
+     */
67
+    public function beforeController($controller, $methodName) {
68
+        if(!$this->reflector->hasAnnotation('NoSubadminRequired')) {
69
+            if(!$this->isSubAdmin) {
70
+                throw new NotAdminException($this->l10n->t('Logged in user must be a subadmin'));
71
+            }
72
+        }
73
+    }
74 74
 
75
-	/**
76
-	 * Return 403 page in case of an exception
77
-	 * @param Controller $controller
78
-	 * @param string $methodName
79
-	 * @param \Exception $exception
80
-	 * @return TemplateResponse
81
-	 * @throws \Exception
82
-	 */
83
-	public function afterException($controller, $methodName, \Exception $exception) {
84
-		if($exception instanceof NotAdminException) {
85
-			$response = new TemplateResponse('core', '403', [], 'guest');
86
-			$response->setStatus(Http::STATUS_FORBIDDEN);
87
-			return $response;
88
-		}
75
+    /**
76
+     * Return 403 page in case of an exception
77
+     * @param Controller $controller
78
+     * @param string $methodName
79
+     * @param \Exception $exception
80
+     * @return TemplateResponse
81
+     * @throws \Exception
82
+     */
83
+    public function afterException($controller, $methodName, \Exception $exception) {
84
+        if($exception instanceof NotAdminException) {
85
+            $response = new TemplateResponse('core', '403', [], 'guest');
86
+            $response->setStatus(Http::STATUS_FORBIDDEN);
87
+            return $response;
88
+        }
89 89
 
90
-		throw $exception;
91
-	}
90
+        throw $exception;
91
+    }
92 92
 
93 93
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/AppSettingsController.php 1 patch
Indentation   +502 added lines, -502 removed lines patch added patch discarded remove patch
@@ -54,507 +54,507 @@
 block discarded – undo
54 54
 
55 55
 class AppSettingsController extends Controller {
56 56
 
57
-	/** @var \OCP\IL10N */
58
-	private $l10n;
59
-	/** @var IConfig */
60
-	private $config;
61
-	/** @var INavigationManager */
62
-	private $navigationManager;
63
-	/** @var IAppManager */
64
-	private $appManager;
65
-	/** @var CategoryFetcher */
66
-	private $categoryFetcher;
67
-	/** @var AppFetcher */
68
-	private $appFetcher;
69
-	/** @var IFactory */
70
-	private $l10nFactory;
71
-	/** @var BundleFetcher */
72
-	private $bundleFetcher;
73
-	/** @var Installer */
74
-	private $installer;
75
-	/** @var IURLGenerator */
76
-	private $urlGenerator;
77
-	/** @var ILogger */
78
-	private $logger;
79
-
80
-	/** @var array */
81
-	private $allApps = [];
82
-
83
-	/**
84
-	 * @param string $appName
85
-	 * @param IRequest $request
86
-	 * @param IL10N $l10n
87
-	 * @param IConfig $config
88
-	 * @param INavigationManager $navigationManager
89
-	 * @param IAppManager $appManager
90
-	 * @param CategoryFetcher $categoryFetcher
91
-	 * @param AppFetcher $appFetcher
92
-	 * @param IFactory $l10nFactory
93
-	 * @param BundleFetcher $bundleFetcher
94
-	 * @param Installer $installer
95
-	 * @param IURLGenerator $urlGenerator
96
-	 * @param ILogger $logger
97
-	 */
98
-	public function __construct(string $appName,
99
-								IRequest $request,
100
-								IL10N $l10n,
101
-								IConfig $config,
102
-								INavigationManager $navigationManager,
103
-								IAppManager $appManager,
104
-								CategoryFetcher $categoryFetcher,
105
-								AppFetcher $appFetcher,
106
-								IFactory $l10nFactory,
107
-								BundleFetcher $bundleFetcher,
108
-								Installer $installer,
109
-								IURLGenerator $urlGenerator,
110
-								ILogger $logger) {
111
-		parent::__construct($appName, $request);
112
-		$this->l10n = $l10n;
113
-		$this->config = $config;
114
-		$this->navigationManager = $navigationManager;
115
-		$this->appManager = $appManager;
116
-		$this->categoryFetcher = $categoryFetcher;
117
-		$this->appFetcher = $appFetcher;
118
-		$this->l10nFactory = $l10nFactory;
119
-		$this->bundleFetcher = $bundleFetcher;
120
-		$this->installer = $installer;
121
-		$this->urlGenerator = $urlGenerator;
122
-		$this->logger = $logger;
123
-	}
124
-
125
-	/**
126
-	 * @NoCSRFRequired
127
-	 *
128
-	 * @return TemplateResponse
129
-	 */
130
-	public function viewApps(): TemplateResponse {
131
-		\OC_Util::addScript('settings', 'apps');
132
-		$params = [];
133
-		$params['appstoreEnabled'] = $this->config->getSystemValue('appstoreenabled', true) === true;
134
-		$params['updateCount'] = count($this->getAppsWithUpdates());
135
-		$params['developerDocumentation'] = $this->urlGenerator->linkToDocs('developer-manual');
136
-		$params['bundles'] = $this->getBundles();
137
-		$this->navigationManager->setActiveEntry('core_apps');
138
-
139
-		$templateResponse = new TemplateResponse('settings', 'settings-vue', ['serverData' => $params]);
140
-		$policy = new ContentSecurityPolicy();
141
-		$policy->addAllowedImageDomain('https://usercontent.apps.nextcloud.com');
142
-		$templateResponse->setContentSecurityPolicy($policy);
143
-
144
-		return $templateResponse;
145
-	}
146
-
147
-	private function getAppsWithUpdates() {
148
-		$appClass = new \OC_App();
149
-		$apps = $appClass->listAllApps();
150
-		foreach($apps as $key => $app) {
151
-			$newVersion = $this->installer->isUpdateAvailable($app['id']);
152
-			if($newVersion === false) {
153
-				unset($apps[$key]);
154
-			}
155
-		}
156
-		return $apps;
157
-	}
158
-
159
-	private function getBundles() {
160
-		$result = [];
161
-		$bundles = $this->bundleFetcher->getBundles();
162
-		foreach ($bundles as $bundle) {
163
-			$result[] = [
164
-				'name' => $bundle->getName(),
165
-				'id' => $bundle->getIdentifier(),
166
-				'appIdentifiers' => $bundle->getAppIdentifiers()
167
-			];
168
-		}
169
-		return $result;
170
-
171
-	}
172
-
173
-	/**
174
-	 * Get all available categories
175
-	 *
176
-	 * @return JSONResponse
177
-	 */
178
-	public function listCategories(): JSONResponse {
179
-		return new JSONResponse($this->getAllCategories());
180
-	}
181
-
182
-	private function getAllCategories() {
183
-		$currentLanguage = substr($this->l10nFactory->findLanguage(), 0, 2);
184
-
185
-		$formattedCategories = [];
186
-		$categories = $this->categoryFetcher->get();
187
-		foreach($categories as $category) {
188
-			$formattedCategories[] = [
189
-				'id' => $category['id'],
190
-				'ident' => $category['id'],
191
-				'displayName' => isset($category['translations'][$currentLanguage]['name']) ? $category['translations'][$currentLanguage]['name'] : $category['translations']['en']['name'],
192
-			];
193
-		}
194
-
195
-		return $formattedCategories;
196
-	}
197
-
198
-	private function fetchApps() {
199
-		$appClass = new \OC_App();
200
-		$apps = $appClass->listAllApps();
201
-		foreach ($apps as $app) {
202
-			$app['installed'] = true;
203
-			$this->allApps[$app['id']] = $app;
204
-		}
205
-
206
-		$apps = $this->getAppsForCategory('');
207
-		foreach ($apps as $app) {
208
-			$app['appstore'] = true;
209
-			if (!array_key_exists($app['id'], $this->allApps)) {
210
-				$this->allApps[$app['id']] = $app;
211
-			} else {
212
-				$this->allApps[$app['id']] = array_merge($app, $this->allApps[$app['id']]);
213
-			}
214
-		}
215
-
216
-		// add bundle information
217
-		$bundles = $this->bundleFetcher->getBundles();
218
-		foreach($bundles as $bundle) {
219
-			foreach($bundle->getAppIdentifiers() as $identifier) {
220
-				foreach($this->allApps as &$app) {
221
-					if($app['id'] === $identifier) {
222
-						$app['bundleIds'][] = $bundle->getIdentifier();
223
-						continue;
224
-					}
225
-				}
226
-			}
227
-		}
228
-	}
229
-
230
-	private function getAllApps() {
231
-		return $this->allApps;
232
-	}
233
-	/**
234
-	 * Get all available apps in a category
235
-	 *
236
-	 * @param string $category
237
-	 * @return JSONResponse
238
-	 * @throws \Exception
239
-	 */
240
-	public function listApps(): JSONResponse {
241
-
242
-		$this->fetchApps();
243
-		$apps = $this->getAllApps();
244
-
245
-		$dependencyAnalyzer = new DependencyAnalyzer(new Platform($this->config), $this->l10n);
246
-
247
-		// Extend existing app details
248
-		$apps = array_map(function($appData) use ($dependencyAnalyzer) {
249
-			if (isset($appData['appstoreData'])) {
250
-				$appstoreData = $appData['appstoreData'];
251
-				$appData['screenshot'] = isset($appstoreData['screenshots'][0]['url']) ? 'https://usercontent.apps.nextcloud.com/' . base64_encode($appstoreData['screenshots'][0]['url']) : '';
252
-				$appData['category'] = $appstoreData['categories'];
253
-			}
254
-
255
-			$newVersion = $this->installer->isUpdateAvailable($appData['id']);
256
-			if($newVersion) {
257
-				$appData['update'] = $newVersion;
258
-			}
259
-
260
-			// fix groups to be an array
261
-			$groups = [];
262
-			if (is_string($appData['groups'])) {
263
-				$groups = json_decode($appData['groups']);
264
-			}
265
-			$appData['groups'] = $groups;
266
-			$appData['canUnInstall'] = !$appData['active'] && $appData['removable'];
267
-
268
-			// fix licence vs license
269
-			if (isset($appData['license']) && !isset($appData['licence'])) {
270
-				$appData['licence'] = $appData['license'];
271
-			}
272
-
273
-			$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
274
-			if (!is_array($ignoreMaxApps)) {
275
-				$this->logger->warning('The value given for app_install_overwrite is not an array. Ignoring...');
276
-				$ignoreMaxApps = [];
277
-			}
278
-			$ignoreMax = in_array($appData['id'], $ignoreMaxApps);
279
-
280
-			// analyse dependencies
281
-			$missing = $dependencyAnalyzer->analyze($appData, $ignoreMax);
282
-			$appData['canInstall'] = empty($missing);
283
-			$appData['missingDependencies'] = $missing;
284
-
285
-			$appData['missingMinOwnCloudVersion'] = !isset($appData['dependencies']['nextcloud']['@attributes']['min-version']);
286
-			$appData['missingMaxOwnCloudVersion'] = !isset($appData['dependencies']['nextcloud']['@attributes']['max-version']);
287
-			$appData['isCompatible'] = $dependencyAnalyzer->isMarkedCompatible($appData);
288
-
289
-			return $appData;
290
-		}, $apps);
291
-
292
-		usort($apps, [$this, 'sortApps']);
293
-
294
-		return new JSONResponse(['apps' => $apps, 'status' => 'success']);
295
-	}
296
-
297
-	/**
298
-	 * Get all apps for a category from the app store
299
-	 *
300
-	 * @param string $requestedCategory
301
-	 * @return array
302
-	 * @throws \Exception
303
-	 */
304
-	private function getAppsForCategory($requestedCategory = ''): array {
305
-		$versionParser = new VersionParser();
306
-		$formattedApps = [];
307
-		$apps = $this->appFetcher->get();
308
-		foreach($apps as $app) {
309
-			// Skip all apps not in the requested category
310
-			if ($requestedCategory !== '') {
311
-				$isInCategory = false;
312
-				foreach($app['categories'] as $category) {
313
-					if($category === $requestedCategory) {
314
-						$isInCategory = true;
315
-					}
316
-				}
317
-				if(!$isInCategory) {
318
-					continue;
319
-				}
320
-			}
321
-
322
-			if (!isset($app['releases'][0]['rawPlatformVersionSpec'])) {
323
-				continue;
324
-			}
325
-			$nextCloudVersion = $versionParser->getVersion($app['releases'][0]['rawPlatformVersionSpec']);
326
-			$nextCloudVersionDependencies = [];
327
-			if($nextCloudVersion->getMinimumVersion() !== '') {
328
-				$nextCloudVersionDependencies['nextcloud']['@attributes']['min-version'] = $nextCloudVersion->getMinimumVersion();
329
-			}
330
-			if($nextCloudVersion->getMaximumVersion() !== '') {
331
-				$nextCloudVersionDependencies['nextcloud']['@attributes']['max-version'] = $nextCloudVersion->getMaximumVersion();
332
-			}
333
-			$phpVersion = $versionParser->getVersion($app['releases'][0]['rawPhpVersionSpec']);
334
-			$existsLocally = \OC_App::getAppPath($app['id']) !== false;
335
-			$phpDependencies = [];
336
-			if($phpVersion->getMinimumVersion() !== '') {
337
-				$phpDependencies['php']['@attributes']['min-version'] = $phpVersion->getMinimumVersion();
338
-			}
339
-			if($phpVersion->getMaximumVersion() !== '') {
340
-				$phpDependencies['php']['@attributes']['max-version'] = $phpVersion->getMaximumVersion();
341
-			}
342
-			if(isset($app['releases'][0]['minIntSize'])) {
343
-				$phpDependencies['php']['@attributes']['min-int-size'] = $app['releases'][0]['minIntSize'];
344
-			}
345
-			$authors = '';
346
-			foreach($app['authors'] as $key => $author) {
347
-				$authors .= $author['name'];
348
-				if($key !== count($app['authors']) - 1) {
349
-					$authors .= ', ';
350
-				}
351
-			}
352
-
353
-			$currentLanguage = substr(\OC::$server->getL10NFactory()->findLanguage(), 0, 2);
354
-			$enabledValue = $this->config->getAppValue($app['id'], 'enabled', 'no');
355
-			$groups = null;
356
-			if($enabledValue !== 'no' && $enabledValue !== 'yes') {
357
-				$groups = $enabledValue;
358
-			}
359
-
360
-			$currentVersion = '';
361
-			if($this->appManager->isInstalled($app['id'])) {
362
-				$currentVersion = $this->appManager->getAppVersion($app['id']);
363
-			} else {
364
-				$currentLanguage = $app['releases'][0]['version'];
365
-			}
366
-
367
-			$formattedApps[] = [
368
-				'id' => $app['id'],
369
-				'name' => isset($app['translations'][$currentLanguage]['name']) ? $app['translations'][$currentLanguage]['name'] : $app['translations']['en']['name'],
370
-				'description' => isset($app['translations'][$currentLanguage]['description']) ? $app['translations'][$currentLanguage]['description'] : $app['translations']['en']['description'],
371
-				'summary' => isset($app['translations'][$currentLanguage]['summary']) ? $app['translations'][$currentLanguage]['summary'] : $app['translations']['en']['summary'],
372
-				'license' => $app['releases'][0]['licenses'],
373
-				'author' => $authors,
374
-				'shipped' => false,
375
-				'version' => $currentVersion,
376
-				'default_enable' => '',
377
-				'types' => [],
378
-				'documentation' => [
379
-					'admin' => $app['adminDocs'],
380
-					'user' => $app['userDocs'],
381
-					'developer' => $app['developerDocs']
382
-				],
383
-				'website' => $app['website'],
384
-				'bugs' => $app['issueTracker'],
385
-				'detailpage' => $app['website'],
386
-				'dependencies' => array_merge(
387
-					$nextCloudVersionDependencies,
388
-					$phpDependencies
389
-				),
390
-				'level' => ($app['isFeatured'] === true) ? 200 : 100,
391
-				'missingMaxOwnCloudVersion' => false,
392
-				'missingMinOwnCloudVersion' => false,
393
-				'canInstall' => true,
394
-				'screenshot' => isset($app['screenshots'][0]['url']) ? 'https://usercontent.apps.nextcloud.com/'.base64_encode($app['screenshots'][0]['url']) : '',
395
-				'score' => $app['ratingOverall'],
396
-				'ratingNumOverall' => $app['ratingNumOverall'],
397
-				'ratingNumThresholdReached' => $app['ratingNumOverall'] > 5,
398
-				'removable' => $existsLocally,
399
-				'active' => $this->appManager->isEnabledForUser($app['id']),
400
-				'needsDownload' => !$existsLocally,
401
-				'groups' => $groups,
402
-				'fromAppStore' => true,
403
-				'appstoreData' => $app,
404
-			];
405
-		}
406
-
407
-		return $formattedApps;
408
-	}
409
-
410
-	/**
411
-	 * @PasswordConfirmationRequired
412
-	 *
413
-	 * @param string $appId
414
-	 * @param array $groups
415
-	 * @return JSONResponse
416
-	 */
417
-	public function enableApp(string $appId, array $groups = []): JSONResponse {
418
-		return $this->enableApps([$appId], $groups);
419
-	}
420
-
421
-	/**
422
-	 * Enable one or more apps
423
-	 *
424
-	 * apps will be enabled for specific groups only if $groups is defined
425
-	 *
426
-	 * @PasswordConfirmationRequired
427
-	 * @param array $appIds
428
-	 * @param array $groups
429
-	 * @return JSONResponse
430
-	 */
431
-	public function enableApps(array $appIds, array $groups = []): JSONResponse {
432
-		try {
433
-			$updateRequired = false;
434
-
435
-			foreach ($appIds as $appId) {
436
-				$appId = OC_App::cleanAppId($appId);
437
-
438
-				// Check if app is already downloaded
439
-				/** @var Installer $installer */
440
-				$installer = \OC::$server->query(Installer::class);
441
-				$isDownloaded = $installer->isDownloaded($appId);
442
-
443
-				if(!$isDownloaded) {
444
-					$installer->downloadApp($appId);
445
-				}
446
-
447
-				$installer->installApp($appId);
448
-
449
-				if (count($groups) > 0) {
450
-					$this->appManager->enableAppForGroups($appId, $this->getGroupList($groups));
451
-				} else {
452
-					$this->appManager->enableApp($appId);
453
-				}
454
-				if (\OC_App::shouldUpgrade($appId)) {
455
-					$updateRequired = true;
456
-				}
457
-			}
458
-			return new JSONResponse(['data' => ['update_required' => $updateRequired]]);
459
-
460
-		} catch (\Exception $e) {
461
-			$this->logger->logException($e);
462
-			return new JSONResponse(['data' => ['message' => $e->getMessage()]], Http::STATUS_INTERNAL_SERVER_ERROR);
463
-		}
464
-	}
465
-
466
-	private function getGroupList(array $groups) {
467
-		$groupManager = \OC::$server->getGroupManager();
468
-		$groupsList = [];
469
-		foreach ($groups as $group) {
470
-			$groupItem = $groupManager->get($group);
471
-			if ($groupItem instanceof \OCP\IGroup) {
472
-				$groupsList[] = $groupManager->get($group);
473
-			}
474
-		}
475
-		return $groupsList;
476
-	}
477
-
478
-	/**
479
-	 * @PasswordConfirmationRequired
480
-	 *
481
-	 * @param string $appId
482
-	 * @return JSONResponse
483
-	 */
484
-	public function disableApp(string $appId): JSONResponse {
485
-		return $this->disableApps([$appId]);
486
-	}
487
-
488
-	/**
489
-	 * @PasswordConfirmationRequired
490
-	 *
491
-	 * @param array $appIds
492
-	 * @return JSONResponse
493
-	 */
494
-	public function disableApps(array $appIds): JSONResponse {
495
-		try {
496
-			foreach ($appIds as $appId) {
497
-				$appId = OC_App::cleanAppId($appId);
498
-				$this->appManager->disableApp($appId);
499
-			}
500
-			return new JSONResponse([]);
501
-		} catch (\Exception $e) {
502
-			$this->logger->logException($e);
503
-			return new JSONResponse(['data' => ['message' => $e->getMessage()]], Http::STATUS_INTERNAL_SERVER_ERROR);
504
-		}
505
-	}
506
-
507
-	/**
508
-	 * @PasswordConfirmationRequired
509
-	 *
510
-	 * @param string $appId
511
-	 * @return JSONResponse
512
-	 */
513
-	public function uninstallApp(string $appId): JSONResponse {
514
-		$appId = OC_App::cleanAppId($appId);
515
-		$result = $this->installer->removeApp($appId);
516
-		if($result !== false) {
517
-			$this->appManager->clearAppsCache();
518
-			return new JSONResponse(['data' => ['appid' => $appId]]);
519
-		}
520
-		return new JSONResponse(['data' => ['message' => $this->l10n->t('Couldn\'t remove app.')]], Http::STATUS_INTERNAL_SERVER_ERROR);
521
-	}
522
-
523
-	/**
524
-	 * @param string $appId
525
-	 * @return JSONResponse
526
-	 */
527
-	public function updateApp(string $appId): JSONResponse {
528
-		$appId = OC_App::cleanAppId($appId);
529
-
530
-		$this->config->setSystemValue('maintenance', true);
531
-		try {
532
-			$result = $this->installer->updateAppstoreApp($appId);
533
-			$this->config->setSystemValue('maintenance', false);
534
-		} catch (\Exception $ex) {
535
-			$this->config->setSystemValue('maintenance', false);
536
-			return new JSONResponse(['data' => ['message' => $ex->getMessage()]], Http::STATUS_INTERNAL_SERVER_ERROR);
537
-		}
538
-
539
-		if ($result !== false) {
540
-			return new JSONResponse(['data' => ['appid' => $appId]]);
541
-		}
542
-		return new JSONResponse(['data' => ['message' => $this->l10n->t('Couldn\'t update app.')]], Http::STATUS_INTERNAL_SERVER_ERROR);
543
-	}
544
-
545
-	private function sortApps($a, $b) {
546
-		$a = (string)$a['name'];
547
-		$b = (string)$b['name'];
548
-		if ($a === $b) {
549
-			return 0;
550
-		}
551
-		return ($a < $b) ? -1 : 1;
552
-	}
553
-
554
-	public function force(string $appId): JSONResponse {
555
-		$appId = OC_App::cleanAppId($appId);
556
-		$this->appManager->ignoreNextcloudRequirementForApp($appId);
557
-		return new JSONResponse();
558
-	}
57
+    /** @var \OCP\IL10N */
58
+    private $l10n;
59
+    /** @var IConfig */
60
+    private $config;
61
+    /** @var INavigationManager */
62
+    private $navigationManager;
63
+    /** @var IAppManager */
64
+    private $appManager;
65
+    /** @var CategoryFetcher */
66
+    private $categoryFetcher;
67
+    /** @var AppFetcher */
68
+    private $appFetcher;
69
+    /** @var IFactory */
70
+    private $l10nFactory;
71
+    /** @var BundleFetcher */
72
+    private $bundleFetcher;
73
+    /** @var Installer */
74
+    private $installer;
75
+    /** @var IURLGenerator */
76
+    private $urlGenerator;
77
+    /** @var ILogger */
78
+    private $logger;
79
+
80
+    /** @var array */
81
+    private $allApps = [];
82
+
83
+    /**
84
+     * @param string $appName
85
+     * @param IRequest $request
86
+     * @param IL10N $l10n
87
+     * @param IConfig $config
88
+     * @param INavigationManager $navigationManager
89
+     * @param IAppManager $appManager
90
+     * @param CategoryFetcher $categoryFetcher
91
+     * @param AppFetcher $appFetcher
92
+     * @param IFactory $l10nFactory
93
+     * @param BundleFetcher $bundleFetcher
94
+     * @param Installer $installer
95
+     * @param IURLGenerator $urlGenerator
96
+     * @param ILogger $logger
97
+     */
98
+    public function __construct(string $appName,
99
+                                IRequest $request,
100
+                                IL10N $l10n,
101
+                                IConfig $config,
102
+                                INavigationManager $navigationManager,
103
+                                IAppManager $appManager,
104
+                                CategoryFetcher $categoryFetcher,
105
+                                AppFetcher $appFetcher,
106
+                                IFactory $l10nFactory,
107
+                                BundleFetcher $bundleFetcher,
108
+                                Installer $installer,
109
+                                IURLGenerator $urlGenerator,
110
+                                ILogger $logger) {
111
+        parent::__construct($appName, $request);
112
+        $this->l10n = $l10n;
113
+        $this->config = $config;
114
+        $this->navigationManager = $navigationManager;
115
+        $this->appManager = $appManager;
116
+        $this->categoryFetcher = $categoryFetcher;
117
+        $this->appFetcher = $appFetcher;
118
+        $this->l10nFactory = $l10nFactory;
119
+        $this->bundleFetcher = $bundleFetcher;
120
+        $this->installer = $installer;
121
+        $this->urlGenerator = $urlGenerator;
122
+        $this->logger = $logger;
123
+    }
124
+
125
+    /**
126
+     * @NoCSRFRequired
127
+     *
128
+     * @return TemplateResponse
129
+     */
130
+    public function viewApps(): TemplateResponse {
131
+        \OC_Util::addScript('settings', 'apps');
132
+        $params = [];
133
+        $params['appstoreEnabled'] = $this->config->getSystemValue('appstoreenabled', true) === true;
134
+        $params['updateCount'] = count($this->getAppsWithUpdates());
135
+        $params['developerDocumentation'] = $this->urlGenerator->linkToDocs('developer-manual');
136
+        $params['bundles'] = $this->getBundles();
137
+        $this->navigationManager->setActiveEntry('core_apps');
138
+
139
+        $templateResponse = new TemplateResponse('settings', 'settings-vue', ['serverData' => $params]);
140
+        $policy = new ContentSecurityPolicy();
141
+        $policy->addAllowedImageDomain('https://usercontent.apps.nextcloud.com');
142
+        $templateResponse->setContentSecurityPolicy($policy);
143
+
144
+        return $templateResponse;
145
+    }
146
+
147
+    private function getAppsWithUpdates() {
148
+        $appClass = new \OC_App();
149
+        $apps = $appClass->listAllApps();
150
+        foreach($apps as $key => $app) {
151
+            $newVersion = $this->installer->isUpdateAvailable($app['id']);
152
+            if($newVersion === false) {
153
+                unset($apps[$key]);
154
+            }
155
+        }
156
+        return $apps;
157
+    }
158
+
159
+    private function getBundles() {
160
+        $result = [];
161
+        $bundles = $this->bundleFetcher->getBundles();
162
+        foreach ($bundles as $bundle) {
163
+            $result[] = [
164
+                'name' => $bundle->getName(),
165
+                'id' => $bundle->getIdentifier(),
166
+                'appIdentifiers' => $bundle->getAppIdentifiers()
167
+            ];
168
+        }
169
+        return $result;
170
+
171
+    }
172
+
173
+    /**
174
+     * Get all available categories
175
+     *
176
+     * @return JSONResponse
177
+     */
178
+    public function listCategories(): JSONResponse {
179
+        return new JSONResponse($this->getAllCategories());
180
+    }
181
+
182
+    private function getAllCategories() {
183
+        $currentLanguage = substr($this->l10nFactory->findLanguage(), 0, 2);
184
+
185
+        $formattedCategories = [];
186
+        $categories = $this->categoryFetcher->get();
187
+        foreach($categories as $category) {
188
+            $formattedCategories[] = [
189
+                'id' => $category['id'],
190
+                'ident' => $category['id'],
191
+                'displayName' => isset($category['translations'][$currentLanguage]['name']) ? $category['translations'][$currentLanguage]['name'] : $category['translations']['en']['name'],
192
+            ];
193
+        }
194
+
195
+        return $formattedCategories;
196
+    }
197
+
198
+    private function fetchApps() {
199
+        $appClass = new \OC_App();
200
+        $apps = $appClass->listAllApps();
201
+        foreach ($apps as $app) {
202
+            $app['installed'] = true;
203
+            $this->allApps[$app['id']] = $app;
204
+        }
205
+
206
+        $apps = $this->getAppsForCategory('');
207
+        foreach ($apps as $app) {
208
+            $app['appstore'] = true;
209
+            if (!array_key_exists($app['id'], $this->allApps)) {
210
+                $this->allApps[$app['id']] = $app;
211
+            } else {
212
+                $this->allApps[$app['id']] = array_merge($app, $this->allApps[$app['id']]);
213
+            }
214
+        }
215
+
216
+        // add bundle information
217
+        $bundles = $this->bundleFetcher->getBundles();
218
+        foreach($bundles as $bundle) {
219
+            foreach($bundle->getAppIdentifiers() as $identifier) {
220
+                foreach($this->allApps as &$app) {
221
+                    if($app['id'] === $identifier) {
222
+                        $app['bundleIds'][] = $bundle->getIdentifier();
223
+                        continue;
224
+                    }
225
+                }
226
+            }
227
+        }
228
+    }
229
+
230
+    private function getAllApps() {
231
+        return $this->allApps;
232
+    }
233
+    /**
234
+     * Get all available apps in a category
235
+     *
236
+     * @param string $category
237
+     * @return JSONResponse
238
+     * @throws \Exception
239
+     */
240
+    public function listApps(): JSONResponse {
241
+
242
+        $this->fetchApps();
243
+        $apps = $this->getAllApps();
244
+
245
+        $dependencyAnalyzer = new DependencyAnalyzer(new Platform($this->config), $this->l10n);
246
+
247
+        // Extend existing app details
248
+        $apps = array_map(function($appData) use ($dependencyAnalyzer) {
249
+            if (isset($appData['appstoreData'])) {
250
+                $appstoreData = $appData['appstoreData'];
251
+                $appData['screenshot'] = isset($appstoreData['screenshots'][0]['url']) ? 'https://usercontent.apps.nextcloud.com/' . base64_encode($appstoreData['screenshots'][0]['url']) : '';
252
+                $appData['category'] = $appstoreData['categories'];
253
+            }
254
+
255
+            $newVersion = $this->installer->isUpdateAvailable($appData['id']);
256
+            if($newVersion) {
257
+                $appData['update'] = $newVersion;
258
+            }
259
+
260
+            // fix groups to be an array
261
+            $groups = [];
262
+            if (is_string($appData['groups'])) {
263
+                $groups = json_decode($appData['groups']);
264
+            }
265
+            $appData['groups'] = $groups;
266
+            $appData['canUnInstall'] = !$appData['active'] && $appData['removable'];
267
+
268
+            // fix licence vs license
269
+            if (isset($appData['license']) && !isset($appData['licence'])) {
270
+                $appData['licence'] = $appData['license'];
271
+            }
272
+
273
+            $ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
274
+            if (!is_array($ignoreMaxApps)) {
275
+                $this->logger->warning('The value given for app_install_overwrite is not an array. Ignoring...');
276
+                $ignoreMaxApps = [];
277
+            }
278
+            $ignoreMax = in_array($appData['id'], $ignoreMaxApps);
279
+
280
+            // analyse dependencies
281
+            $missing = $dependencyAnalyzer->analyze($appData, $ignoreMax);
282
+            $appData['canInstall'] = empty($missing);
283
+            $appData['missingDependencies'] = $missing;
284
+
285
+            $appData['missingMinOwnCloudVersion'] = !isset($appData['dependencies']['nextcloud']['@attributes']['min-version']);
286
+            $appData['missingMaxOwnCloudVersion'] = !isset($appData['dependencies']['nextcloud']['@attributes']['max-version']);
287
+            $appData['isCompatible'] = $dependencyAnalyzer->isMarkedCompatible($appData);
288
+
289
+            return $appData;
290
+        }, $apps);
291
+
292
+        usort($apps, [$this, 'sortApps']);
293
+
294
+        return new JSONResponse(['apps' => $apps, 'status' => 'success']);
295
+    }
296
+
297
+    /**
298
+     * Get all apps for a category from the app store
299
+     *
300
+     * @param string $requestedCategory
301
+     * @return array
302
+     * @throws \Exception
303
+     */
304
+    private function getAppsForCategory($requestedCategory = ''): array {
305
+        $versionParser = new VersionParser();
306
+        $formattedApps = [];
307
+        $apps = $this->appFetcher->get();
308
+        foreach($apps as $app) {
309
+            // Skip all apps not in the requested category
310
+            if ($requestedCategory !== '') {
311
+                $isInCategory = false;
312
+                foreach($app['categories'] as $category) {
313
+                    if($category === $requestedCategory) {
314
+                        $isInCategory = true;
315
+                    }
316
+                }
317
+                if(!$isInCategory) {
318
+                    continue;
319
+                }
320
+            }
321
+
322
+            if (!isset($app['releases'][0]['rawPlatformVersionSpec'])) {
323
+                continue;
324
+            }
325
+            $nextCloudVersion = $versionParser->getVersion($app['releases'][0]['rawPlatformVersionSpec']);
326
+            $nextCloudVersionDependencies = [];
327
+            if($nextCloudVersion->getMinimumVersion() !== '') {
328
+                $nextCloudVersionDependencies['nextcloud']['@attributes']['min-version'] = $nextCloudVersion->getMinimumVersion();
329
+            }
330
+            if($nextCloudVersion->getMaximumVersion() !== '') {
331
+                $nextCloudVersionDependencies['nextcloud']['@attributes']['max-version'] = $nextCloudVersion->getMaximumVersion();
332
+            }
333
+            $phpVersion = $versionParser->getVersion($app['releases'][0]['rawPhpVersionSpec']);
334
+            $existsLocally = \OC_App::getAppPath($app['id']) !== false;
335
+            $phpDependencies = [];
336
+            if($phpVersion->getMinimumVersion() !== '') {
337
+                $phpDependencies['php']['@attributes']['min-version'] = $phpVersion->getMinimumVersion();
338
+            }
339
+            if($phpVersion->getMaximumVersion() !== '') {
340
+                $phpDependencies['php']['@attributes']['max-version'] = $phpVersion->getMaximumVersion();
341
+            }
342
+            if(isset($app['releases'][0]['minIntSize'])) {
343
+                $phpDependencies['php']['@attributes']['min-int-size'] = $app['releases'][0]['minIntSize'];
344
+            }
345
+            $authors = '';
346
+            foreach($app['authors'] as $key => $author) {
347
+                $authors .= $author['name'];
348
+                if($key !== count($app['authors']) - 1) {
349
+                    $authors .= ', ';
350
+                }
351
+            }
352
+
353
+            $currentLanguage = substr(\OC::$server->getL10NFactory()->findLanguage(), 0, 2);
354
+            $enabledValue = $this->config->getAppValue($app['id'], 'enabled', 'no');
355
+            $groups = null;
356
+            if($enabledValue !== 'no' && $enabledValue !== 'yes') {
357
+                $groups = $enabledValue;
358
+            }
359
+
360
+            $currentVersion = '';
361
+            if($this->appManager->isInstalled($app['id'])) {
362
+                $currentVersion = $this->appManager->getAppVersion($app['id']);
363
+            } else {
364
+                $currentLanguage = $app['releases'][0]['version'];
365
+            }
366
+
367
+            $formattedApps[] = [
368
+                'id' => $app['id'],
369
+                'name' => isset($app['translations'][$currentLanguage]['name']) ? $app['translations'][$currentLanguage]['name'] : $app['translations']['en']['name'],
370
+                'description' => isset($app['translations'][$currentLanguage]['description']) ? $app['translations'][$currentLanguage]['description'] : $app['translations']['en']['description'],
371
+                'summary' => isset($app['translations'][$currentLanguage]['summary']) ? $app['translations'][$currentLanguage]['summary'] : $app['translations']['en']['summary'],
372
+                'license' => $app['releases'][0]['licenses'],
373
+                'author' => $authors,
374
+                'shipped' => false,
375
+                'version' => $currentVersion,
376
+                'default_enable' => '',
377
+                'types' => [],
378
+                'documentation' => [
379
+                    'admin' => $app['adminDocs'],
380
+                    'user' => $app['userDocs'],
381
+                    'developer' => $app['developerDocs']
382
+                ],
383
+                'website' => $app['website'],
384
+                'bugs' => $app['issueTracker'],
385
+                'detailpage' => $app['website'],
386
+                'dependencies' => array_merge(
387
+                    $nextCloudVersionDependencies,
388
+                    $phpDependencies
389
+                ),
390
+                'level' => ($app['isFeatured'] === true) ? 200 : 100,
391
+                'missingMaxOwnCloudVersion' => false,
392
+                'missingMinOwnCloudVersion' => false,
393
+                'canInstall' => true,
394
+                'screenshot' => isset($app['screenshots'][0]['url']) ? 'https://usercontent.apps.nextcloud.com/'.base64_encode($app['screenshots'][0]['url']) : '',
395
+                'score' => $app['ratingOverall'],
396
+                'ratingNumOverall' => $app['ratingNumOverall'],
397
+                'ratingNumThresholdReached' => $app['ratingNumOverall'] > 5,
398
+                'removable' => $existsLocally,
399
+                'active' => $this->appManager->isEnabledForUser($app['id']),
400
+                'needsDownload' => !$existsLocally,
401
+                'groups' => $groups,
402
+                'fromAppStore' => true,
403
+                'appstoreData' => $app,
404
+            ];
405
+        }
406
+
407
+        return $formattedApps;
408
+    }
409
+
410
+    /**
411
+     * @PasswordConfirmationRequired
412
+     *
413
+     * @param string $appId
414
+     * @param array $groups
415
+     * @return JSONResponse
416
+     */
417
+    public function enableApp(string $appId, array $groups = []): JSONResponse {
418
+        return $this->enableApps([$appId], $groups);
419
+    }
420
+
421
+    /**
422
+     * Enable one or more apps
423
+     *
424
+     * apps will be enabled for specific groups only if $groups is defined
425
+     *
426
+     * @PasswordConfirmationRequired
427
+     * @param array $appIds
428
+     * @param array $groups
429
+     * @return JSONResponse
430
+     */
431
+    public function enableApps(array $appIds, array $groups = []): JSONResponse {
432
+        try {
433
+            $updateRequired = false;
434
+
435
+            foreach ($appIds as $appId) {
436
+                $appId = OC_App::cleanAppId($appId);
437
+
438
+                // Check if app is already downloaded
439
+                /** @var Installer $installer */
440
+                $installer = \OC::$server->query(Installer::class);
441
+                $isDownloaded = $installer->isDownloaded($appId);
442
+
443
+                if(!$isDownloaded) {
444
+                    $installer->downloadApp($appId);
445
+                }
446
+
447
+                $installer->installApp($appId);
448
+
449
+                if (count($groups) > 0) {
450
+                    $this->appManager->enableAppForGroups($appId, $this->getGroupList($groups));
451
+                } else {
452
+                    $this->appManager->enableApp($appId);
453
+                }
454
+                if (\OC_App::shouldUpgrade($appId)) {
455
+                    $updateRequired = true;
456
+                }
457
+            }
458
+            return new JSONResponse(['data' => ['update_required' => $updateRequired]]);
459
+
460
+        } catch (\Exception $e) {
461
+            $this->logger->logException($e);
462
+            return new JSONResponse(['data' => ['message' => $e->getMessage()]], Http::STATUS_INTERNAL_SERVER_ERROR);
463
+        }
464
+    }
465
+
466
+    private function getGroupList(array $groups) {
467
+        $groupManager = \OC::$server->getGroupManager();
468
+        $groupsList = [];
469
+        foreach ($groups as $group) {
470
+            $groupItem = $groupManager->get($group);
471
+            if ($groupItem instanceof \OCP\IGroup) {
472
+                $groupsList[] = $groupManager->get($group);
473
+            }
474
+        }
475
+        return $groupsList;
476
+    }
477
+
478
+    /**
479
+     * @PasswordConfirmationRequired
480
+     *
481
+     * @param string $appId
482
+     * @return JSONResponse
483
+     */
484
+    public function disableApp(string $appId): JSONResponse {
485
+        return $this->disableApps([$appId]);
486
+    }
487
+
488
+    /**
489
+     * @PasswordConfirmationRequired
490
+     *
491
+     * @param array $appIds
492
+     * @return JSONResponse
493
+     */
494
+    public function disableApps(array $appIds): JSONResponse {
495
+        try {
496
+            foreach ($appIds as $appId) {
497
+                $appId = OC_App::cleanAppId($appId);
498
+                $this->appManager->disableApp($appId);
499
+            }
500
+            return new JSONResponse([]);
501
+        } catch (\Exception $e) {
502
+            $this->logger->logException($e);
503
+            return new JSONResponse(['data' => ['message' => $e->getMessage()]], Http::STATUS_INTERNAL_SERVER_ERROR);
504
+        }
505
+    }
506
+
507
+    /**
508
+     * @PasswordConfirmationRequired
509
+     *
510
+     * @param string $appId
511
+     * @return JSONResponse
512
+     */
513
+    public function uninstallApp(string $appId): JSONResponse {
514
+        $appId = OC_App::cleanAppId($appId);
515
+        $result = $this->installer->removeApp($appId);
516
+        if($result !== false) {
517
+            $this->appManager->clearAppsCache();
518
+            return new JSONResponse(['data' => ['appid' => $appId]]);
519
+        }
520
+        return new JSONResponse(['data' => ['message' => $this->l10n->t('Couldn\'t remove app.')]], Http::STATUS_INTERNAL_SERVER_ERROR);
521
+    }
522
+
523
+    /**
524
+     * @param string $appId
525
+     * @return JSONResponse
526
+     */
527
+    public function updateApp(string $appId): JSONResponse {
528
+        $appId = OC_App::cleanAppId($appId);
529
+
530
+        $this->config->setSystemValue('maintenance', true);
531
+        try {
532
+            $result = $this->installer->updateAppstoreApp($appId);
533
+            $this->config->setSystemValue('maintenance', false);
534
+        } catch (\Exception $ex) {
535
+            $this->config->setSystemValue('maintenance', false);
536
+            return new JSONResponse(['data' => ['message' => $ex->getMessage()]], Http::STATUS_INTERNAL_SERVER_ERROR);
537
+        }
538
+
539
+        if ($result !== false) {
540
+            return new JSONResponse(['data' => ['appid' => $appId]]);
541
+        }
542
+        return new JSONResponse(['data' => ['message' => $this->l10n->t('Couldn\'t update app.')]], Http::STATUS_INTERNAL_SERVER_ERROR);
543
+    }
544
+
545
+    private function sortApps($a, $b) {
546
+        $a = (string)$a['name'];
547
+        $b = (string)$b['name'];
548
+        if ($a === $b) {
549
+            return 0;
550
+        }
551
+        return ($a < $b) ? -1 : 1;
552
+    }
553
+
554
+    public function force(string $appId): JSONResponse {
555
+        $appId = OC_App::cleanAppId($appId);
556
+        $this->appManager->ignoreNextcloudRequirementForApp($appId);
557
+        return new JSONResponse();
558
+    }
559 559
 
560 560
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/PersonalSettingsController.php 1 patch
Indentation   +65 added lines, -65 removed lines patch added patch discarded remove patch
@@ -36,78 +36,78 @@
 block discarded – undo
36 36
 use OCP\Template;
37 37
 
38 38
 class PersonalSettingsController extends Controller {
39
-	use CommonSettingsTrait;
39
+    use CommonSettingsTrait;
40 40
 
41
-	public function __construct(
42
-		$appName,
43
-		IRequest $request,
44
-		INavigationManager $navigationManager,
45
-		ISettingsManager $settingsManager,
46
-		IUserSession $userSession,
47
-		IGroupManager $groupManager,
48
-		ISubAdmin $subAdmin
49
-	) {
50
-		parent::__construct($appName, $request);
51
-		$this->navigationManager = $navigationManager;
52
-		$this->settingsManager = $settingsManager;
53
-		$this->userSession = $userSession;
54
-		$this->subAdmin = $subAdmin;
55
-		$this->groupManager = $groupManager;
56
-	}
41
+    public function __construct(
42
+        $appName,
43
+        IRequest $request,
44
+        INavigationManager $navigationManager,
45
+        ISettingsManager $settingsManager,
46
+        IUserSession $userSession,
47
+        IGroupManager $groupManager,
48
+        ISubAdmin $subAdmin
49
+    ) {
50
+        parent::__construct($appName, $request);
51
+        $this->navigationManager = $navigationManager;
52
+        $this->settingsManager = $settingsManager;
53
+        $this->userSession = $userSession;
54
+        $this->subAdmin = $subAdmin;
55
+        $this->groupManager = $groupManager;
56
+    }
57 57
 
58
-	/**
59
-	 * @param string $section
60
-	 * @return TemplateResponse
61
-	 *
62
-	 * @NoCSRFRequired
63
-	 * @NoAdminRequired
64
-	 * @NoSubadminRequired
65
-	 */
66
-	public function index($section) {
67
-		return $this->getIndexResponse('personal', $section);
58
+    /**
59
+     * @param string $section
60
+     * @return TemplateResponse
61
+     *
62
+     * @NoCSRFRequired
63
+     * @NoAdminRequired
64
+     * @NoSubadminRequired
65
+     */
66
+    public function index($section) {
67
+        return $this->getIndexResponse('personal', $section);
68 68
 
69
-	}
69
+    }
70 70
 
71
-	/**
72
-	 * @param string $section
73
-	 * @return array
74
-	 */
75
-	protected function getSettings($section) {
76
-		$settings = $this->settingsManager->getPersonalSettings($section);
77
-		$formatted = $this->formatSettings($settings);
78
-		if($section === 'additional') {
79
-			$formatted['content'] .= $this->getLegacyForms();
80
-		}
81
-		return $formatted;
82
-	}
71
+    /**
72
+     * @param string $section
73
+     * @return array
74
+     */
75
+    protected function getSettings($section) {
76
+        $settings = $this->settingsManager->getPersonalSettings($section);
77
+        $formatted = $this->formatSettings($settings);
78
+        if($section === 'additional') {
79
+            $formatted['content'] .= $this->getLegacyForms();
80
+        }
81
+        return $formatted;
82
+    }
83 83
 
84
-	/**
85
-	 * @return bool|string
86
-	 */
87
-	private function getLegacyForms() {
88
-		$forms = \OC_App::getForms('personal');
84
+    /**
85
+     * @return bool|string
86
+     */
87
+    private function getLegacyForms() {
88
+        $forms = \OC_App::getForms('personal');
89 89
 
90
-		$forms = array_map(function ($form) {
91
-			if (preg_match('%(<h2(?P<class>[^>]*)>.*?</h2>)%i', $form, $regs)) {
92
-				$sectionName = str_replace('<h2' . $regs['class'] . '>', '', $regs[0]);
93
-				$sectionName = str_replace('</h2>', '', $sectionName);
94
-				$anchor = strtolower($sectionName);
95
-				$anchor = str_replace(' ', '-', $anchor);
90
+        $forms = array_map(function ($form) {
91
+            if (preg_match('%(<h2(?P<class>[^>]*)>.*?</h2>)%i', $form, $regs)) {
92
+                $sectionName = str_replace('<h2' . $regs['class'] . '>', '', $regs[0]);
93
+                $sectionName = str_replace('</h2>', '', $sectionName);
94
+                $anchor = strtolower($sectionName);
95
+                $anchor = str_replace(' ', '-', $anchor);
96 96
 
97
-				return [
98
-					'anchor' => $anchor,
99
-					'section-name' => $sectionName,
100
-					'form' => $form
101
-				];
102
-			}
103
-			return [
104
-				'form' => $form
105
-			];
106
-		}, $forms);
97
+                return [
98
+                    'anchor' => $anchor,
99
+                    'section-name' => $sectionName,
100
+                    'form' => $form
101
+                ];
102
+            }
103
+            return [
104
+                'form' => $form
105
+            ];
106
+        }, $forms);
107 107
 
108
-		$out = new Template('settings', 'settings/additional');
109
-		$out->assign('forms', $forms);
108
+        $out = new Template('settings', 'settings/additional');
109
+        $out->assign('forms', $forms);
110 110
 
111
-		return $out->fetchPage();
112
-	}
111
+        return $out->fetchPage();
112
+    }
113 113
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/UsersController.php 1 patch
Indentation   +465 added lines, -465 removed lines patch added patch discarded remove patch
@@ -57,469 +57,469 @@
 block discarded – undo
57 57
 use function in_array;
58 58
 
59 59
 class UsersController extends Controller {
60
-	/** @var IUserManager */
61
-	private $userManager;
62
-	/** @var IGroupManager */
63
-	private $groupManager;
64
-	/** @var IUserSession */
65
-	private $userSession;
66
-	/** @var IConfig */
67
-	private $config;
68
-	/** @var bool */
69
-	private $isAdmin;
70
-	/** @var IL10N */
71
-	private $l10n;
72
-	/** @var IMailer */
73
-	private $mailer;
74
-	/** @var IFactory */
75
-	private $l10nFactory;
76
-	/** @var IAppManager */
77
-	private $appManager;
78
-	/** @var AccountManager */
79
-	private $accountManager;
80
-	/** @var Manager */
81
-	private $keyManager;
82
-	/** @var IJobList */
83
-	private $jobList;
84
-	/** @var IManager */
85
-	private $encryptionManager;
86
-
87
-
88
-	public function __construct(string $appName,
89
-								IRequest $request,
90
-								IUserManager $userManager,
91
-								IGroupManager $groupManager,
92
-								IUserSession $userSession,
93
-								IConfig $config,
94
-								bool $isAdmin,
95
-								IL10N $l10n,
96
-								IMailer $mailer,
97
-								IFactory $l10nFactory,
98
-								IAppManager $appManager,
99
-								AccountManager $accountManager,
100
-								Manager $keyManager,
101
-								IJobList $jobList,
102
-								IManager $encryptionManager) {
103
-		parent::__construct($appName, $request);
104
-		$this->userManager = $userManager;
105
-		$this->groupManager = $groupManager;
106
-		$this->userSession = $userSession;
107
-		$this->config = $config;
108
-		$this->isAdmin = $isAdmin;
109
-		$this->l10n = $l10n;
110
-		$this->mailer = $mailer;
111
-		$this->l10nFactory = $l10nFactory;
112
-		$this->appManager = $appManager;
113
-		$this->accountManager = $accountManager;
114
-		$this->keyManager = $keyManager;
115
-		$this->jobList = $jobList;
116
-		$this->encryptionManager = $encryptionManager;
117
-	}
118
-
119
-
120
-	/**
121
-	 * @NoCSRFRequired
122
-	 * @NoAdminRequired
123
-	 *
124
-	 * Display users list template
125
-	 *
126
-	 * @return TemplateResponse
127
-	 */
128
-	public function usersListByGroup() {
129
-		return $this->usersList();
130
-	}
131
-
132
-	/**
133
-	 * @NoCSRFRequired
134
-	 * @NoAdminRequired
135
-	 *
136
-	 * Display users list template
137
-	 *
138
-	 * @return TemplateResponse
139
-	 */
140
-	public function usersList() {
141
-		$user = $this->userSession->getUser();
142
-		$uid = $user->getUID();
143
-
144
-		\OC::$server->getNavigationManager()->setActiveEntry('core_users');
145
-
146
-		/* SORT OPTION: SORT_USERCOUNT or SORT_GROUPNAME */
147
-		$sortGroupsBy = \OC\Group\MetaData::SORT_USERCOUNT;
148
-		$isLDAPUsed = false;
149
-		if ($this->config->getSystemValue('sort_groups_by_name', false)) {
150
-			$sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
151
-		} else {
152
-			if ($this->appManager->isEnabledForUser('user_ldap')) {
153
-				$isLDAPUsed =
154
-					$this->groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
155
-				if ($isLDAPUsed) {
156
-					// LDAP user count can be slow, so we sort by group name here
157
-					$sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
158
-				}
159
-			}
160
-		}
161
-
162
-		$canChangePassword = $this->canAdminChangeUserPasswords();
163
-
164
-		/* GROUPS */
165
-		$groupsInfo = new \OC\Group\MetaData(
166
-			$uid,
167
-			$this->isAdmin,
168
-			$this->groupManager,
169
-			$this->userSession
170
-		);
171
-
172
-		$groupsInfo->setSorting($sortGroupsBy);
173
-		list($adminGroup, $groups) = $groupsInfo->get();
174
-
175
-		if(!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) {
176
-			$isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) {
177
-				return $ldapFound || $backend instanceof User_Proxy;
178
-			});
179
-		}
180
-
181
-		$disabledUsers = -1;
182
-		$userCount = 0;
183
-
184
-		if(!$isLDAPUsed) {
185
-			if ($this->isAdmin) {
186
-				$disabledUsers = $this->userManager->countDisabledUsers();
187
-				$userCount = array_reduce($this->userManager->countUsers(), function($v, $w) {
188
-					return $v + (int)$w;
189
-				}, 0);
190
-			} else {
191
-				// User is subadmin !
192
-				// Map group list to names to retrieve the countDisabledUsersOfGroups
193
-				$userGroups = $this->groupManager->getUserGroups($user);
194
-				$groupsNames = [];
195
-
196
-				foreach($groups as $key => $group) {
197
-					// $userCount += (int)$group['usercount'];
198
-					array_push($groupsNames, $group['name']);
199
-					// we prevent subadmins from looking up themselves
200
-					// so we lower the count of the groups he belongs to
201
-					if (array_key_exists($group['id'], $userGroups)) {
202
-						$groups[$key]['usercount']--;
203
-						$userCount -= 1; // we also lower from one the total count
204
-					}
205
-				};
206
-				$userCount += $this->userManager->countUsersOfGroups($groupsInfo->getGroups());
207
-				$disabledUsers = $this->userManager->countDisabledUsersOfGroups($groupsNames);
208
-			}
209
-
210
-			$userCount -= $disabledUsers;
211
-		}
212
-
213
-		$disabledUsersGroup = [
214
-			'id' => 'disabled',
215
-			'name' => 'Disabled users',
216
-			'usercount' => $disabledUsers
217
-		];
218
-
219
-		/* QUOTAS PRESETS */
220
-		$quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'));
221
-		$defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
222
-
223
-		\OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts');
224
-
225
-		/* LANGUAGES */
226
-		$languages = $this->l10nFactory->getLanguages();
227
-
228
-		/* FINAL DATA */
229
-		$serverData = [];
230
-		// groups
231
-		$serverData['groups'] = array_merge_recursive($adminGroup, [$disabledUsersGroup], $groups);
232
-		// Various data
233
-		$serverData['isAdmin'] = $this->isAdmin;
234
-		$serverData['sortGroups'] = $sortGroupsBy;
235
-		$serverData['quotaPreset'] = $quotaPreset;
236
-		$serverData['userCount'] = $userCount;
237
-		$serverData['languages'] = $languages;
238
-		$serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en');
239
-		// Settings
240
-		$serverData['defaultQuota'] = $defaultQuota;
241
-		$serverData['canChangePassword'] = $canChangePassword;
242
-		$serverData['newUserGenerateUserID'] = $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes';
243
-		$serverData['newUserRequireEmail'] = $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes';
244
-		$serverData['newUserSendEmail'] = $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes';
245
-
246
-		return new TemplateResponse('settings', 'settings-vue', ['serverData' => $serverData]);
247
-	}
248
-
249
-	/**
250
-	 * @param string $key
251
-	 * @param string $value
252
-	 *
253
-	 * @return JSONResponse
254
-	 */
255
-	public function setPreference(string $key, string $value): JSONResponse {
256
-		$allowed = ['newUser.sendEmail'];
257
-		if (!in_array($key, $allowed, true)) {
258
-			return new JSONResponse([], Http::STATUS_FORBIDDEN);
259
-		}
260
-
261
-		$this->config->setAppValue('core', $key, $value);
262
-
263
-		return new JSONResponse([]);
264
-	}
265
-
266
-	/**
267
-	 * Parse the app value for quota_present
268
-	 *
269
-	 * @param string $quotaPreset
270
-	 * @return array
271
-	 */
272
-	protected function parseQuotaPreset(string $quotaPreset): array {
273
-		// 1 GB, 5 GB, 10 GB => [1 GB, 5 GB, 10 GB]
274
-		$presets = array_filter(array_map('trim', explode(',', $quotaPreset)));
275
-		// Drop default and none, Make array indexes numerically
276
-		return array_values(array_diff($presets, ['default', 'none']));
277
-	}
278
-
279
-	/**
280
-	 * check if the admin can change the users password
281
-	 *
282
-	 * The admin can change the passwords if:
283
-	 *
284
-	 *   - no encryption module is loaded and encryption is disabled
285
-	 *   - encryption module is loaded but it doesn't require per user keys
286
-	 *
287
-	 * The admin can not change the passwords if:
288
-	 *
289
-	 *   - an encryption module is loaded and it uses per-user keys
290
-	 *   - encryption is enabled but no encryption modules are loaded
291
-	 *
292
-	 * @return bool
293
-	 */
294
-	protected function canAdminChangeUserPasswords() {
295
-		$isEncryptionEnabled = $this->encryptionManager->isEnabled();
296
-		try {
297
-			$noUserSpecificEncryptionKeys =!$this->encryptionManager->getEncryptionModule()->needDetailedAccessList();
298
-			$isEncryptionModuleLoaded = true;
299
-		} catch (ModuleDoesNotExistsException $e) {
300
-			$noUserSpecificEncryptionKeys = true;
301
-			$isEncryptionModuleLoaded = false;
302
-		}
303
-
304
-		$canChangePassword = ($isEncryptionEnabled && $isEncryptionModuleLoaded  && $noUserSpecificEncryptionKeys)
305
-			|| (!$isEncryptionEnabled && !$isEncryptionModuleLoaded)
306
-			|| (!$isEncryptionEnabled && $isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys);
307
-
308
-		return $canChangePassword;
309
-	}
310
-
311
-	/**
312
-	 * @NoAdminRequired
313
-	 * @NoSubadminRequired
314
-	 * @PasswordConfirmationRequired
315
-	 *
316
-	 * @param string $avatarScope
317
-	 * @param string $displayname
318
-	 * @param string $displaynameScope
319
-	 * @param string $phone
320
-	 * @param string $phoneScope
321
-	 * @param string $email
322
-	 * @param string $emailScope
323
-	 * @param string $website
324
-	 * @param string $websiteScope
325
-	 * @param string $address
326
-	 * @param string $addressScope
327
-	 * @param string $twitter
328
-	 * @param string $twitterScope
329
-	 * @return DataResponse
330
-	 */
331
-	public function setUserSettings($avatarScope,
332
-									$displayname,
333
-									$displaynameScope,
334
-									$phone,
335
-									$phoneScope,
336
-									$email,
337
-									$emailScope,
338
-									$website,
339
-									$websiteScope,
340
-									$address,
341
-									$addressScope,
342
-									$twitter,
343
-									$twitterScope
344
-	) {
345
-		if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
346
-			return new DataResponse(
347
-				[
348
-					'status' => 'error',
349
-					'data' => [
350
-						'message' => $this->l10n->t('Invalid mail address')
351
-					]
352
-				],
353
-				Http::STATUS_UNPROCESSABLE_ENTITY
354
-			);
355
-		}
356
-		$user = $this->userSession->getUser();
357
-		$data = $this->accountManager->getUser($user);
358
-		$data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope];
359
-		if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
360
-			$data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope];
361
-			$data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope];
362
-		}
363
-		if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
364
-			$federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
365
-			$shareProvider = $federatedFileSharing->getFederatedShareProvider();
366
-			if ($shareProvider->isLookupServerUploadEnabled()) {
367
-				$data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope];
368
-				$data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope];
369
-				$data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope];
370
-				$data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope];
371
-			}
372
-		}
373
-		try {
374
-			$this->saveUserSettings($user, $data);
375
-			return new DataResponse(
376
-				[
377
-					'status' => 'success',
378
-					'data' => [
379
-						'userId' => $user->getUID(),
380
-						'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'],
381
-						'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'],
382
-						'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
383
-						'email' => $data[AccountManager::PROPERTY_EMAIL]['value'],
384
-						'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'],
385
-						'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'],
386
-						'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'],
387
-						'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'],
388
-						'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'],
389
-						'message' => $this->l10n->t('Settings saved')
390
-					]
391
-				],
392
-				Http::STATUS_OK
393
-			);
394
-		} catch (ForbiddenException $e) {
395
-			return new DataResponse([
396
-				'status' => 'error',
397
-				'data' => [
398
-					'message' => $e->getMessage()
399
-				],
400
-			]);
401
-		}
402
-	}
403
-	/**
404
-	 * update account manager with new user data
405
-	 *
406
-	 * @param IUser $user
407
-	 * @param array $data
408
-	 * @throws ForbiddenException
409
-	 */
410
-	protected function saveUserSettings(IUser $user, array $data) {
411
-		// keep the user back-end up-to-date with the latest display name and email
412
-		// address
413
-		$oldDisplayName = $user->getDisplayName();
414
-		$oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
415
-		if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
416
-			&& $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
417
-		) {
418
-			$result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
419
-			if ($result === false) {
420
-				throw new ForbiddenException($this->l10n->t('Unable to change full name'));
421
-			}
422
-		}
423
-		$oldEmailAddress = $user->getEMailAddress();
424
-		$oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
425
-		if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
426
-			&& $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
427
-		) {
428
-			// this is the only permission a backend provides and is also used
429
-			// for the permission of setting a email address
430
-			if (!$user->canChangeDisplayName()) {
431
-				throw new ForbiddenException($this->l10n->t('Unable to change email address'));
432
-			}
433
-			$user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
434
-		}
435
-		$this->accountManager->updateUser($user, $data);
436
-	}
437
-
438
-	/**
439
-	 * Set the mail address of a user
440
-	 *
441
-	 * @NoAdminRequired
442
-	 * @NoSubadminRequired
443
-	 * @PasswordConfirmationRequired
444
-	 *
445
-	 * @param string $account
446
-	 * @param bool $onlyVerificationCode only return verification code without updating the data
447
-	 * @return DataResponse
448
-	 */
449
-	public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse {
450
-
451
-		$user = $this->userSession->getUser();
452
-
453
-		if ($user === null) {
454
-			return new DataResponse([], Http::STATUS_BAD_REQUEST);
455
-		}
456
-
457
-		$accountData = $this->accountManager->getUser($user);
458
-		$cloudId = $user->getCloudId();
459
-		$message = 'Use my Federated Cloud ID to share with me: ' . $cloudId;
460
-		$signature = $this->signMessage($user, $message);
461
-
462
-		$code = $message . ' ' . $signature;
463
-		$codeMd5 = $message . ' ' . md5($signature);
464
-
465
-		switch ($account) {
466
-			case 'verify-twitter':
467
-				$accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
468
-				$msg = $this->l10n->t('In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):');
469
-				$code = $codeMd5;
470
-				$type = AccountManager::PROPERTY_TWITTER;
471
-				$data = $accountData[AccountManager::PROPERTY_TWITTER]['value'];
472
-				$accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature;
473
-				break;
474
-			case 'verify-website':
475
-				$accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
476
-				$msg = $this->l10n->t('In order to verify your Website, store the following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):');
477
-				$type = AccountManager::PROPERTY_WEBSITE;
478
-				$data = $accountData[AccountManager::PROPERTY_WEBSITE]['value'];
479
-				$accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature;
480
-				break;
481
-			default:
482
-				return new DataResponse([], Http::STATUS_BAD_REQUEST);
483
-		}
484
-
485
-		if ($onlyVerificationCode === false) {
486
-			$this->accountManager->updateUser($user, $accountData);
487
-
488
-			$this->jobList->add(VerifyUserData::class,
489
-				[
490
-					'verificationCode' => $code,
491
-					'data' => $data,
492
-					'type' => $type,
493
-					'uid' => $user->getUID(),
494
-					'try' => 0,
495
-					'lastRun' => $this->getCurrentTime()
496
-				]
497
-			);
498
-		}
499
-
500
-		return new DataResponse(['msg' => $msg, 'code' => $code]);
501
-	}
502
-
503
-	/**
504
-	 * get current timestamp
505
-	 *
506
-	 * @return int
507
-	 */
508
-	protected function getCurrentTime(): int {
509
-		return time();
510
-	}
511
-
512
-	/**
513
-	 * sign message with users private key
514
-	 *
515
-	 * @param IUser $user
516
-	 * @param string $message
517
-	 *
518
-	 * @return string base64 encoded signature
519
-	 */
520
-	protected function signMessage(IUser $user, string $message): string {
521
-		$privateKey = $this->keyManager->getKey($user)->getPrivate();
522
-		openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
523
-		return base64_encode($signature);
524
-	}
60
+    /** @var IUserManager */
61
+    private $userManager;
62
+    /** @var IGroupManager */
63
+    private $groupManager;
64
+    /** @var IUserSession */
65
+    private $userSession;
66
+    /** @var IConfig */
67
+    private $config;
68
+    /** @var bool */
69
+    private $isAdmin;
70
+    /** @var IL10N */
71
+    private $l10n;
72
+    /** @var IMailer */
73
+    private $mailer;
74
+    /** @var IFactory */
75
+    private $l10nFactory;
76
+    /** @var IAppManager */
77
+    private $appManager;
78
+    /** @var AccountManager */
79
+    private $accountManager;
80
+    /** @var Manager */
81
+    private $keyManager;
82
+    /** @var IJobList */
83
+    private $jobList;
84
+    /** @var IManager */
85
+    private $encryptionManager;
86
+
87
+
88
+    public function __construct(string $appName,
89
+                                IRequest $request,
90
+                                IUserManager $userManager,
91
+                                IGroupManager $groupManager,
92
+                                IUserSession $userSession,
93
+                                IConfig $config,
94
+                                bool $isAdmin,
95
+                                IL10N $l10n,
96
+                                IMailer $mailer,
97
+                                IFactory $l10nFactory,
98
+                                IAppManager $appManager,
99
+                                AccountManager $accountManager,
100
+                                Manager $keyManager,
101
+                                IJobList $jobList,
102
+                                IManager $encryptionManager) {
103
+        parent::__construct($appName, $request);
104
+        $this->userManager = $userManager;
105
+        $this->groupManager = $groupManager;
106
+        $this->userSession = $userSession;
107
+        $this->config = $config;
108
+        $this->isAdmin = $isAdmin;
109
+        $this->l10n = $l10n;
110
+        $this->mailer = $mailer;
111
+        $this->l10nFactory = $l10nFactory;
112
+        $this->appManager = $appManager;
113
+        $this->accountManager = $accountManager;
114
+        $this->keyManager = $keyManager;
115
+        $this->jobList = $jobList;
116
+        $this->encryptionManager = $encryptionManager;
117
+    }
118
+
119
+
120
+    /**
121
+     * @NoCSRFRequired
122
+     * @NoAdminRequired
123
+     *
124
+     * Display users list template
125
+     *
126
+     * @return TemplateResponse
127
+     */
128
+    public function usersListByGroup() {
129
+        return $this->usersList();
130
+    }
131
+
132
+    /**
133
+     * @NoCSRFRequired
134
+     * @NoAdminRequired
135
+     *
136
+     * Display users list template
137
+     *
138
+     * @return TemplateResponse
139
+     */
140
+    public function usersList() {
141
+        $user = $this->userSession->getUser();
142
+        $uid = $user->getUID();
143
+
144
+        \OC::$server->getNavigationManager()->setActiveEntry('core_users');
145
+
146
+        /* SORT OPTION: SORT_USERCOUNT or SORT_GROUPNAME */
147
+        $sortGroupsBy = \OC\Group\MetaData::SORT_USERCOUNT;
148
+        $isLDAPUsed = false;
149
+        if ($this->config->getSystemValue('sort_groups_by_name', false)) {
150
+            $sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
151
+        } else {
152
+            if ($this->appManager->isEnabledForUser('user_ldap')) {
153
+                $isLDAPUsed =
154
+                    $this->groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
155
+                if ($isLDAPUsed) {
156
+                    // LDAP user count can be slow, so we sort by group name here
157
+                    $sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
158
+                }
159
+            }
160
+        }
161
+
162
+        $canChangePassword = $this->canAdminChangeUserPasswords();
163
+
164
+        /* GROUPS */
165
+        $groupsInfo = new \OC\Group\MetaData(
166
+            $uid,
167
+            $this->isAdmin,
168
+            $this->groupManager,
169
+            $this->userSession
170
+        );
171
+
172
+        $groupsInfo->setSorting($sortGroupsBy);
173
+        list($adminGroup, $groups) = $groupsInfo->get();
174
+
175
+        if(!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) {
176
+            $isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) {
177
+                return $ldapFound || $backend instanceof User_Proxy;
178
+            });
179
+        }
180
+
181
+        $disabledUsers = -1;
182
+        $userCount = 0;
183
+
184
+        if(!$isLDAPUsed) {
185
+            if ($this->isAdmin) {
186
+                $disabledUsers = $this->userManager->countDisabledUsers();
187
+                $userCount = array_reduce($this->userManager->countUsers(), function($v, $w) {
188
+                    return $v + (int)$w;
189
+                }, 0);
190
+            } else {
191
+                // User is subadmin !
192
+                // Map group list to names to retrieve the countDisabledUsersOfGroups
193
+                $userGroups = $this->groupManager->getUserGroups($user);
194
+                $groupsNames = [];
195
+
196
+                foreach($groups as $key => $group) {
197
+                    // $userCount += (int)$group['usercount'];
198
+                    array_push($groupsNames, $group['name']);
199
+                    // we prevent subadmins from looking up themselves
200
+                    // so we lower the count of the groups he belongs to
201
+                    if (array_key_exists($group['id'], $userGroups)) {
202
+                        $groups[$key]['usercount']--;
203
+                        $userCount -= 1; // we also lower from one the total count
204
+                    }
205
+                };
206
+                $userCount += $this->userManager->countUsersOfGroups($groupsInfo->getGroups());
207
+                $disabledUsers = $this->userManager->countDisabledUsersOfGroups($groupsNames);
208
+            }
209
+
210
+            $userCount -= $disabledUsers;
211
+        }
212
+
213
+        $disabledUsersGroup = [
214
+            'id' => 'disabled',
215
+            'name' => 'Disabled users',
216
+            'usercount' => $disabledUsers
217
+        ];
218
+
219
+        /* QUOTAS PRESETS */
220
+        $quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'));
221
+        $defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
222
+
223
+        \OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts');
224
+
225
+        /* LANGUAGES */
226
+        $languages = $this->l10nFactory->getLanguages();
227
+
228
+        /* FINAL DATA */
229
+        $serverData = [];
230
+        // groups
231
+        $serverData['groups'] = array_merge_recursive($adminGroup, [$disabledUsersGroup], $groups);
232
+        // Various data
233
+        $serverData['isAdmin'] = $this->isAdmin;
234
+        $serverData['sortGroups'] = $sortGroupsBy;
235
+        $serverData['quotaPreset'] = $quotaPreset;
236
+        $serverData['userCount'] = $userCount;
237
+        $serverData['languages'] = $languages;
238
+        $serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en');
239
+        // Settings
240
+        $serverData['defaultQuota'] = $defaultQuota;
241
+        $serverData['canChangePassword'] = $canChangePassword;
242
+        $serverData['newUserGenerateUserID'] = $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes';
243
+        $serverData['newUserRequireEmail'] = $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes';
244
+        $serverData['newUserSendEmail'] = $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes';
245
+
246
+        return new TemplateResponse('settings', 'settings-vue', ['serverData' => $serverData]);
247
+    }
248
+
249
+    /**
250
+     * @param string $key
251
+     * @param string $value
252
+     *
253
+     * @return JSONResponse
254
+     */
255
+    public function setPreference(string $key, string $value): JSONResponse {
256
+        $allowed = ['newUser.sendEmail'];
257
+        if (!in_array($key, $allowed, true)) {
258
+            return new JSONResponse([], Http::STATUS_FORBIDDEN);
259
+        }
260
+
261
+        $this->config->setAppValue('core', $key, $value);
262
+
263
+        return new JSONResponse([]);
264
+    }
265
+
266
+    /**
267
+     * Parse the app value for quota_present
268
+     *
269
+     * @param string $quotaPreset
270
+     * @return array
271
+     */
272
+    protected function parseQuotaPreset(string $quotaPreset): array {
273
+        // 1 GB, 5 GB, 10 GB => [1 GB, 5 GB, 10 GB]
274
+        $presets = array_filter(array_map('trim', explode(',', $quotaPreset)));
275
+        // Drop default and none, Make array indexes numerically
276
+        return array_values(array_diff($presets, ['default', 'none']));
277
+    }
278
+
279
+    /**
280
+     * check if the admin can change the users password
281
+     *
282
+     * The admin can change the passwords if:
283
+     *
284
+     *   - no encryption module is loaded and encryption is disabled
285
+     *   - encryption module is loaded but it doesn't require per user keys
286
+     *
287
+     * The admin can not change the passwords if:
288
+     *
289
+     *   - an encryption module is loaded and it uses per-user keys
290
+     *   - encryption is enabled but no encryption modules are loaded
291
+     *
292
+     * @return bool
293
+     */
294
+    protected function canAdminChangeUserPasswords() {
295
+        $isEncryptionEnabled = $this->encryptionManager->isEnabled();
296
+        try {
297
+            $noUserSpecificEncryptionKeys =!$this->encryptionManager->getEncryptionModule()->needDetailedAccessList();
298
+            $isEncryptionModuleLoaded = true;
299
+        } catch (ModuleDoesNotExistsException $e) {
300
+            $noUserSpecificEncryptionKeys = true;
301
+            $isEncryptionModuleLoaded = false;
302
+        }
303
+
304
+        $canChangePassword = ($isEncryptionEnabled && $isEncryptionModuleLoaded  && $noUserSpecificEncryptionKeys)
305
+            || (!$isEncryptionEnabled && !$isEncryptionModuleLoaded)
306
+            || (!$isEncryptionEnabled && $isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys);
307
+
308
+        return $canChangePassword;
309
+    }
310
+
311
+    /**
312
+     * @NoAdminRequired
313
+     * @NoSubadminRequired
314
+     * @PasswordConfirmationRequired
315
+     *
316
+     * @param string $avatarScope
317
+     * @param string $displayname
318
+     * @param string $displaynameScope
319
+     * @param string $phone
320
+     * @param string $phoneScope
321
+     * @param string $email
322
+     * @param string $emailScope
323
+     * @param string $website
324
+     * @param string $websiteScope
325
+     * @param string $address
326
+     * @param string $addressScope
327
+     * @param string $twitter
328
+     * @param string $twitterScope
329
+     * @return DataResponse
330
+     */
331
+    public function setUserSettings($avatarScope,
332
+                                    $displayname,
333
+                                    $displaynameScope,
334
+                                    $phone,
335
+                                    $phoneScope,
336
+                                    $email,
337
+                                    $emailScope,
338
+                                    $website,
339
+                                    $websiteScope,
340
+                                    $address,
341
+                                    $addressScope,
342
+                                    $twitter,
343
+                                    $twitterScope
344
+    ) {
345
+        if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
346
+            return new DataResponse(
347
+                [
348
+                    'status' => 'error',
349
+                    'data' => [
350
+                        'message' => $this->l10n->t('Invalid mail address')
351
+                    ]
352
+                ],
353
+                Http::STATUS_UNPROCESSABLE_ENTITY
354
+            );
355
+        }
356
+        $user = $this->userSession->getUser();
357
+        $data = $this->accountManager->getUser($user);
358
+        $data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope];
359
+        if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
360
+            $data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope];
361
+            $data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope];
362
+        }
363
+        if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
364
+            $federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
365
+            $shareProvider = $federatedFileSharing->getFederatedShareProvider();
366
+            if ($shareProvider->isLookupServerUploadEnabled()) {
367
+                $data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope];
368
+                $data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope];
369
+                $data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope];
370
+                $data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope];
371
+            }
372
+        }
373
+        try {
374
+            $this->saveUserSettings($user, $data);
375
+            return new DataResponse(
376
+                [
377
+                    'status' => 'success',
378
+                    'data' => [
379
+                        'userId' => $user->getUID(),
380
+                        'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'],
381
+                        'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'],
382
+                        'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
383
+                        'email' => $data[AccountManager::PROPERTY_EMAIL]['value'],
384
+                        'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'],
385
+                        'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'],
386
+                        'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'],
387
+                        'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'],
388
+                        'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'],
389
+                        'message' => $this->l10n->t('Settings saved')
390
+                    ]
391
+                ],
392
+                Http::STATUS_OK
393
+            );
394
+        } catch (ForbiddenException $e) {
395
+            return new DataResponse([
396
+                'status' => 'error',
397
+                'data' => [
398
+                    'message' => $e->getMessage()
399
+                ],
400
+            ]);
401
+        }
402
+    }
403
+    /**
404
+     * update account manager with new user data
405
+     *
406
+     * @param IUser $user
407
+     * @param array $data
408
+     * @throws ForbiddenException
409
+     */
410
+    protected function saveUserSettings(IUser $user, array $data) {
411
+        // keep the user back-end up-to-date with the latest display name and email
412
+        // address
413
+        $oldDisplayName = $user->getDisplayName();
414
+        $oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
415
+        if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
416
+            && $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
417
+        ) {
418
+            $result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
419
+            if ($result === false) {
420
+                throw new ForbiddenException($this->l10n->t('Unable to change full name'));
421
+            }
422
+        }
423
+        $oldEmailAddress = $user->getEMailAddress();
424
+        $oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
425
+        if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
426
+            && $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
427
+        ) {
428
+            // this is the only permission a backend provides and is also used
429
+            // for the permission of setting a email address
430
+            if (!$user->canChangeDisplayName()) {
431
+                throw new ForbiddenException($this->l10n->t('Unable to change email address'));
432
+            }
433
+            $user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
434
+        }
435
+        $this->accountManager->updateUser($user, $data);
436
+    }
437
+
438
+    /**
439
+     * Set the mail address of a user
440
+     *
441
+     * @NoAdminRequired
442
+     * @NoSubadminRequired
443
+     * @PasswordConfirmationRequired
444
+     *
445
+     * @param string $account
446
+     * @param bool $onlyVerificationCode only return verification code without updating the data
447
+     * @return DataResponse
448
+     */
449
+    public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse {
450
+
451
+        $user = $this->userSession->getUser();
452
+
453
+        if ($user === null) {
454
+            return new DataResponse([], Http::STATUS_BAD_REQUEST);
455
+        }
456
+
457
+        $accountData = $this->accountManager->getUser($user);
458
+        $cloudId = $user->getCloudId();
459
+        $message = 'Use my Federated Cloud ID to share with me: ' . $cloudId;
460
+        $signature = $this->signMessage($user, $message);
461
+
462
+        $code = $message . ' ' . $signature;
463
+        $codeMd5 = $message . ' ' . md5($signature);
464
+
465
+        switch ($account) {
466
+            case 'verify-twitter':
467
+                $accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
468
+                $msg = $this->l10n->t('In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):');
469
+                $code = $codeMd5;
470
+                $type = AccountManager::PROPERTY_TWITTER;
471
+                $data = $accountData[AccountManager::PROPERTY_TWITTER]['value'];
472
+                $accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature;
473
+                break;
474
+            case 'verify-website':
475
+                $accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
476
+                $msg = $this->l10n->t('In order to verify your Website, store the following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):');
477
+                $type = AccountManager::PROPERTY_WEBSITE;
478
+                $data = $accountData[AccountManager::PROPERTY_WEBSITE]['value'];
479
+                $accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature;
480
+                break;
481
+            default:
482
+                return new DataResponse([], Http::STATUS_BAD_REQUEST);
483
+        }
484
+
485
+        if ($onlyVerificationCode === false) {
486
+            $this->accountManager->updateUser($user, $accountData);
487
+
488
+            $this->jobList->add(VerifyUserData::class,
489
+                [
490
+                    'verificationCode' => $code,
491
+                    'data' => $data,
492
+                    'type' => $type,
493
+                    'uid' => $user->getUID(),
494
+                    'try' => 0,
495
+                    'lastRun' => $this->getCurrentTime()
496
+                ]
497
+            );
498
+        }
499
+
500
+        return new DataResponse(['msg' => $msg, 'code' => $code]);
501
+    }
502
+
503
+    /**
504
+     * get current timestamp
505
+     *
506
+     * @return int
507
+     */
508
+    protected function getCurrentTime(): int {
509
+        return time();
510
+    }
511
+
512
+    /**
513
+     * sign message with users private key
514
+     *
515
+     * @param IUser $user
516
+     * @param string $message
517
+     *
518
+     * @return string base64 encoded signature
519
+     */
520
+    protected function signMessage(IUser $user, string $message): string {
521
+        $privateKey = $this->keyManager->getKey($user)->getPrivate();
522
+        openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
523
+        return base64_encode($signature);
524
+    }
525 525
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/AdminSettingsController.php 1 patch
Indentation   +71 added lines, -71 removed lines patch added patch discarded remove patch
@@ -38,85 +38,85 @@
 block discarded – undo
38 38
 use OCP\Template;
39 39
 
40 40
 class AdminSettingsController extends Controller {
41
-	use CommonSettingsTrait;
41
+    use CommonSettingsTrait;
42 42
 
43
-	public function __construct(
44
-		$appName,
45
-		IRequest $request,
46
-		INavigationManager $navigationManager,
47
-		ISettingsManager $settingsManager,
48
-		IUserSession $userSession,
49
-		IGroupManager $groupManager,
50
-		ISubAdmin $subAdmin
51
-	) {
52
-		parent::__construct($appName, $request);
53
-		$this->navigationManager = $navigationManager;
54
-		$this->settingsManager = $settingsManager;
55
-		$this->userSession = $userSession;
56
-		$this->groupManager = $groupManager;
57
-		$this->subAdmin = $subAdmin;
58
-	}
43
+    public function __construct(
44
+        $appName,
45
+        IRequest $request,
46
+        INavigationManager $navigationManager,
47
+        ISettingsManager $settingsManager,
48
+        IUserSession $userSession,
49
+        IGroupManager $groupManager,
50
+        ISubAdmin $subAdmin
51
+    ) {
52
+        parent::__construct($appName, $request);
53
+        $this->navigationManager = $navigationManager;
54
+        $this->settingsManager = $settingsManager;
55
+        $this->userSession = $userSession;
56
+        $this->groupManager = $groupManager;
57
+        $this->subAdmin = $subAdmin;
58
+    }
59 59
 
60
-	/**
61
-	 * @param string $section
62
-	 * @return TemplateResponse
63
-	 *
64
-	 * @NoCSRFRequired
65
-	 * @SubAdminRequired
66
-	 */
67
-	public function index($section) {
68
-		return $this->getIndexResponse('admin', $section);
69
-	}
60
+    /**
61
+     * @param string $section
62
+     * @return TemplateResponse
63
+     *
64
+     * @NoCSRFRequired
65
+     * @SubAdminRequired
66
+     */
67
+    public function index($section) {
68
+        return $this->getIndexResponse('admin', $section);
69
+    }
70 70
 
71
-	/**
72
-	 * @param string $section
73
-	 * @return array
74
-	 */
75
-	protected function getSettings($section) {
76
-		/** @var IUser $user */
77
-		$user = $this->userSession->getUser();
78
-		$isSubAdmin = !$this->groupManager->isAdmin($user->getUID()) && $this->subAdmin->isSubAdmin($user);
79
-		$settings = $this->settingsManager->getAdminSettings(
80
-			$section,
81
-			$isSubAdmin
82
-		);
83
-		$formatted = $this->formatSettings($settings);
84
-		// Do not show legacy forms for sub admins
85
-		if($section === 'additional' && !$isSubAdmin) {
86
-			$formatted['content'] .= $this->getLegacyForms();
87
-		}
88
-		return $formatted;
89
-	}
71
+    /**
72
+     * @param string $section
73
+     * @return array
74
+     */
75
+    protected function getSettings($section) {
76
+        /** @var IUser $user */
77
+        $user = $this->userSession->getUser();
78
+        $isSubAdmin = !$this->groupManager->isAdmin($user->getUID()) && $this->subAdmin->isSubAdmin($user);
79
+        $settings = $this->settingsManager->getAdminSettings(
80
+            $section,
81
+            $isSubAdmin
82
+        );
83
+        $formatted = $this->formatSettings($settings);
84
+        // Do not show legacy forms for sub admins
85
+        if($section === 'additional' && !$isSubAdmin) {
86
+            $formatted['content'] .= $this->getLegacyForms();
87
+        }
88
+        return $formatted;
89
+    }
90 90
 
91
-	/**
92
-	 * @return bool|string
93
-	 */
94
-	private function getLegacyForms() {
95
-		$forms = \OC_App::getForms('admin');
91
+    /**
92
+     * @return bool|string
93
+     */
94
+    private function getLegacyForms() {
95
+        $forms = \OC_App::getForms('admin');
96 96
 
97
-		$forms = array_map(function ($form) {
98
-			if (preg_match('%(<h2(?P<class>[^>]*)>.*?</h2>)%i', $form, $regs)) {
99
-				$sectionName = str_replace('<h2' . $regs['class'] . '>', '', $regs[0]);
100
-				$sectionName = str_replace('</h2>', '', $sectionName);
101
-				$anchor = strtolower($sectionName);
102
-				$anchor = str_replace(' ', '-', $anchor);
97
+        $forms = array_map(function ($form) {
98
+            if (preg_match('%(<h2(?P<class>[^>]*)>.*?</h2>)%i', $form, $regs)) {
99
+                $sectionName = str_replace('<h2' . $regs['class'] . '>', '', $regs[0]);
100
+                $sectionName = str_replace('</h2>', '', $sectionName);
101
+                $anchor = strtolower($sectionName);
102
+                $anchor = str_replace(' ', '-', $anchor);
103 103
 
104
-				return [
105
-					'anchor' => $anchor,
106
-					'section-name' => $sectionName,
107
-					'form' => $form
108
-				];
109
-			}
110
-			return [
111
-				'form' => $form
112
-			];
113
-		}, $forms);
104
+                return [
105
+                    'anchor' => $anchor,
106
+                    'section-name' => $sectionName,
107
+                    'form' => $form
108
+                ];
109
+            }
110
+            return [
111
+                'form' => $form
112
+            ];
113
+        }, $forms);
114 114
 
115
-		$out = new Template('settings', 'settings/additional');
116
-		$out->assign('forms', $forms);
115
+        $out = new Template('settings', 'settings/additional');
116
+        $out->assign('forms', $forms);
117 117
 
118
-		return $out->fetchPage();
119
-	}
118
+        return $out->fetchPage();
119
+    }
120 120
 
121 121
 
122 122
 }
Please login to merge, or discard this patch.
remote.php 1 patch
Indentation   +107 added lines, -107 removed lines patch added patch discarded remove patch
@@ -48,43 +48,43 @@  discard block
 block discarded – undo
48 48
  * @param Exception|Error $e
49 49
  */
50 50
 function handleException($e) {
51
-	$request = \OC::$server->getRequest();
52
-	// in case the request content type is text/xml - we assume it's a WebDAV request
53
-	$isXmlContentType = strpos($request->getHeader('Content-Type'), 'text/xml');
54
-	if ($isXmlContentType === 0) {
55
-		// fire up a simple server to properly process the exception
56
-		$server = new Server();
57
-		if (!($e instanceof RemoteException)) {
58
-			// we shall not log on RemoteException
59
-			$server->addPlugin(new ExceptionLoggerPlugin('webdav', \OC::$server->getLogger()));
60
-		}
61
-		$server->on('beforeMethod', function () use ($e) {
62
-			if ($e instanceof RemoteException) {
63
-				switch ($e->getCode()) {
64
-					case 503:
65
-						throw new ServiceUnavailable($e->getMessage());
66
-					case 404:
67
-						throw new \Sabre\DAV\Exception\NotFound($e->getMessage());
68
-				}
69
-			}
70
-			$class = get_class($e);
71
-			$msg = $e->getMessage();
72
-			throw new ServiceUnavailable("$class: $msg");
73
-		});
74
-		$server->exec();
75
-	} else {
76
-		$statusCode = 500;
77
-		if ($e instanceof \OC\ServiceUnavailableException ) {
78
-			$statusCode = 503;
79
-		}
80
-		if ($e instanceof RemoteException) {
81
-			// we shall not log on RemoteException
82
-			OC_Template::printErrorPage($e->getMessage(), '', $e->getCode());
83
-		} else {
84
-			\OC::$server->getLogger()->logException($e, ['app' => 'remote']);
85
-			OC_Template::printExceptionErrorPage($e, $statusCode);
86
-		}
87
-	}
51
+    $request = \OC::$server->getRequest();
52
+    // in case the request content type is text/xml - we assume it's a WebDAV request
53
+    $isXmlContentType = strpos($request->getHeader('Content-Type'), 'text/xml');
54
+    if ($isXmlContentType === 0) {
55
+        // fire up a simple server to properly process the exception
56
+        $server = new Server();
57
+        if (!($e instanceof RemoteException)) {
58
+            // we shall not log on RemoteException
59
+            $server->addPlugin(new ExceptionLoggerPlugin('webdav', \OC::$server->getLogger()));
60
+        }
61
+        $server->on('beforeMethod', function () use ($e) {
62
+            if ($e instanceof RemoteException) {
63
+                switch ($e->getCode()) {
64
+                    case 503:
65
+                        throw new ServiceUnavailable($e->getMessage());
66
+                    case 404:
67
+                        throw new \Sabre\DAV\Exception\NotFound($e->getMessage());
68
+                }
69
+            }
70
+            $class = get_class($e);
71
+            $msg = $e->getMessage();
72
+            throw new ServiceUnavailable("$class: $msg");
73
+        });
74
+        $server->exec();
75
+    } else {
76
+        $statusCode = 500;
77
+        if ($e instanceof \OC\ServiceUnavailableException ) {
78
+            $statusCode = 503;
79
+        }
80
+        if ($e instanceof RemoteException) {
81
+            // we shall not log on RemoteException
82
+            OC_Template::printErrorPage($e->getMessage(), '', $e->getCode());
83
+        } else {
84
+            \OC::$server->getLogger()->logException($e, ['app' => 'remote']);
85
+            OC_Template::printExceptionErrorPage($e, $statusCode);
86
+        }
87
+    }
88 88
 }
89 89
 
90 90
 /**
@@ -92,80 +92,80 @@  discard block
 block discarded – undo
92 92
  * @return string
93 93
  */
94 94
 function resolveService($service) {
95
-	$services = [
96
-		'webdav' => 'dav/appinfo/v1/webdav.php',
97
-		'dav' => 'dav/appinfo/v2/remote.php',
98
-		'caldav' => 'dav/appinfo/v1/caldav.php',
99
-		'calendar' => 'dav/appinfo/v1/caldav.php',
100
-		'carddav' => 'dav/appinfo/v1/carddav.php',
101
-		'contacts' => 'dav/appinfo/v1/carddav.php',
102
-		'files' => 'dav/appinfo/v1/webdav.php',
103
-		'direct' => 'dav/appinfo/v2/direct.php',
104
-	];
105
-	if (isset($services[$service])) {
106
-		return $services[$service];
107
-	}
108
-
109
-	return \OC::$server->getConfig()->getAppValue('core', 'remote_' . $service);
95
+    $services = [
96
+        'webdav' => 'dav/appinfo/v1/webdav.php',
97
+        'dav' => 'dav/appinfo/v2/remote.php',
98
+        'caldav' => 'dav/appinfo/v1/caldav.php',
99
+        'calendar' => 'dav/appinfo/v1/caldav.php',
100
+        'carddav' => 'dav/appinfo/v1/carddav.php',
101
+        'contacts' => 'dav/appinfo/v1/carddav.php',
102
+        'files' => 'dav/appinfo/v1/webdav.php',
103
+        'direct' => 'dav/appinfo/v2/direct.php',
104
+    ];
105
+    if (isset($services[$service])) {
106
+        return $services[$service];
107
+    }
108
+
109
+    return \OC::$server->getConfig()->getAppValue('core', 'remote_' . $service);
110 110
 }
111 111
 
112 112
 try {
113
-	require_once __DIR__ . '/lib/base.php';
114
-
115
-	// All resources served via the DAV endpoint should have the strictest possible
116
-	// policy. Exempted from this is the SabreDAV browser plugin which overwrites
117
-	// this policy with a softer one if debug mode is enabled.
118
-	header("Content-Security-Policy: default-src 'none';");
119
-
120
-	if (\OCP\Util::needUpgrade()) {
121
-		// since the behavior of apps or remotes are unpredictable during
122
-		// an upgrade, return a 503 directly
123
-		throw new RemoteException('Service unavailable', 503);
124
-	}
125
-
126
-	$request = \OC::$server->getRequest();
127
-	$pathInfo = $request->getPathInfo();
128
-	if ($pathInfo === false || $pathInfo === '') {
129
-		throw new RemoteException('Path not found', 404);
130
-	}
131
-	if (!$pos = strpos($pathInfo, '/', 1)) {
132
-		$pos = strlen($pathInfo);
133
-	}
134
-	$service=substr($pathInfo, 1, $pos-1);
135
-
136
-	$file = resolveService($service);
137
-
138
-	if(is_null($file)) {
139
-		throw new RemoteException('Path not found', 404);
140
-	}
141
-
142
-	$file=ltrim($file, '/');
143
-
144
-	$parts=explode('/', $file, 2);
145
-	$app=$parts[0];
146
-
147
-	// Load all required applications
148
-	\OC::$REQUESTEDAPP = $app;
149
-	OC_App::loadApps(['authentication']);
150
-	OC_App::loadApps(['filesystem', 'logging']);
151
-
152
-	switch ($app) {
153
-		case 'core':
154
-			$file =  OC::$SERVERROOT .'/'. $file;
155
-			break;
156
-		default:
157
-			if (!\OC::$server->getAppManager()->isInstalled($app)) {
158
-				throw new RemoteException('App not installed: ' . $app);
159
-			}
160
-			OC_App::loadApp($app);
161
-			$file = OC_App::getAppPath($app) .'/'. $parts[1];
162
-			break;
163
-	}
164
-	$baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/';
165
-	require_once $file;
113
+    require_once __DIR__ . '/lib/base.php';
114
+
115
+    // All resources served via the DAV endpoint should have the strictest possible
116
+    // policy. Exempted from this is the SabreDAV browser plugin which overwrites
117
+    // this policy with a softer one if debug mode is enabled.
118
+    header("Content-Security-Policy: default-src 'none';");
119
+
120
+    if (\OCP\Util::needUpgrade()) {
121
+        // since the behavior of apps or remotes are unpredictable during
122
+        // an upgrade, return a 503 directly
123
+        throw new RemoteException('Service unavailable', 503);
124
+    }
125
+
126
+    $request = \OC::$server->getRequest();
127
+    $pathInfo = $request->getPathInfo();
128
+    if ($pathInfo === false || $pathInfo === '') {
129
+        throw new RemoteException('Path not found', 404);
130
+    }
131
+    if (!$pos = strpos($pathInfo, '/', 1)) {
132
+        $pos = strlen($pathInfo);
133
+    }
134
+    $service=substr($pathInfo, 1, $pos-1);
135
+
136
+    $file = resolveService($service);
137
+
138
+    if(is_null($file)) {
139
+        throw new RemoteException('Path not found', 404);
140
+    }
141
+
142
+    $file=ltrim($file, '/');
143
+
144
+    $parts=explode('/', $file, 2);
145
+    $app=$parts[0];
146
+
147
+    // Load all required applications
148
+    \OC::$REQUESTEDAPP = $app;
149
+    OC_App::loadApps(['authentication']);
150
+    OC_App::loadApps(['filesystem', 'logging']);
151
+
152
+    switch ($app) {
153
+        case 'core':
154
+            $file =  OC::$SERVERROOT .'/'. $file;
155
+            break;
156
+        default:
157
+            if (!\OC::$server->getAppManager()->isInstalled($app)) {
158
+                throw new RemoteException('App not installed: ' . $app);
159
+            }
160
+            OC_App::loadApp($app);
161
+            $file = OC_App::getAppPath($app) .'/'. $parts[1];
162
+            break;
163
+    }
164
+    $baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/';
165
+    require_once $file;
166 166
 
167 167
 } catch (Exception $ex) {
168
-	handleException($ex);
168
+    handleException($ex);
169 169
 } catch (Error $e) {
170
-	handleException($e);
170
+    handleException($e);
171 171
 }
Please login to merge, or discard this patch.
config/config.sample.php 1 patch
Indentation   +135 added lines, -135 removed lines patch added patch discarded remove patch
@@ -41,17 +41,17 @@  discard block
 block discarded – undo
41 41
  */
42 42
 'instanceid' => '',
43 43
 
44
- /**
45
-  * The salt used to hash all passwords, auto-generated by the Nextcloud
46
-  * installer. (There are also per-user salts.) If you lose this salt you lose
47
-  * all your passwords. This example is for documentation only, and you should
48
-  * never use it.
49
-  *
50
-  * @deprecated This salt is deprecated and only used for legacy-compatibility,
51
-  * developers should *NOT* use this value for anything nowadays.
52
-  *
53
-  * 'passwordsalt' => 'd3c944a9af095aa08f',
54
- */
44
+    /**
45
+     * The salt used to hash all passwords, auto-generated by the Nextcloud
46
+     * installer. (There are also per-user salts.) If you lose this salt you lose
47
+     * all your passwords. This example is for documentation only, and you should
48
+     * never use it.
49
+     *
50
+     * @deprecated This salt is deprecated and only used for legacy-compatibility,
51
+     * developers should *NOT* use this value for anything nowadays.
52
+     *
53
+     * 'passwordsalt' => 'd3c944a9af095aa08f',
54
+     */
55 55
 'passwordsalt' => '',
56 56
 
57 57
 /**
@@ -69,12 +69,12 @@  discard block
 block discarded – undo
69 69
  *   Using TLS certificates where commonName=<IP address> is deprecated
70 70
  */
71 71
 'trusted_domains' =>
72
-   [
72
+    [
73 73
     'demo.example.org',
74 74
     'otherdomain.example.org',
75 75
     '10.111.112.113',
76 76
     '[2001:db8::1]'
77
-  ],
77
+    ],
78 78
 
79 79
 
80 80
 /**
@@ -697,10 +697,10 @@  discard block
 block discarded – undo
697 697
  *  - www.edri.org
698 698
  */
699 699
 'connectivity_check_domains' => [
700
-	'www.nextcloud.com',
701
-	'www.startpage.com',
702
-	'www.eff.org',
703
-	'www.edri.org'
700
+    'www.nextcloud.com',
701
+    'www.startpage.com',
702
+    'www.eff.org',
703
+    'www.edri.org'
704 704
 ],
705 705
 
706 706
 /**
@@ -816,9 +816,9 @@  discard block
 block discarded – undo
816 816
  * Defaults to an empty array.
817 817
  */
818 818
 'log.condition' => [
819
-	'shared_secret' => '57b58edb6637fe3059b3595cf9c41b9',
820
-	'users' => ['sample-user'],
821
-	'apps' => ['files'],
819
+    'shared_secret' => '57b58edb6637fe3059b3595cf9c41b9',
820
+    'users' => ['sample-user'],
821
+    'apps' => ['files'],
822 822
 ],
823 823
 
824 824
 /**
@@ -872,18 +872,18 @@  discard block
 block discarded – undo
872 872
  *  - iOS client app id: ``1125420102``
873 873
  */
874 874
 'customclient_desktop' =>
875
-	'https://nextcloud.com/install/#install-clients',
875
+    'https://nextcloud.com/install/#install-clients',
876 876
 'customclient_android' =>
877
-	'https://play.google.com/store/apps/details?id=com.nextcloud.client',
877
+    'https://play.google.com/store/apps/details?id=com.nextcloud.client',
878 878
 'customclient_ios' =>
879
-	'https://itunes.apple.com/us/app/nextcloud/id1125420102?mt=8',
879
+    'https://itunes.apple.com/us/app/nextcloud/id1125420102?mt=8',
880 880
 'customclient_ios_appid' =>
881
-		'1125420102',
881
+        '1125420102',
882 882
 /**
883
- * Apps
884
- *
885
- * Options for the Apps folder, Apps store, and App code checker.
886
- */
883
+         * Apps
884
+         *
885
+         * Options for the Apps folder, Apps store, and App code checker.
886
+         */
887 887
 
888 888
 /**
889 889
  * When enabled, admins may install apps from the Nextcloud app store.
@@ -901,11 +901,11 @@  discard block
 block discarded – undo
901 901
  * indicates if a Web server can write files to that folder.
902 902
  */
903 903
 'apps_paths' => [
904
-	[
905
-		'path'=> '/var/www/nextcloud/apps',
906
-		'url' => '/apps',
907
-		'writable' => true,
908
-	],
904
+    [
905
+        'path'=> '/var/www/nextcloud/apps',
906
+        'url' => '/apps',
907
+        'writable' => true,
908
+    ],
909 909
 ],
910 910
 
911 911
 /**
@@ -970,8 +970,8 @@  discard block
 block discarded – undo
970 970
  * Defaults to ``''`` (empty string)
971 971
  */
972 972
 'preview_office_cl_parameters' =>
973
-	' --headless --nologo --nofirststartwizard --invisible --norestore '.
974
-	'--convert-to png --outdir ',
973
+    ' --headless --nologo --nofirststartwizard --invisible --norestore '.
974
+    '--convert-to png --outdir ',
975 975
 
976 976
 /**
977 977
  * Only register providers that have been explicitly enabled
@@ -1015,15 +1015,15 @@  discard block
 block discarded – undo
1015 1015
  *  - OC\Preview\XBitmap
1016 1016
  */
1017 1017
 'enabledPreviewProviders' => [
1018
-	'OC\Preview\PNG',
1019
-	'OC\Preview\JPEG',
1020
-	'OC\Preview\GIF',
1021
-	'OC\Preview\HEIC',
1022
-	'OC\Preview\BMP',
1023
-	'OC\Preview\XBitmap',
1024
-	'OC\Preview\MP3',
1025
-	'OC\Preview\TXT',
1026
-	'OC\Preview\MarkDown'
1018
+    'OC\Preview\PNG',
1019
+    'OC\Preview\JPEG',
1020
+    'OC\Preview\GIF',
1021
+    'OC\Preview\HEIC',
1022
+    'OC\Preview\BMP',
1023
+    'OC\Preview\XBitmap',
1024
+    'OC\Preview\MP3',
1025
+    'OC\Preview\TXT',
1026
+    'OC\Preview\MarkDown'
1027 1027
 ],
1028 1028
 
1029 1029
 /**
@@ -1099,11 +1099,11 @@  discard block
 block discarded – undo
1099 1099
 
1100 1100
 /**
1101 1101
  * Extra SSL options to be used for configuration.
1102
-  *
1102
+ *
1103 1103
  * Defaults to an empty array.
1104 1104
  */
1105 1105
 'openssl' => [
1106
-	'config' => '/absolute/location/of/openssl.cnf',
1106
+    'config' => '/absolute/location/of/openssl.cnf',
1107 1107
 ],
1108 1108
 
1109 1109
 /**
@@ -1151,11 +1151,11 @@  discard block
 block discarded – undo
1151 1151
  * for more information.
1152 1152
  */
1153 1153
 'redis' => [
1154
-	'host' => 'localhost', // can also be a unix domain socket: '/tmp/redis.sock'
1155
-	'port' => 6379,
1156
-	'timeout' => 0.0,
1157
-	'password' => '', // Optional, if not defined no password will be used.
1158
-	'dbindex' => 0, // Optional, if undefined SELECT will not run and will use Redis Server's default DB Index.
1154
+    'host' => 'localhost', // can also be a unix domain socket: '/tmp/redis.sock'
1155
+    'port' => 6379,
1156
+    'timeout' => 0.0,
1157
+    'password' => '', // Optional, if not defined no password will be used.
1158
+    'dbindex' => 0, // Optional, if undefined SELECT will not run and will use Redis Server's default DB Index.
1159 1159
 ],
1160 1160
 
1161 1161
 /**
@@ -1184,14 +1184,14 @@  discard block
 block discarded – undo
1184 1184
  * https://github.com/phpredis/phpredis/commit/c5994f2a42b8a348af92d3acb4edff1328ad8ce1
1185 1185
  */
1186 1186
 'redis.cluster' => [
1187
-	'seeds' => [ // provide some/all of the cluster servers to bootstrap discovery, port required
1188
-		'localhost:7000',
1189
-		'localhost:7001',
1190
-	],
1191
-	'timeout' => 0.0,
1192
-	'read_timeout' => 0.0,
1193
-	'failover_mode' => \RedisCluster::FAILOVER_ERROR,
1194
-	'password' => '', // Optional, if not defined no password will be used.
1187
+    'seeds' => [ // provide some/all of the cluster servers to bootstrap discovery, port required
1188
+        'localhost:7000',
1189
+        'localhost:7001',
1190
+    ],
1191
+    'timeout' => 0.0,
1192
+    'read_timeout' => 0.0,
1193
+    'failover_mode' => \RedisCluster::FAILOVER_ERROR,
1194
+    'password' => '', // Optional, if not defined no password will be used.
1195 1195
 ],
1196 1196
 
1197 1197
 
@@ -1199,35 +1199,35 @@  discard block
 block discarded – undo
1199 1199
  * Server details for one or more memcached servers to use for memory caching.
1200 1200
  */
1201 1201
 'memcached_servers' => [
1202
-	// hostname, port and optional weight. Also see:
1203
-	// http://www.php.net/manual/en/memcached.addservers.php
1204
-	// http://www.php.net/manual/en/memcached.addserver.php
1205
-	['localhost', 11211],
1206
-	//array('other.host.local', 11211),
1202
+    // hostname, port and optional weight. Also see:
1203
+    // http://www.php.net/manual/en/memcached.addservers.php
1204
+    // http://www.php.net/manual/en/memcached.addserver.php
1205
+    ['localhost', 11211],
1206
+    //array('other.host.local', 11211),
1207 1207
 ],
1208 1208
 
1209 1209
 /**
1210 1210
  * Connection options for memcached
1211 1211
  */
1212 1212
 'memcached_options' => [
1213
-	// Set timeouts to 50ms
1214
-	\Memcached::OPT_CONNECT_TIMEOUT => 50,
1215
-	\Memcached::OPT_RETRY_TIMEOUT =>   50,
1216
-	\Memcached::OPT_SEND_TIMEOUT =>    50,
1217
-	\Memcached::OPT_RECV_TIMEOUT =>    50,
1218
-	\Memcached::OPT_POLL_TIMEOUT =>    50,
1213
+    // Set timeouts to 50ms
1214
+    \Memcached::OPT_CONNECT_TIMEOUT => 50,
1215
+    \Memcached::OPT_RETRY_TIMEOUT =>   50,
1216
+    \Memcached::OPT_SEND_TIMEOUT =>    50,
1217
+    \Memcached::OPT_RECV_TIMEOUT =>    50,
1218
+    \Memcached::OPT_POLL_TIMEOUT =>    50,
1219 1219
 
1220
-	// Enable compression
1221
-	\Memcached::OPT_COMPRESSION =>          true,
1220
+    // Enable compression
1221
+    \Memcached::OPT_COMPRESSION =>          true,
1222 1222
 
1223
-	// Turn on consistent hashing
1224
-	\Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
1223
+    // Turn on consistent hashing
1224
+    \Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
1225 1225
 
1226
-	// Enable Binary Protocol
1227
-	\Memcached::OPT_BINARY_PROTOCOL =>      true,
1226
+    // Enable Binary Protocol
1227
+    \Memcached::OPT_BINARY_PROTOCOL =>      true,
1228 1228
 
1229
-	// Binary serializer vill be enabled if the igbinary PECL module is available
1230
-	//\Memcached::OPT_SERIALIZER => \Memcached::SERIALIZER_IGBINARY,
1229
+    // Binary serializer vill be enabled if the igbinary PECL module is available
1230
+    //\Memcached::OPT_SERIALIZER => \Memcached::SERIALIZER_IGBINARY,
1231 1231
 ],
1232 1232
 
1233 1233
 
@@ -1273,61 +1273,61 @@  discard block
 block discarded – undo
1273 1273
  * One way to test is applying for a trystack account at http://trystack.org/
1274 1274
  */
1275 1275
 'objectstore' => [
1276
-	'class' => 'OC\\Files\\ObjectStore\\Swift',
1277
-	'arguments' => [
1278
-		// trystack will use your facebook id as the user name
1279
-		'username' => 'facebook100000123456789',
1280
-		// in the trystack dashboard go to user -> settings -> API Password to
1281
-		// generate a password
1282
-		'password' => 'Secr3tPaSSWoRdt7',
1283
-		// must already exist in the objectstore, name can be different
1284
-		'container' => 'nextcloud',
1285
-		// prefix to prepend to the fileid, default is 'oid:urn:'
1286
-		'objectPrefix' => 'oid:urn:',
1287
-		// create the container if it does not exist. default is false
1288
-		'autocreate' => true,
1289
-		// required, dev-/trystack defaults to 'RegionOne'
1290
-		'region' => 'RegionOne',
1291
-		// The Identity / Keystone endpoint
1292
-		'url' => 'http://8.21.28.222:5000/v2.0',
1293
-		// required on dev-/trystack
1294
-		'tenantName' => 'facebook100000123456789',
1295
-		// dev-/trystack uses swift by default, the lib defaults to 'cloudFiles'
1296
-		// if omitted
1297
-		'serviceName' => 'swift',
1298
-		// The Interface / url Type, optional
1299
-		'urlType' => 'internal'
1300
-	],
1276
+    'class' => 'OC\\Files\\ObjectStore\\Swift',
1277
+    'arguments' => [
1278
+        // trystack will use your facebook id as the user name
1279
+        'username' => 'facebook100000123456789',
1280
+        // in the trystack dashboard go to user -> settings -> API Password to
1281
+        // generate a password
1282
+        'password' => 'Secr3tPaSSWoRdt7',
1283
+        // must already exist in the objectstore, name can be different
1284
+        'container' => 'nextcloud',
1285
+        // prefix to prepend to the fileid, default is 'oid:urn:'
1286
+        'objectPrefix' => 'oid:urn:',
1287
+        // create the container if it does not exist. default is false
1288
+        'autocreate' => true,
1289
+        // required, dev-/trystack defaults to 'RegionOne'
1290
+        'region' => 'RegionOne',
1291
+        // The Identity / Keystone endpoint
1292
+        'url' => 'http://8.21.28.222:5000/v2.0',
1293
+        // required on dev-/trystack
1294
+        'tenantName' => 'facebook100000123456789',
1295
+        // dev-/trystack uses swift by default, the lib defaults to 'cloudFiles'
1296
+        // if omitted
1297
+        'serviceName' => 'swift',
1298
+        // The Interface / url Type, optional
1299
+        'urlType' => 'internal'
1300
+    ],
1301 1301
 ],
1302 1302
 
1303 1303
 /**
1304 1304
  * To use swift V3
1305 1305
  */
1306 1306
 'objectstore' => [
1307
-	'class' => 'OC\\Files\\ObjectStore\\Swift',
1308
-	'arguments' => [
1309
-		'autocreate' => true,
1310
-		'user' => [
1311
-			'name' => 'swift',
1312
-			'password' => 'swift',
1313
-			'domain' => [
1314
-				'name' => 'default',
1315
-			],
1316
-		],
1317
-		'scope' => [
1318
-			'project' => [
1319
-				'name' => 'service',
1320
-				'domain' => [
1321
-					'name' => 'default',
1322
-				],
1323
-			],
1324
-		],
1325
-		'tenantName' => 'service',
1326
-		'serviceName' => 'swift',
1327
-		'region' => 'regionOne',
1328
-		'url' => 'http://yourswifthost:5000/v3',
1329
-		'bucket' => 'nextcloud',
1330
-	],
1307
+    'class' => 'OC\\Files\\ObjectStore\\Swift',
1308
+    'arguments' => [
1309
+        'autocreate' => true,
1310
+        'user' => [
1311
+            'name' => 'swift',
1312
+            'password' => 'swift',
1313
+            'domain' => [
1314
+                'name' => 'default',
1315
+            ],
1316
+        ],
1317
+        'scope' => [
1318
+            'project' => [
1319
+                'name' => 'service',
1320
+                'domain' => [
1321
+                    'name' => 'default',
1322
+                ],
1323
+            ],
1324
+        ],
1325
+        'tenantName' => 'service',
1326
+        'serviceName' => 'swift',
1327
+        'region' => 'regionOne',
1328
+        'url' => 'http://yourswifthost:5000/v3',
1329
+        'bucket' => 'nextcloud',
1330
+    ],
1331 1331
 ],
1332 1332
 
1333 1333
 
@@ -1379,8 +1379,8 @@  discard block
 block discarded – undo
1379 1379
  * encryption in MySQL or specify a custom wait timeout on a cheap hoster.
1380 1380
  */
1381 1381
 'dbdriveroptions' => [
1382
-	PDO::MYSQL_ATTR_SSL_CA => '/file/path/to/ca_cert.pem',
1383
-	PDO::MYSQL_ATTR_INIT_COMMAND => 'SET wait_timeout = 28800'
1382
+    PDO::MYSQL_ATTR_SSL_CA => '/file/path/to/ca_cert.pem',
1383
+    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET wait_timeout = 28800'
1384 1384
 ],
1385 1385
 
1386 1386
 /**
@@ -1437,10 +1437,10 @@  discard block
 block discarded – undo
1437 1437
  *  - pgsql (PostgreSQL)
1438 1438
  */
1439 1439
 'supportedDatabases' => [
1440
-	'sqlite',
1441
-	'mysql',
1442
-	'pgsql',
1443
-	'oci',
1440
+    'sqlite',
1441
+    'mysql',
1442
+    'pgsql',
1443
+    'oci',
1444 1444
 ],
1445 1445
 
1446 1446
 /**
@@ -1768,8 +1768,8 @@  discard block
 block discarded – undo
1768 1768
  * WARNING: only use this if you know what you are doing
1769 1769
  */
1770 1770
 'csrf.optout' => [
1771
-	'/^WebDAVFS/', // OS X Finder
1772
-	'/^Microsoft-WebDAV-MiniRedir/', // Windows webdav drive
1771
+    '/^WebDAVFS/', // OS X Finder
1772
+    '/^Microsoft-WebDAV-MiniRedir/', // Windows webdav drive
1773 1773
 ],
1774 1774
 
1775 1775
 /**
Please login to merge, or discard this patch.