Completed
Pull Request — master (#3869)
by Björn
13:19
created
settings/routes.php 1 patch
Indentation   +52 added lines, -52 removed lines patch added patch discarded remove patch
@@ -36,77 +36,77 @@
 block discarded – undo
36 36
 
37 37
 $application = new Application();
38 38
 $application->registerRoutes($this, [
39
-	'resources' => [
40
-		'users' => ['url' => '/settings/users/users'],
41
-		'AuthSettings' => ['url' => '/settings/personal/authtokens'],
42
-	],
43
-	'routes' => [
44
-		['name' => 'MailSettings#setMailSettings', 'url' => '/settings/admin/mailsettings', 'verb' => 'POST'],
45
-		['name' => 'MailSettings#storeCredentials', 'url' => '/settings/admin/mailsettings/credentials', 'verb' => 'POST'],
46
-		['name' => 'MailSettings#sendTestMail', 'url' => '/settings/admin/mailtest', 'verb' => 'POST'],
47
-		['name' => 'Encryption#startMigration', 'url' => '/settings/admin/startmigration', 'verb' => 'POST'],
48
-		['name' => 'AppSettings#listCategories', 'url' => '/settings/apps/categories', 'verb' => 'GET'],
49
-		['name' => 'AppSettings#viewApps', 'url' => '/settings/apps', 'verb' => 'GET'],
50
-		['name' => 'AppSettings#listApps', 'url' => '/settings/apps/list', 'verb' => 'GET'],
51
-		['name' => 'SecuritySettings#trustedDomains', 'url' => '/settings/admin/security/trustedDomains', 'verb' => 'POST'],
52
-		['name' => 'Users#setDisplayName', 'url' => '/settings/users/{username}/displayName', 'verb' => 'POST'],
53
-		['name' => 'Users#setEMailAddress', 'url' => '/settings/users/{id}/mailAddress', 'verb' => 'PUT'],
54
-		['name' => 'Users#setUserSettings', 'url' => '/settings/users/{username}/settings', 'verb' => 'PUT'],
55
-		['name' => 'Users#getVerificationCode', 'url' => '/settings/users/{account}/verify', 'verb' => 'GET'],
56
-		['name' => 'Users#stats', 'url' => '/settings/users/stats', 'verb' => 'GET'],
57
-		['name' => 'LogSettings#setLogLevel', 'url' => '/settings/admin/log/level', 'verb' => 'POST'],
58
-		['name' => 'LogSettings#getEntries', 'url' => '/settings/admin/log/entries', 'verb' => 'GET'],
59
-		['name' => 'LogSettings#download', 'url' => '/settings/admin/log/download', 'verb' => 'GET'],
60
-		['name' => 'CheckSetup#check', 'url' => '/settings/ajax/checksetup', 'verb' => 'GET'],
61
-		['name' => 'CheckSetup#getFailedIntegrityCheckFiles', 'url' => '/settings/integrity/failed', 'verb' => 'GET'],
62
-		['name' => 'CheckSetup#rescanFailedIntegrityCheck', 'url' => '/settings/integrity/rescan', 'verb' => 'GET'],
63
-		['name' => 'Certificate#addPersonalRootCertificate', 'url' => '/settings/personal/certificate', 'verb' => 'POST'],
64
-		['name' => 'Certificate#removePersonalRootCertificate', 'url' => '/settings/personal/certificate/{certificateIdentifier}', 'verb' => 'DELETE'],
65
-		['name' => 'Certificate#addSystemRootCertificate', 'url' => '/settings/admin/certificate', 'verb' => 'POST'],
66
-		['name' => 'Certificate#removeSystemRootCertificate', 'url' => '/settings/admin/certificate/{certificateIdentifier}', 'verb' => 'DELETE'],
67
-		['name' => 'AdminSettings#index', 'url' => '/settings/admin/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'server']],
68
-		['name' => 'AdminSettings#form', 'url' => '/settings/admin/{section}', 'verb' => 'GET'],
69
-		['name' => 'ChangePassword#changePersonalPassword', 'url' => '/settings/personal/changepassword', 'verb' => 'POST'],
70
-		['name' => 'ChangePassword#changeUserPassword', 'url' => '/settings/users/changepassword', 'verb' => 'POST'],
71
-		['name' => 'Personal#setLanguage', 'url' => '/settings/ajax/setlanguage.php', 'verb' => 'POST'],
72
-		['name' => 'Groups#index', 'url' => '/settings/users/groups', 'verb' => 'GET'],
73
-		['name' => 'Groups#show', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'GET'],
74
-		['name' => 'Groups#create', 'url' => '/settings/users/groups', 'verb' => 'POST'],
75
-		['name' => 'Groups#update', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'PUT'],
76
-		['name' => 'Groups#destroy', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'DELETE'],
77
-	]
39
+    'resources' => [
40
+        'users' => ['url' => '/settings/users/users'],
41
+        'AuthSettings' => ['url' => '/settings/personal/authtokens'],
42
+    ],
43
+    'routes' => [
44
+        ['name' => 'MailSettings#setMailSettings', 'url' => '/settings/admin/mailsettings', 'verb' => 'POST'],
45
+        ['name' => 'MailSettings#storeCredentials', 'url' => '/settings/admin/mailsettings/credentials', 'verb' => 'POST'],
46
+        ['name' => 'MailSettings#sendTestMail', 'url' => '/settings/admin/mailtest', 'verb' => 'POST'],
47
+        ['name' => 'Encryption#startMigration', 'url' => '/settings/admin/startmigration', 'verb' => 'POST'],
48
+        ['name' => 'AppSettings#listCategories', 'url' => '/settings/apps/categories', 'verb' => 'GET'],
49
+        ['name' => 'AppSettings#viewApps', 'url' => '/settings/apps', 'verb' => 'GET'],
50
+        ['name' => 'AppSettings#listApps', 'url' => '/settings/apps/list', 'verb' => 'GET'],
51
+        ['name' => 'SecuritySettings#trustedDomains', 'url' => '/settings/admin/security/trustedDomains', 'verb' => 'POST'],
52
+        ['name' => 'Users#setDisplayName', 'url' => '/settings/users/{username}/displayName', 'verb' => 'POST'],
53
+        ['name' => 'Users#setEMailAddress', 'url' => '/settings/users/{id}/mailAddress', 'verb' => 'PUT'],
54
+        ['name' => 'Users#setUserSettings', 'url' => '/settings/users/{username}/settings', 'verb' => 'PUT'],
55
+        ['name' => 'Users#getVerificationCode', 'url' => '/settings/users/{account}/verify', 'verb' => 'GET'],
56
+        ['name' => 'Users#stats', 'url' => '/settings/users/stats', 'verb' => 'GET'],
57
+        ['name' => 'LogSettings#setLogLevel', 'url' => '/settings/admin/log/level', 'verb' => 'POST'],
58
+        ['name' => 'LogSettings#getEntries', 'url' => '/settings/admin/log/entries', 'verb' => 'GET'],
59
+        ['name' => 'LogSettings#download', 'url' => '/settings/admin/log/download', 'verb' => 'GET'],
60
+        ['name' => 'CheckSetup#check', 'url' => '/settings/ajax/checksetup', 'verb' => 'GET'],
61
+        ['name' => 'CheckSetup#getFailedIntegrityCheckFiles', 'url' => '/settings/integrity/failed', 'verb' => 'GET'],
62
+        ['name' => 'CheckSetup#rescanFailedIntegrityCheck', 'url' => '/settings/integrity/rescan', 'verb' => 'GET'],
63
+        ['name' => 'Certificate#addPersonalRootCertificate', 'url' => '/settings/personal/certificate', 'verb' => 'POST'],
64
+        ['name' => 'Certificate#removePersonalRootCertificate', 'url' => '/settings/personal/certificate/{certificateIdentifier}', 'verb' => 'DELETE'],
65
+        ['name' => 'Certificate#addSystemRootCertificate', 'url' => '/settings/admin/certificate', 'verb' => 'POST'],
66
+        ['name' => 'Certificate#removeSystemRootCertificate', 'url' => '/settings/admin/certificate/{certificateIdentifier}', 'verb' => 'DELETE'],
67
+        ['name' => 'AdminSettings#index', 'url' => '/settings/admin/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'server']],
68
+        ['name' => 'AdminSettings#form', 'url' => '/settings/admin/{section}', 'verb' => 'GET'],
69
+        ['name' => 'ChangePassword#changePersonalPassword', 'url' => '/settings/personal/changepassword', 'verb' => 'POST'],
70
+        ['name' => 'ChangePassword#changeUserPassword', 'url' => '/settings/users/changepassword', 'verb' => 'POST'],
71
+        ['name' => 'Personal#setLanguage', 'url' => '/settings/ajax/setlanguage.php', 'verb' => 'POST'],
72
+        ['name' => 'Groups#index', 'url' => '/settings/users/groups', 'verb' => 'GET'],
73
+        ['name' => 'Groups#show', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'GET'],
74
+        ['name' => 'Groups#create', 'url' => '/settings/users/groups', 'verb' => 'POST'],
75
+        ['name' => 'Groups#update', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'PUT'],
76
+        ['name' => 'Groups#destroy', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'DELETE'],
77
+    ]
78 78
 ]);
79 79
 
80 80
 /** @var $this \OCP\Route\IRouter */
81 81
 
82 82
 // Settings pages
83 83
 $this->create('settings_help', '/settings/help')
84
-	->actionInclude('settings/help.php');
84
+    ->actionInclude('settings/help.php');
85 85
 $this->create('settings_personal', '/settings/personal')
86
-	->actionInclude('settings/personal.php');
86
+    ->actionInclude('settings/personal.php');
87 87
 $this->create('settings_users', '/settings/users')
88
-	->actionInclude('settings/users.php');
88
+    ->actionInclude('settings/users.php');
89 89
 // Settings ajax actions
90 90
 // users
91 91
 $this->create('settings_ajax_setquota', '/settings/ajax/setquota.php')
92
-	->actionInclude('settings/ajax/setquota.php');
92
+    ->actionInclude('settings/ajax/setquota.php');
93 93
 $this->create('settings_ajax_togglegroups', '/settings/ajax/togglegroups.php')
94
-	->actionInclude('settings/ajax/togglegroups.php');
94
+    ->actionInclude('settings/ajax/togglegroups.php');
95 95
 $this->create('settings_ajax_togglesubadmins', '/settings/ajax/togglesubadmins.php')
96
-	->actionInclude('settings/ajax/togglesubadmins.php');
96
+    ->actionInclude('settings/ajax/togglesubadmins.php');
97 97
 $this->create('settings_ajax_changegorupname', '/settings/ajax/changegroupname.php')
98
-	->actionInclude('settings/ajax/changegroupname.php');
98
+    ->actionInclude('settings/ajax/changegroupname.php');
99 99
 // apps
100 100
 $this->create('settings_ajax_enableapp', '/settings/ajax/enableapp.php')
101
-	->actionInclude('settings/ajax/enableapp.php');
101
+    ->actionInclude('settings/ajax/enableapp.php');
102 102
 $this->create('settings_ajax_disableapp', '/settings/ajax/disableapp.php')
103
-	->actionInclude('settings/ajax/disableapp.php');
103
+    ->actionInclude('settings/ajax/disableapp.php');
104 104
 $this->create('settings_ajax_updateapp', '/settings/ajax/updateapp.php')
105
-	->actionInclude('settings/ajax/updateapp.php');
105
+    ->actionInclude('settings/ajax/updateapp.php');
106 106
 $this->create('settings_ajax_uninstallapp', '/settings/ajax/uninstallapp.php')
107
-	->actionInclude('settings/ajax/uninstallapp.php');
107
+    ->actionInclude('settings/ajax/uninstallapp.php');
108 108
 $this->create('settings_ajax_navigationdetect', '/settings/ajax/navigationdetect.php')
109
-	->actionInclude('settings/ajax/navigationdetect.php');
109
+    ->actionInclude('settings/ajax/navigationdetect.php');
110 110
 // admin
111 111
 $this->create('settings_ajax_excludegroups', '/settings/ajax/excludegroups.php')
112
-	->actionInclude('settings/ajax/excludegroups.php');
112
+    ->actionInclude('settings/ajax/excludegroups.php');
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ShareesAPIController.php 3 patches
Doc Comments   +4 added lines, -1 removed lines patch added patch discarded remove patch
@@ -385,7 +385,7 @@  discard block
 block discarded – undo
385 385
 	 * split user and remote from federated cloud id
386 386
 	 *
387 387
 	 * @param string $address federated share address
388
-	 * @return array [user, remoteURL]
388
+	 * @return string[] [user, remoteURL]
389 389
 	 * @throws \Exception
390 390
 	 */
391 391
 	public function splitUserRemote($address) {
@@ -652,6 +652,9 @@  discard block
 block discarded – undo
652 652
 		return $result;
653 653
 	}
654 654
 
655
+	/**
656
+	 * @param string $search
657
+	 */
655 658
 	protected function getLookup($search) {
656 659
 		$isEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
657 660
 		$lookupServerUrl = $this->config->getSystemValue('lookup_server', 'https://lookup.nextcloud.com');
Please login to merge, or discard this patch.
Indentation   +670 added lines, -670 removed lines patch added patch discarded remove patch
@@ -43,674 +43,674 @@
 block discarded – undo
43 43
 
44 44
 class ShareesAPIController extends OCSController {
45 45
 
46
-	/** @var IGroupManager */
47
-	protected $groupManager;
48
-
49
-	/** @var IUserManager */
50
-	protected $userManager;
51
-
52
-	/** @var IManager */
53
-	protected $contactsManager;
54
-
55
-	/** @var IConfig */
56
-	protected $config;
57
-
58
-	/** @var IUserSession */
59
-	protected $userSession;
60
-
61
-	/** @var IURLGenerator */
62
-	protected $urlGenerator;
63
-
64
-	/** @var ILogger */
65
-	protected $logger;
66
-
67
-	/** @var \OCP\Share\IManager */
68
-	protected $shareManager;
69
-
70
-	/** @var IClientService */
71
-	protected $clientService;
72
-
73
-	/** @var ICloudIdManager  */
74
-	protected $cloudIdManager;
75
-
76
-	/** @var bool */
77
-	protected $shareWithGroupOnly = false;
78
-
79
-	/** @var bool */
80
-	protected $shareeEnumeration = true;
81
-
82
-	/** @var int */
83
-	protected $offset = 0;
84
-
85
-	/** @var int */
86
-	protected $limit = 10;
87
-
88
-	/** @var array */
89
-	protected $result = [
90
-		'exact' => [
91
-			'users' => [],
92
-			'groups' => [],
93
-			'remotes' => [],
94
-			'emails' => [],
95
-			'circles' => [],
96
-		],
97
-		'users' => [],
98
-		'groups' => [],
99
-		'remotes' => [],
100
-		'emails' => [],
101
-		'lookup' => [],
102
-		'circles' => [],
103
-	];
104
-
105
-	protected $reachedEndFor = [];
106
-
107
-	/**
108
-	 * @param string $appName
109
-	 * @param IRequest $request
110
-	 * @param IGroupManager $groupManager
111
-	 * @param IUserManager $userManager
112
-	 * @param IManager $contactsManager
113
-	 * @param IConfig $config
114
-	 * @param IUserSession $userSession
115
-	 * @param IURLGenerator $urlGenerator
116
-	 * @param ILogger $logger
117
-	 * @param \OCP\Share\IManager $shareManager
118
-	 * @param IClientService $clientService
119
-	 * @param ICloudIdManager $cloudIdManager
120
-	 */
121
-	public function __construct($appName,
122
-								IRequest $request,
123
-								IGroupManager $groupManager,
124
-								IUserManager $userManager,
125
-								IManager $contactsManager,
126
-								IConfig $config,
127
-								IUserSession $userSession,
128
-								IURLGenerator $urlGenerator,
129
-								ILogger $logger,
130
-								\OCP\Share\IManager $shareManager,
131
-								IClientService $clientService,
132
-								ICloudIdManager $cloudIdManager
133
-	) {
134
-		parent::__construct($appName, $request);
135
-
136
-		$this->groupManager = $groupManager;
137
-		$this->userManager = $userManager;
138
-		$this->contactsManager = $contactsManager;
139
-		$this->config = $config;
140
-		$this->userSession = $userSession;
141
-		$this->urlGenerator = $urlGenerator;
142
-		$this->logger = $logger;
143
-		$this->shareManager = $shareManager;
144
-		$this->clientService = $clientService;
145
-		$this->cloudIdManager = $cloudIdManager;
146
-	}
147
-
148
-	/**
149
-	 * @param string $search
150
-	 */
151
-	protected function getUsers($search) {
152
-		$this->result['users'] = $this->result['exact']['users'] = $users = [];
153
-
154
-		$userGroups = [];
155
-		if ($this->shareWithGroupOnly) {
156
-			// Search in all the groups this user is part of
157
-			$userGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
158
-			foreach ($userGroups as $userGroup) {
159
-				$usersTmp = $this->groupManager->displayNamesInGroup($userGroup, $search, $this->limit, $this->offset);
160
-				foreach ($usersTmp as $uid => $userDisplayName) {
161
-					$users[$uid] = $userDisplayName;
162
-				}
163
-			}
164
-		} else {
165
-			// Search in all users
166
-			$usersTmp = $this->userManager->searchDisplayName($search, $this->limit, $this->offset);
167
-
168
-			foreach ($usersTmp as $user) {
169
-				$users[$user->getUID()] = $user->getDisplayName();
170
-			}
171
-		}
172
-
173
-		if (!$this->shareeEnumeration || sizeof($users) < $this->limit) {
174
-			$this->reachedEndFor[] = 'users';
175
-		}
176
-
177
-		$foundUserById = false;
178
-		$lowerSearch = strtolower($search);
179
-		foreach ($users as $uid => $userDisplayName) {
180
-			if (strtolower($uid) === $lowerSearch || strtolower($userDisplayName) === $lowerSearch) {
181
-				if (strtolower($uid) === $lowerSearch) {
182
-					$foundUserById = true;
183
-				}
184
-				$this->result['exact']['users'][] = [
185
-					'label' => $userDisplayName,
186
-					'value' => [
187
-						'shareType' => Share::SHARE_TYPE_USER,
188
-						'shareWith' => $uid,
189
-					],
190
-				];
191
-			} else {
192
-				$this->result['users'][] = [
193
-					'label' => $userDisplayName,
194
-					'value' => [
195
-						'shareType' => Share::SHARE_TYPE_USER,
196
-						'shareWith' => $uid,
197
-					],
198
-				];
199
-			}
200
-		}
201
-
202
-		if ($this->offset === 0 && !$foundUserById) {
203
-			// On page one we try if the search result has a direct hit on the
204
-			// user id and if so, we add that to the exact match list
205
-			$user = $this->userManager->get($search);
206
-			if ($user instanceof IUser) {
207
-				$addUser = true;
208
-
209
-				if ($this->shareWithGroupOnly) {
210
-					// Only add, if we have a common group
211
-					$commonGroups = array_intersect($userGroups, $this->groupManager->getUserGroupIds($user));
212
-					$addUser = !empty($commonGroups);
213
-				}
214
-
215
-				if ($addUser) {
216
-					array_push($this->result['exact']['users'], [
217
-						'label' => $user->getDisplayName(),
218
-						'value' => [
219
-							'shareType' => Share::SHARE_TYPE_USER,
220
-							'shareWith' => $user->getUID(),
221
-						],
222
-					]);
223
-				}
224
-			}
225
-		}
226
-
227
-		if (!$this->shareeEnumeration) {
228
-			$this->result['users'] = [];
229
-		}
230
-	}
231
-
232
-	/**
233
-	 * @param string $search
234
-	 */
235
-	protected function getGroups($search) {
236
-		$this->result['groups'] = $this->result['exact']['groups'] = [];
237
-
238
-		$groups = $this->groupManager->search($search, $this->limit, $this->offset);
239
-		$groupIds = array_map(function (IGroup $group) { return $group->getGID(); }, $groups);
240
-
241
-		if (!$this->shareeEnumeration || sizeof($groups) < $this->limit) {
242
-			$this->reachedEndFor[] = 'groups';
243
-		}
244
-
245
-		$userGroups =  [];
246
-		if (!empty($groups) && $this->shareWithGroupOnly) {
247
-			// Intersect all the groups that match with the groups this user is a member of
248
-			$userGroups = $this->groupManager->getUserGroups($this->userSession->getUser());
249
-			$userGroups = array_map(function (IGroup $group) { return $group->getGID(); }, $userGroups);
250
-			$groupIds = array_intersect($groupIds, $userGroups);
251
-		}
252
-
253
-		$lowerSearch = strtolower($search);
254
-		foreach ($groups as $group) {
255
-			// FIXME: use a more efficient approach
256
-			$gid = $group->getGID();
257
-			if (!in_array($gid, $groupIds)) {
258
-				continue;
259
-			}
260
-			if (strtolower($gid) === $lowerSearch || strtolower($group->getDisplayName()) === $lowerSearch) {
261
-				$this->result['exact']['groups'][] = [
262
-					'label' => $group->getDisplayName(),
263
-					'value' => [
264
-						'shareType' => Share::SHARE_TYPE_GROUP,
265
-						'shareWith' => $gid,
266
-					],
267
-				];
268
-			} else {
269
-				$this->result['groups'][] = [
270
-					'label' => $group->getDisplayName(),
271
-					'value' => [
272
-						'shareType' => Share::SHARE_TYPE_GROUP,
273
-						'shareWith' => $gid,
274
-					],
275
-				];
276
-			}
277
-		}
278
-
279
-		if ($this->offset === 0 && empty($this->result['exact']['groups'])) {
280
-			// On page one we try if the search result has a direct hit on the
281
-			// user id and if so, we add that to the exact match list
282
-			$group = $this->groupManager->get($search);
283
-			if ($group instanceof IGroup && (!$this->shareWithGroupOnly || in_array($group->getGID(), $userGroups))) {
284
-				array_push($this->result['exact']['groups'], [
285
-					'label' => $group->getDisplayName(),
286
-					'value' => [
287
-						'shareType' => Share::SHARE_TYPE_GROUP,
288
-						'shareWith' => $group->getGID(),
289
-					],
290
-				]);
291
-			}
292
-		}
293
-
294
-		if (!$this->shareeEnumeration) {
295
-			$this->result['groups'] = [];
296
-		}
297
-	}
298
-
299
-
300
-	/**
301
-	 * @param string $search
302
-	 */
303
-	protected function getCircles($search) {
304
-		$this->result['circles'] = $this->result['exact']['circles'] = [];
305
-
306
-		$result = \OCA\Circles\Api\Sharees::search($search, $this->limit, $this->offset);
307
-		if (array_key_exists('circles', $result['exact'])) {
308
-			$this->result['exact']['circles'] = $result['exact']['circles'];
309
-		}
310
-		if (array_key_exists('circles', $result)) {
311
-			$this->result['circles'] = $result['circles'];
312
-		}
313
-	}
314
-
315
-
316
-	/**
317
-	 * @param string $search
318
-	 * @return array
319
-	 */
320
-	protected function getRemote($search) {
321
-		$result = ['results' => [], 'exact' => []];
322
-
323
-		// Search in contacts
324
-		//@todo Pagination missing
325
-		$addressBookContacts = $this->contactsManager->search($search, ['CLOUD', 'FN']);
326
-		$result['exactIdMatch'] = false;
327
-		foreach ($addressBookContacts as $contact) {
328
-			if (isset($contact['isLocalSystemBook'])) {
329
-				continue;
330
-			}
331
-			if (isset($contact['CLOUD'])) {
332
-				$cloudIds = $contact['CLOUD'];
333
-				if (!is_array($cloudIds)) {
334
-					$cloudIds = [$cloudIds];
335
-				}
336
-				$lowerSearch = strtolower($search);
337
-				foreach ($cloudIds as $cloudId) {
338
-					list(, $serverUrl) = $this->splitUserRemote($cloudId);
339
-					if (strtolower($contact['FN']) === $lowerSearch || strtolower($cloudId) === $lowerSearch) {
340
-						if (strtolower($cloudId) === $lowerSearch) {
341
-							$result['exactIdMatch'] = true;
342
-						}
343
-						$result['exact'][] = [
344
-							'label' => $contact['FN'] . " ($cloudId)",
345
-							'value' => [
346
-								'shareType' => Share::SHARE_TYPE_REMOTE,
347
-								'shareWith' => $cloudId,
348
-								'server' => $serverUrl,
349
-							],
350
-						];
351
-					} else {
352
-						$result['results'][] = [
353
-							'label' => $contact['FN'] . " ($cloudId)",
354
-							'value' => [
355
-								'shareType' => Share::SHARE_TYPE_REMOTE,
356
-								'shareWith' => $cloudId,
357
-								'server' => $serverUrl,
358
-							],
359
-						];
360
-					}
361
-				}
362
-			}
363
-		}
364
-
365
-		if (!$this->shareeEnumeration) {
366
-			$result['results'] = [];
367
-		}
368
-
369
-		if (!$result['exactIdMatch'] && $this->cloudIdManager->isValidCloudId($search) && $this->offset === 0) {
370
-			$result['exact'][] = [
371
-				'label' => $search,
372
-				'value' => [
373
-					'shareType' => Share::SHARE_TYPE_REMOTE,
374
-					'shareWith' => $search,
375
-				],
376
-			];
377
-		}
378
-
379
-		$this->reachedEndFor[] = 'remotes';
380
-
381
-		return $result;
382
-	}
383
-
384
-	/**
385
-	 * split user and remote from federated cloud id
386
-	 *
387
-	 * @param string $address federated share address
388
-	 * @return array [user, remoteURL]
389
-	 * @throws \Exception
390
-	 */
391
-	public function splitUserRemote($address) {
392
-		try {
393
-			$cloudId = $this->cloudIdManager->resolveCloudId($address);
394
-			return [$cloudId->getUser(), $cloudId->getRemote()];
395
-		} catch (\InvalidArgumentException $e) {
396
-			throw new \Exception('Invalid Federated Cloud ID', 0, $e);
397
-		}
398
-	}
399
-
400
-	/**
401
-	 * Strips away a potential file names and trailing slashes:
402
-	 * - http://localhost
403
-	 * - http://localhost/
404
-	 * - http://localhost/index.php
405
-	 * - http://localhost/index.php/s/{shareToken}
406
-	 *
407
-	 * all return: http://localhost
408
-	 *
409
-	 * @param string $remote
410
-	 * @return string
411
-	 */
412
-	protected function fixRemoteURL($remote) {
413
-		$remote = str_replace('\\', '/', $remote);
414
-		if ($fileNamePosition = strpos($remote, '/index.php')) {
415
-			$remote = substr($remote, 0, $fileNamePosition);
416
-		}
417
-		$remote = rtrim($remote, '/');
418
-
419
-		return $remote;
420
-	}
421
-
422
-	/**
423
-	 * @NoAdminRequired
424
-	 *
425
-	 * @param string $search
426
-	 * @param string $itemType
427
-	 * @param int $page
428
-	 * @param int $perPage
429
-	 * @param int|int[] $shareType
430
-	 * @param bool $lookup
431
-	 * @return DataResponse
432
-	 * @throws OCSBadRequestException
433
-	 */
434
-	public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) {
435
-
436
-		// only search for string larger than a given threshold
437
-		$threshold = (int)$this->config->getSystemValue('sharing.minSearchStringLength', 0);
438
-		if (strlen($search) < $threshold) {
439
-			return new DataResponse($this->result);
440
-		}
441
-
442
-		// never return more than the max. number of results configured in the config.php
443
-		$maxResults = (int)$this->config->getSystemValue('sharing.maxAutocompleteResults', 0);
444
-		if ($maxResults > 0) {
445
-			$perPage = min($perPage, $maxResults);
446
-		}
447
-		if ($perPage <= 0) {
448
-			throw new OCSBadRequestException('Invalid perPage argument');
449
-		}
450
-		if ($page <= 0) {
451
-			throw new OCSBadRequestException('Invalid page');
452
-		}
453
-
454
-		$shareTypes = [
455
-			Share::SHARE_TYPE_USER,
456
-		];
457
-
458
-		if ($itemType === 'file' || $itemType === 'folder') {
459
-			if ($this->shareManager->allowGroupSharing()) {
460
-				$shareTypes[] = Share::SHARE_TYPE_GROUP;
461
-			}
462
-
463
-			if ($this->isRemoteSharingAllowed($itemType)) {
464
-				$shareTypes[] = Share::SHARE_TYPE_REMOTE;
465
-			}
466
-
467
-			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
468
-				$shareTypes[] = Share::SHARE_TYPE_EMAIL;
469
-			}
470
-		} else {
471
-			$shareTypes[] = Share::SHARE_TYPE_GROUP;
472
-			$shareTypes[] = Share::SHARE_TYPE_EMAIL;
473
-		}
474
-
475
-		if (\OCP\App::isEnabled('circles')) {
476
-			$shareTypes[] = Share::SHARE_TYPE_CIRCLE;
477
-		}
478
-
479
-		if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
480
-			$shareTypes = array_intersect($shareTypes, $_GET['shareType']);
481
-			sort($shareTypes);
482
-		} else if (is_numeric($shareType)) {
483
-			$shareTypes = array_intersect($shareTypes, [(int) $shareType]);
484
-			sort($shareTypes);
485
-		}
486
-
487
-		$this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
488
-		$this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
489
-		$this->limit = (int) $perPage;
490
-		$this->offset = $perPage * ($page - 1);
491
-
492
-		return $this->searchSharees($search, $itemType, $shareTypes, $page, $perPage, $lookup);
493
-	}
494
-
495
-	/**
496
-	 * Method to get out the static call for better testing
497
-	 *
498
-	 * @param string $itemType
499
-	 * @return bool
500
-	 */
501
-	protected function isRemoteSharingAllowed($itemType) {
502
-		try {
503
-			$backend = Share::getBackend($itemType);
504
-			return $backend->isShareTypeAllowed(Share::SHARE_TYPE_REMOTE);
505
-		} catch (\Exception $e) {
506
-			return false;
507
-		}
508
-	}
509
-
510
-	/**
511
-	 * Testable search function that does not need globals
512
-	 *
513
-	 * @param string $search
514
-	 * @param string $itemType
515
-	 * @param array $shareTypes
516
-	 * @param int $page
517
-	 * @param int $perPage
518
-	 * @param bool $lookup
519
-	 * @return DataResponse
520
-	 * @throws OCSBadRequestException
521
-	 */
522
-	protected function searchSharees($search, $itemType, array $shareTypes, $page, $perPage, $lookup) {
523
-		// Verify arguments
524
-		if ($itemType === null) {
525
-			throw new OCSBadRequestException('Missing itemType');
526
-		}
527
-
528
-		// Get users
529
-		if (in_array(Share::SHARE_TYPE_USER, $shareTypes)) {
530
-			$this->getUsers($search);
531
-		}
532
-
533
-		// Get groups
534
-		if (in_array(Share::SHARE_TYPE_GROUP, $shareTypes)) {
535
-			$this->getGroups($search);
536
-		}
537
-
538
-		// Get circles
539
-		if (in_array(Share::SHARE_TYPE_CIRCLE, $shareTypes)) {
540
-			$this->getCircles($search);
541
-		}
542
-
543
-
544
-		// Get remote
545
-		$remoteResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
546
-		if (in_array(Share::SHARE_TYPE_REMOTE, $shareTypes)) {
547
-			$remoteResults = $this->getRemote($search);
548
-		}
549
-
550
-		// Get emails
551
-		$mailResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
552
-		if (in_array(Share::SHARE_TYPE_EMAIL, $shareTypes)) {
553
-			$mailResults = $this->getEmail($search);
554
-		}
555
-
556
-		// Get from lookup server
557
-		if ($lookup) {
558
-			$this->getLookup($search);
559
-		}
560
-
561
-		// if we have a exact match, either for the federated cloud id or for the
562
-		// email address we only return the exact match. It is highly unlikely
563
-		// that the exact same email address and federated cloud id exists
564
-		if ($mailResults['exactIdMatch'] && !$remoteResults['exactIdMatch']) {
565
-			$this->result['emails'] = $mailResults['results'];
566
-			$this->result['exact']['emails'] = $mailResults['exact'];
567
-		} else if (!$mailResults['exactIdMatch'] && $remoteResults['exactIdMatch']) {
568
-			$this->result['remotes'] = $remoteResults['results'];
569
-			$this->result['exact']['remotes'] = $remoteResults['exact'];
570
-		} else {
571
-			$this->result['remotes'] = $remoteResults['results'];
572
-			$this->result['exact']['remotes'] = $remoteResults['exact'];
573
-			$this->result['emails'] = $mailResults['results'];
574
-			$this->result['exact']['emails'] = $mailResults['exact'];
575
-		}
576
-
577
-		$response = new DataResponse($this->result);
578
-
579
-		if (sizeof($this->reachedEndFor) < 3) {
580
-			$response->addHeader('Link', $this->getPaginationLink($page, [
581
-				'search' => $search,
582
-				'itemType' => $itemType,
583
-				'shareType' => $shareTypes,
584
-				'perPage' => $perPage,
585
-			]));
586
-		}
587
-
588
-		return $response;
589
-	}
590
-
591
-	/**
592
-	 * @param string $search
593
-	 * @return array
594
-	 */
595
-	protected function getEmail($search) {
596
-		$result = ['results' => [], 'exact' => []];
597
-
598
-		// Search in contacts
599
-		//@todo Pagination missing
600
-		$addressBookContacts = $this->contactsManager->search($search, ['EMAIL', 'FN']);
601
-		$result['exactIdMatch'] = false;
602
-		foreach ($addressBookContacts as $contact) {
603
-			if (isset($contact['isLocalSystemBook'])) {
604
-				continue;
605
-			}
606
-			if (isset($contact['EMAIL'])) {
607
-				$emailAddresses = $contact['EMAIL'];
608
-				if (!is_array($emailAddresses)) {
609
-					$emailAddresses = [$emailAddresses];
610
-				}
611
-				foreach ($emailAddresses as $emailAddress) {
612
-					if (strtolower($contact['FN']) === strtolower($search) || strtolower($emailAddress) === strtolower($search)) {
613
-						if (strtolower($emailAddress) === strtolower($search)) {
614
-							$result['exactIdMatch'] = true;
615
-						}
616
-						$result['exact'][] = [
617
-							'label' => $contact['FN'] . " ($emailAddress)",
618
-							'value' => [
619
-								'shareType' => Share::SHARE_TYPE_EMAIL,
620
-								'shareWith' => $emailAddress,
621
-							],
622
-						];
623
-					} else {
624
-						$result['results'][] = [
625
-							'label' => $contact['FN'] . " ($emailAddress)",
626
-							'value' => [
627
-								'shareType' => Share::SHARE_TYPE_EMAIL,
628
-								'shareWith' => $emailAddress,
629
-							],
630
-						];
631
-					}
632
-				}
633
-			}
634
-		}
635
-
636
-		if (!$this->shareeEnumeration) {
637
-			$result['results'] = [];
638
-		}
639
-
640
-		if (!$result['exactIdMatch'] && filter_var($search, FILTER_VALIDATE_EMAIL)) {
641
-			$result['exact'][] = [
642
-				'label' => $search,
643
-				'value' => [
644
-					'shareType' => Share::SHARE_TYPE_EMAIL,
645
-					'shareWith' => $search,
646
-				],
647
-			];
648
-		}
649
-
650
-		$this->reachedEndFor[] = 'emails';
651
-
652
-		return $result;
653
-	}
654
-
655
-	protected function getLookup($search) {
656
-		$isEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
657
-		$lookupServerUrl = $this->config->getSystemValue('lookup_server', 'https://lookup.nextcloud.com');
658
-		$lookupServerUrl = rtrim($lookupServerUrl, '/');
659
-		$result = [];
660
-
661
-		if($isEnabled === 'yes') {
662
-			try {
663
-				$client = $this->clientService->newClient();
664
-				$response = $client->get(
665
-					$lookupServerUrl . '/users?search=' . urlencode($search),
666
-					[
667
-						'timeout' => 10,
668
-						'connect_timeout' => 3,
669
-					]
670
-				);
671
-
672
-				$body = json_decode($response->getBody(), true);
673
-
674
-				$result = [];
675
-				foreach ($body as $lookup) {
676
-					$result[] = [
677
-						'label' => $lookup['federationId'],
678
-						'value' => [
679
-							'shareType' => Share::SHARE_TYPE_REMOTE,
680
-							'shareWith' => $lookup['federationId'],
681
-						],
682
-						'extra' => $lookup,
683
-					];
684
-				}
685
-			} catch (\Exception $e) {}
686
-		}
687
-
688
-		$this->result['lookup'] = $result;
689
-	}
690
-
691
-	/**
692
-	 * Generates a bunch of pagination links for the current page
693
-	 *
694
-	 * @param int $page Current page
695
-	 * @param array $params Parameters for the URL
696
-	 * @return string
697
-	 */
698
-	protected function getPaginationLink($page, array $params) {
699
-		if ($this->isV2()) {
700
-			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees') . '?';
701
-		} else {
702
-			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees') . '?';
703
-		}
704
-		$params['page'] = $page + 1;
705
-		$link = '<' . $url . http_build_query($params) . '>; rel="next"';
706
-
707
-		return $link;
708
-	}
709
-
710
-	/**
711
-	 * @return bool
712
-	 */
713
-	protected function isV2() {
714
-		return $this->request->getScriptName() === '/ocs/v2.php';
715
-	}
46
+    /** @var IGroupManager */
47
+    protected $groupManager;
48
+
49
+    /** @var IUserManager */
50
+    protected $userManager;
51
+
52
+    /** @var IManager */
53
+    protected $contactsManager;
54
+
55
+    /** @var IConfig */
56
+    protected $config;
57
+
58
+    /** @var IUserSession */
59
+    protected $userSession;
60
+
61
+    /** @var IURLGenerator */
62
+    protected $urlGenerator;
63
+
64
+    /** @var ILogger */
65
+    protected $logger;
66
+
67
+    /** @var \OCP\Share\IManager */
68
+    protected $shareManager;
69
+
70
+    /** @var IClientService */
71
+    protected $clientService;
72
+
73
+    /** @var ICloudIdManager  */
74
+    protected $cloudIdManager;
75
+
76
+    /** @var bool */
77
+    protected $shareWithGroupOnly = false;
78
+
79
+    /** @var bool */
80
+    protected $shareeEnumeration = true;
81
+
82
+    /** @var int */
83
+    protected $offset = 0;
84
+
85
+    /** @var int */
86
+    protected $limit = 10;
87
+
88
+    /** @var array */
89
+    protected $result = [
90
+        'exact' => [
91
+            'users' => [],
92
+            'groups' => [],
93
+            'remotes' => [],
94
+            'emails' => [],
95
+            'circles' => [],
96
+        ],
97
+        'users' => [],
98
+        'groups' => [],
99
+        'remotes' => [],
100
+        'emails' => [],
101
+        'lookup' => [],
102
+        'circles' => [],
103
+    ];
104
+
105
+    protected $reachedEndFor = [];
106
+
107
+    /**
108
+     * @param string $appName
109
+     * @param IRequest $request
110
+     * @param IGroupManager $groupManager
111
+     * @param IUserManager $userManager
112
+     * @param IManager $contactsManager
113
+     * @param IConfig $config
114
+     * @param IUserSession $userSession
115
+     * @param IURLGenerator $urlGenerator
116
+     * @param ILogger $logger
117
+     * @param \OCP\Share\IManager $shareManager
118
+     * @param IClientService $clientService
119
+     * @param ICloudIdManager $cloudIdManager
120
+     */
121
+    public function __construct($appName,
122
+                                IRequest $request,
123
+                                IGroupManager $groupManager,
124
+                                IUserManager $userManager,
125
+                                IManager $contactsManager,
126
+                                IConfig $config,
127
+                                IUserSession $userSession,
128
+                                IURLGenerator $urlGenerator,
129
+                                ILogger $logger,
130
+                                \OCP\Share\IManager $shareManager,
131
+                                IClientService $clientService,
132
+                                ICloudIdManager $cloudIdManager
133
+    ) {
134
+        parent::__construct($appName, $request);
135
+
136
+        $this->groupManager = $groupManager;
137
+        $this->userManager = $userManager;
138
+        $this->contactsManager = $contactsManager;
139
+        $this->config = $config;
140
+        $this->userSession = $userSession;
141
+        $this->urlGenerator = $urlGenerator;
142
+        $this->logger = $logger;
143
+        $this->shareManager = $shareManager;
144
+        $this->clientService = $clientService;
145
+        $this->cloudIdManager = $cloudIdManager;
146
+    }
147
+
148
+    /**
149
+     * @param string $search
150
+     */
151
+    protected function getUsers($search) {
152
+        $this->result['users'] = $this->result['exact']['users'] = $users = [];
153
+
154
+        $userGroups = [];
155
+        if ($this->shareWithGroupOnly) {
156
+            // Search in all the groups this user is part of
157
+            $userGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
158
+            foreach ($userGroups as $userGroup) {
159
+                $usersTmp = $this->groupManager->displayNamesInGroup($userGroup, $search, $this->limit, $this->offset);
160
+                foreach ($usersTmp as $uid => $userDisplayName) {
161
+                    $users[$uid] = $userDisplayName;
162
+                }
163
+            }
164
+        } else {
165
+            // Search in all users
166
+            $usersTmp = $this->userManager->searchDisplayName($search, $this->limit, $this->offset);
167
+
168
+            foreach ($usersTmp as $user) {
169
+                $users[$user->getUID()] = $user->getDisplayName();
170
+            }
171
+        }
172
+
173
+        if (!$this->shareeEnumeration || sizeof($users) < $this->limit) {
174
+            $this->reachedEndFor[] = 'users';
175
+        }
176
+
177
+        $foundUserById = false;
178
+        $lowerSearch = strtolower($search);
179
+        foreach ($users as $uid => $userDisplayName) {
180
+            if (strtolower($uid) === $lowerSearch || strtolower($userDisplayName) === $lowerSearch) {
181
+                if (strtolower($uid) === $lowerSearch) {
182
+                    $foundUserById = true;
183
+                }
184
+                $this->result['exact']['users'][] = [
185
+                    'label' => $userDisplayName,
186
+                    'value' => [
187
+                        'shareType' => Share::SHARE_TYPE_USER,
188
+                        'shareWith' => $uid,
189
+                    ],
190
+                ];
191
+            } else {
192
+                $this->result['users'][] = [
193
+                    'label' => $userDisplayName,
194
+                    'value' => [
195
+                        'shareType' => Share::SHARE_TYPE_USER,
196
+                        'shareWith' => $uid,
197
+                    ],
198
+                ];
199
+            }
200
+        }
201
+
202
+        if ($this->offset === 0 && !$foundUserById) {
203
+            // On page one we try if the search result has a direct hit on the
204
+            // user id and if so, we add that to the exact match list
205
+            $user = $this->userManager->get($search);
206
+            if ($user instanceof IUser) {
207
+                $addUser = true;
208
+
209
+                if ($this->shareWithGroupOnly) {
210
+                    // Only add, if we have a common group
211
+                    $commonGroups = array_intersect($userGroups, $this->groupManager->getUserGroupIds($user));
212
+                    $addUser = !empty($commonGroups);
213
+                }
214
+
215
+                if ($addUser) {
216
+                    array_push($this->result['exact']['users'], [
217
+                        'label' => $user->getDisplayName(),
218
+                        'value' => [
219
+                            'shareType' => Share::SHARE_TYPE_USER,
220
+                            'shareWith' => $user->getUID(),
221
+                        ],
222
+                    ]);
223
+                }
224
+            }
225
+        }
226
+
227
+        if (!$this->shareeEnumeration) {
228
+            $this->result['users'] = [];
229
+        }
230
+    }
231
+
232
+    /**
233
+     * @param string $search
234
+     */
235
+    protected function getGroups($search) {
236
+        $this->result['groups'] = $this->result['exact']['groups'] = [];
237
+
238
+        $groups = $this->groupManager->search($search, $this->limit, $this->offset);
239
+        $groupIds = array_map(function (IGroup $group) { return $group->getGID(); }, $groups);
240
+
241
+        if (!$this->shareeEnumeration || sizeof($groups) < $this->limit) {
242
+            $this->reachedEndFor[] = 'groups';
243
+        }
244
+
245
+        $userGroups =  [];
246
+        if (!empty($groups) && $this->shareWithGroupOnly) {
247
+            // Intersect all the groups that match with the groups this user is a member of
248
+            $userGroups = $this->groupManager->getUserGroups($this->userSession->getUser());
249
+            $userGroups = array_map(function (IGroup $group) { return $group->getGID(); }, $userGroups);
250
+            $groupIds = array_intersect($groupIds, $userGroups);
251
+        }
252
+
253
+        $lowerSearch = strtolower($search);
254
+        foreach ($groups as $group) {
255
+            // FIXME: use a more efficient approach
256
+            $gid = $group->getGID();
257
+            if (!in_array($gid, $groupIds)) {
258
+                continue;
259
+            }
260
+            if (strtolower($gid) === $lowerSearch || strtolower($group->getDisplayName()) === $lowerSearch) {
261
+                $this->result['exact']['groups'][] = [
262
+                    'label' => $group->getDisplayName(),
263
+                    'value' => [
264
+                        'shareType' => Share::SHARE_TYPE_GROUP,
265
+                        'shareWith' => $gid,
266
+                    ],
267
+                ];
268
+            } else {
269
+                $this->result['groups'][] = [
270
+                    'label' => $group->getDisplayName(),
271
+                    'value' => [
272
+                        'shareType' => Share::SHARE_TYPE_GROUP,
273
+                        'shareWith' => $gid,
274
+                    ],
275
+                ];
276
+            }
277
+        }
278
+
279
+        if ($this->offset === 0 && empty($this->result['exact']['groups'])) {
280
+            // On page one we try if the search result has a direct hit on the
281
+            // user id and if so, we add that to the exact match list
282
+            $group = $this->groupManager->get($search);
283
+            if ($group instanceof IGroup && (!$this->shareWithGroupOnly || in_array($group->getGID(), $userGroups))) {
284
+                array_push($this->result['exact']['groups'], [
285
+                    'label' => $group->getDisplayName(),
286
+                    'value' => [
287
+                        'shareType' => Share::SHARE_TYPE_GROUP,
288
+                        'shareWith' => $group->getGID(),
289
+                    ],
290
+                ]);
291
+            }
292
+        }
293
+
294
+        if (!$this->shareeEnumeration) {
295
+            $this->result['groups'] = [];
296
+        }
297
+    }
298
+
299
+
300
+    /**
301
+     * @param string $search
302
+     */
303
+    protected function getCircles($search) {
304
+        $this->result['circles'] = $this->result['exact']['circles'] = [];
305
+
306
+        $result = \OCA\Circles\Api\Sharees::search($search, $this->limit, $this->offset);
307
+        if (array_key_exists('circles', $result['exact'])) {
308
+            $this->result['exact']['circles'] = $result['exact']['circles'];
309
+        }
310
+        if (array_key_exists('circles', $result)) {
311
+            $this->result['circles'] = $result['circles'];
312
+        }
313
+    }
314
+
315
+
316
+    /**
317
+     * @param string $search
318
+     * @return array
319
+     */
320
+    protected function getRemote($search) {
321
+        $result = ['results' => [], 'exact' => []];
322
+
323
+        // Search in contacts
324
+        //@todo Pagination missing
325
+        $addressBookContacts = $this->contactsManager->search($search, ['CLOUD', 'FN']);
326
+        $result['exactIdMatch'] = false;
327
+        foreach ($addressBookContacts as $contact) {
328
+            if (isset($contact['isLocalSystemBook'])) {
329
+                continue;
330
+            }
331
+            if (isset($contact['CLOUD'])) {
332
+                $cloudIds = $contact['CLOUD'];
333
+                if (!is_array($cloudIds)) {
334
+                    $cloudIds = [$cloudIds];
335
+                }
336
+                $lowerSearch = strtolower($search);
337
+                foreach ($cloudIds as $cloudId) {
338
+                    list(, $serverUrl) = $this->splitUserRemote($cloudId);
339
+                    if (strtolower($contact['FN']) === $lowerSearch || strtolower($cloudId) === $lowerSearch) {
340
+                        if (strtolower($cloudId) === $lowerSearch) {
341
+                            $result['exactIdMatch'] = true;
342
+                        }
343
+                        $result['exact'][] = [
344
+                            'label' => $contact['FN'] . " ($cloudId)",
345
+                            'value' => [
346
+                                'shareType' => Share::SHARE_TYPE_REMOTE,
347
+                                'shareWith' => $cloudId,
348
+                                'server' => $serverUrl,
349
+                            ],
350
+                        ];
351
+                    } else {
352
+                        $result['results'][] = [
353
+                            'label' => $contact['FN'] . " ($cloudId)",
354
+                            'value' => [
355
+                                'shareType' => Share::SHARE_TYPE_REMOTE,
356
+                                'shareWith' => $cloudId,
357
+                                'server' => $serverUrl,
358
+                            ],
359
+                        ];
360
+                    }
361
+                }
362
+            }
363
+        }
364
+
365
+        if (!$this->shareeEnumeration) {
366
+            $result['results'] = [];
367
+        }
368
+
369
+        if (!$result['exactIdMatch'] && $this->cloudIdManager->isValidCloudId($search) && $this->offset === 0) {
370
+            $result['exact'][] = [
371
+                'label' => $search,
372
+                'value' => [
373
+                    'shareType' => Share::SHARE_TYPE_REMOTE,
374
+                    'shareWith' => $search,
375
+                ],
376
+            ];
377
+        }
378
+
379
+        $this->reachedEndFor[] = 'remotes';
380
+
381
+        return $result;
382
+    }
383
+
384
+    /**
385
+     * split user and remote from federated cloud id
386
+     *
387
+     * @param string $address federated share address
388
+     * @return array [user, remoteURL]
389
+     * @throws \Exception
390
+     */
391
+    public function splitUserRemote($address) {
392
+        try {
393
+            $cloudId = $this->cloudIdManager->resolveCloudId($address);
394
+            return [$cloudId->getUser(), $cloudId->getRemote()];
395
+        } catch (\InvalidArgumentException $e) {
396
+            throw new \Exception('Invalid Federated Cloud ID', 0, $e);
397
+        }
398
+    }
399
+
400
+    /**
401
+     * Strips away a potential file names and trailing slashes:
402
+     * - http://localhost
403
+     * - http://localhost/
404
+     * - http://localhost/index.php
405
+     * - http://localhost/index.php/s/{shareToken}
406
+     *
407
+     * all return: http://localhost
408
+     *
409
+     * @param string $remote
410
+     * @return string
411
+     */
412
+    protected function fixRemoteURL($remote) {
413
+        $remote = str_replace('\\', '/', $remote);
414
+        if ($fileNamePosition = strpos($remote, '/index.php')) {
415
+            $remote = substr($remote, 0, $fileNamePosition);
416
+        }
417
+        $remote = rtrim($remote, '/');
418
+
419
+        return $remote;
420
+    }
421
+
422
+    /**
423
+     * @NoAdminRequired
424
+     *
425
+     * @param string $search
426
+     * @param string $itemType
427
+     * @param int $page
428
+     * @param int $perPage
429
+     * @param int|int[] $shareType
430
+     * @param bool $lookup
431
+     * @return DataResponse
432
+     * @throws OCSBadRequestException
433
+     */
434
+    public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) {
435
+
436
+        // only search for string larger than a given threshold
437
+        $threshold = (int)$this->config->getSystemValue('sharing.minSearchStringLength', 0);
438
+        if (strlen($search) < $threshold) {
439
+            return new DataResponse($this->result);
440
+        }
441
+
442
+        // never return more than the max. number of results configured in the config.php
443
+        $maxResults = (int)$this->config->getSystemValue('sharing.maxAutocompleteResults', 0);
444
+        if ($maxResults > 0) {
445
+            $perPage = min($perPage, $maxResults);
446
+        }
447
+        if ($perPage <= 0) {
448
+            throw new OCSBadRequestException('Invalid perPage argument');
449
+        }
450
+        if ($page <= 0) {
451
+            throw new OCSBadRequestException('Invalid page');
452
+        }
453
+
454
+        $shareTypes = [
455
+            Share::SHARE_TYPE_USER,
456
+        ];
457
+
458
+        if ($itemType === 'file' || $itemType === 'folder') {
459
+            if ($this->shareManager->allowGroupSharing()) {
460
+                $shareTypes[] = Share::SHARE_TYPE_GROUP;
461
+            }
462
+
463
+            if ($this->isRemoteSharingAllowed($itemType)) {
464
+                $shareTypes[] = Share::SHARE_TYPE_REMOTE;
465
+            }
466
+
467
+            if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
468
+                $shareTypes[] = Share::SHARE_TYPE_EMAIL;
469
+            }
470
+        } else {
471
+            $shareTypes[] = Share::SHARE_TYPE_GROUP;
472
+            $shareTypes[] = Share::SHARE_TYPE_EMAIL;
473
+        }
474
+
475
+        if (\OCP\App::isEnabled('circles')) {
476
+            $shareTypes[] = Share::SHARE_TYPE_CIRCLE;
477
+        }
478
+
479
+        if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
480
+            $shareTypes = array_intersect($shareTypes, $_GET['shareType']);
481
+            sort($shareTypes);
482
+        } else if (is_numeric($shareType)) {
483
+            $shareTypes = array_intersect($shareTypes, [(int) $shareType]);
484
+            sort($shareTypes);
485
+        }
486
+
487
+        $this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
488
+        $this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
489
+        $this->limit = (int) $perPage;
490
+        $this->offset = $perPage * ($page - 1);
491
+
492
+        return $this->searchSharees($search, $itemType, $shareTypes, $page, $perPage, $lookup);
493
+    }
494
+
495
+    /**
496
+     * Method to get out the static call for better testing
497
+     *
498
+     * @param string $itemType
499
+     * @return bool
500
+     */
501
+    protected function isRemoteSharingAllowed($itemType) {
502
+        try {
503
+            $backend = Share::getBackend($itemType);
504
+            return $backend->isShareTypeAllowed(Share::SHARE_TYPE_REMOTE);
505
+        } catch (\Exception $e) {
506
+            return false;
507
+        }
508
+    }
509
+
510
+    /**
511
+     * Testable search function that does not need globals
512
+     *
513
+     * @param string $search
514
+     * @param string $itemType
515
+     * @param array $shareTypes
516
+     * @param int $page
517
+     * @param int $perPage
518
+     * @param bool $lookup
519
+     * @return DataResponse
520
+     * @throws OCSBadRequestException
521
+     */
522
+    protected function searchSharees($search, $itemType, array $shareTypes, $page, $perPage, $lookup) {
523
+        // Verify arguments
524
+        if ($itemType === null) {
525
+            throw new OCSBadRequestException('Missing itemType');
526
+        }
527
+
528
+        // Get users
529
+        if (in_array(Share::SHARE_TYPE_USER, $shareTypes)) {
530
+            $this->getUsers($search);
531
+        }
532
+
533
+        // Get groups
534
+        if (in_array(Share::SHARE_TYPE_GROUP, $shareTypes)) {
535
+            $this->getGroups($search);
536
+        }
537
+
538
+        // Get circles
539
+        if (in_array(Share::SHARE_TYPE_CIRCLE, $shareTypes)) {
540
+            $this->getCircles($search);
541
+        }
542
+
543
+
544
+        // Get remote
545
+        $remoteResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
546
+        if (in_array(Share::SHARE_TYPE_REMOTE, $shareTypes)) {
547
+            $remoteResults = $this->getRemote($search);
548
+        }
549
+
550
+        // Get emails
551
+        $mailResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
552
+        if (in_array(Share::SHARE_TYPE_EMAIL, $shareTypes)) {
553
+            $mailResults = $this->getEmail($search);
554
+        }
555
+
556
+        // Get from lookup server
557
+        if ($lookup) {
558
+            $this->getLookup($search);
559
+        }
560
+
561
+        // if we have a exact match, either for the federated cloud id or for the
562
+        // email address we only return the exact match. It is highly unlikely
563
+        // that the exact same email address and federated cloud id exists
564
+        if ($mailResults['exactIdMatch'] && !$remoteResults['exactIdMatch']) {
565
+            $this->result['emails'] = $mailResults['results'];
566
+            $this->result['exact']['emails'] = $mailResults['exact'];
567
+        } else if (!$mailResults['exactIdMatch'] && $remoteResults['exactIdMatch']) {
568
+            $this->result['remotes'] = $remoteResults['results'];
569
+            $this->result['exact']['remotes'] = $remoteResults['exact'];
570
+        } else {
571
+            $this->result['remotes'] = $remoteResults['results'];
572
+            $this->result['exact']['remotes'] = $remoteResults['exact'];
573
+            $this->result['emails'] = $mailResults['results'];
574
+            $this->result['exact']['emails'] = $mailResults['exact'];
575
+        }
576
+
577
+        $response = new DataResponse($this->result);
578
+
579
+        if (sizeof($this->reachedEndFor) < 3) {
580
+            $response->addHeader('Link', $this->getPaginationLink($page, [
581
+                'search' => $search,
582
+                'itemType' => $itemType,
583
+                'shareType' => $shareTypes,
584
+                'perPage' => $perPage,
585
+            ]));
586
+        }
587
+
588
+        return $response;
589
+    }
590
+
591
+    /**
592
+     * @param string $search
593
+     * @return array
594
+     */
595
+    protected function getEmail($search) {
596
+        $result = ['results' => [], 'exact' => []];
597
+
598
+        // Search in contacts
599
+        //@todo Pagination missing
600
+        $addressBookContacts = $this->contactsManager->search($search, ['EMAIL', 'FN']);
601
+        $result['exactIdMatch'] = false;
602
+        foreach ($addressBookContacts as $contact) {
603
+            if (isset($contact['isLocalSystemBook'])) {
604
+                continue;
605
+            }
606
+            if (isset($contact['EMAIL'])) {
607
+                $emailAddresses = $contact['EMAIL'];
608
+                if (!is_array($emailAddresses)) {
609
+                    $emailAddresses = [$emailAddresses];
610
+                }
611
+                foreach ($emailAddresses as $emailAddress) {
612
+                    if (strtolower($contact['FN']) === strtolower($search) || strtolower($emailAddress) === strtolower($search)) {
613
+                        if (strtolower($emailAddress) === strtolower($search)) {
614
+                            $result['exactIdMatch'] = true;
615
+                        }
616
+                        $result['exact'][] = [
617
+                            'label' => $contact['FN'] . " ($emailAddress)",
618
+                            'value' => [
619
+                                'shareType' => Share::SHARE_TYPE_EMAIL,
620
+                                'shareWith' => $emailAddress,
621
+                            ],
622
+                        ];
623
+                    } else {
624
+                        $result['results'][] = [
625
+                            'label' => $contact['FN'] . " ($emailAddress)",
626
+                            'value' => [
627
+                                'shareType' => Share::SHARE_TYPE_EMAIL,
628
+                                'shareWith' => $emailAddress,
629
+                            ],
630
+                        ];
631
+                    }
632
+                }
633
+            }
634
+        }
635
+
636
+        if (!$this->shareeEnumeration) {
637
+            $result['results'] = [];
638
+        }
639
+
640
+        if (!$result['exactIdMatch'] && filter_var($search, FILTER_VALIDATE_EMAIL)) {
641
+            $result['exact'][] = [
642
+                'label' => $search,
643
+                'value' => [
644
+                    'shareType' => Share::SHARE_TYPE_EMAIL,
645
+                    'shareWith' => $search,
646
+                ],
647
+            ];
648
+        }
649
+
650
+        $this->reachedEndFor[] = 'emails';
651
+
652
+        return $result;
653
+    }
654
+
655
+    protected function getLookup($search) {
656
+        $isEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
657
+        $lookupServerUrl = $this->config->getSystemValue('lookup_server', 'https://lookup.nextcloud.com');
658
+        $lookupServerUrl = rtrim($lookupServerUrl, '/');
659
+        $result = [];
660
+
661
+        if($isEnabled === 'yes') {
662
+            try {
663
+                $client = $this->clientService->newClient();
664
+                $response = $client->get(
665
+                    $lookupServerUrl . '/users?search=' . urlencode($search),
666
+                    [
667
+                        'timeout' => 10,
668
+                        'connect_timeout' => 3,
669
+                    ]
670
+                );
671
+
672
+                $body = json_decode($response->getBody(), true);
673
+
674
+                $result = [];
675
+                foreach ($body as $lookup) {
676
+                    $result[] = [
677
+                        'label' => $lookup['federationId'],
678
+                        'value' => [
679
+                            'shareType' => Share::SHARE_TYPE_REMOTE,
680
+                            'shareWith' => $lookup['federationId'],
681
+                        ],
682
+                        'extra' => $lookup,
683
+                    ];
684
+                }
685
+            } catch (\Exception $e) {}
686
+        }
687
+
688
+        $this->result['lookup'] = $result;
689
+    }
690
+
691
+    /**
692
+     * Generates a bunch of pagination links for the current page
693
+     *
694
+     * @param int $page Current page
695
+     * @param array $params Parameters for the URL
696
+     * @return string
697
+     */
698
+    protected function getPaginationLink($page, array $params) {
699
+        if ($this->isV2()) {
700
+            $url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees') . '?';
701
+        } else {
702
+            $url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees') . '?';
703
+        }
704
+        $params['page'] = $page + 1;
705
+        $link = '<' . $url . http_build_query($params) . '>; rel="next"';
706
+
707
+        return $link;
708
+    }
709
+
710
+    /**
711
+     * @return bool
712
+     */
713
+    protected function isV2() {
714
+        return $this->request->getScriptName() === '/ocs/v2.php';
715
+    }
716 716
 }
