Passed
Push — master ( 157c65...2ad95f )
by Morris
10:50 queued 10s
created
apps/settings/lib/Controller/UsersController.php 1 patch
Indentation   +464 added lines, -464 removed lines patch added patch discarded remove patch
@@ -58,468 +58,468 @@
 block discarded – undo
58 58
 use function in_array;
59 59
 
60 60
 class UsersController extends Controller {
61
-	/** @var IUserManager */
62
-	private $userManager;
63
-	/** @var IGroupManager */
64
-	private $groupManager;
65
-	/** @var IUserSession */
66
-	private $userSession;
67
-	/** @var IConfig */
68
-	private $config;
69
-	/** @var bool */
70
-	private $isAdmin;
71
-	/** @var IL10N */
72
-	private $l10n;
73
-	/** @var IMailer */
74
-	private $mailer;
75
-	/** @var IFactory */
76
-	private $l10nFactory;
77
-	/** @var IAppManager */
78
-	private $appManager;
79
-	/** @var AccountManager */
80
-	private $accountManager;
81
-	/** @var Manager */
82
-	private $keyManager;
83
-	/** @var IJobList */
84
-	private $jobList;
85
-	/** @var IManager */
86
-	private $encryptionManager;
87
-
88
-
89
-	public function __construct(string $appName,
90
-								IRequest $request,
91
-								IUserManager $userManager,
92
-								IGroupManager $groupManager,
93
-								IUserSession $userSession,
94
-								IConfig $config,
95
-								bool $isAdmin,
96
-								IL10N $l10n,
97
-								IMailer $mailer,
98
-								IFactory $l10nFactory,
99
-								IAppManager $appManager,
100
-								AccountManager $accountManager,
101
-								Manager $keyManager,
102
-								IJobList $jobList,
103
-								IManager $encryptionManager) {
104
-		parent::__construct($appName, $request);
105
-		$this->userManager = $userManager;
106
-		$this->groupManager = $groupManager;
107
-		$this->userSession = $userSession;
108
-		$this->config = $config;
109
-		$this->isAdmin = $isAdmin;
110
-		$this->l10n = $l10n;
111
-		$this->mailer = $mailer;
112
-		$this->l10nFactory = $l10nFactory;
113
-		$this->appManager = $appManager;
114
-		$this->accountManager = $accountManager;
115
-		$this->keyManager = $keyManager;
116
-		$this->jobList = $jobList;
117
-		$this->encryptionManager = $encryptionManager;
118
-	}
119
-
120
-
121
-	/**
122
-	 * @NoCSRFRequired
123
-	 * @NoAdminRequired
124
-	 *
125
-	 * Display users list template
126
-	 *
127
-	 * @return TemplateResponse
128
-	 */
129
-	public function usersListByGroup() {
130
-		return $this->usersList();
131
-	}
132
-
133
-	/**
134
-	 * @NoCSRFRequired
135
-	 * @NoAdminRequired
136
-	 *
137
-	 * Display users list template
138
-	 *
139
-	 * @return TemplateResponse
140
-	 */
141
-	public function usersList() {
142
-		$user = $this->userSession->getUser();
143
-		$uid = $user->getUID();
144
-
145
-		\OC::$server->getNavigationManager()->setActiveEntry('core_users');
146
-
147
-		/* SORT OPTION: SORT_USERCOUNT or SORT_GROUPNAME */
148
-		$sortGroupsBy = \OC\Group\MetaData::SORT_USERCOUNT;
149
-		$isLDAPUsed = false;
150
-		if ($this->config->getSystemValue('sort_groups_by_name', false)) {
151
-			$sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
152
-		} else {
153
-			if ($this->appManager->isEnabledForUser('user_ldap')) {
154
-				$isLDAPUsed =
155
-					$this->groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
156
-				if ($isLDAPUsed) {
157
-					// LDAP user count can be slow, so we sort by group name here
158
-					$sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
159
-				}
160
-			}
161
-		}
162
-
163
-		$canChangePassword = $this->canAdminChangeUserPasswords();
164
-
165
-		/* GROUPS */
166
-		$groupsInfo = new \OC\Group\MetaData(
167
-			$uid,
168
-			$this->isAdmin,
169
-			$this->groupManager,
170
-			$this->userSession
171
-		);
172
-
173
-		$groupsInfo->setSorting($sortGroupsBy);
174
-		list($adminGroup, $groups) = $groupsInfo->get();
175
-
176
-		if (!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) {
177
-			$isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) {
178
-				return $ldapFound || $backend instanceof User_Proxy;
179
-			});
180
-		}
181
-
182
-		$disabledUsers = -1;
183
-		$userCount = 0;
184
-
185
-		if (!$isLDAPUsed) {
186
-			if ($this->isAdmin) {
187
-				$disabledUsers = $this->userManager->countDisabledUsers();
188
-				$userCount = array_reduce($this->userManager->countUsers(), function ($v, $w) {
189
-					return $v + (int)$w;
190
-				}, 0);
191
-			} else {
192
-				// User is subadmin !
193
-				// Map group list to names to retrieve the countDisabledUsersOfGroups
194
-				$userGroups = $this->groupManager->getUserGroups($user);
195
-				$groupsNames = [];
196
-
197
-				foreach ($groups as $key => $group) {
198
-					// $userCount += (int)$group['usercount'];
199
-					array_push($groupsNames, $group['name']);
200
-					// we prevent subadmins from looking up themselves
201
-					// so we lower the count of the groups he belongs to
202
-					if (array_key_exists($group['id'], $userGroups)) {
203
-						$groups[$key]['usercount']--;
204
-						$userCount -= 1; // we also lower from one the total count
205
-					}
206
-				};
207
-				$userCount += $this->userManager->countUsersOfGroups($groupsInfo->getGroups());
208
-				$disabledUsers = $this->userManager->countDisabledUsersOfGroups($groupsNames);
209
-			}
210
-
211
-			$userCount -= $disabledUsers;
212
-		}
213
-
214
-		$disabledUsersGroup = [
215
-			'id' => 'disabled',
216
-			'name' => 'Disabled users',
217
-			'usercount' => $disabledUsers
218
-		];
219
-
220
-		/* QUOTAS PRESETS */
221
-		$quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'));
222
-		$defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
223
-
224
-		\OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts');
225
-
226
-		/* LANGUAGES */
227
-		$languages = $this->l10nFactory->getLanguages();
228
-
229
-		/* FINAL DATA */
230
-		$serverData = [];
231
-		// groups
232
-		$serverData['groups'] = array_merge_recursive($adminGroup, [$disabledUsersGroup], $groups);
233
-		// Various data
234
-		$serverData['isAdmin'] = $this->isAdmin;
235
-		$serverData['sortGroups'] = $sortGroupsBy;
236
-		$serverData['quotaPreset'] = $quotaPreset;
237
-		$serverData['userCount'] = $userCount;
238
-		$serverData['languages'] = $languages;
239
-		$serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en');
240
-		$serverData['forceLanguage'] = $this->config->getSystemValue('force_language', false);
241
-		// Settings
242
-		$serverData['defaultQuota'] = $defaultQuota;
243
-		$serverData['canChangePassword'] = $canChangePassword;
244
-		$serverData['newUserGenerateUserID'] = $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes';
245
-		$serverData['newUserRequireEmail'] = $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes';
246
-		$serverData['newUserSendEmail'] = $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes';
247
-
248
-		return new TemplateResponse('settings', 'settings-vue', ['serverData' => $serverData]);
249
-	}
250
-
251
-	/**
252
-	 * @param string $key
253
-	 * @param string $value
254
-	 *
255
-	 * @return JSONResponse
256
-	 */
257
-	public function setPreference(string $key, string $value): JSONResponse {
258
-		$allowed = ['newUser.sendEmail'];
259
-		if (!in_array($key, $allowed, true)) {
260
-			return new JSONResponse([], Http::STATUS_FORBIDDEN);
261
-		}
262
-
263
-		$this->config->setAppValue('core', $key, $value);
264
-
265
-		return new JSONResponse([]);
266
-	}
267
-
268
-	/**
269
-	 * Parse the app value for quota_present
270
-	 *
271
-	 * @param string $quotaPreset
272
-	 * @return array
273
-	 */
274
-	protected function parseQuotaPreset(string $quotaPreset): array {
275
-		// 1 GB, 5 GB, 10 GB => [1 GB, 5 GB, 10 GB]
276
-		$presets = array_filter(array_map('trim', explode(',', $quotaPreset)));
277
-		// Drop default and none, Make array indexes numerically
278
-		return array_values(array_diff($presets, ['default', 'none']));
279
-	}
280
-
281
-	/**
282
-	 * check if the admin can change the users password
283
-	 *
284
-	 * The admin can change the passwords if:
285
-	 *
286
-	 *   - no encryption module is loaded and encryption is disabled
287
-	 *   - encryption module is loaded but it doesn't require per user keys
288
-	 *
289
-	 * The admin can not change the passwords if:
290
-	 *
291
-	 *   - an encryption module is loaded and it uses per-user keys
292
-	 *   - encryption is enabled but no encryption modules are loaded
293
-	 *
294
-	 * @return bool
295
-	 */
296
-	protected function canAdminChangeUserPasswords() {
297
-		$isEncryptionEnabled = $this->encryptionManager->isEnabled();
298
-		try {
299
-			$noUserSpecificEncryptionKeys =!$this->encryptionManager->getEncryptionModule()->needDetailedAccessList();
300
-			$isEncryptionModuleLoaded = true;
301
-		} catch (ModuleDoesNotExistsException $e) {
302
-			$noUserSpecificEncryptionKeys = true;
303
-			$isEncryptionModuleLoaded = false;
304
-		}
305
-
306
-		$canChangePassword = ($isEncryptionEnabled && $isEncryptionModuleLoaded  && $noUserSpecificEncryptionKeys)
307
-			|| (!$isEncryptionEnabled && !$isEncryptionModuleLoaded)
308
-			|| (!$isEncryptionEnabled && $isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys);
309
-
310
-		return $canChangePassword;
311
-	}
312
-
313
-	/**
314
-	 * @NoAdminRequired
315
-	 * @NoSubAdminRequired
316
-	 * @PasswordConfirmationRequired
317
-	 *
318
-	 * @param string $avatarScope
319
-	 * @param string $displayname
320
-	 * @param string $displaynameScope
321
-	 * @param string $phone
322
-	 * @param string $phoneScope
323
-	 * @param string $email
324
-	 * @param string $emailScope
325
-	 * @param string $website
326
-	 * @param string $websiteScope
327
-	 * @param string $address
328
-	 * @param string $addressScope
329
-	 * @param string $twitter
330
-	 * @param string $twitterScope
331
-	 * @return DataResponse
332
-	 */
333
-	public function setUserSettings($avatarScope,
334
-									$displayname,
335
-									$displaynameScope,
336
-									$phone,
337
-									$phoneScope,
338
-									$email,
339
-									$emailScope,
340
-									$website,
341
-									$websiteScope,
342
-									$address,
343
-									$addressScope,
344
-									$twitter,
345
-									$twitterScope
346
-	) {
347
-		if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
348
-			return new DataResponse(
349
-				[
350
-					'status' => 'error',
351
-					'data' => [
352
-						'message' => $this->l10n->t('Invalid mail address')
353
-					]
354
-				],
355
-				Http::STATUS_UNPROCESSABLE_ENTITY
356
-			);
357
-		}
358
-		$user = $this->userSession->getUser();
359
-		$data = $this->accountManager->getUser($user);
360
-		$data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope];
361
-		if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
362
-			$data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope];
363
-			$data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope];
364
-		}
365
-		if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
366
-			$shareProvider = \OC::$server->query(FederatedShareProvider::class);
367
-			if ($shareProvider->isLookupServerUploadEnabled()) {
368
-				$data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope];
369
-				$data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope];
370
-				$data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope];
371
-				$data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope];
372
-			}
373
-		}
374
-		try {
375
-			$this->saveUserSettings($user, $data);
376
-			return new DataResponse(
377
-				[
378
-					'status' => 'success',
379
-					'data' => [
380
-						'userId' => $user->getUID(),
381
-						'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'],
382
-						'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'],
383
-						'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
384
-						'email' => $data[AccountManager::PROPERTY_EMAIL]['value'],
385
-						'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'],
386
-						'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'],
387
-						'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'],
388
-						'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'],
389
-						'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'],
390
-						'message' => $this->l10n->t('Settings saved')
391
-					]
392
-				],
393
-				Http::STATUS_OK
394
-			);
395
-		} catch (ForbiddenException $e) {
396
-			return new DataResponse([
397
-				'status' => 'error',
398
-				'data' => [
399
-					'message' => $e->getMessage()
400
-				],
401
-			]);
402
-		}
403
-	}
404
-	/**
405
-	 * update account manager with new user data
406
-	 *
407
-	 * @param IUser $user
408
-	 * @param array $data
409
-	 * @throws ForbiddenException
410
-	 */
411
-	protected function saveUserSettings(IUser $user, array $data) {
412
-		// keep the user back-end up-to-date with the latest display name and email
413
-		// address
414
-		$oldDisplayName = $user->getDisplayName();
415
-		$oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
416
-		if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
417
-			&& $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
418
-		) {
419
-			$result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
420
-			if ($result === false) {
421
-				throw new ForbiddenException($this->l10n->t('Unable to change full name'));
422
-			}
423
-		}
424
-		$oldEmailAddress = $user->getEMailAddress();
425
-		$oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
426
-		if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
427
-			&& $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
428
-		) {
429
-			// this is the only permission a backend provides and is also used
430
-			// for the permission of setting a email address
431
-			if (!$user->canChangeDisplayName()) {
432
-				throw new ForbiddenException($this->l10n->t('Unable to change email address'));
433
-			}
434
-			$user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
435
-		}
436
-		$this->accountManager->updateUser($user, $data);
437
-	}
438
-
439
-	/**
440
-	 * Set the mail address of a user
441
-	 *
442
-	 * @NoAdminRequired
443
-	 * @NoSubAdminRequired
444
-	 * @PasswordConfirmationRequired
445
-	 *
446
-	 * @param string $account
447
-	 * @param bool $onlyVerificationCode only return verification code without updating the data
448
-	 * @return DataResponse
449
-	 */
450
-	public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse {
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
-	}
61
+    /** @var IUserManager */
62
+    private $userManager;
63
+    /** @var IGroupManager */
64
+    private $groupManager;
65
+    /** @var IUserSession */
66
+    private $userSession;
67
+    /** @var IConfig */
68
+    private $config;
69
+    /** @var bool */
70
+    private $isAdmin;
71
+    /** @var IL10N */
72
+    private $l10n;
73
+    /** @var IMailer */
74
+    private $mailer;
75
+    /** @var IFactory */
76
+    private $l10nFactory;
77
+    /** @var IAppManager */
78
+    private $appManager;
79
+    /** @var AccountManager */
80
+    private $accountManager;
81
+    /** @var Manager */
82
+    private $keyManager;
83
+    /** @var IJobList */
84
+    private $jobList;
85
+    /** @var IManager */
86
+    private $encryptionManager;
87
+
88
+
89
+    public function __construct(string $appName,
90
+                                IRequest $request,
91
+                                IUserManager $userManager,
92
+                                IGroupManager $groupManager,
93
+                                IUserSession $userSession,
94
+                                IConfig $config,
95
+                                bool $isAdmin,
96
+                                IL10N $l10n,
97
+                                IMailer $mailer,
98
+                                IFactory $l10nFactory,
99
+                                IAppManager $appManager,
100
+                                AccountManager $accountManager,
101
+                                Manager $keyManager,
102
+                                IJobList $jobList,
103
+                                IManager $encryptionManager) {
104
+        parent::__construct($appName, $request);
105
+        $this->userManager = $userManager;
106
+        $this->groupManager = $groupManager;
107
+        $this->userSession = $userSession;
108
+        $this->config = $config;
109
+        $this->isAdmin = $isAdmin;
110
+        $this->l10n = $l10n;
111
+        $this->mailer = $mailer;
112
+        $this->l10nFactory = $l10nFactory;
113
+        $this->appManager = $appManager;
114
+        $this->accountManager = $accountManager;
115
+        $this->keyManager = $keyManager;
116
+        $this->jobList = $jobList;
117
+        $this->encryptionManager = $encryptionManager;
118
+    }
119
+
120
+
121
+    /**
122
+     * @NoCSRFRequired
123
+     * @NoAdminRequired
124
+     *
125
+     * Display users list template
126
+     *
127
+     * @return TemplateResponse
128
+     */
129
+    public function usersListByGroup() {
130
+        return $this->usersList();
131
+    }
132
+
133
+    /**
134
+     * @NoCSRFRequired
135
+     * @NoAdminRequired
136
+     *
137
+     * Display users list template
138
+     *
139
+     * @return TemplateResponse
140
+     */
141
+    public function usersList() {
142
+        $user = $this->userSession->getUser();
143
+        $uid = $user->getUID();
144
+
145
+        \OC::$server->getNavigationManager()->setActiveEntry('core_users');
146
+
147
+        /* SORT OPTION: SORT_USERCOUNT or SORT_GROUPNAME */
148
+        $sortGroupsBy = \OC\Group\MetaData::SORT_USERCOUNT;
149
+        $isLDAPUsed = false;
150
+        if ($this->config->getSystemValue('sort_groups_by_name', false)) {
151
+            $sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
152
+        } else {
153
+            if ($this->appManager->isEnabledForUser('user_ldap')) {
154
+                $isLDAPUsed =
155
+                    $this->groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
156
+                if ($isLDAPUsed) {
157
+                    // LDAP user count can be slow, so we sort by group name here
158
+                    $sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
159
+                }
160
+            }
161
+        }
162
+
163
+        $canChangePassword = $this->canAdminChangeUserPasswords();
164
+
165
+        /* GROUPS */
166
+        $groupsInfo = new \OC\Group\MetaData(
167
+            $uid,
168
+            $this->isAdmin,
169
+            $this->groupManager,
170
+            $this->userSession
171
+        );
172
+
173
+        $groupsInfo->setSorting($sortGroupsBy);
174
+        list($adminGroup, $groups) = $groupsInfo->get();
175
+
176
+        if (!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) {
177
+            $isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) {
178
+                return $ldapFound || $backend instanceof User_Proxy;
179
+            });
180
+        }
181
+
182
+        $disabledUsers = -1;
183
+        $userCount = 0;
184
+
185
+        if (!$isLDAPUsed) {
186
+            if ($this->isAdmin) {
187
+                $disabledUsers = $this->userManager->countDisabledUsers();
188
+                $userCount = array_reduce($this->userManager->countUsers(), function ($v, $w) {
189
+                    return $v + (int)$w;
190
+                }, 0);
191
+            } else {
192
+                // User is subadmin !
193
+                // Map group list to names to retrieve the countDisabledUsersOfGroups
194
+                $userGroups = $this->groupManager->getUserGroups($user);
195
+                $groupsNames = [];
196
+
197
+                foreach ($groups as $key => $group) {
198
+                    // $userCount += (int)$group['usercount'];
199
+                    array_push($groupsNames, $group['name']);
200
+                    // we prevent subadmins from looking up themselves
201
+                    // so we lower the count of the groups he belongs to
202
+                    if (array_key_exists($group['id'], $userGroups)) {
203
+                        $groups[$key]['usercount']--;
204
+                        $userCount -= 1; // we also lower from one the total count
205
+                    }
206
+                };
207
+                $userCount += $this->userManager->countUsersOfGroups($groupsInfo->getGroups());
208
+                $disabledUsers = $this->userManager->countDisabledUsersOfGroups($groupsNames);
209
+            }
210
+
211
+            $userCount -= $disabledUsers;
212
+        }
213
+
214
+        $disabledUsersGroup = [
215
+            'id' => 'disabled',
216
+            'name' => 'Disabled users',
217
+            'usercount' => $disabledUsers
218
+        ];
219
+
220
+        /* QUOTAS PRESETS */
221
+        $quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'));
222
+        $defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
223
+
224
+        \OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts');
225
+
226
+        /* LANGUAGES */
227
+        $languages = $this->l10nFactory->getLanguages();
228
+
229
+        /* FINAL DATA */
230
+        $serverData = [];
231
+        // groups
232
+        $serverData['groups'] = array_merge_recursive($adminGroup, [$disabledUsersGroup], $groups);
233
+        // Various data
234
+        $serverData['isAdmin'] = $this->isAdmin;
235
+        $serverData['sortGroups'] = $sortGroupsBy;
236
+        $serverData['quotaPreset'] = $quotaPreset;
237
+        $serverData['userCount'] = $userCount;
238
+        $serverData['languages'] = $languages;
239
+        $serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en');
240
+        $serverData['forceLanguage'] = $this->config->getSystemValue('force_language', false);
241
+        // Settings
242
+        $serverData['defaultQuota'] = $defaultQuota;
243
+        $serverData['canChangePassword'] = $canChangePassword;
244
+        $serverData['newUserGenerateUserID'] = $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes';
245
+        $serverData['newUserRequireEmail'] = $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes';
246
+        $serverData['newUserSendEmail'] = $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes';
247
+
248
+        return new TemplateResponse('settings', 'settings-vue', ['serverData' => $serverData]);
249
+    }
250
+
251
+    /**
252
+     * @param string $key
253
+     * @param string $value
254
+     *
255
+     * @return JSONResponse
256
+     */
257
+    public function setPreference(string $key, string $value): JSONResponse {
258
+        $allowed = ['newUser.sendEmail'];
259
+        if (!in_array($key, $allowed, true)) {
260
+            return new JSONResponse([], Http::STATUS_FORBIDDEN);
261
+        }
262
+
263
+        $this->config->setAppValue('core', $key, $value);
264
+
265
+        return new JSONResponse([]);
266
+    }
267
+
268
+    /**
269
+     * Parse the app value for quota_present
270
+     *
271
+     * @param string $quotaPreset
272
+     * @return array
273
+     */
274
+    protected function parseQuotaPreset(string $quotaPreset): array {
275
+        // 1 GB, 5 GB, 10 GB => [1 GB, 5 GB, 10 GB]
276
+        $presets = array_filter(array_map('trim', explode(',', $quotaPreset)));
277
+        // Drop default and none, Make array indexes numerically
278
+        return array_values(array_diff($presets, ['default', 'none']));
279
+    }
280
+
281
+    /**
282
+     * check if the admin can change the users password
283
+     *
284
+     * The admin can change the passwords if:
285
+     *
286
+     *   - no encryption module is loaded and encryption is disabled
287
+     *   - encryption module is loaded but it doesn't require per user keys
288
+     *
289
+     * The admin can not change the passwords if:
290
+     *
291
+     *   - an encryption module is loaded and it uses per-user keys
292
+     *   - encryption is enabled but no encryption modules are loaded
293
+     *
294
+     * @return bool
295
+     */
296
+    protected function canAdminChangeUserPasswords() {
297
+        $isEncryptionEnabled = $this->encryptionManager->isEnabled();
298
+        try {
299
+            $noUserSpecificEncryptionKeys =!$this->encryptionManager->getEncryptionModule()->needDetailedAccessList();
300
+            $isEncryptionModuleLoaded = true;
301
+        } catch (ModuleDoesNotExistsException $e) {
302
+            $noUserSpecificEncryptionKeys = true;
303
+            $isEncryptionModuleLoaded = false;
304
+        }
305
+
306
+        $canChangePassword = ($isEncryptionEnabled && $isEncryptionModuleLoaded  && $noUserSpecificEncryptionKeys)
307
+            || (!$isEncryptionEnabled && !$isEncryptionModuleLoaded)
308
+            || (!$isEncryptionEnabled && $isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys);
309
+
310
+        return $canChangePassword;
311
+    }
312
+
313
+    /**
314
+     * @NoAdminRequired
315
+     * @NoSubAdminRequired
316
+     * @PasswordConfirmationRequired
317
+     *
318
+     * @param string $avatarScope
319
+     * @param string $displayname
320
+     * @param string $displaynameScope
321
+     * @param string $phone
322
+     * @param string $phoneScope
323
+     * @param string $email
324
+     * @param string $emailScope
325
+     * @param string $website
326
+     * @param string $websiteScope
327
+     * @param string $address
328
+     * @param string $addressScope
329
+     * @param string $twitter
330
+     * @param string $twitterScope
331
+     * @return DataResponse
332
+     */
333
+    public function setUserSettings($avatarScope,
334
+                                    $displayname,
335
+                                    $displaynameScope,
336
+                                    $phone,
337
+                                    $phoneScope,
338
+                                    $email,
339
+                                    $emailScope,
340
+                                    $website,
341
+                                    $websiteScope,
342
+                                    $address,
343
+                                    $addressScope,
344
+                                    $twitter,
345
+                                    $twitterScope
346
+    ) {
347
+        if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
348
+            return new DataResponse(
349
+                [
350
+                    'status' => 'error',
351
+                    'data' => [
352
+                        'message' => $this->l10n->t('Invalid mail address')
353
+                    ]
354
+                ],
355
+                Http::STATUS_UNPROCESSABLE_ENTITY
356
+            );
357
+        }
358
+        $user = $this->userSession->getUser();
359
+        $data = $this->accountManager->getUser($user);
360
+        $data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope];
361
+        if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
362
+            $data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope];
363
+            $data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope];
364
+        }
365
+        if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
366
+            $shareProvider = \OC::$server->query(FederatedShareProvider::class);
367
+            if ($shareProvider->isLookupServerUploadEnabled()) {
368
+                $data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope];
369
+                $data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope];
370
+                $data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope];
371
+                $data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope];
372
+            }
373
+        }
374
+        try {
375
+            $this->saveUserSettings($user, $data);
376
+            return new DataResponse(
377
+                [
378
+                    'status' => 'success',
379
+                    'data' => [
380
+                        'userId' => $user->getUID(),
381
+                        'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'],
382
+                        'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'],
383
+                        'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
384
+                        'email' => $data[AccountManager::PROPERTY_EMAIL]['value'],
385
+                        'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'],
386
+                        'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'],
387
+                        'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'],
388
+                        'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'],
389
+                        'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'],
390
+                        'message' => $this->l10n->t('Settings saved')
391
+                    ]
392
+                ],
393
+                Http::STATUS_OK
394
+            );
395
+        } catch (ForbiddenException $e) {
396
+            return new DataResponse([
397
+                'status' => 'error',
398
+                'data' => [
399
+                    'message' => $e->getMessage()
400
+                ],
401
+            ]);
402
+        }
403
+    }
404
+    /**
405
+     * update account manager with new user data
406
+     *
407
+     * @param IUser $user
408
+     * @param array $data
409
+     * @throws ForbiddenException
410
+     */
411
+    protected function saveUserSettings(IUser $user, array $data) {
412
+        // keep the user back-end up-to-date with the latest display name and email
413
+        // address
414
+        $oldDisplayName = $user->getDisplayName();
415
+        $oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
416
+        if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
417
+            && $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
418
+        ) {
419
+            $result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
420
+            if ($result === false) {
421
+                throw new ForbiddenException($this->l10n->t('Unable to change full name'));
422
+            }
423
+        }
424
+        $oldEmailAddress = $user->getEMailAddress();
425
+        $oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
426
+        if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
427
+            && $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
428
+        ) {
429
+            // this is the only permission a backend provides and is also used
430
+            // for the permission of setting a email address
431
+            if (!$user->canChangeDisplayName()) {
432
+                throw new ForbiddenException($this->l10n->t('Unable to change email address'));
433
+            }
434
+            $user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
435
+        }
436
+        $this->accountManager->updateUser($user, $data);
437
+    }
438
+
439
+    /**
440
+     * Set the mail address of a user
441
+     *
442
+     * @NoAdminRequired
443
+     * @NoSubAdminRequired
444
+     * @PasswordConfirmationRequired
445
+     *
446
+     * @param string $account
447
+     * @param bool $onlyVerificationCode only return verification code without updating the data
448
+     * @return DataResponse
449
+     */
450
+    public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse {
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/Settings/Personal/PersonalInfo.php 1 patch
Indentation   +241 added lines, -241 removed lines patch added patch discarded remove patch
@@ -47,245 +47,245 @@
 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
-			/** @var FederatedShareProvider $shareProvider */
100
-			$shareProvider = \OC::$server->query(FederatedShareProvider::class);
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
-			$userLocale = reset($userLocale);
248
-		}
249
-
250
-		$localesForLanguage = array_filter($localeCodes, function ($localeCode) use ($userLang) {
251
-			return 0 === strpos($localeCode['code'], $userLang);
252
-		});
253
-
254
-		if (!$userLocale) {
255
-			$userLocale = [
256
-				'code' => 'en',
257
-				'name' => 'English'
258
-			];
259
-		}
260
-
261
-		return [
262
-			'activelocaleLang' => $userLocaleString,
263
-			'activelocale' => $userLocale,
264
-			'locales' => $localeCodes,
265
-			'localesForLanguage' => $localesForLanguage,
266
-		];
267
-	}
268
-
269
-	/**
270
-	 * @param array $userData
271
-	 * @return array
272
-	 */
273
-	private function getMessageParameters(array $userData) {
274
-		$needVerifyMessage = [AccountManager::PROPERTY_EMAIL, AccountManager::PROPERTY_WEBSITE, AccountManager::PROPERTY_TWITTER];
275
-		$messageParameters = [];
276
-		foreach ($needVerifyMessage as $property) {
277
-			switch ($userData[$property]['verified']) {
278
-				case AccountManager::VERIFIED:
279
-					$message = $this->l->t('Verifying');
280
-					break;
281
-				case AccountManager::VERIFICATION_IN_PROGRESS:
282
-					$message = $this->l->t('Verifying …');
283
-					break;
284
-				default:
285
-					$message = $this->l->t('Verify');
286
-			}
287
-			$messageParameters[$property . 'Message'] = $message;
288
-		}
289
-		return $messageParameters;
290
-	}
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
+            /** @var FederatedShareProvider $shareProvider */
100
+            $shareProvider = \OC::$server->query(FederatedShareProvider::class);
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
+            $userLocale = reset($userLocale);
248
+        }
249
+
250
+        $localesForLanguage = array_filter($localeCodes, function ($localeCode) use ($userLang) {
251
+            return 0 === strpos($localeCode['code'], $userLang);
252
+        });
253
+
254
+        if (!$userLocale) {
255
+            $userLocale = [
256
+                'code' => 'en',
257
+                'name' => 'English'
258
+            ];
259
+        }
260
+
261
+        return [
262
+            'activelocaleLang' => $userLocaleString,
263
+            'activelocale' => $userLocale,
264
+            'locales' => $localeCodes,
265
+            'localesForLanguage' => $localesForLanguage,
266
+        ];
267
+    }
268
+
269
+    /**
270
+     * @param array $userData
271
+     * @return array
272
+     */
273
+    private function getMessageParameters(array $userData) {
274
+        $needVerifyMessage = [AccountManager::PROPERTY_EMAIL, AccountManager::PROPERTY_WEBSITE, AccountManager::PROPERTY_TWITTER];
275
+        $messageParameters = [];
276
+        foreach ($needVerifyMessage as $property) {
277
+            switch ($userData[$property]['verified']) {
278
+                case AccountManager::VERIFIED:
279
+                    $message = $this->l->t('Verifying');
280
+                    break;
281
+                case AccountManager::VERIFICATION_IN_PROGRESS:
282
+                    $message = $this->l->t('Verifying …');
283
+                    break;
284
+                default:
285
+                    $message = $this->l->t('Verify');
286
+            }
287
+            $messageParameters[$property . 'Message'] = $message;
288
+        }
289
+        return $messageParameters;
290
+    }
291 291
 }
Please login to merge, or discard this patch.