Passed
Push — master ( c2dddf...46e6c4 )
by Joas
14:48 queued 13s
created
lib/private/User/User.php 1 patch
Indentation   +507 added lines, -507 removed lines patch added patch discarded remove patch
@@ -57,511 +57,511 @@
 block discarded – undo
57 57
 use Symfony\Component\EventDispatcher\GenericEvent;
58 58
 
59 59
 class User implements IUser {
60
-	/** @var IAccountManager */
61
-	protected $accountManager;
62
-	/** @var string */
63
-	private $uid;
64
-
65
-	/** @var string|null */
66
-	private $displayName;
67
-
68
-	/** @var UserInterface|null */
69
-	private $backend;
70
-	/** @var EventDispatcherInterface */
71
-	private $legacyDispatcher;
72
-
73
-	/** @var IEventDispatcher */
74
-	private $dispatcher;
75
-
76
-	/** @var bool|null */
77
-	private $enabled;
78
-
79
-	/** @var Emitter|Manager */
80
-	private $emitter;
81
-
82
-	/** @var string */
83
-	private $home;
84
-
85
-	/** @var int|null */
86
-	private $lastLogin;
87
-
88
-	/** @var \OCP\IConfig */
89
-	private $config;
90
-
91
-	/** @var IAvatarManager */
92
-	private $avatarManager;
93
-
94
-	/** @var IURLGenerator */
95
-	private $urlGenerator;
96
-
97
-	public function __construct(string $uid, ?UserInterface $backend, EventDispatcherInterface $dispatcher, $emitter = null, IConfig $config = null, $urlGenerator = null) {
98
-		$this->uid = $uid;
99
-		$this->backend = $backend;
100
-		$this->legacyDispatcher = $dispatcher;
101
-		$this->emitter = $emitter;
102
-		if (is_null($config)) {
103
-			$config = \OC::$server->getConfig();
104
-		}
105
-		$this->config = $config;
106
-		$this->urlGenerator = $urlGenerator;
107
-		if (is_null($this->urlGenerator)) {
108
-			$this->urlGenerator = \OC::$server->getURLGenerator();
109
-		}
110
-		// TODO: inject
111
-		$this->dispatcher = \OC::$server->query(IEventDispatcher::class);
112
-	}
113
-
114
-	/**
115
-	 * get the user id
116
-	 *
117
-	 * @return string
118
-	 */
119
-	public function getUID() {
120
-		return $this->uid;
121
-	}
122
-
123
-	/**
124
-	 * get the display name for the user, if no specific display name is set it will fallback to the user id
125
-	 *
126
-	 * @return string
127
-	 */
128
-	public function getDisplayName() {
129
-		if ($this->displayName === null) {
130
-			$displayName = '';
131
-			if ($this->backend && $this->backend->implementsActions(Backend::GET_DISPLAYNAME)) {
132
-				// get display name and strip whitespace from the beginning and end of it
133
-				$backendDisplayName = $this->backend->getDisplayName($this->uid);
134
-				if (is_string($backendDisplayName)) {
135
-					$displayName = trim($backendDisplayName);
136
-				}
137
-			}
138
-
139
-			if (!empty($displayName)) {
140
-				$this->displayName = $displayName;
141
-			} else {
142
-				$this->displayName = $this->uid;
143
-			}
144
-		}
145
-		return $this->displayName;
146
-	}
147
-
148
-	/**
149
-	 * set the displayname for the user
150
-	 *
151
-	 * @param string $displayName
152
-	 * @return bool
153
-	 */
154
-	public function setDisplayName($displayName) {
155
-		$displayName = trim($displayName);
156
-		$oldDisplayName = $this->getDisplayName();
157
-		if ($this->backend->implementsActions(Backend::SET_DISPLAYNAME) && !empty($displayName) && $displayName !== $oldDisplayName) {
158
-			$result = $this->backend->setDisplayName($this->uid, $displayName);
159
-			if ($result) {
160
-				$this->displayName = $displayName;
161
-				$this->triggerChange('displayName', $displayName, $oldDisplayName);
162
-			}
163
-			return $result !== false;
164
-		}
165
-		return false;
166
-	}
167
-
168
-	/**
169
-	 * @inheritDoc
170
-	 */
171
-	public function setEMailAddress($mailAddress) {
172
-		$this->setSystemEMailAddress($mailAddress);
173
-	}
174
-
175
-	/**
176
-	 * @inheritDoc
177
-	 */
178
-	public function setSystemEMailAddress(string $mailAddress): void {
179
-		$oldMailAddress = $this->getSystemEMailAddress();
180
-
181
-		if ($mailAddress === '') {
182
-			$this->config->deleteUserValue($this->uid, 'settings', 'email');
183
-		} else {
184
-			$this->config->setUserValue($this->uid, 'settings', 'email', $mailAddress);
185
-		}
186
-
187
-		$primaryAddress = $this->getPrimaryEMailAddress();
188
-		if ($primaryAddress === $mailAddress) {
189
-			// on match no dedicated primary settings is necessary
190
-			$this->setPrimaryEMailAddress('');
191
-		}
192
-
193
-		if ($oldMailAddress !== $mailAddress) {
194
-			$this->triggerChange('eMailAddress', $mailAddress, $oldMailAddress);
195
-		}
196
-	}
197
-
198
-	/**
199
-	 * @inheritDoc
200
-	 */
201
-	public function setPrimaryEMailAddress(string $mailAddress): void {
202
-		if ($mailAddress === '') {
203
-			$this->config->deleteUserValue($this->uid, 'settings', 'primary_email');
204
-			return;
205
-		}
206
-
207
-		$this->ensureAccountManager();
208
-		$account = $this->accountManager->getAccount($this);
209
-		$property = $account->getPropertyCollection(IAccountManager::COLLECTION_EMAIL)
210
-			->getPropertyByValue($mailAddress);
211
-
212
-		if ($property === null || $property->getLocallyVerified() !== IAccountManager::VERIFIED) {
213
-			throw new InvalidArgumentException('Only verified emails can be set as primary');
214
-		}
215
-		$this->config->setUserValue($this->uid, 'settings', 'primary_email', $mailAddress);
216
-	}
217
-
218
-	private function ensureAccountManager() {
219
-		if (!$this->accountManager instanceof IAccountManager) {
220
-			$this->accountManager = \OC::$server->get(IAccountManager::class);
221
-		}
222
-	}
223
-
224
-	/**
225
-	 * returns the timestamp of the user's last login or 0 if the user did never
226
-	 * login
227
-	 *
228
-	 * @return int
229
-	 */
230
-	public function getLastLogin() {
231
-		if ($this->lastLogin === null) {
232
-			$this->lastLogin = (int) $this->config->getUserValue($this->uid, 'login', 'lastLogin', 0);
233
-		}
234
-		return (int) $this->lastLogin;
235
-	}
236
-
237
-	/**
238
-	 * updates the timestamp of the most recent login of this user
239
-	 */
240
-	public function updateLastLoginTimestamp() {
241
-		$firstTimeLogin = ($this->getLastLogin() === 0);
242
-		$this->lastLogin = time();
243
-		$this->config->setUserValue(
244
-			$this->uid, 'login', 'lastLogin', $this->lastLogin);
245
-
246
-		return $firstTimeLogin;
247
-	}
248
-
249
-	/**
250
-	 * Delete the user
251
-	 *
252
-	 * @return bool
253
-	 */
254
-	public function delete() {
255
-		/** @deprecated 21.0.0 use BeforeUserDeletedEvent event with the IEventDispatcher instead */
256
-		$this->legacyDispatcher->dispatch(IUser::class . '::preDelete', new GenericEvent($this));
257
-		if ($this->emitter) {
258
-			/** @deprecated 21.0.0 use BeforeUserDeletedEvent event with the IEventDispatcher instead */
259
-			$this->emitter->emit('\OC\User', 'preDelete', [$this]);
260
-		}
261
-		$this->dispatcher->dispatchTyped(new BeforeUserDeletedEvent($this));
262
-		$result = $this->backend->deleteUser($this->uid);
263
-		if ($result) {
264
-
265
-			// FIXME: Feels like an hack - suggestions?
266
-
267
-			$groupManager = \OC::$server->getGroupManager();
268
-			// We have to delete the user from all groups
269
-			foreach ($groupManager->getUserGroupIds($this) as $groupId) {
270
-				$group = $groupManager->get($groupId);
271
-				if ($group) {
272
-					$this->dispatcher->dispatchTyped(new BeforeUserRemovedEvent($group, $this));
273
-					$group->removeUser($this);
274
-					$this->dispatcher->dispatchTyped(new UserRemovedEvent($group, $this));
275
-				}
276
-			}
277
-			// Delete the user's keys in preferences
278
-			\OC::$server->getConfig()->deleteAllUserValues($this->uid);
279
-
280
-			\OC::$server->getCommentsManager()->deleteReferencesOfActor('users', $this->uid);
281
-			\OC::$server->getCommentsManager()->deleteReadMarksFromUser($this);
282
-
283
-			/** @var IAvatarManager $avatarManager */
284
-			$avatarManager = \OC::$server->query(AvatarManager::class);
285
-			$avatarManager->deleteUserAvatar($this->uid);
286
-
287
-			$notification = \OC::$server->getNotificationManager()->createNotification();
288
-			$notification->setUser($this->uid);
289
-			\OC::$server->getNotificationManager()->markProcessed($notification);
290
-
291
-			/** @var AccountManager $accountManager */
292
-			$accountManager = \OC::$server->query(AccountManager::class);
293
-			$accountManager->deleteUser($this);
294
-
295
-			/** @deprecated 21.0.0 use UserDeletedEvent event with the IEventDispatcher instead */
296
-			$this->legacyDispatcher->dispatch(IUser::class . '::postDelete', new GenericEvent($this));
297
-			if ($this->emitter) {
298
-				/** @deprecated 21.0.0 use UserDeletedEvent event with the IEventDispatcher instead */
299
-				$this->emitter->emit('\OC\User', 'postDelete', [$this]);
300
-			}
301
-			$this->dispatcher->dispatchTyped(new UserDeletedEvent($this));
302
-		}
303
-		return !($result === false);
304
-	}
305
-
306
-	/**
307
-	 * Set the password of the user
308
-	 *
309
-	 * @param string $password
310
-	 * @param string $recoveryPassword for the encryption app to reset encryption keys
311
-	 * @return bool
312
-	 */
313
-	public function setPassword($password, $recoveryPassword = null) {
314
-		$this->legacyDispatcher->dispatch(IUser::class . '::preSetPassword', new GenericEvent($this, [
315
-			'password' => $password,
316
-			'recoveryPassword' => $recoveryPassword,
317
-		]));
318
-		if ($this->emitter) {
319
-			$this->emitter->emit('\OC\User', 'preSetPassword', [$this, $password, $recoveryPassword]);
320
-		}
321
-		if ($this->backend->implementsActions(Backend::SET_PASSWORD)) {
322
-			$result = $this->backend->setPassword($this->uid, $password);
323
-			$this->legacyDispatcher->dispatch(IUser::class . '::postSetPassword', new GenericEvent($this, [
324
-				'password' => $password,
325
-				'recoveryPassword' => $recoveryPassword,
326
-			]));
327
-			if ($this->emitter) {
328
-				$this->emitter->emit('\OC\User', 'postSetPassword', [$this, $password, $recoveryPassword]);
329
-			}
330
-			return !($result === false);
331
-		} else {
332
-			return false;
333
-		}
334
-	}
335
-
336
-	/**
337
-	 * get the users home folder to mount
338
-	 *
339
-	 * @return string
340
-	 */
341
-	public function getHome() {
342
-		if (!$this->home) {
343
-			if ($this->backend->implementsActions(Backend::GET_HOME) and $home = $this->backend->getHome($this->uid)) {
344
-				$this->home = $home;
345
-			} elseif ($this->config) {
346
-				$this->home = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $this->uid;
347
-			} else {
348
-				$this->home = \OC::$SERVERROOT . '/data/' . $this->uid;
349
-			}
350
-		}
351
-		return $this->home;
352
-	}
353
-
354
-	/**
355
-	 * Get the name of the backend class the user is connected with
356
-	 *
357
-	 * @return string
358
-	 */
359
-	public function getBackendClassName() {
360
-		if ($this->backend instanceof IUserBackend) {
361
-			return $this->backend->getBackendName();
362
-		}
363
-		return get_class($this->backend);
364
-	}
365
-
366
-	public function getBackend() {
367
-		return $this->backend;
368
-	}
369
-
370
-	/**
371
-	 * check if the backend allows the user to change his avatar on Personal page
372
-	 *
373
-	 * @return bool
374
-	 */
375
-	public function canChangeAvatar() {
376
-		if ($this->backend->implementsActions(Backend::PROVIDE_AVATAR)) {
377
-			return $this->backend->canChangeAvatar($this->uid);
378
-		}
379
-		return true;
380
-	}
381
-
382
-	/**
383
-	 * check if the backend supports changing passwords
384
-	 *
385
-	 * @return bool
386
-	 */
387
-	public function canChangePassword() {
388
-		return $this->backend->implementsActions(Backend::SET_PASSWORD);
389
-	}
390
-
391
-	/**
392
-	 * check if the backend supports changing display names
393
-	 *
394
-	 * @return bool
395
-	 */
396
-	public function canChangeDisplayName() {
397
-		if ($this->config->getSystemValue('allow_user_to_change_display_name') === false) {
398
-			return false;
399
-		}
400
-		return $this->backend->implementsActions(Backend::SET_DISPLAYNAME);
401
-	}
402
-
403
-	/**
404
-	 * check if the user is enabled
405
-	 *
406
-	 * @return bool
407
-	 */
408
-	public function isEnabled() {
409
-		if ($this->enabled === null) {
410
-			$enabled = $this->config->getUserValue($this->uid, 'core', 'enabled', 'true');
411
-			$this->enabled = $enabled === 'true';
412
-		}
413
-		return (bool) $this->enabled;
414
-	}
415
-
416
-	/**
417
-	 * set the enabled status for the user
418
-	 *
419
-	 * @param bool $enabled
420
-	 */
421
-	public function setEnabled(bool $enabled = true) {
422
-		$oldStatus = $this->isEnabled();
423
-		$this->enabled = $enabled;
424
-		if ($oldStatus !== $this->enabled) {
425
-			// TODO: First change the value, then trigger the event as done for all other properties.
426
-			$this->triggerChange('enabled', $enabled, $oldStatus);
427
-			$this->config->setUserValue($this->uid, 'core', 'enabled', $enabled ? 'true' : 'false');
428
-		}
429
-	}
430
-
431
-	/**
432
-	 * get the users email address
433
-	 *
434
-	 * @return string|null
435
-	 * @since 9.0.0
436
-	 */
437
-	public function getEMailAddress() {
438
-		return $this->getPrimaryEMailAddress() ?? $this->getSystemEMailAddress();
439
-	}
440
-
441
-	/**
442
-	 * @inheritDoc
443
-	 */
444
-	public function getSystemEMailAddress(): ?string {
445
-		return $this->config->getUserValue($this->uid, 'settings', 'email', null);
446
-	}
447
-
448
-	/**
449
-	 * @inheritDoc
450
-	 */
451
-	public function getPrimaryEMailAddress(): ?string {
452
-		return $this->config->getUserValue($this->uid, 'settings', 'primary_email', null);
453
-	}
454
-
455
-	/**
456
-	 * get the users' quota
457
-	 *
458
-	 * @return string
459
-	 * @since 9.0.0
460
-	 */
461
-	public function getQuota() {
462
-		// allow apps to modify the user quota by hooking into the event
463
-		$event = new GetQuotaEvent($this);
464
-		$this->dispatcher->dispatchTyped($event);
465
-		$overwriteQuota = $event->getQuota();
466
-		if ($overwriteQuota) {
467
-			$quota = $overwriteQuota;
468
-		} else {
469
-			$quota = $this->config->getUserValue($this->uid, 'files', 'quota', 'default');
470
-		}
471
-		if ($quota === 'default') {
472
-			$quota = $this->config->getAppValue('files', 'default_quota', 'none');
473
-
474
-			// if unlimited quota is not allowed => avoid getting 'unlimited' as default_quota fallback value
475
-			// use the first preset instead
476
-			$allowUnlimitedQuota = $this->config->getAppValue('files', 'allow_unlimited_quota', '1') === '1';
477
-			if (!$allowUnlimitedQuota) {
478
-				$presets = $this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB');
479
-				$presets = array_filter(array_map('trim', explode(',', $presets)));
480
-				$quotaPreset = array_values(array_diff($presets, ['default', 'none']));
481
-				if (count($quotaPreset) > 0) {
482
-					$quota = $this->config->getAppValue('files', 'default_quota', $quotaPreset[0]);
483
-				}
484
-			}
485
-		}
486
-		return $quota;
487
-	}
488
-
489
-	/**
490
-	 * set the users' quota
491
-	 *
492
-	 * @param string $quota
493
-	 * @return void
494
-	 * @since 9.0.0
495
-	 */
496
-	public function setQuota($quota) {
497
-		$oldQuota = $this->config->getUserValue($this->uid, 'files', 'quota', '');
498
-		if ($quota !== 'none' and $quota !== 'default') {
499
-			$quota = OC_Helper::computerFileSize($quota);
500
-			$quota = OC_Helper::humanFileSize($quota);
501
-		}
502
-		if ($quota !== $oldQuota) {
503
-			$this->config->setUserValue($this->uid, 'files', 'quota', $quota);
504
-			$this->triggerChange('quota', $quota, $oldQuota);
505
-		}
506
-	}
507
-
508
-	/**
509
-	 * get the avatar image if it exists
510
-	 *
511
-	 * @param int $size
512
-	 * @return IImage|null
513
-	 * @since 9.0.0
514
-	 */
515
-	public function getAvatarImage($size) {
516
-		// delay the initialization
517
-		if (is_null($this->avatarManager)) {
518
-			$this->avatarManager = \OC::$server->getAvatarManager();
519
-		}
520
-
521
-		$avatar = $this->avatarManager->getAvatar($this->uid);
522
-		$image = $avatar->get(-1);
523
-		if ($image) {
524
-			return $image;
525
-		}
526
-
527
-		return null;
528
-	}
529
-
530
-	/**
531
-	 * get the federation cloud id
532
-	 *
533
-	 * @return string
534
-	 * @since 9.0.0
535
-	 */
536
-	public function getCloudId() {
537
-		$uid = $this->getUID();
538
-		$server = $this->urlGenerator->getAbsoluteURL('/');
539
-		$server = rtrim($this->removeProtocolFromUrl($server), '/');
540
-		return $uid . '@' . $server;
541
-	}
542
-
543
-	/**
544
-	 * @param string $url
545
-	 * @return string
546
-	 */
547
-	private function removeProtocolFromUrl($url) {
548
-		if (strpos($url, 'https://') === 0) {
549
-			return substr($url, strlen('https://'));
550
-		} elseif (strpos($url, 'http://') === 0) {
551
-			return substr($url, strlen('http://'));
552
-		}
553
-
554
-		return $url;
555
-	}
556
-
557
-	public function triggerChange($feature, $value = null, $oldValue = null) {
558
-		$this->legacyDispatcher->dispatch(IUser::class . '::changeUser', new GenericEvent($this, [
559
-			'feature' => $feature,
560
-			'value' => $value,
561
-			'oldValue' => $oldValue,
562
-		]));
563
-		if ($this->emitter) {
564
-			$this->emitter->emit('\OC\User', 'changeUser', [$this, $feature, $value, $oldValue]);
565
-		}
566
-	}
60
+    /** @var IAccountManager */
61
+    protected $accountManager;
62
+    /** @var string */
63
+    private $uid;
64
+
65
+    /** @var string|null */
66
+    private $displayName;
67
+
68
+    /** @var UserInterface|null */
69
+    private $backend;
70
+    /** @var EventDispatcherInterface */
71
+    private $legacyDispatcher;
72
+
73
+    /** @var IEventDispatcher */
74
+    private $dispatcher;
75
+
76
+    /** @var bool|null */
77
+    private $enabled;
78
+
79
+    /** @var Emitter|Manager */
80
+    private $emitter;
81
+
82
+    /** @var string */
83
+    private $home;
84
+
85
+    /** @var int|null */
86
+    private $lastLogin;
87
+
88
+    /** @var \OCP\IConfig */
89
+    private $config;
90
+
91
+    /** @var IAvatarManager */
92
+    private $avatarManager;
93
+
94
+    /** @var IURLGenerator */
95
+    private $urlGenerator;
96
+
97
+    public function __construct(string $uid, ?UserInterface $backend, EventDispatcherInterface $dispatcher, $emitter = null, IConfig $config = null, $urlGenerator = null) {
98
+        $this->uid = $uid;
99
+        $this->backend = $backend;
100
+        $this->legacyDispatcher = $dispatcher;
101
+        $this->emitter = $emitter;
102
+        if (is_null($config)) {
103
+            $config = \OC::$server->getConfig();
104
+        }
105
+        $this->config = $config;
106
+        $this->urlGenerator = $urlGenerator;
107
+        if (is_null($this->urlGenerator)) {
108
+            $this->urlGenerator = \OC::$server->getURLGenerator();
109
+        }
110
+        // TODO: inject
111
+        $this->dispatcher = \OC::$server->query(IEventDispatcher::class);
112
+    }
113
+
114
+    /**
115
+     * get the user id
116
+     *
117
+     * @return string
118
+     */
119
+    public function getUID() {
120
+        return $this->uid;
121
+    }
122
+
123
+    /**
124
+     * get the display name for the user, if no specific display name is set it will fallback to the user id
125
+     *
126
+     * @return string
127
+     */
128
+    public function getDisplayName() {
129
+        if ($this->displayName === null) {
130
+            $displayName = '';
131
+            if ($this->backend && $this->backend->implementsActions(Backend::GET_DISPLAYNAME)) {
132
+                // get display name and strip whitespace from the beginning and end of it
133
+                $backendDisplayName = $this->backend->getDisplayName($this->uid);
134
+                if (is_string($backendDisplayName)) {
135
+                    $displayName = trim($backendDisplayName);
136
+                }
137
+            }
138
+
139
+            if (!empty($displayName)) {
140
+                $this->displayName = $displayName;
141
+            } else {
142
+                $this->displayName = $this->uid;
143
+            }
144
+        }
145
+        return $this->displayName;
146
+    }
147
+
148
+    /**
149
+     * set the displayname for the user
150
+     *
151
+     * @param string $displayName
152
+     * @return bool
153
+     */
154
+    public function setDisplayName($displayName) {
155
+        $displayName = trim($displayName);
156
+        $oldDisplayName = $this->getDisplayName();
157
+        if ($this->backend->implementsActions(Backend::SET_DISPLAYNAME) && !empty($displayName) && $displayName !== $oldDisplayName) {
158
+            $result = $this->backend->setDisplayName($this->uid, $displayName);
159
+            if ($result) {
160
+                $this->displayName = $displayName;
161
+                $this->triggerChange('displayName', $displayName, $oldDisplayName);
162
+            }
163
+            return $result !== false;
164
+        }
165
+        return false;
166
+    }
167
+
168
+    /**
169
+     * @inheritDoc
170
+     */
171
+    public function setEMailAddress($mailAddress) {
172
+        $this->setSystemEMailAddress($mailAddress);
173
+    }
174
+
175
+    /**
176
+     * @inheritDoc
177
+     */
178
+    public function setSystemEMailAddress(string $mailAddress): void {
179
+        $oldMailAddress = $this->getSystemEMailAddress();
180
+
181
+        if ($mailAddress === '') {
182
+            $this->config->deleteUserValue($this->uid, 'settings', 'email');
183
+        } else {
184
+            $this->config->setUserValue($this->uid, 'settings', 'email', $mailAddress);
185
+        }
186
+
187
+        $primaryAddress = $this->getPrimaryEMailAddress();
188
+        if ($primaryAddress === $mailAddress) {
189
+            // on match no dedicated primary settings is necessary
190
+            $this->setPrimaryEMailAddress('');
191
+        }
192
+
193
+        if ($oldMailAddress !== $mailAddress) {
194
+            $this->triggerChange('eMailAddress', $mailAddress, $oldMailAddress);
195
+        }
196
+    }
197
+
198
+    /**
199
+     * @inheritDoc
200
+     */
201
+    public function setPrimaryEMailAddress(string $mailAddress): void {
202
+        if ($mailAddress === '') {
203
+            $this->config->deleteUserValue($this->uid, 'settings', 'primary_email');
204
+            return;
205
+        }
206
+
207
+        $this->ensureAccountManager();
208
+        $account = $this->accountManager->getAccount($this);
209
+        $property = $account->getPropertyCollection(IAccountManager::COLLECTION_EMAIL)
210
+            ->getPropertyByValue($mailAddress);
211
+
212
+        if ($property === null || $property->getLocallyVerified() !== IAccountManager::VERIFIED) {
213
+            throw new InvalidArgumentException('Only verified emails can be set as primary');
214
+        }
215
+        $this->config->setUserValue($this->uid, 'settings', 'primary_email', $mailAddress);
216
+    }
217
+
218
+    private function ensureAccountManager() {
219
+        if (!$this->accountManager instanceof IAccountManager) {
220
+            $this->accountManager = \OC::$server->get(IAccountManager::class);
221
+        }
222
+    }
223
+
224
+    /**
225
+     * returns the timestamp of the user's last login or 0 if the user did never
226
+     * login
227
+     *
228
+     * @return int
229
+     */
230
+    public function getLastLogin() {
231
+        if ($this->lastLogin === null) {
232
+            $this->lastLogin = (int) $this->config->getUserValue($this->uid, 'login', 'lastLogin', 0);
233
+        }
234
+        return (int) $this->lastLogin;
235
+    }
236
+
237
+    /**
238
+     * updates the timestamp of the most recent login of this user
239
+     */
240
+    public function updateLastLoginTimestamp() {
241
+        $firstTimeLogin = ($this->getLastLogin() === 0);
242
+        $this->lastLogin = time();
243
+        $this->config->setUserValue(
244
+            $this->uid, 'login', 'lastLogin', $this->lastLogin);
245
+
246
+        return $firstTimeLogin;
247
+    }
248
+
249
+    /**
250
+     * Delete the user
251
+     *
252
+     * @return bool
253
+     */
254
+    public function delete() {
255
+        /** @deprecated 21.0.0 use BeforeUserDeletedEvent event with the IEventDispatcher instead */
256
+        $this->legacyDispatcher->dispatch(IUser::class . '::preDelete', new GenericEvent($this));
257
+        if ($this->emitter) {
258
+            /** @deprecated 21.0.0 use BeforeUserDeletedEvent event with the IEventDispatcher instead */
259
+            $this->emitter->emit('\OC\User', 'preDelete', [$this]);
260
+        }
261
+        $this->dispatcher->dispatchTyped(new BeforeUserDeletedEvent($this));
262
+        $result = $this->backend->deleteUser($this->uid);
263
+        if ($result) {
264
+
265
+            // FIXME: Feels like an hack - suggestions?
266
+
267
+            $groupManager = \OC::$server->getGroupManager();
268
+            // We have to delete the user from all groups
269
+            foreach ($groupManager->getUserGroupIds($this) as $groupId) {
270
+                $group = $groupManager->get($groupId);
271
+                if ($group) {
272
+                    $this->dispatcher->dispatchTyped(new BeforeUserRemovedEvent($group, $this));
273
+                    $group->removeUser($this);
274
+                    $this->dispatcher->dispatchTyped(new UserRemovedEvent($group, $this));
275
+                }
276
+            }
277
+            // Delete the user's keys in preferences
278
+            \OC::$server->getConfig()->deleteAllUserValues($this->uid);
279
+
280
+            \OC::$server->getCommentsManager()->deleteReferencesOfActor('users', $this->uid);
281
+            \OC::$server->getCommentsManager()->deleteReadMarksFromUser($this);
282
+
283
+            /** @var IAvatarManager $avatarManager */
284
+            $avatarManager = \OC::$server->query(AvatarManager::class);
285
+            $avatarManager->deleteUserAvatar($this->uid);
286
+
287
+            $notification = \OC::$server->getNotificationManager()->createNotification();
288
+            $notification->setUser($this->uid);
289
+            \OC::$server->getNotificationManager()->markProcessed($notification);
290
+
291
+            /** @var AccountManager $accountManager */
292
+            $accountManager = \OC::$server->query(AccountManager::class);
293
+            $accountManager->deleteUser($this);
294
+
295
+            /** @deprecated 21.0.0 use UserDeletedEvent event with the IEventDispatcher instead */
296
+            $this->legacyDispatcher->dispatch(IUser::class . '::postDelete', new GenericEvent($this));
297
+            if ($this->emitter) {
298
+                /** @deprecated 21.0.0 use UserDeletedEvent event with the IEventDispatcher instead */
299
+                $this->emitter->emit('\OC\User', 'postDelete', [$this]);
300
+            }
301
+            $this->dispatcher->dispatchTyped(new UserDeletedEvent($this));
302
+        }
303
+        return !($result === false);
304
+    }
305
+
306
+    /**
307
+     * Set the password of the user
308
+     *
309
+     * @param string $password
310
+     * @param string $recoveryPassword for the encryption app to reset encryption keys
311
+     * @return bool
312
+     */
313
+    public function setPassword($password, $recoveryPassword = null) {
314
+        $this->legacyDispatcher->dispatch(IUser::class . '::preSetPassword', new GenericEvent($this, [
315
+            'password' => $password,
316
+            'recoveryPassword' => $recoveryPassword,
317
+        ]));
318
+        if ($this->emitter) {
319
+            $this->emitter->emit('\OC\User', 'preSetPassword', [$this, $password, $recoveryPassword]);
320
+        }
321
+        if ($this->backend->implementsActions(Backend::SET_PASSWORD)) {
322
+            $result = $this->backend->setPassword($this->uid, $password);
323
+            $this->legacyDispatcher->dispatch(IUser::class . '::postSetPassword', new GenericEvent($this, [
324
+                'password' => $password,
325
+                'recoveryPassword' => $recoveryPassword,
326
+            ]));
327
+            if ($this->emitter) {
328
+                $this->emitter->emit('\OC\User', 'postSetPassword', [$this, $password, $recoveryPassword]);
329
+            }
330
+            return !($result === false);
331
+        } else {
332
+            return false;
333
+        }
334
+    }
335
+
336
+    /**
337
+     * get the users home folder to mount
338
+     *
339
+     * @return string
340
+     */
341
+    public function getHome() {
342
+        if (!$this->home) {
343
+            if ($this->backend->implementsActions(Backend::GET_HOME) and $home = $this->backend->getHome($this->uid)) {
344
+                $this->home = $home;
345
+            } elseif ($this->config) {
346
+                $this->home = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $this->uid;
347
+            } else {
348
+                $this->home = \OC::$SERVERROOT . '/data/' . $this->uid;
349
+            }
350
+        }
351
+        return $this->home;
352
+    }
353
+
354
+    /**
355
+     * Get the name of the backend class the user is connected with
356
+     *
357
+     * @return string
358
+     */
359
+    public function getBackendClassName() {
360
+        if ($this->backend instanceof IUserBackend) {
361
+            return $this->backend->getBackendName();
362
+        }
363
+        return get_class($this->backend);
364
+    }
365
+
366
+    public function getBackend() {
367
+        return $this->backend;
368
+    }
369
+
370
+    /**
371
+     * check if the backend allows the user to change his avatar on Personal page
372
+     *
373
+     * @return bool
374
+     */
375
+    public function canChangeAvatar() {
376
+        if ($this->backend->implementsActions(Backend::PROVIDE_AVATAR)) {
377
+            return $this->backend->canChangeAvatar($this->uid);
378
+        }
379
+        return true;
380
+    }
381
+
382
+    /**
383
+     * check if the backend supports changing passwords
384
+     *
385
+     * @return bool
386
+     */
387
+    public function canChangePassword() {
388
+        return $this->backend->implementsActions(Backend::SET_PASSWORD);
389
+    }
390
+
391
+    /**
392
+     * check if the backend supports changing display names
393
+     *
394
+     * @return bool
395
+     */
396
+    public function canChangeDisplayName() {
397
+        if ($this->config->getSystemValue('allow_user_to_change_display_name') === false) {
398
+            return false;
399
+        }
400
+        return $this->backend->implementsActions(Backend::SET_DISPLAYNAME);
401
+    }
402
+
403
+    /**
404
+     * check if the user is enabled
405
+     *
406
+     * @return bool
407
+     */
408
+    public function isEnabled() {
409
+        if ($this->enabled === null) {
410
+            $enabled = $this->config->getUserValue($this->uid, 'core', 'enabled', 'true');
411
+            $this->enabled = $enabled === 'true';
412
+        }
413
+        return (bool) $this->enabled;
414
+    }
415
+
416
+    /**
417
+     * set the enabled status for the user
418
+     *
419
+     * @param bool $enabled
420
+     */
421
+    public function setEnabled(bool $enabled = true) {
422
+        $oldStatus = $this->isEnabled();
423
+        $this->enabled = $enabled;
424
+        if ($oldStatus !== $this->enabled) {
425
+            // TODO: First change the value, then trigger the event as done for all other properties.
426
+            $this->triggerChange('enabled', $enabled, $oldStatus);
427
+            $this->config->setUserValue($this->uid, 'core', 'enabled', $enabled ? 'true' : 'false');
428
+        }
429
+    }
430
+
431
+    /**
432
+     * get the users email address
433
+     *
434
+     * @return string|null
435
+     * @since 9.0.0
436
+     */
437
+    public function getEMailAddress() {
438
+        return $this->getPrimaryEMailAddress() ?? $this->getSystemEMailAddress();
439
+    }
440
+
441
+    /**
442
+     * @inheritDoc
443
+     */
444
+    public function getSystemEMailAddress(): ?string {
445
+        return $this->config->getUserValue($this->uid, 'settings', 'email', null);
446
+    }
447
+
448
+    /**
449
+     * @inheritDoc
450
+     */
451
+    public function getPrimaryEMailAddress(): ?string {
452
+        return $this->config->getUserValue($this->uid, 'settings', 'primary_email', null);
453
+    }
454
+
455
+    /**
456
+     * get the users' quota
457
+     *
458
+     * @return string
459
+     * @since 9.0.0
460
+     */
461
+    public function getQuota() {
462
+        // allow apps to modify the user quota by hooking into the event
463
+        $event = new GetQuotaEvent($this);
464
+        $this->dispatcher->dispatchTyped($event);
465
+        $overwriteQuota = $event->getQuota();
466
+        if ($overwriteQuota) {
467
+            $quota = $overwriteQuota;
468
+        } else {
469
+            $quota = $this->config->getUserValue($this->uid, 'files', 'quota', 'default');
470
+        }
471
+        if ($quota === 'default') {
472
+            $quota = $this->config->getAppValue('files', 'default_quota', 'none');
473
+
474
+            // if unlimited quota is not allowed => avoid getting 'unlimited' as default_quota fallback value
475
+            // use the first preset instead
476
+            $allowUnlimitedQuota = $this->config->getAppValue('files', 'allow_unlimited_quota', '1') === '1';
477
+            if (!$allowUnlimitedQuota) {
478
+                $presets = $this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB');
479
+                $presets = array_filter(array_map('trim', explode(',', $presets)));
480
+                $quotaPreset = array_values(array_diff($presets, ['default', 'none']));
481
+                if (count($quotaPreset) > 0) {
482
+                    $quota = $this->config->getAppValue('files', 'default_quota', $quotaPreset[0]);
483
+                }
484
+            }
485
+        }
486
+        return $quota;
487
+    }
488
+
489
+    /**
490
+     * set the users' quota
491
+     *
492
+     * @param string $quota
493
+     * @return void
494
+     * @since 9.0.0
495
+     */
496
+    public function setQuota($quota) {
497
+        $oldQuota = $this->config->getUserValue($this->uid, 'files', 'quota', '');
498
+        if ($quota !== 'none' and $quota !== 'default') {
499
+            $quota = OC_Helper::computerFileSize($quota);
500
+            $quota = OC_Helper::humanFileSize($quota);
501
+        }
502
+        if ($quota !== $oldQuota) {
503
+            $this->config->setUserValue($this->uid, 'files', 'quota', $quota);
504
+            $this->triggerChange('quota', $quota, $oldQuota);
505
+        }
506
+    }
507
+
508
+    /**
509
+     * get the avatar image if it exists
510
+     *
511
+     * @param int $size
512
+     * @return IImage|null
513
+     * @since 9.0.0
514
+     */
515
+    public function getAvatarImage($size) {
516
+        // delay the initialization
517
+        if (is_null($this->avatarManager)) {
518
+            $this->avatarManager = \OC::$server->getAvatarManager();
519
+        }
520
+
521
+        $avatar = $this->avatarManager->getAvatar($this->uid);
522
+        $image = $avatar->get(-1);
523
+        if ($image) {
524
+            return $image;
525
+        }
526
+
527
+        return null;
528
+    }
529
+
530
+    /**
531
+     * get the federation cloud id
532
+     *
533
+     * @return string
534
+     * @since 9.0.0
535
+     */
536
+    public function getCloudId() {
537
+        $uid = $this->getUID();
538
+        $server = $this->urlGenerator->getAbsoluteURL('/');
539
+        $server = rtrim($this->removeProtocolFromUrl($server), '/');
540
+        return $uid . '@' . $server;
541
+    }
542
+
543
+    /**
544
+     * @param string $url
545
+     * @return string
546
+     */
547
+    private function removeProtocolFromUrl($url) {
548
+        if (strpos($url, 'https://') === 0) {
549
+            return substr($url, strlen('https://'));
550
+        } elseif (strpos($url, 'http://') === 0) {
551
+            return substr($url, strlen('http://'));
552
+        }
553
+
554
+        return $url;
555
+    }
556
+
557
+    public function triggerChange($feature, $value = null, $oldValue = null) {
558
+        $this->legacyDispatcher->dispatch(IUser::class . '::changeUser', new GenericEvent($this, [
559
+            'feature' => $feature,
560
+            'value' => $value,
561
+            'oldValue' => $oldValue,
562
+        ]));
563
+        if ($this->emitter) {
564
+            $this->emitter->emit('\OC\User', 'changeUser', [$this, $feature, $value, $oldValue]);
565
+        }
566
+    }
567 567
 }
Please login to merge, or discard this patch.