Please login to merge, or discard this patch.
Spacing   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -236,17 +236,17 @@  discard block
 block discarded – undo
236 236
 		$this->result['groups'] = $this->result['exact']['groups'] = [];
237 237
 
238 238
 		$groups = $this->groupManager->search($search, $this->limit, $this->offset);
239
-		$groupIds = array_map(function (IGroup $group) { return $group->getGID(); }, $groups);
239
+		$groupIds = array_map(function(IGroup $group) { return $group->getGID(); }, $groups);
240 240
 
241 241
 		if (!$this->shareeEnumeration || sizeof($groups) < $this->limit) {
242 242
 			$this->reachedEndFor[] = 'groups';
243 243
 		}
244 244
 
245
-		$userGroups =  [];
245
+		$userGroups = [];
246 246
 		if (!empty($groups) && $this->shareWithGroupOnly) {
247 247
 			// Intersect all the groups that match with the groups this user is a member of
248 248
 			$userGroups = $this->groupManager->getUserGroups($this->userSession->getUser());
249
-			$userGroups = array_map(function (IGroup $group) { return $group->getGID(); }, $userGroups);
249
+			$userGroups = array_map(function(IGroup $group) { return $group->getGID(); }, $userGroups);
250 250
 			$groupIds = array_intersect($groupIds, $userGroups);
251 251
 		}
252 252
 
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
 							$result['exactIdMatch'] = true;
342 342
 						}
343 343
 						$result['exact'][] = [
344
-							'label' => $contact['FN'] . " ($cloudId)",
344
+							'label' => $contact['FN']." ($cloudId)",
345 345
 							'value' => [
346 346
 								'shareType' => Share::SHARE_TYPE_REMOTE,
347 347
 								'shareWith' => $cloudId,
@@ -350,7 +350,7 @@  discard block
 block discarded – undo
350 350
 						];
351 351
 					} else {
352 352
 						$result['results'][] = [
353
-							'label' => $contact['FN'] . " ($cloudId)",
353
+							'label' => $contact['FN']." ($cloudId)",
354 354
 							'value' => [
355 355
 								'shareType' => Share::SHARE_TYPE_REMOTE,
356 356
 								'shareWith' => $cloudId,
@@ -434,13 +434,13 @@  discard block
 block discarded – undo
434 434
 	public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) {
435 435
 
436 436
 		// only search for string larger than a given threshold
437
-		$threshold = (int)$this->config->getSystemValue('sharing.minSearchStringLength', 0);
437
+		$threshold = (int) $this->config->getSystemValue('sharing.minSearchStringLength', 0);
438 438
 		if (strlen($search) < $threshold) {
439 439
 			return new DataResponse($this->result);
440 440
 		}
441 441
 
442 442
 		// never return more than the max. number of results configured in the config.php
443
-		$maxResults = (int)$this->config->getSystemValue('sharing.maxAutocompleteResults', 0);
443
+		$maxResults = (int) $this->config->getSystemValue('sharing.maxAutocompleteResults', 0);
444 444
 		if ($maxResults > 0) {
445 445
 			$perPage = min($perPage, $maxResults);
446 446
 		}
@@ -614,7 +614,7 @@  discard block
 block discarded – undo
614 614
 							$result['exactIdMatch'] = true;
615 615
 						}
616 616
 						$result['exact'][] = [
617
-							'label' => $contact['FN'] . " ($emailAddress)",
617
+							'label' => $contact['FN']." ($emailAddress)",
618 618
 							'value' => [
619 619
 								'shareType' => Share::SHARE_TYPE_EMAIL,
620 620
 								'shareWith' => $emailAddress,
@@ -622,7 +622,7 @@  discard block
 block discarded – undo
622 622
 						];
623 623
 					} else {
624 624
 						$result['results'][] = [
625
-							'label' => $contact['FN'] . " ($emailAddress)",
625
+							'label' => $contact['FN']." ($emailAddress)",
626 626
 							'value' => [
627 627
 								'shareType' => Share::SHARE_TYPE_EMAIL,
628 628
 								'shareWith' => $emailAddress,
@@ -658,11 +658,11 @@  discard block
 block discarded – undo
658 658
 		$lookupServerUrl = rtrim($lookupServerUrl, '/');
659 659
 		$result = [];
660 660
 
661
-		if($isEnabled === 'yes') {
661
+		if ($isEnabled === 'yes') {
662 662
 			try {
663 663
 				$client = $this->clientService->newClient();
664 664
 				$response = $client->get(
665
-					$lookupServerUrl . '/users?search=' . urlencode($search),
665
+					$lookupServerUrl.'/users?search='.urlencode($search),
666 666
 					[
667 667
 						'timeout' => 10,
668 668
 						'connect_timeout' => 3,
@@ -697,12 +697,12 @@  discard block
 block discarded – undo
697 697
 	 */
698 698
 	protected function getPaginationLink($page, array $params) {
699 699
 		if ($this->isV2()) {
700
-			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees') . '?';
700
+			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees').'?';
701 701
 		} else {
702
-			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees') . '?';
702
+			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees').'?';
703 703
 		}
704 704
 		$params['page'] = $page + 1;
705
-		$link = '<' . $url . http_build_query($params) . '>; rel="next"';
705
+		$link = '<'.$url.http_build_query($params).'>; rel="next"';
706 706
 
707 707
 		return $link;
708 708
 	}
Please login to merge, or discard this patch.
settings/Controller/UsersController.php 2 patches
Spacing   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
 
158 158
 		// check for encryption state - TODO see formatUserForIndex
159 159
 		$this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption');
160
-		if($this->isEncryptionAppEnabled) {
160
+		if ($this->isEncryptionAppEnabled) {
161 161
 			// putting this directly in empty is possible in PHP 5.5+
162 162
 			$result = $config->getAppValue('encryption', 'recoveryAdminEnabled', 0);
163 163
 			$this->isRestoreEnabled = !empty($result);
@@ -197,7 +197,7 @@  discard block
 block discarded – undo
197 197
 		}
198 198
 
199 199
 		$subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
200
-		foreach($subAdminGroups as $key => $subAdminGroup) {
200
+		foreach ($subAdminGroups as $key => $subAdminGroup) {
201 201
 			$subAdminGroups[$key] = $subAdminGroup->getGID();
202 202
 		}
203 203
 
@@ -254,16 +254,16 @@  discard block
 block discarded – undo
254 254
 	 */
255 255
 	public function index($offset = 0, $limit = 10, $gid = '', $pattern = '', $backend = '') {
256 256
 		// FIXME: The JS sends the group '_everyone' instead of no GID for the "all users" group.
257
-		if($gid === '_everyone') {
257
+		if ($gid === '_everyone') {
258 258
 			$gid = '';
259 259
 		}
260 260
 
261 261
 		// Remove backends
262
-		if(!empty($backend)) {
262
+		if (!empty($backend)) {
263 263
 			$activeBackends = $this->userManager->getBackends();
264 264
 			$this->userManager->clearBackends();
265
-			foreach($activeBackends as $singleActiveBackend) {
266
-				if($backend === get_class($singleActiveBackend)) {
265
+			foreach ($activeBackends as $singleActiveBackend) {
266
+				if ($backend === get_class($singleActiveBackend)) {
267 267
 					$this->userManager->registerBackend($singleActiveBackend);
268 268
 					break;
269 269
 				}
@@ -273,7 +273,7 @@  discard block
 block discarded – undo
273 273
 		$users = [];
274 274
 		if ($this->isAdmin) {
275 275
 
276
-			if($gid !== '') {
276
+			if ($gid !== '') {
277 277
 				$batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset));
278 278
 			} else {
279 279
 				$batch = $this->userManager->search($pattern, $limit, $offset);
@@ -293,17 +293,17 @@  discard block
 block discarded – undo
293 293
 			$subAdminOfGroups = $gids;
294 294
 
295 295
 			// Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group
296
-			if($gid !== '' && !in_array($gid, $subAdminOfGroups)) {
296
+			if ($gid !== '' && !in_array($gid, $subAdminOfGroups)) {
297 297
 				$gid = '';
298 298
 			}
299 299
 
300 300
 			// Batch all groups the user is subadmin of when a group is specified
301 301
 			$batch = [];
302
-			if($gid === '') {
303
-				foreach($subAdminOfGroups as $group) {
302
+			if ($gid === '') {
303
+				foreach ($subAdminOfGroups as $group) {
304 304
 					$groupUsers = $this->groupManager->displayNamesInGroup($group, $pattern, $limit, $offset);
305 305
 
306
-					foreach($groupUsers as $uid => $displayName) {
306
+					foreach ($groupUsers as $uid => $displayName) {
307 307
 						$batch[$uid] = $displayName;
308 308
 					}
309 309
 				}
@@ -335,11 +335,11 @@  discard block
 block discarded – undo
335 335
 	 * @param string $email
336 336
 	 * @return DataResponse
337 337
 	 */
338
-	public function create($username, $password, array $groups=array(), $email='') {
339
-		if($email !== '' && !$this->mailer->validateMailAddress($email)) {
338
+	public function create($username, $password, array $groups = array(), $email = '') {
339
+		if ($email !== '' && !$this->mailer->validateMailAddress($email)) {
340 340
 			return new DataResponse(
341 341
 				array(
342
-					'message' => (string)$this->l10n->t('Invalid mail address')
342
+					'message' => (string) $this->l10n->t('Invalid mail address')
343 343
 				),
344 344
 				Http::STATUS_UNPROCESSABLE_ENTITY
345 345
 			);
@@ -351,7 +351,7 @@  discard block
 block discarded – undo
351 351
 			if (!empty($groups)) {
352 352
 				foreach ($groups as $key => $group) {
353 353
 					$groupObject = $this->groupManager->get($group);
354
-					if($groupObject === null) {
354
+					if ($groupObject === null) {
355 355
 						unset($groups[$key]);
356 356
 						continue;
357 357
 					}
@@ -375,7 +375,7 @@  discard block
 block discarded – undo
375 375
 		if ($this->userManager->userExists($username)) {
376 376
 			return new DataResponse(
377 377
 				array(
378
-					'message' => (string)$this->l10n->t('A user with that name already exists.')
378
+					'message' => (string) $this->l10n->t('A user with that name already exists.')
379 379
 				),
380 380
 				Http::STATUS_CONFLICT
381 381
 			);
@@ -386,7 +386,7 @@  discard block
 block discarded – undo
386 386
 			if ($email === '') {
387 387
 				return new DataResponse(
388 388
 					array(
389
-						'message' => (string)$this->l10n->t('To send a password link to the user an email address is required.')
389
+						'message' => (string) $this->l10n->t('To send a password link to the user an email address is required.')
390 390
 					),
391 391
 					Http::STATUS_UNPROCESSABLE_ENTITY
392 392
 				);
@@ -411,12 +411,12 @@  discard block
 block discarded – undo
411 411
 			);
412 412
 		}
413 413
 
414
-		if($user instanceof IUser) {
415
-			if($groups !== null) {
416
-				foreach($groups as $groupName) {
414
+		if ($user instanceof IUser) {
415
+			if ($groups !== null) {
416
+				foreach ($groups as $groupName) {
417 417
 					$group = $this->groupManager->get($groupName);
418 418
 
419
-					if(empty($group)) {
419
+					if (empty($group)) {
420 420
 						$group = $this->groupManager->createGroup($groupName);
421 421
 					}
422 422
 					$group->addUser($user);
@@ -425,13 +425,13 @@  discard block
 block discarded – undo
425 425
 			/**
426 426
 			 * Send new user mail only if a mail is set
427 427
 			 */
428
-			if($email !== '') {
428
+			if ($email !== '') {
429 429
 				$user->setEMailAddress($email);
430 430
 				try {
431 431
 					$emailTemplate = $this->newUserMailHelper->generateTemplate($user, $generatePasswordResetToken);
432 432
 					$this->newUserMailHelper->sendMail($user, $emailTemplate);
433
-				} catch(\Exception $e) {
434
-					$this->log->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
433
+				} catch (\Exception $e) {
434
+					$this->log->error("Can't send new user mail to $email: ".$e->getMessage(), array('app' => 'settings'));
435 435
 				}
436 436
 			}
437 437
 			// fetch users groups
@@ -445,7 +445,7 @@  discard block
 block discarded – undo
445 445
 
446 446
 		return new DataResponse(
447 447
 			array(
448
-				'message' => (string)$this->l10n->t('Unable to create user.')
448
+				'message' => (string) $this->l10n->t('Unable to create user.')
449 449
 			),
450 450
 			Http::STATUS_FORBIDDEN
451 451
 		);
@@ -463,32 +463,32 @@  discard block
 block discarded – undo
463 463
 		$userId = $this->userSession->getUser()->getUID();
464 464
 		$user = $this->userManager->get($id);
465 465
 
466
-		if($userId === $id) {
466
+		if ($userId === $id) {
467 467
 			return new DataResponse(
468 468
 				array(
469 469
 					'status' => 'error',
470 470
 					'data' => array(
471
-						'message' => (string)$this->l10n->t('Unable to delete user.')
471
+						'message' => (string) $this->l10n->t('Unable to delete user.')
472 472
 					)
473 473
 				),
474 474
 				Http::STATUS_FORBIDDEN
475 475
 			);
476 476
 		}
477 477
 
478
-		if(!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
478
+		if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
479 479
 			return new DataResponse(
480 480
 				array(
481 481
 					'status' => 'error',
482 482
 					'data' => array(
483
-						'message' => (string)$this->l10n->t('Authentication error')
483
+						'message' => (string) $this->l10n->t('Authentication error')
484 484
 					)
485 485
 				),
486 486
 				Http::STATUS_FORBIDDEN
487 487
 			);
488 488
 		}
489 489
 
490
-		if($user) {
491
-			if($user->delete()) {
490
+		if ($user) {
491
+			if ($user->delete()) {
492 492
 				return new DataResponse(
493 493
 					array(
494 494
 						'status' => 'success',
@@ -505,7 +505,7 @@  discard block
 block discarded – undo
505 505
 			array(
506 506
 				'status' => 'error',
507 507
 				'data' => array(
508
-					'message' => (string)$this->l10n->t('Unable to delete user.')
508
+					'message' => (string) $this->l10n->t('Unable to delete user.')
509 509
 				)
510 510
 			),
511 511
 			Http::STATUS_FORBIDDEN
@@ -530,11 +530,11 @@  discard block
 block discarded – undo
530 530
 
531 531
 		$accountData = $this->accountManager->getUser($user);
532 532
 		$cloudId = $user->getCloudId();
533
-		$message = "Use my Federated Cloud ID to share with me: " . $cloudId;
533
+		$message = "Use my Federated Cloud ID to share with me: ".$cloudId;
534 534
 		$signature = $this->signMessage($user, $message);
535 535
 
536
-		$code = $message . ' ' . $signature;
537
-		$codeMd5 = $message . ' ' . md5($signature);
536
+		$code = $message.' '.$signature;
537
+		$codeMd5 = $message.' '.md5($signature);
538 538
 
539 539
 		switch ($account) {
540 540
 			case 'verify-twitter':
@@ -631,12 +631,12 @@  discard block
 block discarded – undo
631 631
 									$twitterScope
632 632
 	) {
633 633
 
634
-		if(!empty($email) && !$this->mailer->validateMailAddress($email)) {
634
+		if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
635 635
 			return new DataResponse(
636 636
 				array(
637 637
 					'status' => 'error',
638 638
 					'data' => array(
639
-						'message' => (string)$this->l10n->t('Invalid mail address')
639
+						'message' => (string) $this->l10n->t('Invalid mail address')
640 640
 					)
641 641
 				),
642 642
 				Http::STATUS_UNPROCESSABLE_ENTITY
@@ -671,7 +671,7 @@  discard block
 block discarded – undo
671 671
 						'websiteScope' => $websiteScope,
672 672
 						'address' => $address,
673 673
 						'addressScope' => $addressScope,
674
-						'message' => (string)$this->l10n->t('Settings saved')
674
+						'message' => (string) $this->l10n->t('Settings saved')
675 675
 					)
676 676
 				),
677 677
 				Http::STATUS_OK
@@ -748,7 +748,7 @@  discard block
 block discarded – undo
748 748
 
749 749
 			$uniqueUsers = [];
750 750
 			foreach ($groups as $group) {
751
-				foreach($group->getUsers() as $uid => $displayName) {
751
+				foreach ($group->getUsers() as $uid => $displayName) {
752 752
 					$uniqueUsers[$uid] = true;
753 753
 				}
754 754
 			}
@@ -842,19 +842,19 @@  discard block
 block discarded – undo
842 842
 				array(
843 843
 					'status' => 'error',
844 844
 					'data' => array(
845
-						'message' => (string)$this->l10n->t('Forbidden')
845
+						'message' => (string) $this->l10n->t('Forbidden')
846 846
 					)
847 847
 				),
848 848
 				Http::STATUS_FORBIDDEN
849 849
 			);
850 850
 		}
851 851
 
852
-		if($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) {
852
+		if ($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) {
853 853
 			return new DataResponse(
854 854
 				array(
855 855
 					'status' => 'error',
856 856
 					'data' => array(
857
-						'message' => (string)$this->l10n->t('Invalid mail address')
857
+						'message' => (string) $this->l10n->t('Invalid mail address')
858 858
 					)
859 859
 				),
860 860
 				Http::STATUS_UNPROCESSABLE_ENTITY
@@ -866,7 +866,7 @@  discard block
 block discarded – undo
866 866
 				array(
867 867
 					'status' => 'error',
868 868
 					'data' => array(
869
-						'message' => (string)$this->l10n->t('Invalid user')
869
+						'message' => (string) $this->l10n->t('Invalid user')
870 870
 					)
871 871
 				),
872 872
 				Http::STATUS_UNPROCESSABLE_ENTITY
@@ -879,7 +879,7 @@  discard block
 block discarded – undo
879 879
 				array(
880 880
 					'status' => 'error',
881 881
 					'data' => array(
882
-						'message' => (string)$this->l10n->t('Unable to change mail address')
882
+						'message' => (string) $this->l10n->t('Unable to change mail address')
883 883
 					)
884 884
 				),
885 885
 				Http::STATUS_FORBIDDEN
@@ -897,7 +897,7 @@  discard block
 block discarded – undo
897 897
 					'data' => array(
898 898
 						'username' => $id,
899 899
 						'mailAddress' => $mailAddress,
900
-						'message' => (string)$this->l10n->t('Email saved')
900
+						'message' => (string) $this->l10n->t('Email saved')
901 901
 					)
902 902
 				),
903 903
 				Http::STATUS_OK
Please login to merge, or discard this patch.
Indentation   +857 added lines, -857 removed lines patch added patch discarded remove patch
@@ -58,862 +58,862 @@
 block discarded – undo
58 58
  * @package OC\Settings\Controller
59 59
  */
60 60
 class UsersController extends Controller {
61
-	/** @var IL10N */
62
-	private $l10n;
63
-	/** @var IUserSession */
64
-	private $userSession;
65
-	/** @var bool */
66
-	private $isAdmin;
67
-	/** @var IUserManager */
68
-	private $userManager;
69
-	/** @var IGroupManager */
70
-	private $groupManager;
71
-	/** @var IConfig */
72
-	private $config;
73
-	/** @var ILogger */
74
-	private $log;
75
-	/** @var IMailer */
76
-	private $mailer;
77
-	/** @var bool contains the state of the encryption app */
78
-	private $isEncryptionAppEnabled;
79
-	/** @var bool contains the state of the admin recovery setting */
80
-	private $isRestoreEnabled = false;
81
-	/** @var IAvatarManager */
82
-	private $avatarManager;
83
-	/** @var AccountManager */
84
-	private $accountManager;
85
-	/** @var ISecureRandom */
86
-	private $secureRandom;
87
-	/** @var NewUserMailHelper */
88
-	private $newUserMailHelper;
89
-	/** @var ITimeFactory */
90
-	private $timeFactory;
91
-	/** @var ICrypto */
92
-	private $crypto;
93
-	/** @var Manager */
94
-	private $keyManager;
95
-	/** @var IJobList */
96
-	private $jobList;
97
-
98
-	/**
99
-	 * @param string $appName
100
-	 * @param IRequest $request
101
-	 * @param IUserManager $userManager
102
-	 * @param IGroupManager $groupManager
103
-	 * @param IUserSession $userSession
104
-	 * @param IConfig $config
105
-	 * @param bool $isAdmin
106
-	 * @param IL10N $l10n
107
-	 * @param ILogger $log
108
-	 * @param IMailer $mailer
109
-	 * @param IURLGenerator $urlGenerator
110
-	 * @param IAppManager $appManager
111
-	 * @param IAvatarManager $avatarManager
112
-	 * @param AccountManager $accountManager
113
-	 * @param ISecureRandom $secureRandom
114
-	 * @param NewUserMailHelper $newUserMailHelper
115
-	 * @param ITimeFactory $timeFactory
116
-	 * @param ICrypto $crypto
117
-	 * @param Manager $keyManager
118
-	 * @param IJobList $jobList
119
-	 */
120
-	public function __construct($appName,
121
-								IRequest $request,
122
-								IUserManager $userManager,
123
-								IGroupManager $groupManager,
124
-								IUserSession $userSession,
125
-								IConfig $config,
126
-								$isAdmin,
127
-								IL10N $l10n,
128
-								ILogger $log,
129
-								IMailer $mailer,
130
-								IURLGenerator $urlGenerator,
131
-								IAppManager $appManager,
132
-								IAvatarManager $avatarManager,
133
-								AccountManager $accountManager,
134
-								ISecureRandom $secureRandom,
135
-								NewUserMailHelper $newUserMailHelper,
136
-								ITimeFactory $timeFactory,
137
-								ICrypto $crypto,
138
-								Manager $keyManager,
139
-								IJobList $jobList) {
140
-		parent::__construct($appName, $request);
141
-		$this->userManager = $userManager;
142
-		$this->groupManager = $groupManager;
143
-		$this->userSession = $userSession;
144
-		$this->config = $config;
145
-		$this->isAdmin = $isAdmin;
146
-		$this->l10n = $l10n;
147
-		$this->log = $log;
148
-		$this->mailer = $mailer;
149
-		$this->avatarManager = $avatarManager;
150
-		$this->accountManager = $accountManager;
151
-		$this->secureRandom = $secureRandom;
152
-		$this->newUserMailHelper = $newUserMailHelper;
153
-		$this->timeFactory = $timeFactory;
154
-		$this->crypto = $crypto;
155
-		$this->keyManager = $keyManager;
156
-		$this->jobList = $jobList;
157
-
158
-		// check for encryption state - TODO see formatUserForIndex
159
-		$this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption');
160
-		if($this->isEncryptionAppEnabled) {
161
-			// putting this directly in empty is possible in PHP 5.5+
162
-			$result = $config->getAppValue('encryption', 'recoveryAdminEnabled', 0);
163
-			$this->isRestoreEnabled = !empty($result);
164
-		}
165
-	}
166
-
167
-	/**
168
-	 * @param IUser $user
169
-	 * @param array $userGroups
170
-	 * @return array
171
-	 */
172
-	private function formatUserForIndex(IUser $user, array $userGroups = null) {
173
-
174
-		// TODO: eliminate this encryption specific code below and somehow
175
-		// hook in additional user info from other apps
176
-
177
-		// recovery isn't possible if admin or user has it disabled and encryption
178
-		// is enabled - so we eliminate the else paths in the conditional tree
179
-		// below
180
-		$restorePossible = false;
181
-
182
-		if ($this->isEncryptionAppEnabled) {
183
-			if ($this->isRestoreEnabled) {
184
-				// check for the users recovery setting
185
-				$recoveryMode = $this->config->getUserValue($user->getUID(), 'encryption', 'recoveryEnabled', '0');
186
-				// method call inside empty is possible with PHP 5.5+
187
-				$recoveryModeEnabled = !empty($recoveryMode);
188
-				if ($recoveryModeEnabled) {
189
-					// user also has recovery mode enabled
190
-					$restorePossible = true;
191
-				}
192
-			}
193
-		} else {
194
-			// recovery is possible if encryption is disabled (plain files are
195
-			// available)
196
-			$restorePossible = true;
197
-		}
198
-
199
-		$subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
200
-		foreach($subAdminGroups as $key => $subAdminGroup) {
201
-			$subAdminGroups[$key] = $subAdminGroup->getGID();
202
-		}
203
-
204
-		$displayName = $user->getEMailAddress();
205
-		if (is_null($displayName)) {
206
-			$displayName = '';
207
-		}
208
-
209
-		$avatarAvailable = false;
210
-		try {
211
-			$avatarAvailable = $this->avatarManager->getAvatar($user->getUID())->exists();
212
-		} catch (\Exception $e) {
213
-			//No avatar yet
214
-		}
215
-
216
-		return [
217
-			'name' => $user->getUID(),
218
-			'displayname' => $user->getDisplayName(),
219
-			'groups' => (empty($userGroups)) ? $this->groupManager->getUserGroupIds($user) : $userGroups,
220
-			'subadmin' => $subAdminGroups,
221
-			'quota' => $user->getQuota(),
222
-			'storageLocation' => $user->getHome(),
223
-			'lastLogin' => $user->getLastLogin() * 1000,
224
-			'backend' => $user->getBackendClassName(),
225
-			'email' => $displayName,
226
-			'isRestoreDisabled' => !$restorePossible,
227
-			'isAvatarAvailable' => $avatarAvailable,
228
-		];
229
-	}
230
-
231
-	/**
232
-	 * @param array $userIDs Array with schema [$uid => $displayName]
233
-	 * @return IUser[]
234
-	 */
235
-	private function getUsersForUID(array $userIDs) {
236
-		$users = [];
237
-		foreach ($userIDs as $uid => $displayName) {
238
-			$users[$uid] = $this->userManager->get($uid);
239
-		}
240
-		return $users;
241
-	}
242
-
243
-	/**
244
-	 * @NoAdminRequired
245
-	 *
246
-	 * @param int $offset
247
-	 * @param int $limit
248
-	 * @param string $gid GID to filter for
249
-	 * @param string $pattern Pattern to search for in the username
250
-	 * @param string $backend Backend to filter for (class-name)
251
-	 * @return DataResponse
252
-	 *
253
-	 * TODO: Tidy up and write unit tests - code is mainly static method calls
254
-	 */
255
-	public function index($offset = 0, $limit = 10, $gid = '', $pattern = '', $backend = '') {
256
-		// FIXME: The JS sends the group '_everyone' instead of no GID for the "all users" group.
257
-		if($gid === '_everyone') {
258
-			$gid = '';
259
-		}
260
-
261
-		// Remove backends
262
-		if(!empty($backend)) {
263
-			$activeBackends = $this->userManager->getBackends();
264
-			$this->userManager->clearBackends();
265
-			foreach($activeBackends as $singleActiveBackend) {
266
-				if($backend === get_class($singleActiveBackend)) {
267
-					$this->userManager->registerBackend($singleActiveBackend);
268
-					break;
269
-				}
270
-			}
271
-		}
272
-
273
-		$users = [];
274
-		if ($this->isAdmin) {
275
-
276
-			if($gid !== '') {
277
-				$batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset));
278
-			} else {
279
-				$batch = $this->userManager->search($pattern, $limit, $offset);
280
-			}
281
-
282
-			foreach ($batch as $user) {
283
-				$users[] = $this->formatUserForIndex($user);
284
-			}
285
-
286
-		} else {
287
-			$subAdminOfGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
288
-			// New class returns IGroup[] so convert back
289
-			$gids = [];
290
-			foreach ($subAdminOfGroups as $group) {
291
-				$gids[] = $group->getGID();
292
-			}
293
-			$subAdminOfGroups = $gids;
294
-
295
-			// Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group
296
-			if($gid !== '' && !in_array($gid, $subAdminOfGroups)) {
297
-				$gid = '';
298
-			}
299
-
300
-			// Batch all groups the user is subadmin of when a group is specified
301
-			$batch = [];
302
-			if($gid === '') {
303
-				foreach($subAdminOfGroups as $group) {
304
-					$groupUsers = $this->groupManager->displayNamesInGroup($group, $pattern, $limit, $offset);
305
-
306
-					foreach($groupUsers as $uid => $displayName) {
307
-						$batch[$uid] = $displayName;
308
-					}
309
-				}
310
-			} else {
311
-				$batch = $this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset);
312
-			}
313
-			$batch = $this->getUsersForUID($batch);
314
-
315
-			foreach ($batch as $user) {
316
-				// Only add the groups, this user is a subadmin of
317
-				$userGroups = array_values(array_intersect(
318
-					$this->groupManager->getUserGroupIds($user),
319
-					$subAdminOfGroups
320
-				));
321
-				$users[] = $this->formatUserForIndex($user, $userGroups);
322
-			}
323
-		}
324
-
325
-		return new DataResponse($users);
326
-	}
327
-
328
-	/**
329
-	 * @NoAdminRequired
330
-	 * @PasswordConfirmationRequired
331
-	 *
332
-	 * @param string $username
333
-	 * @param string $password
334
-	 * @param array $groups
335
-	 * @param string $email
336
-	 * @return DataResponse
337
-	 */
338
-	public function create($username, $password, array $groups=array(), $email='') {
339
-		if($email !== '' && !$this->mailer->validateMailAddress($email)) {
340
-			return new DataResponse(
341
-				array(
342
-					'message' => (string)$this->l10n->t('Invalid mail address')
343
-				),
344
-				Http::STATUS_UNPROCESSABLE_ENTITY
345
-			);
346
-		}
347
-
348
-		$currentUser = $this->userSession->getUser();
349
-
350
-		if (!$this->isAdmin) {
351
-			if (!empty($groups)) {
352
-				foreach ($groups as $key => $group) {
353
-					$groupObject = $this->groupManager->get($group);
354
-					if($groupObject === null) {
355
-						unset($groups[$key]);
356
-						continue;
357
-					}
358
-
359
-					if (!$this->groupManager->getSubAdmin()->isSubAdminofGroup($currentUser, $groupObject)) {
360
-						unset($groups[$key]);
361
-					}
362
-				}
363
-			}
364
-
365
-			if (empty($groups)) {
366
-				return new DataResponse(
367
-					array(
368
-						'message' => $this->l10n->t('No valid group selected'),
369
-					),
370
-					Http::STATUS_FORBIDDEN
371
-				);
372
-			}
373
-		}
374
-
375
-		if ($this->userManager->userExists($username)) {
376
-			return new DataResponse(
377
-				array(
378
-					'message' => (string)$this->l10n->t('A user with that name already exists.')
379
-				),
380
-				Http::STATUS_CONFLICT
381
-			);
382
-		}
383
-
384
-		$generatePasswordResetToken = false;
385
-		if ($password === '') {
386
-			if ($email === '') {
387
-				return new DataResponse(
388
-					array(
389
-						'message' => (string)$this->l10n->t('To send a password link to the user an email address is required.')
390
-					),
391
-					Http::STATUS_UNPROCESSABLE_ENTITY
392
-				);
393
-			}
394
-
395
-			$password = $this->secureRandom->generate(32);
396
-			$generatePasswordResetToken = true;
397
-		}
398
-
399
-		try {
400
-			$user = $this->userManager->createUser($username, $password);
401
-		} catch (\Exception $exception) {
402
-			$message = $exception->getMessage();
403
-			if (!$message) {
404
-				$message = $this->l10n->t('Unable to create user.');
405
-			}
406
-			return new DataResponse(
407
-				array(
408
-					'message' => (string) $message,
409
-				),
410
-				Http::STATUS_FORBIDDEN
411
-			);
412
-		}
413
-
414
-		if($user instanceof IUser) {
415
-			if($groups !== null) {
416
-				foreach($groups as $groupName) {
417
-					$group = $this->groupManager->get($groupName);
418
-
419
-					if(empty($group)) {
420
-						$group = $this->groupManager->createGroup($groupName);
421
-					}
422
-					$group->addUser($user);
423
-				}
424
-			}
425
-			/**
426
-			 * Send new user mail only if a mail is set
427
-			 */
428
-			if($email !== '') {
429
-				$user->setEMailAddress($email);
430
-				try {
431
-					$emailTemplate = $this->newUserMailHelper->generateTemplate($user, $generatePasswordResetToken);
432
-					$this->newUserMailHelper->sendMail($user, $emailTemplate);
433
-				} catch(\Exception $e) {
434
-					$this->log->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
435
-				}
436
-			}
437
-			// fetch users groups
438
-			$userGroups = $this->groupManager->getUserGroupIds($user);
439
-
440
-			return new DataResponse(
441
-				$this->formatUserForIndex($user, $userGroups),
442
-				Http::STATUS_CREATED
443
-			);
444
-		}
445
-
446
-		return new DataResponse(
447
-			array(
448
-				'message' => (string)$this->l10n->t('Unable to create user.')
449
-			),
450
-			Http::STATUS_FORBIDDEN
451
-		);
452
-
453
-	}
454
-
455
-	/**
456
-	 * @NoAdminRequired
457
-	 * @PasswordConfirmationRequired
458
-	 *
459
-	 * @param string $id
460
-	 * @return DataResponse
461
-	 */
462
-	public function destroy($id) {
463
-		$userId = $this->userSession->getUser()->getUID();
464
-		$user = $this->userManager->get($id);
465
-
466
-		if($userId === $id) {
467
-			return new DataResponse(
468
-				array(
469
-					'status' => 'error',
470
-					'data' => array(
471
-						'message' => (string)$this->l10n->t('Unable to delete user.')
472
-					)
473
-				),
474
-				Http::STATUS_FORBIDDEN
475
-			);
476
-		}
477
-
478
-		if(!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
479
-			return new DataResponse(
480
-				array(
481
-					'status' => 'error',
482
-					'data' => array(
483
-						'message' => (string)$this->l10n->t('Authentication error')
484
-					)
485
-				),
486
-				Http::STATUS_FORBIDDEN
487
-			);
488
-		}
489
-
490
-		if($user) {
491
-			if($user->delete()) {
492
-				return new DataResponse(
493
-					array(
494
-						'status' => 'success',
495
-						'data' => array(
496
-							'username' => $id
497
-						)
498
-					),
499
-					Http::STATUS_NO_CONTENT
500
-				);
501
-			}
502
-		}
503
-
504
-		return new DataResponse(
505
-			array(
506
-				'status' => 'error',
507
-				'data' => array(
508
-					'message' => (string)$this->l10n->t('Unable to delete user.')
509
-				)
510
-			),
511
-			Http::STATUS_FORBIDDEN
512
-		);
513
-	}
514
-
515
-	/**
516
-	 * @NoAdminRequired
517
-	 * @NoSubadminRequired
518
-	 * @PasswordConfirmationRequired
519
-	 *
520
-	 * @param string $account
521
-	 * @param bool $onlyVerificationCode only return verification code without updating the data
522
-	 * @return DataResponse
523
-	 */
524
-	public function getVerificationCode($account, $onlyVerificationCode) {
525
-
526
-		$user = $this->userSession->getUser();
527
-
528
-		if ($user === null) {
529
-			return new DataResponse([], Http::STATUS_BAD_REQUEST);
530
-		}
531
-
532
-		$accountData = $this->accountManager->getUser($user);
533
-		$cloudId = $user->getCloudId();
534
-		$message = "Use my Federated Cloud ID to share with me: " . $cloudId;
535
-		$signature = $this->signMessage($user, $message);
536
-
537
-		$code = $message . ' ' . $signature;
538
-		$codeMd5 = $message . ' ' . md5($signature);
539
-
540
-		switch ($account) {
541
-			case 'verify-twitter':
542
-				$accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
543
-				$msg = $this->l10n->t('In order to verify your Twitter account post following tweet on Twitter (please make sure to post it without any line breaks):');
544
-				$code = $codeMd5;
545
-				$type = AccountManager::PROPERTY_TWITTER;
546
-				$data = $accountData[AccountManager::PROPERTY_TWITTER]['value'];
547
-				$accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature;
548
-				break;
549
-			case 'verify-website':
550
-				$accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
551
-				$msg = $this->l10n->t('In order to verify your Website store following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):');
552
-				$type = AccountManager::PROPERTY_WEBSITE;
553
-				$data = $accountData[AccountManager::PROPERTY_WEBSITE]['value'];
554
-				$accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature;
555
-				break;
556
-			default:
557
-				return new DataResponse([], Http::STATUS_BAD_REQUEST);
558
-		}
559
-
560
-		if ($onlyVerificationCode === false) {
561
-			$this->accountManager->updateUser($user, $accountData);
562
-
563
-			$this->jobList->add('OC\Settings\BackgroundJobs\VerifyUserData',
564
-				[
565
-					'verificationCode' => $code,
566
-					'data' => $data,
567
-					'type' => $type,
568
-					'uid' => $user->getUID(),
569
-					'try' => 0,
570
-					'lastRun' => $this->getCurrentTime()
571
-				]
572
-			);
573
-		}
574
-
575
-		return new DataResponse(['msg' => $msg, 'code' => $code]);
576
-	}
577
-
578
-	/**
579
-	 * get current timestamp
580
-	 *
581
-	 * @return int
582
-	 */
583
-	protected function getCurrentTime() {
584
-		return time();
585
-	}
586
-
587
-	/**
588
-	 * sign message with users private key
589
-	 *
590
-	 * @param IUser $user
591
-	 * @param string $message
592
-	 *
593
-	 * @return string base64 encoded signature
594
-	 */
595
-	protected function signMessage(IUser $user, $message) {
596
-		$privateKey = $this->keyManager->getKey($user)->getPrivate();
597
-		openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
598
-		$signatureBase64 = base64_encode($signature);
599
-
600
-		return $signatureBase64;
601
-	}
602
-
603
-	/**
604
-	 * @NoAdminRequired
605
-	 * @NoSubadminRequired
606
-	 * @PasswordConfirmationRequired
607
-	 *
608
-	 * @param string $avatarScope
609
-	 * @param string $displayname
610
-	 * @param string $displaynameScope
611
-	 * @param string $phone
612
-	 * @param string $phoneScope
613
-	 * @param string $email
614
-	 * @param string $emailScope
615
-	 * @param string $website
616
-	 * @param string $websiteScope
617
-	 * @param string $address
618
-	 * @param string $addressScope
619
-	 * @param string $twitter
620
-	 * @param string $twitterScope
621
-	 * @return DataResponse
622
-	 */
623
-	public function setUserSettings($avatarScope,
624
-									$displayname,
625
-									$displaynameScope,
626
-									$phone,
627
-									$phoneScope,
628
-									$email,
629
-									$emailScope,
630
-									$website,
631
-									$websiteScope,
632
-									$address,
633
-									$addressScope,
634
-									$twitter,
635
-									$twitterScope
636
-	) {
637
-
638
-		if(!empty($email) && !$this->mailer->validateMailAddress($email)) {
639
-			return new DataResponse(
640
-				array(
641
-					'status' => 'error',
642
-					'data' => array(
643
-						'message' => (string)$this->l10n->t('Invalid mail address')
644
-					)
645
-				),
646
-				Http::STATUS_UNPROCESSABLE_ENTITY
647
-			);
648
-		}
649
-
650
-		$data = [
651
-			AccountManager::PROPERTY_AVATAR =>  ['scope' => $avatarScope],
652
-			AccountManager::PROPERTY_DISPLAYNAME => ['value' => $displayname, 'scope' => $displaynameScope],
653
-			AccountManager::PROPERTY_EMAIL=> ['value' => $email, 'scope' => $emailScope],
654
-			AccountManager::PROPERTY_WEBSITE => ['value' => $website, 'scope' => $websiteScope],
655
-			AccountManager::PROPERTY_ADDRESS => ['value' => $address, 'scope' => $addressScope],
656
-			AccountManager::PROPERTY_PHONE => ['value' => $phone, 'scope' => $phoneScope],
657
-			AccountManager::PROPERTY_TWITTER => ['value' => $twitter, 'scope' => $twitterScope]
658
-		];
659
-
660
-		$user = $this->userSession->getUser();
661
-
662
-		try {
663
-			$this->saveUserSettings($user, $data);
664
-			return new DataResponse(
665
-				array(
666
-					'status' => 'success',
667
-					'data' => array(
668
-						'userId' => $user->getUID(),
669
-						'avatarScope' => $avatarScope,
670
-						'displayname' => $displayname,
671
-						'displaynameScope' => $displaynameScope,
672
-						'email' => $email,
673
-						'emailScope' => $emailScope,
674
-						'website' => $website,
675
-						'websiteScope' => $websiteScope,
676
-						'address' => $address,
677
-						'addressScope' => $addressScope,
678
-						'message' => (string)$this->l10n->t('Settings saved')
679
-					)
680
-				),
681
-				Http::STATUS_OK
682
-			);
683
-		} catch (ForbiddenException $e) {
684
-			return new DataResponse([
685
-				'status' => 'error',
686
-				'data' => [
687
-					'message' => $e->getMessage()
688
-				],
689
-			]);
690
-		}
691
-
692
-	}
693
-
694
-
695
-	/**
696
-	 * update account manager with new user data
697
-	 *
698
-	 * @param IUser $user
699
-	 * @param array $data
700
-	 * @throws ForbiddenException
701
-	 */
702
-	protected function saveUserSettings(IUser $user, $data) {
703
-
704
-		// keep the user back-end up-to-date with the latest display name and email
705
-		// address
706
-		$oldDisplayName = $user->getDisplayName();
707
-		$oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
708
-		if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
709
-			&& $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
710
-		) {
711
-			$result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
712
-			if ($result === false) {
713
-				throw new ForbiddenException($this->l10n->t('Unable to change full name'));
714
-			}
715
-		}
716
-
717
-		$oldEmailAddress = $user->getEMailAddress();
718
-		$oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
719
-		if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
720
-			&& $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
721
-		) {
722
-			// this is the only permission a backend provides and is also used
723
-			// for the permission of setting a email address
724
-			if (!$user->canChangeDisplayName()) {
725
-				throw new ForbiddenException($this->l10n->t('Unable to change email address'));
726
-			}
727
-			$user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
728
-		}
729
-
730
-		$this->accountManager->updateUser($user, $data);
731
-	}
732
-
733
-	/**
734
-	 * Count all unique users visible for the current admin/subadmin.
735
-	 *
736
-	 * @NoAdminRequired
737
-	 *
738
-	 * @return DataResponse
739
-	 */
740
-	public function stats() {
741
-		$userCount = 0;
742
-		if ($this->isAdmin) {
743
-			$countByBackend = $this->userManager->countUsers();
744
-
745
-			if (!empty($countByBackend)) {
746
-				foreach ($countByBackend as $count) {
747
-					$userCount += $count;
748
-				}
749
-			}
750
-		} else {
751
-			$groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
752
-
753
-			$uniqueUsers = [];
754
-			foreach ($groups as $group) {
755
-				foreach($group->getUsers() as $uid => $displayName) {
756
-					$uniqueUsers[$uid] = true;
757
-				}
758
-			}
759
-
760
-			$userCount = count($uniqueUsers);
761
-		}
762
-
763
-		return new DataResponse(
764
-			[
765
-				'totalUsers' => $userCount
766
-			]
767
-		);
768
-	}
769
-
770
-
771
-	/**
772
-	 * Set the displayName of a user
773
-	 *
774
-	 * @NoAdminRequired
775
-	 * @NoSubadminRequired
776
-	 * @PasswordConfirmationRequired
777
-	 * @todo merge into saveUserSettings
778
-	 *
779
-	 * @param string $username
780
-	 * @param string $displayName
781
-	 * @return DataResponse
782
-	 */
783
-	public function setDisplayName($username, $displayName) {
784
-		$currentUser = $this->userSession->getUser();
785
-		$user = $this->userManager->get($username);
786
-
787
-		if ($user === null ||
788
-			!$user->canChangeDisplayName() ||
789
-			(
790
-				!$this->groupManager->isAdmin($currentUser->getUID()) &&
791
-				!$this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $user) &&
792
-				$currentUser->getUID() !== $username
793
-
794
-			)
795
-		) {
796
-			return new DataResponse([
797
-				'status' => 'error',
798
-				'data' => [
799
-					'message' => $this->l10n->t('Authentication error'),
800
-				],
801
-			]);
802
-		}
803
-
804
-		$userData = $this->accountManager->getUser($user);
805
-		$userData[AccountManager::PROPERTY_DISPLAYNAME]['value'] = $displayName;
806
-
807
-
808
-		try {
809
-			$this->saveUserSettings($user, $userData);
810
-			return new DataResponse([
811
-				'status' => 'success',
812
-				'data' => [
813
-					'message' => $this->l10n->t('Your full name has been changed.'),
814
-					'username' => $username,
815
-					'displayName' => $displayName,
816
-				],
817
-			]);
818
-		} catch (ForbiddenException $e) {
819
-			return new DataResponse([
820
-				'status' => 'error',
821
-				'data' => [
822
-					'message' => $e->getMessage(),
823
-					'displayName' => $user->getDisplayName(),
824
-				],
825
-			]);
826
-		}
827
-	}
828
-
829
-	/**
830
-	 * Set the mail address of a user
831
-	 *
832
-	 * @NoAdminRequired
833
-	 * @NoSubadminRequired
834
-	 * @PasswordConfirmationRequired
835
-	 *
836
-	 * @param string $id
837
-	 * @param string $mailAddress
838
-	 * @return DataResponse
839
-	 */
840
-	public function setEMailAddress($id, $mailAddress) {
841
-		$user = $this->userManager->get($id);
842
-		if (!$this->isAdmin
843
-			&& !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)
844
-		) {
845
-			return new DataResponse(
846
-				array(
847
-					'status' => 'error',
848
-					'data' => array(
849
-						'message' => (string)$this->l10n->t('Forbidden')
850
-					)
851
-				),
852
-				Http::STATUS_FORBIDDEN
853
-			);
854
-		}
855
-
856
-		if($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) {
857
-			return new DataResponse(
858
-				array(
859
-					'status' => 'error',
860
-					'data' => array(
861
-						'message' => (string)$this->l10n->t('Invalid mail address')
862
-					)
863
-				),
864
-				Http::STATUS_UNPROCESSABLE_ENTITY
865
-			);
866
-		}
867
-
868
-		if (!$user) {
869
-			return new DataResponse(
870
-				array(
871
-					'status' => 'error',
872
-					'data' => array(
873
-						'message' => (string)$this->l10n->t('Invalid user')
874
-					)
875
-				),
876
-				Http::STATUS_UNPROCESSABLE_ENTITY
877
-			);
878
-		}
879
-		// this is the only permission a backend provides and is also used
880
-		// for the permission of setting a email address
881
-		if (!$user->canChangeDisplayName()) {
882
-			return new DataResponse(
883
-				array(
884
-					'status' => 'error',
885
-					'data' => array(
886
-						'message' => (string)$this->l10n->t('Unable to change mail address')
887
-					)
888
-				),
889
-				Http::STATUS_FORBIDDEN
890
-			);
891
-		}
892
-
893
-		$userData = $this->accountManager->getUser($user);
894
-		$userData[AccountManager::PROPERTY_EMAIL]['value'] = $mailAddress;
895
-
896
-		try {
897
-			$this->saveUserSettings($user, $userData);
898
-			return new DataResponse(
899
-				array(
900
-					'status' => 'success',
901
-					'data' => array(
902
-						'username' => $id,
903
-						'mailAddress' => $mailAddress,
904
-						'message' => (string)$this->l10n->t('Email saved')
905
-					)
906
-				),
907
-				Http::STATUS_OK
908
-			);
909
-		} catch (ForbiddenException $e) {
910
-			return new DataResponse([
911
-				'status' => 'error',
912
-				'data' => [
913
-					'message' => $e->getMessage()
914
-				],
915
-			]);
916
-		}
917
-	}
61
+    /** @var IL10N */
62
+    private $l10n;
63
+    /** @var IUserSession */
64
+    private $userSession;
65
+    /** @var bool */
66
+    private $isAdmin;
67
+    /** @var IUserManager */
68
+    private $userManager;
69
+    /** @var IGroupManager */
70
+    private $groupManager;
71
+    /** @var IConfig */
72
+    private $config;
73
+    /** @var ILogger */
74
+    private $log;
75
+    /** @var IMailer */
76
+    private $mailer;
77
+    /** @var bool contains the state of the encryption app */
78
+    private $isEncryptionAppEnabled;
79
+    /** @var bool contains the state of the admin recovery setting */
80
+    private $isRestoreEnabled = false;
81
+    /** @var IAvatarManager */
82
+    private $avatarManager;
83
+    /** @var AccountManager */
84
+    private $accountManager;
85
+    /** @var ISecureRandom */
86
+    private $secureRandom;
87
+    /** @var NewUserMailHelper */
88
+    private $newUserMailHelper;
89
+    /** @var ITimeFactory */
90
+    private $timeFactory;
91
+    /** @var ICrypto */
92
+    private $crypto;
93
+    /** @var Manager */
94
+    private $keyManager;
95
+    /** @var IJobList */
96
+    private $jobList;
97
+
98
+    /**
99
+     * @param string $appName
100
+     * @param IRequest $request
101
+     * @param IUserManager $userManager
102
+     * @param IGroupManager $groupManager
103
+     * @param IUserSession $userSession
104
+     * @param IConfig $config
105
+     * @param bool $isAdmin
106
+     * @param IL10N $l10n
107
+     * @param ILogger $log
108
+     * @param IMailer $mailer
109
+     * @param IURLGenerator $urlGenerator
110
+     * @param IAppManager $appManager
111
+     * @param IAvatarManager $avatarManager
112
+     * @param AccountManager $accountManager
113
+     * @param ISecureRandom $secureRandom
114
+     * @param NewUserMailHelper $newUserMailHelper
115
+     * @param ITimeFactory $timeFactory
116
+     * @param ICrypto $crypto
117
+     * @param Manager $keyManager
118
+     * @param IJobList $jobList
119
+     */
120
+    public function __construct($appName,
121
+                                IRequest $request,
122
+                                IUserManager $userManager,
123
+                                IGroupManager $groupManager,
124
+                                IUserSession $userSession,
125
+                                IConfig $config,
126
+                                $isAdmin,
127
+                                IL10N $l10n,
128
+                                ILogger $log,
129
+                                IMailer $mailer,
130
+                                IURLGenerator $urlGenerator,
131
+                                IAppManager $appManager,
132
+                                IAvatarManager $avatarManager,
133
+                                AccountManager $accountManager,
134
+                                ISecureRandom $secureRandom,
135
+                                NewUserMailHelper $newUserMailHelper,
136
+                                ITimeFactory $timeFactory,
137
+                                ICrypto $crypto,
138
+                                Manager $keyManager,
139
+                                IJobList $jobList) {
140
+        parent::__construct($appName, $request);
141
+        $this->userManager = $userManager;
142
+        $this->groupManager = $groupManager;
143
+        $this->userSession = $userSession;
144
+        $this->config = $config;
145
+        $this->isAdmin = $isAdmin;
146
+        $this->l10n = $l10n;
147
+        $this->log = $log;
148
+        $this->mailer = $mailer;
149
+        $this->avatarManager = $avatarManager;
150
+        $this->accountManager = $accountManager;
151
+        $this->secureRandom = $secureRandom;
152
+        $this->newUserMailHelper = $newUserMailHelper;
153
+        $this->timeFactory = $timeFactory;
154
+        $this->crypto = $crypto;
155
+        $this->keyManager = $keyManager;
156
+        $this->jobList = $jobList;
157
+
158
+        // check for encryption state - TODO see formatUserForIndex
159
+        $this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption');
160
+        if($this->isEncryptionAppEnabled) {
161
+            // putting this directly in empty is possible in PHP 5.5+
162
+            $result = $config->getAppValue('encryption', 'recoveryAdminEnabled', 0);
163
+            $this->isRestoreEnabled = !empty($result);
164
+        }
165
+    }
166
+
167
+    /**
168
+     * @param IUser $user
169
+     * @param array $userGroups
170
+     * @return array
171
+     */
172
+    private function formatUserForIndex(IUser $user, array $userGroups = null) {
173
+
174
+        // TODO: eliminate this encryption specific code below and somehow
175
+        // hook in additional user info from other apps
176
+
177
+        // recovery isn't possible if admin or user has it disabled and encryption
178
+        // is enabled - so we eliminate the else paths in the conditional tree
179
+        // below
180
+        $restorePossible = false;
181
+
182
+        if ($this->isEncryptionAppEnabled) {
183
+            if ($this->isRestoreEnabled) {
184
+                // check for the users recovery setting
185
+                $recoveryMode = $this->config->getUserValue($user->getUID(), 'encryption', 'recoveryEnabled', '0');
186
+                // method call inside empty is possible with PHP 5.5+
187
+                $recoveryModeEnabled = !empty($recoveryMode);
188
+                if ($recoveryModeEnabled) {
189
+                    // user also has recovery mode enabled
190
+                    $restorePossible = true;
191
+                }
192
+            }
193
+        } else {
194
+            // recovery is possible if encryption is disabled (plain files are
195
+            // available)
196
+            $restorePossible = true;
197
+        }
198
+
199
+        $subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
200
+        foreach($subAdminGroups as $key => $subAdminGroup) {
201
+            $subAdminGroups[$key] = $subAdminGroup->getGID();
202
+        }
203
+
204
+        $displayName = $user->getEMailAddress();
205
+        if (is_null($displayName)) {
206
+            $displayName = '';
207
+        }
208
+
209
+        $avatarAvailable = false;
210
+        try {
211
+            $avatarAvailable = $this->avatarManager->getAvatar($user->getUID())->exists();
212
+        } catch (\Exception $e) {
213
+            //No avatar yet
214
+        }
215
+
216
+        return [
217
+            'name' => $user->getUID(),
218
+            'displayname' => $user->getDisplayName(),
219
+            'groups' => (empty($userGroups)) ? $this->groupManager->getUserGroupIds($user) : $userGroups,
220
+            'subadmin' => $subAdminGroups,
221
+            'quota' => $user->getQuota(),
222
+            'storageLocation' => $user->getHome(),
223
+            'lastLogin' => $user->getLastLogin() * 1000,
224
+            'backend' => $user->getBackendClassName(),
225
+            'email' => $displayName,
226
+            'isRestoreDisabled' => !$restorePossible,
227
+            'isAvatarAvailable' => $avatarAvailable,
228
+        ];
229
+    }
230
+
231
+    /**
232
+     * @param array $userIDs Array with schema [$uid => $displayName]
233
+     * @return IUser[]
234
+     */
235
+    private function getUsersForUID(array $userIDs) {
236
+        $users = [];
237
+        foreach ($userIDs as $uid => $displayName) {
238
+            $users[$uid] = $this->userManager->get($uid);
239
+        }
240
+        return $users;
241
+    }
242
+
243
+    /**
244
+     * @NoAdminRequired
245
+     *
246
+     * @param int $offset
247
+     * @param int $limit
248
+     * @param string $gid GID to filter for
249
+     * @param string $pattern Pattern to search for in the username
250
+     * @param string $backend Backend to filter for (class-name)
251
+     * @return DataResponse
252
+     *
253
+     * TODO: Tidy up and write unit tests - code is mainly static method calls
254
+     */
255
+    public function index($offset = 0, $limit = 10, $gid = '', $pattern = '', $backend = '') {
256
+        // FIXME: The JS sends the group '_everyone' instead of no GID for the "all users" group.
257
+        if($gid === '_everyone') {
258
+            $gid = '';
259
+        }
260
+
261
+        // Remove backends
262
+        if(!empty($backend)) {
263
+            $activeBackends = $this->userManager->getBackends();
264
+            $this->userManager->clearBackends();
265
+            foreach($activeBackends as $singleActiveBackend) {
266
+                if($backend === get_class($singleActiveBackend)) {
267
+                    $this->userManager->registerBackend($singleActiveBackend);
268
+                    break;
269
+                }
270
+            }
271
+        }
272
+
273
+        $users = [];
274
+        if ($this->isAdmin) {
275
+
276
+            if($gid !== '') {
277
+                $batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset));
278
+            } else {
279
+                $batch = $this->userManager->search($pattern, $limit, $offset);
280
+            }
281
+
282
+            foreach ($batch as $user) {
283
+                $users[] = $this->formatUserForIndex($user);
284
+            }
285
+
286
+        } else {
287
+            $subAdminOfGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
288
+            // New class returns IGroup[] so convert back
289
+            $gids = [];
290
+            foreach ($subAdminOfGroups as $group) {
291
+                $gids[] = $group->getGID();
292
+            }
293
+            $subAdminOfGroups = $gids;
294
+
295
+            // Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group
296
+            if($gid !== '' && !in_array($gid, $subAdminOfGroups)) {
297
+                $gid = '';
298
+            }
299
+
300
+            // Batch all groups the user is subadmin of when a group is specified
301
+            $batch = [];
302
+            if($gid === '') {
303
+                foreach($subAdminOfGroups as $group) {
304
+                    $groupUsers = $this->groupManager->displayNamesInGroup($group, $pattern, $limit, $offset);
305
+
306
+                    foreach($groupUsers as $uid => $displayName) {
307
+                        $batch[$uid] = $displayName;
308
+                    }
309
+                }
310
+            } else {
311
+                $batch = $this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset);
312
+            }
313
+            $batch = $this->getUsersForUID($batch);
314
+
315
+            foreach ($batch as $user) {
316
+                // Only add the groups, this user is a subadmin of
317
+                $userGroups = array_values(array_intersect(
318
+                    $this->groupManager->getUserGroupIds($user),
319
+                    $subAdminOfGroups
320
+                ));
321
+                $users[] = $this->formatUserForIndex($user, $userGroups);
322
+            }
323
+        }
324
+
325
+        return new DataResponse($users);
326
+    }
327
+
328
+    /**
329
+     * @NoAdminRequired
330
+     * @PasswordConfirmationRequired
331
+     *
332
+     * @param string $username
333
+     * @param string $password
334
+     * @param array $groups
335
+     * @param string $email
336
+     * @return DataResponse
337
+     */
338
+    public function create($username, $password, array $groups=array(), $email='') {
339
+        if($email !== '' && !$this->mailer->validateMailAddress($email)) {
340
+            return new DataResponse(
341
+                array(
342
+                    'message' => (string)$this->l10n->t('Invalid mail address')
343
+                ),
344
+                Http::STATUS_UNPROCESSABLE_ENTITY
345
+            );
346
+        }
347
+
348
+        $currentUser = $this->userSession->getUser();
349
+
350
+        if (!$this->isAdmin) {
351
+            if (!empty($groups)) {
352
+                foreach ($groups as $key => $group) {
353
+                    $groupObject = $this->groupManager->get($group);
354
+                    if($groupObject === null) {
355
+                        unset($groups[$key]);
356
+                        continue;
357
+                    }
358
+
359
+                    if (!$this->groupManager->getSubAdmin()->isSubAdminofGroup($currentUser, $groupObject)) {
360
+                        unset($groups[$key]);
361
+                    }
362
+                }
363
+            }
364
+
365
+            if (empty($groups)) {
366
+                return new DataResponse(
367
+                    array(
368
+                        'message' => $this->l10n->t('No valid group selected'),
369
+                    ),
370
+                    Http::STATUS_FORBIDDEN
371
+                );
372
+            }
373
+        }
374
+
375
+        if ($this->userManager->userExists($username)) {
376
+            return new DataResponse(
377
+                array(
378
+                    'message' => (string)$this->l10n->t('A user with that name already exists.')
379
+                ),
380
+                Http::STATUS_CONFLICT
381
+            );
382
+        }
383
+
384
+        $generatePasswordResetToken = false;
385
+        if ($password === '') {
386
+            if ($email === '') {
387
+                return new DataResponse(
388
+                    array(
389
+                        'message' => (string)$this->l10n->t('To send a password link to the user an email address is required.')
390
+                    ),
391
+                    Http::STATUS_UNPROCESSABLE_ENTITY
392
+                );
393
+            }
394
+
395
+            $password = $this->secureRandom->generate(32);
396
+            $generatePasswordResetToken = true;
397
+        }
398
+
399
+        try {
400
+            $user = $this->userManager->createUser($username, $password);
401
+        } catch (\Exception $exception) {
402
+            $message = $exception->getMessage();
403
+            if (!$message) {
404
+                $message = $this->l10n->t('Unable to create user.');
405
+            }
406
+            return new DataResponse(
407
+                array(
408
+                    'message' => (string) $message,
409
+                ),
410
+                Http::STATUS_FORBIDDEN
411
+            );
412
+        }
413
+
414
+        if($user instanceof IUser) {
415
+            if($groups !== null) {
416
+                foreach($groups as $groupName) {
417
+                    $group = $this->groupManager->get($groupName);
418
+
419
+                    if(empty($group)) {
420
+                        $group = $this->groupManager->createGroup($groupName);
421
+                    }
422
+                    $group->addUser($user);
423
+                }
424
+            }
425
+            /**
426
+             * Send new user mail only if a mail is set
427
+             */
428
+            if($email !== '') {
429
+                $user->setEMailAddress($email);
430
+                try {
431
+                    $emailTemplate = $this->newUserMailHelper->generateTemplate($user, $generatePasswordResetToken);
432
+                    $this->newUserMailHelper->sendMail($user, $emailTemplate);
433
+                } catch(\Exception $e) {
434
+                    $this->log->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
435
+                }
436
+            }
437
+            // fetch users groups
438
+            $userGroups = $this->groupManager->getUserGroupIds($user);
439
+
440
+            return new DataResponse(
441
+                $this->formatUserForIndex($user, $userGroups),
442
+                Http::STATUS_CREATED
443
+            );
444
+        }
445
+
446
+        return new DataResponse(
447
+            array(
448
+                'message' => (string)$this->l10n->t('Unable to create user.')
449
+            ),
450
+            Http::STATUS_FORBIDDEN
451
+        );
452
+
453
+    }
454
+
455
+    /**
456
+     * @NoAdminRequired
457
+     * @PasswordConfirmationRequired
458
+     *
459
+     * @param string $id
460
+     * @return DataResponse
461
+     */
462
+    public function destroy($id) {
463
+        $userId = $this->userSession->getUser()->getUID();
464
+        $user = $this->userManager->get($id);
465
+
466
+        if($userId === $id) {
467
+            return new DataResponse(
468
+                array(
469
+                    'status' => 'error',
470
+                    'data' => array(
471
+                        'message' => (string)$this->l10n->t('Unable to delete user.')
472
+                    )
473
+                ),
474
+                Http::STATUS_FORBIDDEN
475
+            );
476
+        }
477
+
478
+        if(!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
479
+            return new DataResponse(
480
+                array(
481
+                    'status' => 'error',
482
+                    'data' => array(
483
+                        'message' => (string)$this->l10n->t('Authentication error')
484
+                    )
485
+                ),
486
+                Http::STATUS_FORBIDDEN
487
+            );
488
+        }
489
+
490
+        if($user) {
491
+            if($user->delete()) {
492
+                return new DataResponse(
493
+                    array(
494
+                        'status' => 'success',
495
+                        'data' => array(
496
+                            'username' => $id
497
+                        )
498
+                    ),
499
+                    Http::STATUS_NO_CONTENT
500
+                );
501
+            }
502
+        }
503
+
504
+        return new DataResponse(
505
+            array(
506
+                'status' => 'error',
507
+                'data' => array(
508
+                    'message' => (string)$this->l10n->t('Unable to delete user.')
509
+                )
510
+            ),
511
+            Http::STATUS_FORBIDDEN
512
+        );
513
+    }
514
+
515
+    /**
516
+     * @NoAdminRequired
517
+     * @NoSubadminRequired
518
+     * @PasswordConfirmationRequired
519
+     *
520
+     * @param string $account
521
+     * @param bool $onlyVerificationCode only return verification code without updating the data
522
+     * @return DataResponse
523
+     */
524
+    public function getVerificationCode($account, $onlyVerificationCode) {
525
+
526
+        $user = $this->userSession->getUser();
527
+
528
+        if ($user === null) {
529
+            return new DataResponse([], Http::STATUS_BAD_REQUEST);
530
+        }
531
+
532
+        $accountData = $this->accountManager->getUser($user);
533
+        $cloudId = $user->getCloudId();
534
+        $message = "Use my Federated Cloud ID to share with me: " . $cloudId;
535
+        $signature = $this->signMessage($user, $message);
536
+
537
+        $code = $message . ' ' . $signature;
538
+        $codeMd5 = $message . ' ' . md5($signature);
539
+
540
+        switch ($account) {
541
+            case 'verify-twitter':
542
+                $accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
543
+                $msg = $this->l10n->t('In order to verify your Twitter account post following tweet on Twitter (please make sure to post it without any line breaks):');
544
+                $code = $codeMd5;
545
+                $type = AccountManager::PROPERTY_TWITTER;
546
+                $data = $accountData[AccountManager::PROPERTY_TWITTER]['value'];
547
+                $accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature;
548
+                break;
549
+            case 'verify-website':
550
+                $accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
551
+                $msg = $this->l10n->t('In order to verify your Website store following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):');
552
+                $type = AccountManager::PROPERTY_WEBSITE;
553
+                $data = $accountData[AccountManager::PROPERTY_WEBSITE]['value'];
554
+                $accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature;
555
+                break;
556
+            default:
557
+                return new DataResponse([], Http::STATUS_BAD_REQUEST);
558
+        }
559
+
560
+        if ($onlyVerificationCode === false) {
561
+            $this->accountManager->updateUser($user, $accountData);
562
+
563
+            $this->jobList->add('OC\Settings\BackgroundJobs\VerifyUserData',
564
+                [
565
+                    'verificationCode' => $code,
566
+                    'data' => $data,
567
+                    'type' => $type,
568
+                    'uid' => $user->getUID(),
569
+                    'try' => 0,
570
+                    'lastRun' => $this->getCurrentTime()
571
+                ]
572
+            );
573
+        }
574
+
575
+        return new DataResponse(['msg' => $msg, 'code' => $code]);
576
+    }
577
+
578
+    /**
579
+     * get current timestamp
580
+     *
581
+     * @return int
582
+     */
583
+    protected function getCurrentTime() {
584
+        return time();
585
+    }
586
+
587
+    /**
588
+     * sign message with users private key
589
+     *
590
+     * @param IUser $user
591
+     * @param string $message
592
+     *
593
+     * @return string base64 encoded signature
594
+     */
595
+    protected function signMessage(IUser $user, $message) {
596
+        $privateKey = $this->keyManager->getKey($user)->getPrivate();
597
+        openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
598
+        $signatureBase64 = base64_encode($signature);
599
+
600
+        return $signatureBase64;
601
+    }
602
+
603
+    /**
604
+     * @NoAdminRequired
605
+     * @NoSubadminRequired
606
+     * @PasswordConfirmationRequired
607
+     *
608
+     * @param string $avatarScope
609
+     * @param string $displayname
610
+     * @param string $displaynameScope
611
+     * @param string $phone
612
+     * @param string $phoneScope
613
+     * @param string $email
614
+     * @param string $emailScope
615
+     * @param string $website
616
+     * @param string $websiteScope
617
+     * @param string $address
618
+     * @param string $addressScope
619
+     * @param string $twitter
620
+     * @param string $twitterScope
621
+     * @return DataResponse
622
+     */
623
+    public function setUserSettings($avatarScope,
624
+                                    $displayname,
625
+                                    $displaynameScope,
626
+                                    $phone,
627
+                                    $phoneScope,
628
+                                    $email,
629
+                                    $emailScope,
630
+                                    $website,
631
+                                    $websiteScope,
632
+                                    $address,
633
+                                    $addressScope,
634
+                                    $twitter,
635
+                                    $twitterScope
636
+    ) {
637
+
638
+        if(!empty($email) && !$this->mailer->validateMailAddress($email)) {
639
+            return new DataResponse(
640
+                array(
641
+                    'status' => 'error',
642
+                    'data' => array(
643
+                        'message' => (string)$this->l10n->t('Invalid mail address')
644
+                    )
645
+                ),
646
+                Http::STATUS_UNPROCESSABLE_ENTITY
647
+            );
648
+        }
649
+
650
+        $data = [
651
+            AccountManager::PROPERTY_AVATAR =>  ['scope' => $avatarScope],
652
+            AccountManager::PROPERTY_DISPLAYNAME => ['value' => $displayname, 'scope' => $displaynameScope],
653
+            AccountManager::PROPERTY_EMAIL=> ['value' => $email, 'scope' => $emailScope],
654
+            AccountManager::PROPERTY_WEBSITE => ['value' => $website, 'scope' => $websiteScope],
655
+            AccountManager::PROPERTY_ADDRESS => ['value' => $address, 'scope' => $addressScope],
656
+            AccountManager::PROPERTY_PHONE => ['value' => $phone, 'scope' => $phoneScope],
657
+            AccountManager::PROPERTY_TWITTER => ['value' => $twitter, 'scope' => $twitterScope]
658
+        ];
659
+
660
+        $user = $this->userSession->getUser();
661
+
662
+        try {
663
+            $this->saveUserSettings($user, $data);
664
+            return new DataResponse(
665
+                array(
666
+                    'status' => 'success',
667
+                    'data' => array(
668
+                        'userId' => $user->getUID(),
669
+                        'avatarScope' => $avatarScope,
670
+                        'displayname' => $displayname,
671
+                        'displaynameScope' => $displaynameScope,
672
+                        'email' => $email,
673
+                        'emailScope' => $emailScope,
674
+                        'website' => $website,
675
+                        'websiteScope' => $websiteScope,
676
+                        'address' => $address,
677
+                        'addressScope' => $addressScope,
678
+                        'message' => (string)$this->l10n->t('Settings saved')
679
+                    )
680
+                ),
681
+                Http::STATUS_OK
682
+            );
683
+        } catch (ForbiddenException $e) {
684
+            return new DataResponse([
685
+                'status' => 'error',
686
+                'data' => [
687
+                    'message' => $e->getMessage()
688
+                ],
689
+            ]);
690
+        }
691
+
692
+    }
693
+
694
+
695
+    /**
696
+     * update account manager with new user data
697
+     *
698
+     * @param IUser $user
699
+     * @param array $data
700
+     * @throws ForbiddenException
701
+     */
702
+    protected function saveUserSettings(IUser $user, $data) {
703
+
704
+        // keep the user back-end up-to-date with the latest display name and email
705
+        // address
706
+        $oldDisplayName = $user->getDisplayName();
707
+        $oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
708
+        if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
709
+            && $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
710
+        ) {
711
+            $result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
712
+            if ($result === false) {
713
+                throw new ForbiddenException($this->l10n->t('Unable to change full name'));
714
+            }
715
+        }
716
+
717
+        $oldEmailAddress = $user->getEMailAddress();
718
+        $oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
719
+        if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
720
+            && $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
721
+        ) {
722
+            // this is the only permission a backend provides and is also used
723
+            // for the permission of setting a email address
724
+            if (!$user->canChangeDisplayName()) {
725
+                throw new ForbiddenException($this->l10n->t('Unable to change email address'));
726
+            }
727
+            $user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
728
+        }
729
+
730
+        $this->accountManager->updateUser($user, $data);
731
+    }
732
+
733
+    /**
734
+     * Count all unique users visible for the current admin/subadmin.
735
+     *
736
+     * @NoAdminRequired
737
+     *
738
+     * @return DataResponse
739
+     */
740
+    public function stats() {
741
+        $userCount = 0;
742
+        if ($this->isAdmin) {
743
+            $countByBackend = $this->userManager->countUsers();
744
+
745
+            if (!empty($countByBackend)) {
746
+                foreach ($countByBackend as $count) {
747
+                    $userCount += $count;
748
+                }
749
+            }
750
+        } else {
751
+            $groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
752
+
753
+            $uniqueUsers = [];
754
+            foreach ($groups as $group) {
755
+                foreach($group->getUsers() as $uid => $displayName) {
756
+                    $uniqueUsers[$uid] = true;
757
+                }
758
+            }
759
+
760
+            $userCount = count($uniqueUsers);
761
+        }
762
+
763
+        return new DataResponse(
764
+            [
765
+                'totalUsers' => $userCount
766
+            ]
767
+        );
768
+    }
769
+
770
+
771
+    /**
772
+     * Set the displayName of a user
773
+     *
774
+     * @NoAdminRequired
775
+     * @NoSubadminRequired
776
+     * @PasswordConfirmationRequired
777
+     * @todo merge into saveUserSettings
778
+     *
779
+     * @param string $username
780
+     * @param string $displayName
781
+     * @return DataResponse
782
+     */
783
+    public function setDisplayName($username, $displayName) {
784
+        $currentUser = $this->userSession->getUser();
785
+        $user = $this->userManager->get($username);
786
+
787
+        if ($user === null ||
788
+            !$user->canChangeDisplayName() ||
789
+            (
790
+                !$this->groupManager->isAdmin($currentUser->getUID()) &&
791
+                !$this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $user) &&
792
+                $currentUser->getUID() !== $username
793
+
794
+            )
795
+        ) {
796
+            return new DataResponse([
797
+                'status' => 'error',
798
+                'data' => [
799
+                    'message' => $this->l10n->t('Authentication error'),
800
+                ],
801
+            ]);
802
+        }
803
+
804
+        $userData = $this->accountManager->getUser($user);
805
+        $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'] = $displayName;
806
+
807
+
808
+        try {
809
+            $this->saveUserSettings($user, $userData);
810
+            return new DataResponse([
811
+                'status' => 'success',
812
+                'data' => [
813
+                    'message' => $this->l10n->t('Your full name has been changed.'),
814
+                    'username' => $username,
815
+                    'displayName' => $displayName,
816
+                ],
817
+            ]);
818
+        } catch (ForbiddenException $e) {
819
+            return new DataResponse([
820
+                'status' => 'error',
821
+                'data' => [
822
+                    'message' => $e->getMessage(),
823
+                    'displayName' => $user->getDisplayName(),
824
+                ],
825
+            ]);
826
+        }
827
+    }
828
+
829
+    /**
830
+     * Set the mail address of a user
831
+     *
832
+     * @NoAdminRequired
833
+     * @NoSubadminRequired
834
+     * @PasswordConfirmationRequired
835
+     *
836
+     * @param string $id
837
+     * @param string $mailAddress
838
+     * @return DataResponse
839
+     */
840
+    public function setEMailAddress($id, $mailAddress) {
841
+        $user = $this->userManager->get($id);
842
+        if (!$this->isAdmin
843
+            && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)
844
+        ) {
845
+            return new DataResponse(
846
+                array(
847
+                    'status' => 'error',
848
+                    'data' => array(
849
+                        'message' => (string)$this->l10n->t('Forbidden')
850
+                    )
851
+                ),
852
+                Http::STATUS_FORBIDDEN
853
+            );
854
+        }
855
+
856
+        if($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) {
857
+            return new DataResponse(
858
+                array(
859
+                    'status' => 'error',
860
+                    'data' => array(
861
+                        'message' => (string)$this->l10n->t('Invalid mail address')
862
+                    )
863
+                ),
864
+                Http::STATUS_UNPROCESSABLE_ENTITY
865
+            );
866
+        }
867
+
868
+        if (!$user) {
869
+            return new DataResponse(
870
+                array(
871
+                    'status' => 'error',
872
+                    'data' => array(
873
+                        'message' => (string)$this->l10n->t('Invalid user')
874
+                    )
875
+                ),
876
+                Http::STATUS_UNPROCESSABLE_ENTITY
877
+            );
878
+        }
879
+        // this is the only permission a backend provides and is also used
880
+        // for the permission of setting a email address
881
+        if (!$user->canChangeDisplayName()) {
882
+            return new DataResponse(
883
+                array(
884
+                    'status' => 'error',
885
+                    'data' => array(
886
+                        'message' => (string)$this->l10n->t('Unable to change mail address')
887
+                    )
888
+                ),
889
+                Http::STATUS_FORBIDDEN
890
+            );
891
+        }
892
+
893
+        $userData = $this->accountManager->getUser($user);
894
+        $userData[AccountManager::PROPERTY_EMAIL]['value'] = $mailAddress;
895
+
896
+        try {
897
+            $this->saveUserSettings($user, $userData);
898
+            return new DataResponse(
899
+                array(
900
+                    'status' => 'success',
901
+                    'data' => array(
902
+                        'username' => $id,
903
+                        'mailAddress' => $mailAddress,
904
+                        'message' => (string)$this->l10n->t('Email saved')
905
+                    )
906
+                ),
907
+                Http::STATUS_OK
908
+            );
909
+        } catch (ForbiddenException $e) {
910
+            return new DataResponse([
911
+                'status' => 'error',
912
+                'data' => [
913
+                    'message' => $e->getMessage()
914
+                ],
915
+            ]);
916
+        }
917
+    }
918 918
 
919 919
 }
Please login to merge, or discard this patch.
lib/private/Accounts/Hooks.php 1 patch
Indentation   +68 added lines, -68 removed lines patch added patch discarded remove patch
@@ -27,73 +27,73 @@
 block discarded – undo
27 27
 
28 28
 class Hooks {
29 29
 
30
-	/** @var  AccountManager */
31
-	private $accountManager = null;
32
-
33
-	/** @var ILogger */
34
-	private $logger;
35
-
36
-	/**
37
-	 * Hooks constructor.
38
-	 *
39
-	 * @param ILogger $logger
40
-	 */
41
-	public function __construct(ILogger $logger) {
42
-		$this->logger = $logger;
43
-	}
44
-
45
-	/**
46
-	 * update accounts table if email address or display name was changed from outside
47
-	 *
48
-	 * @param array $params
49
-	 */
50
-	public function changeUserHook($params) {
51
-
52
-		$accountManager = $this->getAccountManager();
53
-
54
-		/** @var IUser $user */
55
-		$user = isset($params['user']) ? $params['user'] : null;
56
-		$feature = isset($params['feature']) ? $params['feature'] : null;
57
-		$newValue = isset($params['value']) ? $params['value'] : null;
58
-
59
-		if (is_null($user) || is_null($feature) || is_null($newValue)) {
60
-			$this->logger->warning('Missing expected parameters in change user hook');
61
-			return;
62
-		}
63
-
64
-		$accountData = $accountManager->getUser($user);
65
-
66
-		switch ($feature) {
67
-			case 'eMailAddress':
68
-				if ($accountData[AccountManager::PROPERTY_EMAIL]['value'] !== $newValue) {
69
-					$accountData[AccountManager::PROPERTY_EMAIL]['value'] = $newValue;
70
-					$accountManager->updateUser($user, $accountData);
71
-				}
72
-				break;
73
-			case 'displayName':
74
-				if ($accountData[AccountManager::PROPERTY_DISPLAYNAME]['value'] !== $newValue) {
75
-					$accountData[AccountManager::PROPERTY_DISPLAYNAME]['value'] = $newValue;
76
-					$accountManager->updateUser($user, $accountData);
77
-				}
78
-				break;
79
-		}
80
-
81
-	}
82
-
83
-	/**
84
-	 * return instance of accountManager
85
-	 *
86
-	 * @return AccountManager
87
-	 */
88
-	protected function getAccountManager() {
89
-		if (is_null($this->accountManager)) {
90
-			$this->accountManager = new AccountManager(
91
-				\OC::$server->getDatabaseConnection(),
92
-				\OC::$server->getEventDispatcher(),
93
-				\OC::$server->getJobList()
94
-			);
95
-		}
96
-		return $this->accountManager;
97
-	}
30
+    /** @var  AccountManager */
31
+    private $accountManager = null;
32
+
33
+    /** @var ILogger */
34
+    private $logger;
35
+
36
+    /**
37
+     * Hooks constructor.
38
+     *
39
+     * @param ILogger $logger
40
+     */
41
+    public function __construct(ILogger $logger) {
42
+        $this->logger = $logger;
43
+    }
44
+
45
+    /**
46
+     * update accounts table if email address or display name was changed from outside
47
+     *
48
+     * @param array $params
49
+     */
50
+    public function changeUserHook($params) {
51
+
52
+        $accountManager = $this->getAccountManager();
53
+
54
+        /** @var IUser $user */
55
+        $user = isset($params['user']) ? $params['user'] : null;
56
+        $feature = isset($params['feature']) ? $params['feature'] : null;
57
+        $newValue = isset($params['value']) ? $params['value'] : null;
58
+
59
+        if (is_null($user) || is_null($feature) || is_null($newValue)) {
60
+            $this->logger->warning('Missing expected parameters in change user hook');
61
+            return;
62
+        }
63
+
64
+        $accountData = $accountManager->getUser($user);
65
+
66
+        switch ($feature) {
67
+            case 'eMailAddress':
68
+                if ($accountData[AccountManager::PROPERTY_EMAIL]['value'] !== $newValue) {
69
+                    $accountData[AccountManager::PROPERTY_EMAIL]['value'] = $newValue;
70
+                    $accountManager->updateUser($user, $accountData);
71
+                }
72
+                break;
73
+            case 'displayName':
74
+                if ($accountData[AccountManager::PROPERTY_DISPLAYNAME]['value'] !== $newValue) {
75
+                    $accountData[AccountManager::PROPERTY_DISPLAYNAME]['value'] = $newValue;
76
+                    $accountManager->updateUser($user, $accountData);
77
+                }
78
+                break;
79
+        }
80
+
81
+    }
82
+
83
+    /**
84
+     * return instance of accountManager
85
+     *
86
+     * @return AccountManager
87
+     */
88
+    protected function getAccountManager() {
89
+        if (is_null($this->accountManager)) {
90
+            $this->accountManager = new AccountManager(
91
+                \OC::$server->getDatabaseConnection(),
92
+                \OC::$server->getEventDispatcher(),
93
+                \OC::$server->getJobList()
94
+            );
95
+        }
96
+        return $this->accountManager;
97
+    }
98 98
 
99 99
 }
Please login to merge, or discard this patch.
apps/lookup_server_connector/appinfo/app.php 1 patch
Indentation   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -22,30 +22,30 @@
 block discarded – undo
22 22
 $dispatcher = \OC::$server->getEventDispatcher();
23 23
 
24 24
 $dispatcher->addListener('OC\AccountManager::userUpdated', function(\Symfony\Component\EventDispatcher\GenericEvent $event) {
25
-	$user = $event->getSubject();
25
+    $user = $event->getSubject();
26 26
 
27
-	$keyManager = new \OC\Security\IdentityProof\Manager(
28
-		\OC::$server->getAppDataDir('identityproof'),
29
-		\OC::$server->getCrypto()
30
-	);
27
+    $keyManager = new \OC\Security\IdentityProof\Manager(
28
+        \OC::$server->getAppDataDir('identityproof'),
29
+        \OC::$server->getCrypto()
30
+    );
31 31
 
32
-	$config = \OC::$server->getConfig();
33
-	$lookupServer = $config->getSystemValue('lookup_server', '');
32
+    $config = \OC::$server->getConfig();
33
+    $lookupServer = $config->getSystemValue('lookup_server', '');
34 34
 
35
-	$updateLookupServer = new \OCA\LookupServerConnector\UpdateLookupServer(
36
-		new \OC\Accounts\AccountManager(
37
-			\OC::$server->getDatabaseConnection(),
38
-			\OC::$server->getEventDispatcher(),
39
-			\OC::$server->getJobList()
40
-		),
41
-		\OC::$server->getHTTPClientService(),
42
-		new \OC\Security\IdentityProof\Signer(
43
-			$keyManager,
44
-			new \OC\AppFramework\Utility\TimeFactory(),
45
-			\OC::$server->getUserManager()
46
-		),
47
-		\OC::$server->getJobList(),
48
-		$lookupServer
49
-	);
50
-	$updateLookupServer->userUpdated($user);
35
+    $updateLookupServer = new \OCA\LookupServerConnector\UpdateLookupServer(
36
+        new \OC\Accounts\AccountManager(
37
+            \OC::$server->getDatabaseConnection(),
38
+            \OC::$server->getEventDispatcher(),
39
+            \OC::$server->getJobList()
40
+        ),
41
+        \OC::$server->getHTTPClientService(),
42
+        new \OC\Security\IdentityProof\Signer(
43
+            $keyManager,
44
+            new \OC\AppFramework\Utility\TimeFactory(),
45
+            \OC::$server->getUserManager()
46
+        ),
47
+        \OC::$server->getJobList(),
48
+        $lookupServer
49
+    );
50
+    $updateLookupServer->userUpdated($user);
51 51
 });
Please login to merge, or discard this patch.
lib/private/Accounts/AccountManager.php 2 patches
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -195,38 +195,38 @@
 block discarded – undo
195 195
 		$emailVerified = isset($oldData[self::PROPERTY_EMAIL]['verified']) && $oldData[self::PROPERTY_EMAIL]['verified'] === self::VERIFIED;
196 196
 
197 197
 		// keep old verification status if we don't have a new one
198
-		if(!isset($newData[self::PROPERTY_TWITTER]['verified'])) {
198
+		if (!isset($newData[self::PROPERTY_TWITTER]['verified'])) {
199 199
 			// keep old verification status if value didn't changed and an old value exists
200 200
 			$keepOldStatus = $newData[self::PROPERTY_TWITTER]['value'] === $oldData[self::PROPERTY_TWITTER]['value'] && isset($oldData[self::PROPERTY_TWITTER]['verified']);
201 201
 			$newData[self::PROPERTY_TWITTER]['verified'] = $keepOldStatus ? $oldData[self::PROPERTY_TWITTER]['verified'] : self::NOT_VERIFIED;
202 202
 		}
203 203
 
204
-		if(!isset($newData[self::PROPERTY_WEBSITE]['verified'])) {
204
+		if (!isset($newData[self::PROPERTY_WEBSITE]['verified'])) {
205 205
 			// keep old verification status if value didn't changed and an old value exists
206 206
 			$keepOldStatus = $newData[self::PROPERTY_WEBSITE]['value'] === $oldData[self::PROPERTY_WEBSITE]['value'] && isset($oldData[self::PROPERTY_WEBSITE]['verified']);
207 207
 			$newData[self::PROPERTY_WEBSITE]['verified'] = $keepOldStatus ? $oldData[self::PROPERTY_WEBSITE]['verified'] : self::NOT_VERIFIED;
208 208
 		}
209 209
 
210
-		if(!isset($newData[self::PROPERTY_EMAIL]['verified'])) {
210
+		if (!isset($newData[self::PROPERTY_EMAIL]['verified'])) {
211 211
 			// keep old verification status if value didn't changed and an old value exists
212 212
 			$keepOldStatus = $newData[self::PROPERTY_EMAIL]['value'] === $oldData[self::PROPERTY_EMAIL]['value'] && isset($oldData[self::PROPERTY_EMAIL]['verified']);
213 213
 			$newData[self::PROPERTY_EMAIL]['verified'] = $keepOldStatus ? $oldData[self::PROPERTY_EMAIL]['verified'] : self::VERIFICATION_IN_PROGRESS;
214 214
 		}
215 215
 
216 216
 		// reset verification status if a value from a previously verified data was changed
217
-		if($twitterVerified &&
217
+		if ($twitterVerified &&
218 218
 			$oldData[self::PROPERTY_TWITTER]['value'] !== $newData[self::PROPERTY_TWITTER]['value']
219 219
 		) {
220 220
 			$newData[self::PROPERTY_TWITTER]['verified'] = self::NOT_VERIFIED;
221 221
 		}
222 222
 
223
-		if($websiteVerified &&
223
+		if ($websiteVerified &&
224 224
 			$oldData[self::PROPERTY_WEBSITE]['value'] !== $newData[self::PROPERTY_WEBSITE]['value']
225 225
 		) {
226 226
 			$newData[self::PROPERTY_WEBSITE]['verified'] = self::NOT_VERIFIED;
227 227
 		}
228 228
 
229
-		if($emailVerified &&
229
+		if ($emailVerified &&
230 230
 			$oldData[self::PROPERTY_EMAIL]['value'] !== $newData[self::PROPERTY_EMAIL]['value']
231 231
 		) {
232 232
 			$newData[self::PROPERTY_EMAIL]['verified'] = self::NOT_VERIFIED;
Please login to merge, or discard this patch.
Indentation   +287 added lines, -287 removed lines patch added patch discarded remove patch
@@ -39,292 +39,292 @@
 block discarded – undo
39 39
  */
40 40
 class AccountManager {
41 41
 
42
-	/** nobody can see my account details */
43
-	const VISIBILITY_PRIVATE = 'private';
44
-	/** only contacts, especially trusted servers can see my contact details */
45
-	const VISIBILITY_CONTACTS_ONLY = 'contacts';
46
-	/** every body ca see my contact detail, will be published to the lookup server */
47
-	const VISIBILITY_PUBLIC = 'public';
48
-
49
-	const PROPERTY_AVATAR = 'avatar';
50
-	const PROPERTY_DISPLAYNAME = 'displayname';
51
-	const PROPERTY_PHONE = 'phone';
52
-	const PROPERTY_EMAIL = 'email';
53
-	const PROPERTY_WEBSITE = 'website';
54
-	const PROPERTY_ADDRESS = 'address';
55
-	const PROPERTY_TWITTER = 'twitter';
56
-
57
-	const NOT_VERIFIED = '0';
58
-	const VERIFICATION_IN_PROGRESS = '1';
59
-	const VERIFIED = '2';
60
-
61
-	/** @var  IDBConnection database connection */
62
-	private $connection;
63
-
64
-	/** @var string table name */
65
-	private $table = 'accounts';
66
-
67
-	/** @var EventDispatcherInterface */
68
-	private $eventDispatcher;
69
-
70
-	/** @var IJobList */
71
-	private $jobList;
72
-
73
-	/**
74
-	 * AccountManager constructor.
75
-	 *
76
-	 * @param IDBConnection $connection
77
-	 * @param EventDispatcherInterface $eventDispatcher
78
-	 * @param IJobList $jobList
79
-	 */
80
-	public function __construct(IDBConnection $connection,
81
-								EventDispatcherInterface $eventDispatcher,
82
-								IJobList $jobList) {
83
-		$this->connection = $connection;
84
-		$this->eventDispatcher = $eventDispatcher;
85
-		$this->jobList = $jobList;
86
-	}
87
-
88
-	/**
89
-	 * update user record
90
-	 *
91
-	 * @param IUser $user
92
-	 * @param $data
93
-	 */
94
-	public function updateUser(IUser $user, $data) {
95
-		$userData = $this->getUser($user);
96
-		$updated = true;
97
-		if (empty($userData)) {
98
-			$this->insertNewUser($user, $data);
99
-		} elseif ($userData !== $data) {
100
-			$data = $this->checkEmailVerification($userData, $data, $user);
101
-			$data = $this->updateVerifyStatus($userData, $data);
102
-			$this->updateExistingUser($user, $data);
103
-		} else {
104
-			// nothing needs to be done if new and old data set are the same
105
-			$updated = false;
106
-		}
107
-
108
-		if ($updated) {
109
-			$this->eventDispatcher->dispatch(
110
-				'OC\AccountManager::userUpdated',
111
-				new GenericEvent($user, $data)
112
-			);
113
-		}
114
-	}
115
-
116
-	/**
117
-	 * get stored data from a given user
118
-	 *
119
-	 * @param IUser $user
120
-	 * @return array
121
-	 */
122
-	public function getUser(IUser $user) {
123
-		$uid = $user->getUID();
124
-		$query = $this->connection->getQueryBuilder();
125
-		$query->select('data')->from($this->table)
126
-			->where($query->expr()->eq('uid', $query->createParameter('uid')))
127
-			->setParameter('uid', $uid);
128
-		$query->execute();
129
-		$result = $query->execute()->fetchAll();
130
-
131
-		if (empty($result)) {
132
-			$userData = $this->buildDefaultUserRecord($user);
133
-			$this->insertNewUser($user, $userData);
134
-			return $userData;
135
-		}
136
-
137
-		$userDataArray = json_decode($result[0]['data'], true);
138
-
139
-		$userDataArray = $this->addMissingDefaultValues($userDataArray);
140
-
141
-		return $userDataArray;
142
-	}
143
-
144
-	/**
145
-	 * check if we need to ask the server for email verification, if yes we create a cronjob
146
-	 *
147
-	 * @param $oldData
148
-	 * @param $newData
149
-	 * @param IUser $user
150
-	 * @return array
151
-	 */
152
-	protected function checkEmailVerification($oldData, $newData, IUser $user) {
153
-		if ($oldData[self::PROPERTY_EMAIL]['value'] !== $newData[self::PROPERTY_EMAIL]['value']) {
154
-			$this->jobList->add('OC\Settings\BackgroundJobs\VerifyUserData',
155
-				[
156
-					'verificationCode' => '',
157
-					'data' => $newData[self::PROPERTY_EMAIL]['value'],
158
-					'type' => self::PROPERTY_EMAIL,
159
-					'uid' => $user->getUID(),
160
-					'try' => 0,
161
-					'lastRun' => time()
162
-				]
163
-			);
164
-			$newData[AccountManager::PROPERTY_EMAIL]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
165
-		}
166
-
167
-		return $newData;
168
-	}
169
-
170
-	/**
171
-	 * make sure that all expected data are set
172
-	 *
173
-	 * @param array $userData
174
-	 * @return array
175
-	 */
176
-	protected function addMissingDefaultValues(array $userData) {
177
-
178
-		foreach ($userData as $key => $value) {
179
-			if (!isset($userData[$key]['verified'])) {
180
-				$userData[$key]['verified'] = self::NOT_VERIFIED;
181
-			}
182
-		}
183
-
184
-		return $userData;
185
-	}
186
-
187
-	/**
188
-	 * reset verification status if personal data changed
189
-	 *
190
-	 * @param array $oldData
191
-	 * @param array $newData
192
-	 * @return array
193
-	 */
194
-	protected function updateVerifyStatus($oldData, $newData) {
195
-
196
-		// which account was already verified successfully?
197
-		$twitterVerified = isset($oldData[self::PROPERTY_TWITTER]['verified']) && $oldData[self::PROPERTY_TWITTER]['verified'] === self::VERIFIED;
198
-		$websiteVerified = isset($oldData[self::PROPERTY_WEBSITE]['verified']) && $oldData[self::PROPERTY_WEBSITE]['verified'] === self::VERIFIED;
199
-		$emailVerified = isset($oldData[self::PROPERTY_EMAIL]['verified']) && $oldData[self::PROPERTY_EMAIL]['verified'] === self::VERIFIED;
200
-
201
-		// keep old verification status if we don't have a new one
202
-		if(!isset($newData[self::PROPERTY_TWITTER]['verified'])) {
203
-			// keep old verification status if value didn't changed and an old value exists
204
-			$keepOldStatus = $newData[self::PROPERTY_TWITTER]['value'] === $oldData[self::PROPERTY_TWITTER]['value'] && isset($oldData[self::PROPERTY_TWITTER]['verified']);
205
-			$newData[self::PROPERTY_TWITTER]['verified'] = $keepOldStatus ? $oldData[self::PROPERTY_TWITTER]['verified'] : self::NOT_VERIFIED;
206
-		}
207
-
208
-		if(!isset($newData[self::PROPERTY_WEBSITE]['verified'])) {
209
-			// keep old verification status if value didn't changed and an old value exists
210
-			$keepOldStatus = $newData[self::PROPERTY_WEBSITE]['value'] === $oldData[self::PROPERTY_WEBSITE]['value'] && isset($oldData[self::PROPERTY_WEBSITE]['verified']);
211
-			$newData[self::PROPERTY_WEBSITE]['verified'] = $keepOldStatus ? $oldData[self::PROPERTY_WEBSITE]['verified'] : self::NOT_VERIFIED;
212
-		}
213
-
214
-		if(!isset($newData[self::PROPERTY_EMAIL]['verified'])) {
215
-			// keep old verification status if value didn't changed and an old value exists
216
-			$keepOldStatus = $newData[self::PROPERTY_EMAIL]['value'] === $oldData[self::PROPERTY_EMAIL]['value'] && isset($oldData[self::PROPERTY_EMAIL]['verified']);
217
-			$newData[self::PROPERTY_EMAIL]['verified'] = $keepOldStatus ? $oldData[self::PROPERTY_EMAIL]['verified'] : self::VERIFICATION_IN_PROGRESS;
218
-		}
219
-
220
-		// reset verification status if a value from a previously verified data was changed
221
-		if($twitterVerified &&
222
-			$oldData[self::PROPERTY_TWITTER]['value'] !== $newData[self::PROPERTY_TWITTER]['value']
223
-		) {
224
-			$newData[self::PROPERTY_TWITTER]['verified'] = self::NOT_VERIFIED;
225
-		}
226
-
227
-		if($websiteVerified &&
228
-			$oldData[self::PROPERTY_WEBSITE]['value'] !== $newData[self::PROPERTY_WEBSITE]['value']
229
-		) {
230
-			$newData[self::PROPERTY_WEBSITE]['verified'] = self::NOT_VERIFIED;
231
-		}
232
-
233
-		if($emailVerified &&
234
-			$oldData[self::PROPERTY_EMAIL]['value'] !== $newData[self::PROPERTY_EMAIL]['value']
235
-		) {
236
-			$newData[self::PROPERTY_EMAIL]['verified'] = self::NOT_VERIFIED;
237
-		}
238
-
239
-		return $newData;
240
-
241
-	}
242
-
243
-	/**
244
-	 * add new user to accounts table
245
-	 *
246
-	 * @param IUser $user
247
-	 * @param array $data
248
-	 */
249
-	protected function insertNewUser(IUser $user, $data) {
250
-		$uid = $user->getUID();
251
-		$jsonEncodedData = json_encode($data);
252
-		$query = $this->connection->getQueryBuilder();
253
-		$query->insert($this->table)
254
-			->values(
255
-				[
256
-					'uid' => $query->createNamedParameter($uid),
257
-					'data' => $query->createNamedParameter($jsonEncodedData),
258
-				]
259
-			)
260
-			->execute();
261
-	}
262
-
263
-	/**
264
-	 * update existing user in accounts table
265
-	 *
266
-	 * @param IUser $user
267
-	 * @param array $data
268
-	 */
269
-	protected function updateExistingUser(IUser $user, $data) {
270
-		$uid = $user->getUID();
271
-		$jsonEncodedData = json_encode($data);
272
-		$query = $this->connection->getQueryBuilder();
273
-		$query->update($this->table)
274
-			->set('data', $query->createNamedParameter($jsonEncodedData))
275
-			->where($query->expr()->eq('uid', $query->createNamedParameter($uid)))
276
-			->execute();
277
-	}
278
-
279
-	/**
280
-	 * build default user record in case not data set exists yet
281
-	 *
282
-	 * @param IUser $user
283
-	 * @return array
284
-	 */
285
-	protected function buildDefaultUserRecord(IUser $user) {
286
-		return [
287
-			self::PROPERTY_DISPLAYNAME =>
288
-				[
289
-					'value' => $user->getDisplayName(),
290
-					'scope' => self::VISIBILITY_CONTACTS_ONLY,
291
-					'verified' => self::NOT_VERIFIED,
292
-				],
293
-			self::PROPERTY_ADDRESS =>
294
-				[
295
-					'value' => '',
296
-					'scope' => self::VISIBILITY_PRIVATE,
297
-					'verified' => self::NOT_VERIFIED,
298
-				],
299
-			self::PROPERTY_WEBSITE =>
300
-				[
301
-					'value' => '',
302
-					'scope' => self::VISIBILITY_PRIVATE,
303
-					'verified' => self::NOT_VERIFIED,
304
-				],
305
-			self::PROPERTY_EMAIL =>
306
-				[
307
-					'value' => $user->getEMailAddress(),
308
-					'scope' => self::VISIBILITY_CONTACTS_ONLY,
309
-					'verified' => self::NOT_VERIFIED,
310
-				],
311
-			self::PROPERTY_AVATAR =>
312
-				[
313
-					'scope' => self::VISIBILITY_CONTACTS_ONLY
314
-				],
315
-			self::PROPERTY_PHONE =>
316
-				[
317
-					'value' => '',
318
-					'scope' => self::VISIBILITY_PRIVATE,
319
-					'verified' => self::NOT_VERIFIED,
320
-				],
321
-			self::PROPERTY_TWITTER =>
322
-				[
323
-					'value' => '',
324
-					'scope' => self::VISIBILITY_PRIVATE,
325
-					'verified' => self::NOT_VERIFIED,
326
-				],
327
-		];
328
-	}
42
+    /** nobody can see my account details */
43
+    const VISIBILITY_PRIVATE = 'private';
44
+    /** only contacts, especially trusted servers can see my contact details */
45
+    const VISIBILITY_CONTACTS_ONLY = 'contacts';
46
+    /** every body ca see my contact detail, will be published to the lookup server */
47
+    const VISIBILITY_PUBLIC = 'public';
48
+
49
+    const PROPERTY_AVATAR = 'avatar';
50
+    const PROPERTY_DISPLAYNAME = 'displayname';
51
+    const PROPERTY_PHONE = 'phone';
52
+    const PROPERTY_EMAIL = 'email';
53
+    const PROPERTY_WEBSITE = 'website';
54
+    const PROPERTY_ADDRESS = 'address';
55
+    const PROPERTY_TWITTER = 'twitter';
56
+
57
+    const NOT_VERIFIED = '0';
58
+    const VERIFICATION_IN_PROGRESS = '1';
59
+    const VERIFIED = '2';
60
+
61
+    /** @var  IDBConnection database connection */
62
+    private $connection;
63
+
64
+    /** @var string table name */
65
+    private $table = 'accounts';
66
+
67
+    /** @var EventDispatcherInterface */
68
+    private $eventDispatcher;
69
+
70
+    /** @var IJobList */
71
+    private $jobList;
72
+
73
+    /**
74
+     * AccountManager constructor.
75
+     *
76
+     * @param IDBConnection $connection
77
+     * @param EventDispatcherInterface $eventDispatcher
78
+     * @param IJobList $jobList
79
+     */
80
+    public function __construct(IDBConnection $connection,
81
+                                EventDispatcherInterface $eventDispatcher,
82
+                                IJobList $jobList) {
83
+        $this->connection = $connection;
84
+        $this->eventDispatcher = $eventDispatcher;
85
+        $this->jobList = $jobList;
86
+    }
87
+
88
+    /**
89
+     * update user record
90
+     *
91
+     * @param IUser $user
92
+     * @param $data
93
+     */
94
+    public function updateUser(IUser $user, $data) {
95
+        $userData = $this->getUser($user);
96
+        $updated = true;
97
+        if (empty($userData)) {
98
+            $this->insertNewUser($user, $data);
99
+        } elseif ($userData !== $data) {
100
+            $data = $this->checkEmailVerification($userData, $data, $user);
101
+            $data = $this->updateVerifyStatus($userData, $data);
102
+            $this->updateExistingUser($user, $data);
103
+        } else {
104
+            // nothing needs to be done if new and old data set are the same
105
+            $updated = false;
106
+        }
107
+
108
+        if ($updated) {
109
+            $this->eventDispatcher->dispatch(
110
+                'OC\AccountManager::userUpdated',
111
+                new GenericEvent($user, $data)
112
+            );
113
+        }
114
+    }
115
+
116
+    /**
117
+     * get stored data from a given user
118
+     *
119
+     * @param IUser $user
120
+     * @return array
121
+     */
122
+    public function getUser(IUser $user) {
123
+        $uid = $user->getUID();
124
+        $query = $this->connection->getQueryBuilder();
125
+        $query->select('data')->from($this->table)
126
+            ->where($query->expr()->eq('uid', $query->createParameter('uid')))
127
+            ->setParameter('uid', $uid);
128
+        $query->execute();
129
+        $result = $query->execute()->fetchAll();
130
+
131
+        if (empty($result)) {
132
+            $userData = $this->buildDefaultUserRecord($user);
133
+            $this->insertNewUser($user, $userData);
134
+            return $userData;
135
+        }
136
+
137
+        $userDataArray = json_decode($result[0]['data'], true);
138
+
139
+        $userDataArray = $this->addMissingDefaultValues($userDataArray);
140
+
141
+        return $userDataArray;
142
+    }
143
+
144
+    /**
145
+     * check if we need to ask the server for email verification, if yes we create a cronjob
146
+     *
147
+     * @param $oldData
148
+     * @param $newData
149
+     * @param IUser $user
150
+     * @return array
151
+     */
152
+    protected function checkEmailVerification($oldData, $newData, IUser $user) {
153
+        if ($oldData[self::PROPERTY_EMAIL]['value'] !== $newData[self::PROPERTY_EMAIL]['value']) {
154
+            $this->jobList->add('OC\Settings\BackgroundJobs\VerifyUserData',
155
+                [
156
+                    'verificationCode' => '',
157
+                    'data' => $newData[self::PROPERTY_EMAIL]['value'],
158
+                    'type' => self::PROPERTY_EMAIL,
159
+                    'uid' => $user->getUID(),
160
+                    'try' => 0,
161
+                    'lastRun' => time()
162
+                ]
163
+            );
164
+            $newData[AccountManager::PROPERTY_EMAIL]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
165
+        }
166
+
167
+        return $newData;
168
+    }
169
+
170
+    /**
171
+     * make sure that all expected data are set
172
+     *
173
+     * @param array $userData
174
+     * @return array
175
+     */
176
+    protected function addMissingDefaultValues(array $userData) {
177
+
178
+        foreach ($userData as $key => $value) {
179
+            if (!isset($userData[$key]['verified'])) {
180
+                $userData[$key]['verified'] = self::NOT_VERIFIED;
181
+            }
182
+        }
183
+
184
+        return $userData;
185
+    }
186
+
187
+    /**
188
+     * reset verification status if personal data changed
189
+     *
190
+     * @param array $oldData
191
+     * @param array $newData
192
+     * @return array
193
+     */
194
+    protected function updateVerifyStatus($oldData, $newData) {
195
+
196
+        // which account was already verified successfully?
197
+        $twitterVerified = isset($oldData[self::PROPERTY_TWITTER]['verified']) && $oldData[self::PROPERTY_TWITTER]['verified'] === self::VERIFIED;
198
+        $websiteVerified = isset($oldData[self::PROPERTY_WEBSITE]['verified']) && $oldData[self::PROPERTY_WEBSITE]['verified'] === self::VERIFIED;
199
+        $emailVerified = isset($oldData[self::PROPERTY_EMAIL]['verified']) && $oldData[self::PROPERTY_EMAIL]['verified'] === self::VERIFIED;
200
+
201
+        // keep old verification status if we don't have a new one
202
+        if(!isset($newData[self::PROPERTY_TWITTER]['verified'])) {
203
+            // keep old verification status if value didn't changed and an old value exists
204
+            $keepOldStatus = $newData[self::PROPERTY_TWITTER]['value'] === $oldData[self::PROPERTY_TWITTER]['value'] && isset($oldData[self::PROPERTY_TWITTER]['verified']);
205
+            $newData[self::PROPERTY_TWITTER]['verified'] = $keepOldStatus ? $oldData[self::PROPERTY_TWITTER]['verified'] : self::NOT_VERIFIED;
206
+        }
207
+
208
+        if(!isset($newData[self::PROPERTY_WEBSITE]['verified'])) {
209
+            // keep old verification status if value didn't changed and an old value exists
210
+            $keepOldStatus = $newData[self::PROPERTY_WEBSITE]['value'] === $oldData[self::PROPERTY_WEBSITE]['value'] && isset($oldData[self::PROPERTY_WEBSITE]['verified']);
211
+            $newData[self::PROPERTY_WEBSITE]['verified'] = $keepOldStatus ? $oldData[self::PROPERTY_WEBSITE]['verified'] : self::NOT_VERIFIED;
212
+        }
213
+
214
+        if(!isset($newData[self::PROPERTY_EMAIL]['verified'])) {
215
+            // keep old verification status if value didn't changed and an old value exists
216
+            $keepOldStatus = $newData[self::PROPERTY_EMAIL]['value'] === $oldData[self::PROPERTY_EMAIL]['value'] && isset($oldData[self::PROPERTY_EMAIL]['verified']);
217
+            $newData[self::PROPERTY_EMAIL]['verified'] = $keepOldStatus ? $oldData[self::PROPERTY_EMAIL]['verified'] : self::VERIFICATION_IN_PROGRESS;
218
+        }
219
+
220
+        // reset verification status if a value from a previously verified data was changed
221
+        if($twitterVerified &&
222
+            $oldData[self::PROPERTY_TWITTER]['value'] !== $newData[self::PROPERTY_TWITTER]['value']
223
+        ) {
224
+            $newData[self::PROPERTY_TWITTER]['verified'] = self::NOT_VERIFIED;
225
+        }
226
+
227
+        if($websiteVerified &&
228
+            $oldData[self::PROPERTY_WEBSITE]['value'] !== $newData[self::PROPERTY_WEBSITE]['value']
229
+        ) {
230
+            $newData[self::PROPERTY_WEBSITE]['verified'] = self::NOT_VERIFIED;
231
+        }
232
+
233
+        if($emailVerified &&
234
+            $oldData[self::PROPERTY_EMAIL]['value'] !== $newData[self::PROPERTY_EMAIL]['value']
235
+        ) {
236
+            $newData[self::PROPERTY_EMAIL]['verified'] = self::NOT_VERIFIED;
237
+        }
238
+
239
+        return $newData;
240
+
241
+    }
242
+
243
+    /**
244
+     * add new user to accounts table
245
+     *
246
+     * @param IUser $user
247
+     * @param array $data
248
+     */
249
+    protected function insertNewUser(IUser $user, $data) {
250
+        $uid = $user->getUID();
251
+        $jsonEncodedData = json_encode($data);
252
+        $query = $this->connection->getQueryBuilder();
253
+        $query->insert($this->table)
254
+            ->values(
255
+                [
256
+                    'uid' => $query->createNamedParameter($uid),
257
+                    'data' => $query->createNamedParameter($jsonEncodedData),
258
+                ]
259
+            )
260
+            ->execute();
261
+    }
262
+
263
+    /**
264
+     * update existing user in accounts table
265
+     *
266
+     * @param IUser $user
267
+     * @param array $data
268
+     */
269
+    protected function updateExistingUser(IUser $user, $data) {
270
+        $uid = $user->getUID();
271
+        $jsonEncodedData = json_encode($data);
272
+        $query = $this->connection->getQueryBuilder();
273
+        $query->update($this->table)
274
+            ->set('data', $query->createNamedParameter($jsonEncodedData))
275
+            ->where($query->expr()->eq('uid', $query->createNamedParameter($uid)))
276
+            ->execute();
277
+    }
278
+
279
+    /**
280
+     * build default user record in case not data set exists yet
281
+     *
282
+     * @param IUser $user
283
+     * @return array
284
+     */
285
+    protected function buildDefaultUserRecord(IUser $user) {
286
+        return [
287
+            self::PROPERTY_DISPLAYNAME =>
288
+                [
289
+                    'value' => $user->getDisplayName(),
290
+                    'scope' => self::VISIBILITY_CONTACTS_ONLY,
291
+                    'verified' => self::NOT_VERIFIED,
292
+                ],
293
+            self::PROPERTY_ADDRESS =>
294
+                [
295
+                    'value' => '',
296
+                    'scope' => self::VISIBILITY_PRIVATE,
297
+                    'verified' => self::NOT_VERIFIED,
298
+                ],
299
+            self::PROPERTY_WEBSITE =>
300
+                [
301
+                    'value' => '',
302
+                    'scope' => self::VISIBILITY_PRIVATE,
303
+                    'verified' => self::NOT_VERIFIED,
304
+                ],
305
+            self::PROPERTY_EMAIL =>
306
+                [
307
+                    'value' => $user->getEMailAddress(),
308
+                    'scope' => self::VISIBILITY_CONTACTS_ONLY,
309
+                    'verified' => self::NOT_VERIFIED,
310
+                ],
311
+            self::PROPERTY_AVATAR =>
312
+                [
313
+                    'scope' => self::VISIBILITY_CONTACTS_ONLY
314
+                ],
315
+            self::PROPERTY_PHONE =>
316
+                [
317
+                    'value' => '',
318
+                    'scope' => self::VISIBILITY_PRIVATE,
319
+                    'verified' => self::NOT_VERIFIED,
320
+                ],
321
+            self::PROPERTY_TWITTER =>
322
+                [
323
+                    'value' => '',
324
+                    'scope' => self::VISIBILITY_PRIVATE,
325
+                    'verified' => self::NOT_VERIFIED,
326
+                ],
327
+        ];
328
+    }
329 329
 
330 330
 }
Please login to merge, or discard this patch.
settings/personal.php 2 patches
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@  discard block
 block discarded – undo
57 57
 OC_Util::addScript('settings', 'federationscopemenu');
58 58
 OC_Util::addScript('settings', 'personal');
59 59
 OC_Util::addScript('settings', 'certificates');
60
-OC_Util::addStyle( 'settings', 'settings' );
60
+OC_Util::addStyle('settings', 'settings');
61 61
 \OC_Util::addVendorScript('strengthify/jquery.strengthify');
62 62
 \OC_Util::addVendorStyle('strengthify/strengthify');
63 63
 \OC_Util::addScript('files', 'jquery.fileupload');
@@ -69,11 +69,11 @@  discard block
 block discarded – undo
69 69
 // Highlight navigation entry
70 70
 OC::$server->getNavigationManager()->setActiveEntry('personal');
71 71
 
72
-$storageInfo=OC_Helper::getStorageInfo('/');
72
+$storageInfo = OC_Helper::getStorageInfo('/');
73 73
 
74 74
 $user = OC::$server->getUserManager()->get(OC_User::getUser());
75 75
 
76
-$userLang=$config->getUserValue( OC_User::getUser(), 'core', 'lang', \OC::$server->getL10NFactory()->findLanguage() );
76
+$userLang = $config->getUserValue(OC_User::getUser(), 'core', 'lang', \OC::$server->getL10NFactory()->findLanguage());
77 77
 $languageCodes = \OC::$server->getL10NFactory()->findAvailableLanguages();
78 78
 
79 79
 // array of common languages
@@ -81,18 +81,18 @@  discard block
 block discarded – undo
81 81
 	'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it', 'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko'
82 82
 );
83 83
 
84
-$languages=array();
84
+$languages = array();
85 85
 $commonLanguages = array();
86
-foreach($languageCodes as $lang) {
86
+foreach ($languageCodes as $lang) {
87 87
 	$l = \OC::$server->getL10N('settings', $lang);
88 88
 	// TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
89 89
 	$potentialName = (string) $l->t('__language_name__');
90
-	if($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file
90
+	if ($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file
91 91
 		$ln = array('code' => $lang, 'name' => $potentialName);
92 92
 	} elseif ($lang === 'en') {
93 93
 		$ln = ['code' => $lang, 'name' => 'English (US)'];
94
-	}else{//fallback to language code
95
-		$ln=array('code'=>$lang, 'name'=>$lang);
94
+	} else {//fallback to language code
95
+		$ln = array('code'=>$lang, 'name'=>$lang);
96 96
 	}
97 97
 
98 98
 	// put appropriate languages into appropriate arrays, to print them sorted
@@ -100,9 +100,9 @@  discard block
 block discarded – undo
100 100
 	if ($lang === $userLang) {
101 101
 		$userLang = $ln;
102 102
 	} elseif (in_array($lang, $commonLangCodes)) {
103
-		$commonLanguages[array_search($lang, $commonLangCodes)]=$ln;
103
+		$commonLanguages[array_search($lang, $commonLangCodes)] = $ln;
104 104
 	} else {
105
-		$languages[]=$ln;
105
+		$languages[] = $ln;
106 106
 	}
107 107
 }
108 108
 
@@ -117,7 +117,7 @@  discard block
 block discarded – undo
117 117
 ksort($commonLanguages);
118 118
 
119 119
 // sort now by displayed language not the iso-code
120
-usort( $languages, function ($a, $b) {
120
+usort($languages, function($a, $b) {
121 121
 	if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) {
122 122
 		// If a doesn't have a name, but b does, list b before a
123 123
 		return 1;
@@ -149,7 +149,7 @@  discard block
 block discarded – undo
149 149
 
150 150
 // Return template
151 151
 $l = \OC::$server->getL10N('settings');
152
-$tmpl = new OC_Template( 'settings', 'personal', 'user');
152
+$tmpl = new OC_Template('settings', 'personal', 'user');
153 153
 $tmpl->assign('usage', OC_Helper::humanFileSize($storageInfo['used']));
154 154
 if ($storageInfo['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED) {
155 155
 	$totalSpace = $l->t('Unlimited');
@@ -204,7 +204,7 @@  discard block
 block discarded – undo
204 204
 			$message = $l->t('Verify');
205 205
 	}
206 206
 
207
-	$tmpl->assign($property . 'Message', $message);
207
+	$tmpl->assign($property.'Message', $message);
208 208
 }
209 209
 
210 210
 $tmpl->assign('avatarChangeSupported', OC_User::canUserChangeAvatar(OC_User::getUser()));
@@ -224,12 +224,12 @@  discard block
 block discarded – undo
224 224
 
225 225
 // add hardcoded forms from the template
226 226
 $formsAndMore = [];
227
-$formsAndMore[]= ['anchor' => 'personal-settings', 'section-name' => $l->t('Personal info')];
228
-$formsAndMore[]= ['anchor' => 'sessions', 'section-name' => $l->t('Sessions')];
229
-$formsAndMore[]= ['anchor' => 'apppasswords', 'section-name' => $l->t('App passwords')];
230
-$formsAndMore[]= ['anchor' => 'clientsbox', 'section-name' => $l->t('Sync clients')];
227
+$formsAndMore[] = ['anchor' => 'personal-settings', 'section-name' => $l->t('Personal info')];
228
+$formsAndMore[] = ['anchor' => 'sessions', 'section-name' => $l->t('Sessions')];
229
+$formsAndMore[] = ['anchor' => 'apppasswords', 'section-name' => $l->t('App passwords')];
230
+$formsAndMore[] = ['anchor' => 'clientsbox', 'section-name' => $l->t('Sync clients')];
231 231
 
232
-$forms=OC_App::getForms('personal');
232
+$forms = OC_App::getForms('personal');
233 233
 
234 234
 
235 235
 // add bottom hardcoded forms from the template
@@ -242,7 +242,7 @@  discard block
 block discarded – undo
242 242
 	$forms[] = $certificatesTemplate->fetchPage();
243 243
 }
244 244
 
245
-$formsMap = array_map(function($form){
245
+$formsMap = array_map(function($form) {
246 246
 	if (preg_match('%(<h2(?P<class>[^>]*)>.*?</h2>)%i', $form, $regs)) {
247 247
 		$sectionName = str_replace('<h2'.$regs['class'].'>', '', $regs[0]);
248 248
 		$sectionName = str_replace('</h2>', '', $sectionName);
Please login to merge, or discard this patch.
Indentation   +84 added lines, -84 removed lines patch added patch discarded remove patch
@@ -41,9 +41,9 @@  discard block
 block discarded – undo
41 41
 $defaults = \OC::$server->getThemingDefaults();
42 42
 $certificateManager = \OC::$server->getCertificateManager();
43 43
 $accountManager = new \OC\Accounts\AccountManager(
44
-	\OC::$server->getDatabaseConnection(),
45
-	\OC::$server->getEventDispatcher(),
46
-	\OC::$server->getJobList()
44
+    \OC::$server->getDatabaseConnection(),
45
+    \OC::$server->getEventDispatcher(),
46
+    \OC::$server->getJobList()
47 47
 );
48 48
 $config = \OC::$server->getConfig();
49 49
 $urlGenerator = \OC::$server->getURLGenerator();
@@ -78,72 +78,72 @@  discard block
 block discarded – undo
78 78
 
79 79
 // array of common languages
80 80
 $commonLangCodes = array(
81
-	'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it', 'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko'
81
+    'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it', 'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko'
82 82
 );
83 83
 
84 84
 $languages=array();
85 85
 $commonLanguages = array();
86 86
 foreach($languageCodes as $lang) {
87
-	$l = \OC::$server->getL10N('settings', $lang);
88
-	// TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
89
-	$potentialName = (string) $l->t('__language_name__');
90
-	if($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file
91
-		$ln = array('code' => $lang, 'name' => $potentialName);
92
-	} elseif ($lang === 'en') {
93
-		$ln = ['code' => $lang, 'name' => 'English (US)'];
94
-	}else{//fallback to language code
95
-		$ln=array('code'=>$lang, 'name'=>$lang);
96
-	}
97
-
98
-	// put appropriate languages into appropriate arrays, to print them sorted
99
-	// used language -> common languages -> divider -> other languages
100
-	if ($lang === $userLang) {
101
-		$userLang = $ln;
102
-	} elseif (in_array($lang, $commonLangCodes)) {
103
-		$commonLanguages[array_search($lang, $commonLangCodes)]=$ln;
104
-	} else {
105
-		$languages[]=$ln;
106
-	}
87
+    $l = \OC::$server->getL10N('settings', $lang);
88
+    // TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
89
+    $potentialName = (string) $l->t('__language_name__');
90
+    if($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file
91
+        $ln = array('code' => $lang, 'name' => $potentialName);
92
+    } elseif ($lang === 'en') {
93
+        $ln = ['code' => $lang, 'name' => 'English (US)'];
94
+    }else{//fallback to language code
95
+        $ln=array('code'=>$lang, 'name'=>$lang);
96
+    }
97
+
98
+    // put appropriate languages into appropriate arrays, to print them sorted
99
+    // used language -> common languages -> divider -> other languages
100
+    if ($lang === $userLang) {
101
+        $userLang = $ln;
102
+    } elseif (in_array($lang, $commonLangCodes)) {
103
+        $commonLanguages[array_search($lang, $commonLangCodes)]=$ln;
104
+    } else {
105
+        $languages[]=$ln;
106
+    }
107 107
 }
108 108
 
109 109
 // if user language is not available but set somehow: show the actual code as name
110 110
 if (!is_array($userLang)) {
111
-	$userLang = [
112
-		'code' => $userLang,
113
-		'name' => $userLang,
114
-	];
111
+    $userLang = [
112
+        'code' => $userLang,
113
+        'name' => $userLang,
114
+    ];
115 115
 }
116 116
 
117 117
 ksort($commonLanguages);
118 118
 
119 119
 // sort now by displayed language not the iso-code
120 120
 usort( $languages, function ($a, $b) {
121
-	if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) {
122
-		// If a doesn't have a name, but b does, list b before a
123
-		return 1;
124
-	}
125
-	if ($a['code'] !== $a['name'] && $b['code'] === $b['name']) {
126
-		// If a does have a name, but b doesn't, list a before b
127
-		return -1;
128
-	}
129
-	// Otherwise compare the names
130
-	return strcmp($a['name'], $b['name']);
121
+    if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) {
122
+        // If a doesn't have a name, but b does, list b before a
123
+        return 1;
124
+    }
125
+    if ($a['code'] !== $a['name'] && $b['code'] === $b['name']) {
126
+        // If a does have a name, but b doesn't, list a before b
127
+        return -1;
128
+    }
129
+    // Otherwise compare the names
130
+    return strcmp($a['name'], $b['name']);
131 131
 });
132 132
 
133 133
 //links to clients
134 134
 $clients = array(
135
-	'desktop' => $config->getSystemValue('customclient_desktop', $defaults->getSyncClientUrl()),
136
-	'android' => $config->getSystemValue('customclient_android', $defaults->getAndroidClientUrl()),
137
-	'ios'     => $config->getSystemValue('customclient_ios', $defaults->getiOSClientUrl())
135
+    'desktop' => $config->getSystemValue('customclient_desktop', $defaults->getSyncClientUrl()),
136
+    'android' => $config->getSystemValue('customclient_android', $defaults->getAndroidClientUrl()),
137
+    'ios'     => $config->getSystemValue('customclient_ios', $defaults->getiOSClientUrl())
138 138
 );
139 139
 
140 140
 // only show root certificate import if external storages are enabled
141 141
 $enableCertImport = false;
142 142
 $externalStorageEnabled = \OC::$server->getAppManager()->isEnabledForUser('files_external');
143 143
 if ($externalStorageEnabled) {
144
-	/** @var \OCA\Files_External\Service\BackendService $backendService */
145
-	$backendService = \OC_Mount_Config::$app->getContainer()->query('\OCA\Files_External\Service\BackendService');
146
-	$enableCertImport = $backendService->isUserMountingAllowed();
144
+    /** @var \OCA\Files_External\Service\BackendService $backendService */
145
+    $backendService = \OC_Mount_Config::$app->getContainer()->query('\OCA\Files_External\Service\BackendService');
146
+    $enableCertImport = $backendService->isUserMountingAllowed();
147 147
 }
148 148
 
149 149
 
@@ -152,9 +152,9 @@  discard block
 block discarded – undo
152 152
 $tmpl = new OC_Template( 'settings', 'personal', 'user');
153 153
 $tmpl->assign('usage', OC_Helper::humanFileSize($storageInfo['used']));
154 154
 if ($storageInfo['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED) {
155
-	$totalSpace = $l->t('Unlimited');
155
+    $totalSpace = $l->t('Unlimited');
156 156
 } else {
157
-	$totalSpace = OC_Helper::humanFileSize($storageInfo['total']);
157
+    $totalSpace = OC_Helper::humanFileSize($storageInfo['total']);
158 158
 }
159 159
 
160 160
 $uid = $user->getUID();
@@ -193,18 +193,18 @@  discard block
 block discarded – undo
193 193
 
194 194
 foreach ($needVerifyMessage as $property) {
195 195
 
196
-	switch ($userData[$property]['verified']) {
197
-		case \OC\Accounts\AccountManager::VERIFIED:
198
-			$message = $l->t('Verifying');
199
-			break;
200
-		case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
201
-			$message = $l->t('Verifying …');
202
-			break;
203
-		default:
204
-			$message = $l->t('Verify');
205
-	}
206
-
207
-	$tmpl->assign($property . 'Message', $message);
196
+    switch ($userData[$property]['verified']) {
197
+        case \OC\Accounts\AccountManager::VERIFIED:
198
+            $message = $l->t('Verifying');
199
+            break;
200
+        case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
201
+            $message = $l->t('Verifying …');
202
+            break;
203
+        default:
204
+            $message = $l->t('Verify');
205
+    }
206
+
207
+    $tmpl->assign($property . 'Message', $message);
208 208
 }
209 209
 
210 210
 $tmpl->assign('avatarChangeSupported', OC_User::canUserChangeAvatar(OC_User::getUser()));
@@ -234,35 +234,35 @@  discard block
 block discarded – undo
234 234
 
235 235
 // add bottom hardcoded forms from the template
236 236
 if ($enableCertImport) {
237
-	$certificatesTemplate = new OC_Template('settings', 'certificates');
238
-	$certificatesTemplate->assign('type', 'personal');
239
-	$certificatesTemplate->assign('uploadRoute', 'settings.Certificate.addPersonalRootCertificate');
240
-	$certificatesTemplate->assign('certs', $certificateManager->listCertificates());
241
-	$certificatesTemplate->assign('urlGenerator', $urlGenerator);
242
-	$forms[] = $certificatesTemplate->fetchPage();
237
+    $certificatesTemplate = new OC_Template('settings', 'certificates');
238
+    $certificatesTemplate->assign('type', 'personal');
239
+    $certificatesTemplate->assign('uploadRoute', 'settings.Certificate.addPersonalRootCertificate');
240
+    $certificatesTemplate->assign('certs', $certificateManager->listCertificates());
241
+    $certificatesTemplate->assign('urlGenerator', $urlGenerator);
242
+    $forms[] = $certificatesTemplate->fetchPage();
243 243
 }
244 244
 
245 245
 $formsMap = array_map(function($form){
246
-	if (preg_match('%(<h2(?P<class>[^>]*)>.*?</h2>)%i', $form, $regs)) {
247
-		$sectionName = str_replace('<h2'.$regs['class'].'>', '', $regs[0]);
248
-		$sectionName = str_replace('</h2>', '', $sectionName);
249
-		if (strpos($regs['class'], 'data-anchor-name') !== false) {
250
-			preg_match('%.*data-anchor-name="(?P<anchor>[^"]*)"%i', $regs['class'], $matches);
251
-			$anchor = $matches['anchor'];
252
-		} else {
253
-			$anchor = strtolower($sectionName);
254
-			$anchor = str_replace(' ', '-', $anchor);
255
-		}
256
-
257
-		return array(
258
-			'anchor' => $anchor,
259
-			'section-name' => $sectionName,
260
-			'form' => $form
261
-		);
262
-	}
263
-	return array(
264
-		'form' => $form
265
-	);
246
+    if (preg_match('%(<h2(?P<class>[^>]*)>.*?</h2>)%i', $form, $regs)) {
247
+        $sectionName = str_replace('<h2'.$regs['class'].'>', '', $regs[0]);
248
+        $sectionName = str_replace('</h2>', '', $sectionName);
249
+        if (strpos($regs['class'], 'data-anchor-name') !== false) {
250
+            preg_match('%.*data-anchor-name="(?P<anchor>[^"]*)"%i', $regs['class'], $matches);
251
+            $anchor = $matches['anchor'];
252
+        } else {
253
+            $anchor = strtolower($sectionName);
254
+            $anchor = str_replace(' ', '-', $anchor);
255
+        }
256
+
257
+        return array(
258
+            'anchor' => $anchor,
259
+            'section-name' => $sectionName,
260
+            'form' => $form
261
+        );
262
+    }
263
+    return array(
264
+        'form' => $form
265
+    );
266 266
 }, $forms);
267 267
 
268 268
 $formsAndMore = array_merge($formsAndMore, $formsMap);
Please login to merge, or discard this patch.
apps/lookup_server_connector/lib/BackgroundJobs/RetryJob.php 2 patches
Indentation   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -29,61 +29,61 @@
 block discarded – undo
29 29
 use OCP\ILogger;
30 30
 
31 31
 class RetryJob extends Job {
32
-	/** @var IClientService */
33
-	private $clientService;
34
-	/** @var IJobList */
35
-	private $jobList;
36
-	/** @var string */
37
-	private $lookupServer = 'https://lookup.nextcloud.com/users';
32
+    /** @var IClientService */
33
+    private $clientService;
34
+    /** @var IJobList */
35
+    private $jobList;
36
+    /** @var string */
37
+    private $lookupServer = 'https://lookup.nextcloud.com/users';
38 38
 
39
-	/**
40
-	 * @param IClientService $clientService
41
-	 * @param IJobList $jobList
42
-	 */
43
-	public function __construct(IClientService $clientService,
44
-								IJobList $jobList) {
45
-		$this->clientService = $clientService;
46
-		$this->jobList = $jobList;
47
-	}
39
+    /**
40
+     * @param IClientService $clientService
41
+     * @param IJobList $jobList
42
+     */
43
+    public function __construct(IClientService $clientService,
44
+                                IJobList $jobList) {
45
+        $this->clientService = $clientService;
46
+        $this->jobList = $jobList;
47
+    }
48 48
 
49
-	/**
50
-	 * run the job, then remove it from the jobList
51
-	 *
52
-	 * @param JobList $jobList
53
-	 * @param ILogger $logger
54
-	 */
55
-	public function execute($jobList, ILogger $logger = null) {
49
+    /**
50
+     * run the job, then remove it from the jobList
51
+     *
52
+     * @param JobList $jobList
53
+     * @param ILogger $logger
54
+     */
55
+    public function execute($jobList, ILogger $logger = null) {
56 56
 
57
-		if ($this->shouldRun($this->argument)) {
58
-			parent::execute($jobList, $logger);
59
-			$jobList->remove($this, $this->argument);
60
-		}
57
+        if ($this->shouldRun($this->argument)) {
58
+            parent::execute($jobList, $logger);
59
+            $jobList->remove($this, $this->argument);
60
+        }
61 61
 
62
-	}
62
+    }
63 63
 
64
-	protected function run($argument) {
65
-		if($argument['retryNo'] === 5) {
66
-			return;
67
-		}
64
+    protected function run($argument) {
65
+        if($argument['retryNo'] === 5) {
66
+            return;
67
+        }
68 68
 
69
-		$client = $this->clientService->newClient();
69
+        $client = $this->clientService->newClient();
70 70
 
71
-		try {
72
-			$client->post($this->lookupServer,
73
-				[
74
-					'body' => json_encode($argument['dataArray']),
75
-					'timeout' => 10,
76
-					'connect_timeout' => 3,
77
-				]
78
-			);
79
-		} catch (\Exception $e) {
80
-			$this->jobList->add(RetryJob::class,
81
-				[
82
-					'dataArray' => $argument['dataArray'],
83
-					'retryNo' => $argument['retryNo'] + 1,
84
-				]
85
-			);
71
+        try {
72
+            $client->post($this->lookupServer,
73
+                [
74
+                    'body' => json_encode($argument['dataArray']),
75
+                    'timeout' => 10,
76
+                    'connect_timeout' => 3,
77
+                ]
78
+            );
79
+        } catch (\Exception $e) {
80
+            $this->jobList->add(RetryJob::class,
81
+                [
82
+                    'dataArray' => $argument['dataArray'],
83
+                    'retryNo' => $argument['retryNo'] + 1,
84
+                ]
85
+            );
86 86
 
87
-		}
88
-	}
87
+        }
88
+    }
89 89
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -62,7 +62,7 @@
 block discarded – undo
62 62
 	}
63 63
 
64 64
 	protected function run($argument) {
65
-		if($argument['retryNo'] === 5) {
65
+		if ($argument['retryNo'] === 5) {
66 66
 			return;
67 67
 		}
68 68
 
Please login to merge, or discard this patch.
settings/templates/personal.php 3 patches
Indentation   +54 added lines, -54 removed lines patch added patch discarded remove patch
@@ -11,14 +11,14 @@  discard block
 block discarded – undo
11 11
 <div id="app-navigation">
12 12
 	<ul class="with-icon">
13 13
 	<?php foreach($_['forms'] as $form) {
14
-		if (isset($form['anchor'])) {
15
-			$anchor = '#' . $form['anchor'];
16
-			$class = 'nav-icon-' . $form['anchor'];
17
-			$sectionName = $form['section-name'];
18
-			print_unescaped(sprintf("<li><a href='%s' class='%s'>%s</a></li>", \OCP\Util::sanitizeHTML($anchor),
19
-			\OCP\Util::sanitizeHTML($class), \OCP\Util::sanitizeHTML($sectionName)));
20
-		}
21
-	}?>
14
+        if (isset($form['anchor'])) {
15
+            $anchor = '#' . $form['anchor'];
16
+            $class = 'nav-icon-' . $form['anchor'];
17
+            $sectionName = $form['section-name'];
18
+            print_unescaped(sprintf("<li><a href='%s' class='%s'>%s</a></li>", \OCP\Util::sanitizeHTML($anchor),
19
+            \OCP\Util::sanitizeHTML($class), \OCP\Util::sanitizeHTML($sectionName)));
20
+        }
21
+    }?>
22 22
 	</ul>
23 23
 </div>
24 24
 
@@ -30,10 +30,10 @@  discard block
 block discarded – undo
30 30
 		<p id="quotatext">
31 31
 			<?php if ($_['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED): ?>
32 32
 				<?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong>',
33
-					[$_['usage'], $_['total_space']]));?>
33
+                    [$_['usage'], $_['total_space']]));?>
34 34
 			<?php else: ?>
35 35
 				<?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong> (<strong>%s %%</strong>)',
36
-					[$_['usage'], $_['total_space'],  $_['usage_relative']]));?>
36
+                    [$_['usage'], $_['total_space'],  $_['usage_relative']]));?>
37 37
 			<?php endif ?>
38 38
 		</p>
39 39
 	</div>
@@ -102,17 +102,17 @@  discard block
 block discarded – undo
102 102
 			<div class="verify <?php if ($_['email'] === ''  || $_['emailScope'] !== 'public') p('hidden'); ?>">
103 103
 				<img id="verify-email" title="<?php p($_['emailMessage']); ?>" data-status="<?php p($_['emailVerification']) ?>" src="
104 104
 				<?php
105
-				switch($_['emailVerification']) {
106
-					case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
107
-						p(image_path('core', 'actions/verifying.svg'));
108
-						break;
109
-					case \OC\Accounts\AccountManager::VERIFIED:
110
-						p(image_path('core', 'actions/verified.svg'));
111
-						break;
112
-					default:
113
-						p(image_path('core', 'actions/verify.svg'));
114
-				}
115
-				?>">
105
+                switch($_['emailVerification']) {
106
+                    case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
107
+                        p(image_path('core', 'actions/verifying.svg'));
108
+                        break;
109
+                    case \OC\Accounts\AccountManager::VERIFIED:
110
+                        p(image_path('core', 'actions/verified.svg'));
111
+                        break;
112
+                    default:
113
+                        p(image_path('core', 'actions/verify.svg'));
114
+                }
115
+                ?>">
116 116
 			</div>
117 117
 			<input type="email" name="email" id="email" value="<?php p($_['email']); ?>"
118 118
 				<?php if(!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
@@ -169,17 +169,17 @@  discard block
 block discarded – undo
169 169
 			<div class="verify <?php if ($_['website'] === ''  || $_['websiteScope'] !== 'public') p('hidden'); ?>">
170 170
 				<img id="verify-website" title="<?php p($_['websiteMessage']); ?>" data-status="<?php p($_['websiteVerification']) ?>" src="
171 171
 				<?php
172
-				switch($_['websiteVerification']) {
173
-					case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
174
-						p(image_path('core', 'actions/verifying.svg'));
175
-						break;
176
-					case \OC\Accounts\AccountManager::VERIFIED:
177
-						p(image_path('core', 'actions/verified.svg'));
178
-						break;
179
-					default:
180
-						p(image_path('core', 'actions/verify.svg'));
181
-				}
182
-				?>"
172
+                switch($_['websiteVerification']) {
173
+                    case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
174
+                        p(image_path('core', 'actions/verifying.svg'));
175
+                        break;
176
+                    case \OC\Accounts\AccountManager::VERIFIED:
177
+                        p(image_path('core', 'actions/verified.svg'));
178
+                        break;
179
+                    default:
180
+                        p(image_path('core', 'actions/verify.svg'));
181
+                }
182
+                ?>"
183 183
 				<?php if($_['websiteVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['websiteVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
184 184
 				>
185 185
 				<div class="verification-dialog popovermenu bubble menu">
@@ -206,17 +206,17 @@  discard block
 block discarded – undo
206 206
 			<div class="verify <?php if ($_['twitter'] === ''  || $_['twitterScope'] !== 'public') p('hidden'); ?>">
207 207
 				<img id="verify-twitter" title="<?php p($_['twitterMessage']); ?>" data-status="<?php p($_['twitterVerification']) ?>" src="
208 208
 				<?php
209
-				switch($_['twitterVerification']) {
210
-					case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
211
-						p(image_path('core', 'actions/verifying.svg'));
212
-						break;
213
-					case \OC\Accounts\AccountManager::VERIFIED:
214
-						p(image_path('core', 'actions/verified.svg'));
215
-						break;
216
-					default:
217
-						p(image_path('core', 'actions/verify.svg'));
218
-				}
219
-				?>"
209
+                switch($_['twitterVerification']) {
210
+                    case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
211
+                        p(image_path('core', 'actions/verifying.svg'));
212
+                        break;
213
+                    case \OC\Accounts\AccountManager::VERIFIED:
214
+                        p(image_path('core', 'actions/verified.svg'));
215
+                        break;
216
+                    default:
217
+                        p(image_path('core', 'actions/verify.svg'));
218
+                }
219
+                ?>"
220 220
 				<?php if($_['twitterVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['twitterVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
221 221
 				>
222 222
 				<div class="verification-dialog popovermenu bubble menu">
@@ -249,7 +249,7 @@  discard block
 block discarded – undo
249 249
 
250 250
 <?php
251 251
 if($_['passwordChangeSupported']) {
252
-	script('jquery-showpassword');
252
+    script('jquery-showpassword');
253 253
 ?>
254 254
 <form id="passwordform" class="section">
255 255
 	<h2 class="inlineblock"><?php p($l->t('Password'));?></h2>
@@ -318,15 +318,15 @@  discard block
 block discarded – undo
318 318
 
319 319
 		<p>
320 320
 			<?php print_unescaped(str_replace(
321
-				[
322
-					'{contributeopen}',
323
-					'{linkclose}',
324
-				],
325
-				[
326
-					'<a href="https://nextcloud.com/contribute" target="_blank" rel="noreferrer">',
327
-					'</a>',
328
-				],
329
-				$l->t('If you want to support the project {contributeopen}join development{linkclose} or {contributeopen}spread the word{linkclose}!'))); ?>
321
+                [
322
+                    '{contributeopen}',
323
+                    '{linkclose}',
324
+                ],
325
+                [
326
+                    '<a href="https://nextcloud.com/contribute" target="_blank" rel="noreferrer">',
327
+                    '</a>',
328
+                ],
329
+                $l->t('If you want to support the project {contributeopen}join development{linkclose} or {contributeopen}spread the word{linkclose}!'))); ?>
330 330
 		</p>
331 331
 
332 332
 	<?php if(OC_APP::isEnabled('firstrunwizard')) {?>
@@ -387,7 +387,7 @@  discard block
 block discarded – undo
387 387
 </div>
388 388
 
389 389
 <?php foreach($_['forms'] as $form) {
390
-	if (isset($form['form'])) {?>
390
+    if (isset($form['form'])) {?>
391 391
 	<div id="<?php isset($form['anchor']) ? p($form['anchor']) : p('');?>"><?php print_unescaped($form['form']);?></div>
392 392
 	<?php }
393 393
 };?>
Please login to merge, or discard this patch.
Braces   +32 added lines, -11 removed lines patch added patch discarded remove patch
@@ -31,9 +31,12 @@  discard block
 block discarded – undo
31 31
 			<?php if ($_['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED): ?>
32 32
 				<?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong>',
33 33
 					[$_['usage'], $_['total_space']]));?>
34
-			<?php else: ?>
34
+			<?php else {
35
+    : ?>
35 36
 				<?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong> (<strong>%s %%</strong>)',
36
-					[$_['usage'], $_['total_space'],  $_['usage_relative']]));?>
37
+					[$_['usage'], $_['total_space'],  $_['usage_relative']]));
38
+}
39
+?>
37 40
 			<?php endif ?>
38 41
 		</p>
39 42
 	</div>
@@ -55,8 +58,11 @@  discard block
 block discarded – undo
55 58
 				<div class="hidden button icon-delete svg" id="removeavatar" title="<?php p($l->t('Remove image')); ?>"></div>
56 59
 				<input type="file" name="files[]" id="uploadavatar" class="hiddenuploadfield">
57 60
 				<p><em><?php p($l->t('png or jpg, max. 20 MB')); ?></em></p>
58
-			<?php else: ?>
59
-				<?php p($l->t('Picture provided by original account')); ?>
61
+			<?php else {
62
+    : ?>
63
+				<?php p($l->t('Picture provided by original account'));
64
+}
65
+?>
60 66
 			<?php endif; ?>
61 67
 		</div>
62 68
 
@@ -99,7 +105,10 @@  discard block
 block discarded – undo
99 105
 				<label for="email"><?php p($l->t('Email')); ?></label>
100 106
 				<span class="icon-password"/>
101 107
 			</h2>
102
-			<div class="verify <?php if ($_['email'] === ''  || $_['emailScope'] !== 'public') p('hidden'); ?>">
108
+			<div class="verify <?php if ($_['email'] === ''  || $_['emailScope'] !== 'public') {
109
+    p('hidden');
110
+}
111
+?>">
103 112
 				<img id="verify-email" title="<?php p($_['emailMessage']); ?>" data-status="<?php p($_['emailVerification']) ?>" src="
104 113
 				<?php
105 114
 				switch($_['emailVerification']) {
@@ -166,7 +175,10 @@  discard block
 block discarded – undo
166 175
 				<label for="website"><?php p($l->t('Website')); ?></label>
167 176
 				<span class="icon-password"/>
168 177
 			</h2>
169
-			<div class="verify <?php if ($_['website'] === ''  || $_['websiteScope'] !== 'public') p('hidden'); ?>">
178
+			<div class="verify <?php if ($_['website'] === ''  || $_['websiteScope'] !== 'public') {
179
+    p('hidden');
180
+}
181
+?>">
170 182
 				<img id="verify-website" title="<?php p($_['websiteMessage']); ?>" data-status="<?php p($_['websiteVerification']) ?>" src="
171 183
 				<?php
172 184
 				switch($_['websiteVerification']) {
@@ -180,13 +192,16 @@  discard block
 block discarded – undo
180 192
 						p(image_path('core', 'actions/verify.svg'));
181 193
 				}
182 194
 				?>"
183
-				<?php if($_['websiteVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['websiteVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
195
+				<?php if($_['websiteVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['websiteVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) {
196
+    print_unescaped(' class="verify-action"') ?>
184 197
 				>
185 198
 				<div class="verification-dialog popovermenu bubble menu">
186 199
 					<div class="verification-dialog-content">
187 200
 						<p class="explainVerification"></p>
188 201
 						<p class="verificationCode"></p>
189
-						<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.'));?></p>
202
+						<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.'));
203
+}
204
+?></p>
190 205
 					</div>
191 206
 				</div>
192 207
 			</div>
@@ -203,7 +218,10 @@  discard block
 block discarded – undo
203 218
 				<label for="twitter"><?php p($l->t('Twitter')); ?></label>
204 219
 				<span class="icon-password"/>
205 220
 			</h2>
206
-			<div class="verify <?php if ($_['twitter'] === ''  || $_['twitterScope'] !== 'public') p('hidden'); ?>">
221
+			<div class="verify <?php if ($_['twitter'] === ''  || $_['twitterScope'] !== 'public') {
222
+    p('hidden');
223
+}
224
+?>">
207 225
 				<img id="verify-twitter" title="<?php p($_['twitterMessage']); ?>" data-status="<?php p($_['twitterVerification']) ?>" src="
208 226
 				<?php
209 227
 				switch($_['twitterVerification']) {
@@ -217,13 +235,16 @@  discard block
 block discarded – undo
217 235
 						p(image_path('core', 'actions/verify.svg'));
218 236
 				}
219 237
 				?>"
220
-				<?php if($_['twitterVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['twitterVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
238
+				<?php if($_['twitterVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['twitterVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) {
239
+    print_unescaped(' class="verify-action"') ?>
221 240
 				>
222 241
 				<div class="verification-dialog popovermenu bubble menu">
223 242
 					<div class="verification-dialog-content">
224 243
 						<p class="explainVerification"></p>
225 244
 						<p class="verificationCode"></p>
226
-						<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.'));?></p>
245
+						<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.'));
246
+}
247
+?></p>
227 248
 					</div>
228 249
 				</div>
229 250
 			</div>
Please login to merge, or discard this patch.
Spacing   +62 added lines, -62 removed lines patch added patch discarded remove patch
@@ -10,10 +10,10 @@  discard block
 block discarded – undo
10 10
 
11 11
 <div id="app-navigation">
12 12
 	<ul class="with-icon">
13
-	<?php foreach($_['forms'] as $form) {
13
+	<?php foreach ($_['forms'] as $form) {
14 14
 		if (isset($form['anchor'])) {
15
-			$anchor = '#' . $form['anchor'];
16
-			$class = 'nav-icon-' . $form['anchor'];
15
+			$anchor = '#'.$form['anchor'];
16
+			$class = 'nav-icon-'.$form['anchor'];
17 17
 			$sectionName = $form['section-name'];
18 18
 			print_unescaped(sprintf("<li><a href='%s' class='%s'>%s</a></li>", \OCP\Util::sanitizeHTML($anchor),
19 19
 			\OCP\Util::sanitizeHTML($class), \OCP\Util::sanitizeHTML($sectionName)));
@@ -25,15 +25,15 @@  discard block
 block discarded – undo
25 25
 <div id="app-content">
26 26
 
27 27
 <div id="quota" class="section">
28
-	<div style="width:<?php p($_['usage_relative']);?>%"
29
-		<?php if($_['usage_relative'] > 80): ?> class="quota-warning" <?php endif; ?>>
28
+	<div style="width:<?php p($_['usage_relative']); ?>%"
29
+		<?php if ($_['usage_relative'] > 80): ?> class="quota-warning" <?php endif; ?>>
30 30
 		<p id="quotatext">
31 31
 			<?php if ($_['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED): ?>
32 32
 				<?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong>',
33
-					[$_['usage'], $_['total_space']]));?>
33
+					[$_['usage'], $_['total_space']])); ?>
34 34
 			<?php else: ?>
35 35
 				<?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong> (<strong>%s %%</strong>)',
36
-					[$_['usage'], $_['total_space'],  $_['usage_relative']]));?>
36
+					[$_['usage'], $_['total_space'], $_['usage_relative']])); ?>
37 37
 			<?php endif ?>
38 38
 		</p>
39 39
 	</div>
@@ -67,7 +67,7 @@  discard block
 block discarded – undo
67 67
 			</div>
68 68
 		</div>
69 69
 		<span class="icon-checkmark hidden"/>
70
-		<?php if($_['lookupServerUploadEnabled']) { ?>
70
+		<?php if ($_['lookupServerUploadEnabled']) { ?>
71 71
 		<input type="hidden" id="avatarscope" value="<?php p($_['avatarScope']) ?>">
72 72
 		<?php } ?>
73 73
 	</form>
@@ -81,14 +81,14 @@  discard block
 block discarded – undo
81 81
 				<span class="icon-password"/>
82 82
 			</h2>
83 83
 			<input type="text" id="displayname" name="displayname"
84
-				<?php if(!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
84
+				<?php if (!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
85 85
 				value="<?php p($_['displayName']) ?>"
86 86
 				autocomplete="on" autocapitalize="none" autocorrect="off" />
87
-			<?php if(!$_['displayNameChangeSupported']) { ?>
88
-				<span><?php if(isset($_['displayName']) && !empty($_['displayName'])) { p($_['displayName']); } else { p($l->t('No display name set')); } ?></span>
87
+			<?php if (!$_['displayNameChangeSupported']) { ?>
88
+				<span><?php if (isset($_['displayName']) && !empty($_['displayName'])) { p($_['displayName']); } else { p($l->t('No display name set')); } ?></span>
89 89
 			<?php } ?>
90 90
 			<span class="icon-checkmark hidden"/>
91
-			<?php if($_['lookupServerUploadEnabled']) { ?>
91
+			<?php if ($_['lookupServerUploadEnabled']) { ?>
92 92
 			<input type="hidden" id="displaynamescope" value="<?php p($_['displayNameScope']) ?>">
93 93
 			<?php } ?>
94 94
 		</form>
@@ -99,10 +99,10 @@  discard block
 block discarded – undo
99 99
 				<label for="email"><?php p($l->t('Email')); ?></label>
100 100
 				<span class="icon-password"/>
101 101
 			</h2>
102
-			<div class="verify <?php if ($_['email'] === ''  || $_['emailScope'] !== 'public') p('hidden'); ?>">
102
+			<div class="verify <?php if ($_['email'] === '' || $_['emailScope'] !== 'public') p('hidden'); ?>">
103 103
 				<img id="verify-email" title="<?php p($_['emailMessage']); ?>" data-status="<?php p($_['emailVerification']) ?>" src="
104 104
 				<?php
105
-				switch($_['emailVerification']) {
105
+				switch ($_['emailVerification']) {
106 106
 					case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
107 107
 						p(image_path('core', 'actions/verifying.svg'));
108 108
 						break;
@@ -115,23 +115,23 @@  discard block
 block discarded – undo
115 115
 				?>">
116 116
 			</div>
117 117
 			<input type="email" name="email" id="email" value="<?php p($_['email']); ?>"
118
-				<?php if(!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
118
+				<?php if (!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
119 119
 				placeholder="<?php p($l->t('Your email address')); ?>"
120 120
 				autocomplete="on" autocapitalize="none" autocorrect="off" />
121
-			<?php if(!$_['displayNameChangeSupported']) { ?>
122
-				<span><?php if(isset($_['email']) && !empty($_['email'])) { p($_['email']); } else { p($l->t('No email address set')); }?></span>
121
+			<?php if (!$_['displayNameChangeSupported']) { ?>
122
+				<span><?php if (isset($_['email']) && !empty($_['email'])) { p($_['email']); } else { p($l->t('No email address set')); }?></span>
123 123
 			<?php } ?>
124
-			<?php if($_['displayNameChangeSupported']) { ?>
124
+			<?php if ($_['displayNameChangeSupported']) { ?>
125 125
 				<br />
126 126
 				<em><?php p($l->t('For password reset and notifications')); ?></em>
127 127
 			<?php } ?>
128 128
 			<span class="icon-checkmark hidden"/>
129
-			<?php if($_['lookupServerUploadEnabled']) { ?>
129
+			<?php if ($_['lookupServerUploadEnabled']) { ?>
130 130
 			<input type="hidden" id="emailscope" value="<?php p($_['emailScope']) ?>">
131 131
 			<?php } ?>
132 132
 		</form>
133 133
 	</div>
134
-	<?php if($_['lookupServerUploadEnabled']) { ?>
134
+	<?php if ($_['lookupServerUploadEnabled']) { ?>
135 135
 	<div class="personal-settings-setting-box">
136 136
 		<form id="phoneform" class="section">
137 137
 			<h2>
@@ -166,10 +166,10 @@  discard block
 block discarded – undo
166 166
 				<label for="website"><?php p($l->t('Website')); ?></label>
167 167
 				<span class="icon-password"/>
168 168
 			</h2>
169
-			<div class="verify <?php if ($_['website'] === ''  || $_['websiteScope'] !== 'public') p('hidden'); ?>">
169
+			<div class="verify <?php if ($_['website'] === '' || $_['websiteScope'] !== 'public') p('hidden'); ?>">
170 170
 				<img id="verify-website" title="<?php p($_['websiteMessage']); ?>" data-status="<?php p($_['websiteVerification']) ?>" src="
171 171
 				<?php
172
-				switch($_['websiteVerification']) {
172
+				switch ($_['websiteVerification']) {
173 173
 					case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
174 174
 						p(image_path('core', 'actions/verifying.svg'));
175 175
 						break;
@@ -180,13 +180,13 @@  discard block
 block discarded – undo
180 180
 						p(image_path('core', 'actions/verify.svg'));
181 181
 				}
182 182
 				?>"
183
-				<?php if($_['websiteVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['websiteVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
183
+				<?php if ($_['websiteVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['websiteVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
184 184
 				>
185 185
 				<div class="verification-dialog popovermenu bubble menu">
186 186
 					<div class="verification-dialog-content">
187 187
 						<p class="explainVerification"></p>
188 188
 						<p class="verificationCode"></p>
189
-						<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.'));?></p>
189
+						<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.')); ?></p>
190 190
 					</div>
191 191
 				</div>
192 192
 			</div>
@@ -203,10 +203,10 @@  discard block
 block discarded – undo
203 203
 				<label for="twitter"><?php p($l->t('Twitter')); ?></label>
204 204
 				<span class="icon-password"/>
205 205
 			</h2>
206
-			<div class="verify <?php if ($_['twitter'] === ''  || $_['twitterScope'] !== 'public') p('hidden'); ?>">
206
+			<div class="verify <?php if ($_['twitter'] === '' || $_['twitterScope'] !== 'public') p('hidden'); ?>">
207 207
 				<img id="verify-twitter" title="<?php p($_['twitterMessage']); ?>" data-status="<?php p($_['twitterVerification']) ?>" src="
208 208
 				<?php
209
-				switch($_['twitterVerification']) {
209
+				switch ($_['twitterVerification']) {
210 210
 					case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
211 211
 						p(image_path('core', 'actions/verifying.svg'));
212 212
 						break;
@@ -217,13 +217,13 @@  discard block
 block discarded – undo
217 217
 						p(image_path('core', 'actions/verify.svg'));
218 218
 				}
219 219
 				?>"
220
-				<?php if($_['twitterVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['twitterVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
220
+				<?php if ($_['twitterVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['twitterVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
221 221
 				>
222 222
 				<div class="verification-dialog popovermenu bubble menu">
223 223
 					<div class="verification-dialog-content">
224 224
 						<p class="explainVerification"></p>
225 225
 						<p class="verificationCode"></p>
226
-						<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.'));?></p>
226
+						<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.')); ?></p>
227 227
 					</div>
228 228
 				</div>
229 229
 			</div>
@@ -248,19 +248,19 @@  discard block
 block discarded – undo
248 248
 </div>
249 249
 
250 250
 <?php
251
-if($_['passwordChangeSupported']) {
251
+if ($_['passwordChangeSupported']) {
252 252
 	script('jquery-showpassword');
253 253
 ?>
254 254
 <form id="passwordform" class="section">
255
-	<h2 class="inlineblock"><?php p($l->t('Password'));?></h2>
255
+	<h2 class="inlineblock"><?php p($l->t('Password')); ?></h2>
256 256
 	<div id="password-error-msg" class="msg success inlineblock" style="display: none;">Saved</div>
257 257
 	<br>
258 258
 	<label for="pass1" class="hidden-visually"><?php p($l->t('Current password')); ?>: </label>
259 259
 	<input type="password" id="pass1" name="oldpassword"
260
-		placeholder="<?php p($l->t('Current password'));?>"
260
+		placeholder="<?php p($l->t('Current password')); ?>"
261 261
 		autocomplete="off" autocapitalize="none" autocorrect="off" />
262 262
 	<div class="personal-show-container">
263
-		<label for="pass2" class="hidden-visually"><?php p($l->t('New password'));?>: </label>
263
+		<label for="pass2" class="hidden-visually"><?php p($l->t('New password')); ?>: </label>
264 264
 		<input type="password" id="pass2" name="newpassword"
265 265
 			placeholder="<?php p($l->t('New password')); ?>"
266 266
 			data-typetoggle="#personal-show"
@@ -276,44 +276,44 @@  discard block
 block discarded – undo
276 276
 
277 277
 <form id="language" class="section">
278 278
 	<h2>
279
-		<label for="languageinput"><?php p($l->t('Language'));?></label>
279
+		<label for="languageinput"><?php p($l->t('Language')); ?></label>
280 280
 	</h2>
281
-	<select id="languageinput" name="lang" data-placeholder="<?php p($l->t('Language'));?>">
282
-		<option value="<?php p($_['activelanguage']['code']);?>">
283
-			<?php p($_['activelanguage']['name']);?>
281
+	<select id="languageinput" name="lang" data-placeholder="<?php p($l->t('Language')); ?>">
282
+		<option value="<?php p($_['activelanguage']['code']); ?>">
283
+			<?php p($_['activelanguage']['name']); ?>
284 284
 		</option>
285
-		<?php foreach($_['commonlanguages'] as $language):?>
286
-			<option value="<?php p($language['code']);?>">
287
-				<?php p($language['name']);?>
285
+		<?php foreach ($_['commonlanguages'] as $language):?>
286
+			<option value="<?php p($language['code']); ?>">
287
+				<?php p($language['name']); ?>
288 288
 			</option>
289
-		<?php endforeach;?>
289
+		<?php endforeach; ?>
290 290
 		<optgroup label="––––––––––"></optgroup>
291
-		<?php foreach($_['languages'] as $language):?>
292
-			<option value="<?php p($language['code']);?>">
293
-				<?php p($language['name']);?>
291
+		<?php foreach ($_['languages'] as $language):?>
292
+			<option value="<?php p($language['code']); ?>">
293
+				<?php p($language['name']); ?>
294 294
 			</option>
295
-		<?php endforeach;?>
295
+		<?php endforeach; ?>
296 296
 	</select>
297 297
 	<a href="https://www.transifex.com/nextcloud/nextcloud/"
298 298
 		target="_blank" rel="noreferrer">
299
-		<em><?php p($l->t('Help translate'));?></em>
299
+		<em><?php p($l->t('Help translate')); ?></em>
300 300
 	</a>
301 301
 </form>
302 302
 
303 303
 
304 304
 <div id="clientsbox" class="section clientsbox">
305
-	<h2><?php p($l->t('Get the apps to sync your files'));?></h2>
305
+	<h2><?php p($l->t('Get the apps to sync your files')); ?></h2>
306 306
 	<a href="<?php p($_['clients']['desktop']); ?>" rel="noreferrer" target="_blank">
307 307
 		<img src="<?php print_unescaped(image_path('core', 'desktopapp.svg')); ?>"
308
-			 alt="<?php p($l->t('Desktop client'));?>" />
308
+			 alt="<?php p($l->t('Desktop client')); ?>" />
309 309
 	</a>
310 310
 	<a href="<?php p($_['clients']['android']); ?>" rel="noreferrer" target="_blank">
311 311
 		<img src="<?php print_unescaped(image_path('core', 'googleplay.png')); ?>"
312
-			 alt="<?php p($l->t('Android app'));?>" />
312
+			 alt="<?php p($l->t('Android app')); ?>" />
313 313
 	</a>
314 314
 	<a href="<?php p($_['clients']['ios']); ?>" rel="noreferrer" target="_blank">
315 315
 		<img src="<?php print_unescaped(image_path('core', 'appstore.svg')); ?>"
316
-			 alt="<?php p($l->t('iOS app'));?>" />
316
+			 alt="<?php p($l->t('iOS app')); ?>" />
317 317
 	</a>
318 318
 
319 319
 		<p>
@@ -329,19 +329,19 @@  discard block
 block discarded – undo
329 329
 				$l->t('If you want to support the project {contributeopen}join development{linkclose} or {contributeopen}spread the word{linkclose}!'))); ?>
330 330
 		</p>
331 331
 
332
-	<?php if(OC_APP::isEnabled('firstrunwizard')) {?>
333
-		<p><a class="button" href="#" id="showWizard"><?php p($l->t('Show First Run Wizard again'));?></a></p>
332
+	<?php if (OC_APP::isEnabled('firstrunwizard')) {?>
333
+		<p><a class="button" href="#" id="showWizard"><?php p($l->t('Show First Run Wizard again')); ?></a></p>
334 334
 	<?php }?>
335 335
 </div>
336 336
 
337 337
 <div id="sessions" class="section">
338
-	<h2><?php p($l->t('Sessions'));?></h2>
339
-	<p class="settings-hint hidden-when-empty"><?php p($l->t('Web, desktop and mobile clients currently logged in to your account.'));?></p>
338
+	<h2><?php p($l->t('Sessions')); ?></h2>
339
+	<p class="settings-hint hidden-when-empty"><?php p($l->t('Web, desktop and mobile clients currently logged in to your account.')); ?></p>
340 340
 	<table class="icon-loading">
341 341
 		<thead class="token-list-header">
342 342
 			<tr>
343
-				<th><?php p($l->t('Device'));?></th>
344
-				<th><?php p($l->t('Last activity'));?></th>
343
+				<th><?php p($l->t('Device')); ?></th>
344
+				<th><?php p($l->t('Last activity')); ?></th>
345 345
 				<th></th>
346 346
 			</tr>
347 347
 		</thead>
@@ -351,13 +351,13 @@  discard block
 block discarded – undo
351 351
 </div>
352 352
 
353 353
 <div id="apppasswords" class="section">
354
-	<h2><?php p($l->t('App passwords'));?></h2>
355
-	<p class="settings-hint"><?php p($l->t('Here you can generate individual passwords for apps so you don’t have to give out your password. You can revoke them individually too.'));?></p>
354
+	<h2><?php p($l->t('App passwords')); ?></h2>
355
+	<p class="settings-hint"><?php p($l->t('Here you can generate individual passwords for apps so you don’t have to give out your password. You can revoke them individually too.')); ?></p>
356 356
 	<table class="icon-loading">
357 357
 		<thead class="hidden-when-empty">
358 358
 			<tr>
359
-				<th><?php p($l->t('Name'));?></th>
360
-				<th><?php p($l->t('Last activity'));?></th>
359
+				<th><?php p($l->t('Name')); ?></th>
360
+				<th><?php p($l->t('Last activity')); ?></th>
361 361
 				<th></th>
362 362
 			</tr>
363 363
 		</thead>
@@ -386,14 +386,14 @@  discard block
 block discarded – undo
386 386
 	</div>
387 387
 </div>
388 388
 
389
-<?php foreach($_['forms'] as $form) {
389
+<?php foreach ($_['forms'] as $form) {
390 390
 	if (isset($form['form'])) {?>
391
-	<div id="<?php isset($form['anchor']) ? p($form['anchor']) : p('');?>"><?php print_unescaped($form['form']);?></div>
391
+	<div id="<?php isset($form['anchor']) ? p($form['anchor']) : p(''); ?>"><?php print_unescaped($form['form']); ?></div>
392 392
 	<?php }
393 393
 };?>
394 394
 
395 395
 <div class="section">
396
-	<h2><?php p($l->t('Version'));?></h2>
396
+	<h2><?php p($l->t('Version')); ?></h2>
397 397
 	<p><a href="<?php print_unescaped($theme->getBaseUrl()); ?>" target="_blank"><?php p($theme->getTitle()); ?></a> <?php p(OC_Util::getHumanVersion()) ?></p>
398 398
 	<p><?php include('settings.development.notice.php'); ?></p>
399 399
 </div>
Please login to merge, or discard this patch.