Completed
Pull Request — master (#551)
by Maxence
01:59
created

FederatedUserService   F

Complexity

Total Complexity 68

Size/Duplication

Total Lines 652
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 17

Importance

Changes 0
Metric Value
wmc 68
lcom 1
cbo 17
dl 0
loc 652
rs 2.908
c 0
b 0
f 0

22 Methods

Rating   Name   Duplication   Size   Complexity  
A commandLineInitiator() 0 25 5
A __construct() 0 11 1
A setCurrentUser() 0 11 2
A getCurrentUser() 0 3 1
A hasCurrentUser() 0 3 1
A mustHaveCurrentUser() 0 8 4
A bypassCurrentUserCondition() 0 3 1
A setRemoteInstance() 0 3 1
A getRemoteInstance() 0 3 1
A hasRemoteInstance() 0 3 1
A getLocalFederatedUser() 0 12 2
A getFederatedMember() 0 13 2
F generateFederatedUser() 0 47 18
B getFederatedUser() 0 21 6
A getFederatedUser_SingleId() 0 15 3
A getFederatedUser_User() 0 11 2
A getFederatedUser_Circle() 0 15 2
A extractIdAndInstance() 0 11 2
A fillSingleCircleId() 0 8 2
A getSingleCircle() 0 29 3
A confirmFederatedUser() 0 9 5
A confirmLocalSingleId() 0 13 3

How to fix   Complexity   

Complex Class

Complex classes like FederatedUserService often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FederatedUserService, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
6
/**
7
 * Circles - Bring cloud-users closer together.
8
 *
9
 * This file is licensed under the Affero General Public License version 3 or
10
 * later. See the COPYING file.
11
 *
12
 * @author Maxence Lange <[email protected]>
13
 * @copyright 2021
14
 * @license GNU AGPL version 3 or any later version
15
 *
16
 * This program is free software: you can redistribute it and/or modify
17
 * it under the terms of the GNU Affero General Public License as
18
 * published by the Free Software Foundation, either version 3 of the
19
 * License, or (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU Affero General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU Affero General Public License
27
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
28
 *
29
 */
30
31
32
namespace OCA\Circles\Service;
33
34
35
use daita\MySmallPhpTools\Exceptions\InvalidItemException;
36
use daita\MySmallPhpTools\Exceptions\RequestNetworkException;
37
use daita\MySmallPhpTools\Exceptions\SignatoryException;
38
use daita\MySmallPhpTools\Traits\Nextcloud\nc21\TNC21Logger;
39
use daita\MySmallPhpTools\Traits\TArrayTools;
40
use daita\MySmallPhpTools\Traits\TStringTools;
41
use Exception;
42
use OCA\Circles\Db\CircleRequest;
43
use OCA\Circles\Db\MemberRequest;
44
use OCA\Circles\Db\MembershipRequest;
45
use OCA\Circles\Exceptions\CircleNotFoundException;
46
use OCA\Circles\Exceptions\FederatedUserException;
47
use OCA\Circles\Exceptions\FederatedUserNotFoundException;
48
use OCA\Circles\Exceptions\InitiatorNotFoundException;
49
use OCA\Circles\Exceptions\InvalidIdException;
50
use OCA\Circles\Exceptions\MemberNotFoundException;
51
use OCA\Circles\Exceptions\OwnerNotFoundException;
52
use OCA\Circles\Exceptions\RemoteInstanceException;
53
use OCA\Circles\Exceptions\RemoteNotFoundException;
54
use OCA\Circles\Exceptions\RemoteResourceNotFoundException;
55
use OCA\Circles\Exceptions\UnknownRemoteException;
56
use OCA\Circles\Exceptions\UserTypeNotFoundException;
57
use OCA\Circles\IFederatedUser;
58
use OCA\Circles\Model\Circle;
59
use OCA\Circles\Model\Federated\RemoteInstance;
60
use OCA\Circles\Model\FederatedUser;
61
use OCA\Circles\Model\ManagedModel;
62
use OCA\Circles\Model\Member;
63
use OCP\IUserManager;
64
65
66
/**
67
 * Class FederatedUserService
68
 *
69
 * @package OCA\Circles\Service
70
 */
71
class FederatedUserService {
72
73
74
	use TArrayTools;
75
	use TStringTools;
76
	use TNC21Logger;
77
78
79
	/** @var IUserManager */
80
	private $userManager;
81
82
	/** @var MembershipRequest */
83
	private $membershipRequest;
84
85
	/** @var CircleRequest */
86
	private $circleRequest;
87
88
	/** @var MemberRequest */
89
	private $memberRequest;
90
91
	/** @var RemoteService */
92
	private $remoteService;
93
94
	/** @var ConfigService */
95
	private $configService;
96
97
98
	/** @var FederatedUser */
99
	private $currentUser = null;
100
101
	/** @var RemoteInstance */
102
	private $remoteInstance = null;
103
104
	/** @var bool */
105
	private $bypass = false;
106
107
108
	/**
109
	 * FederatedUserService constructor.
110
	 *
111
	 * @param IUserManager $userManager
112
	 * @param MembershipRequest $membershipRequest
113
	 * @param CircleRequest $circleRequest
114
	 * @param MemberRequest $memberRequest
115
	 * @param RemoteService $remoteService
116
	 * @param ConfigService $configService
117
	 */
118
	public function __construct(
119
		IUserManager $userManager, MembershipRequest $membershipRequest, CircleRequest $circleRequest,
120
		MemberRequest $memberRequest, RemoteService $remoteService, ConfigService $configService
121
	) {
122
		$this->userManager = $userManager;
123
		$this->membershipRequest = $membershipRequest;
124
		$this->circleRequest = $circleRequest;
125
		$this->memberRequest = $memberRequest;
126
		$this->remoteService = $remoteService;
127
		$this->configService = $configService;
128
	}
129
130
131
//	/**
132
//	 * @param string $userId
133
//	 *
134
//	 * @throws CircleNotFoundException
135
//	 * @throws NoUserException
136
//	 */
137
//	public function setLocalInitiator(string $userId): void {
138
//		$this->currentUser = $this->createLocalFederatedUser($userId);
139
//	}
140
141
	/**
142
	 * set a CurrentUser, based on a IFederatedUser.
143
	 * CurrentUser is mainly used to manage rights when requesting the database.
144
	 *
145
	 * @param IFederatedUser $federatedUser
146
	 *
147
	 * @throws FederatedUserException
148
	 */
149
	public function setCurrentUser(IFederatedUser $federatedUser): void {
150
		if (!($federatedUser instanceof FederatedUser)) {
151
			$tmp = new FederatedUser();
152
			$tmp->importFromIFederatedUser($federatedUser);
153
			$federatedUser = $tmp;
154
		}
155
156
		$this->confirmFederatedUser($federatedUser);
157
158
		$this->currentUser = $federatedUser;
159
	}
160
161
	/**
162
	 * @return FederatedUser|null
163
	 */
164
	public function getCurrentUser(): ?FederatedUser {
165
		return $this->currentUser;
166
	}
167
168
	/**
169
	 * @return bool
170
	 */
171
	public function hasCurrentUser(): bool {
172
		return !is_null($this->currentUser);
173
	}
174
175
	/**
176
	 * @throws InitiatorNotFoundException
177
	 */
178
	public function mustHaveCurrentUser(): void {
179
		if ($this->bypass) {
180
			return;
181
		}
182
		if (!$this->hasCurrentUser() && !$this->hasRemoteInstance()) {
183
			throw new InitiatorNotFoundException();
184
		}
185
	}
186
187
	/**
188
	 * @param bool $bypass
189
	 */
190
	public function bypassCurrentUserCondition(bool $bypass): void {
191
		$this->bypass = $bypass;
192
	}
193
194
195
	/**
196
	 * set a RemoteInstance, mostly from a remote request (RemoteController)
197
	 * Used to limit rights in some request in the local database.
198
	 *
199
	 * @param RemoteInstance $remoteInstance
200
	 */
201
	public function setRemoteInstance(RemoteInstance $remoteInstance): void {
202
		$this->remoteInstance = $remoteInstance;
203
	}
204
205
	/**
206
	 * @return RemoteInstance|null
207
	 */
208
	public function getRemoteInstance(): ?RemoteInstance {
209
		return $this->remoteInstance;
210
	}
211
212
	/**
213
	 * @return bool
214
	 */
215
	public function hasRemoteInstance(): bool {
216
		return !is_null($this->remoteInstance);
217
	}
218
219
220
	/**
221
	 * Get the full FederatedUser for a local user.
222
	 * Will generate the SingleId if none exist
223
	 *
224
	 * @param string $userId
225
	 *
226
	 * @return FederatedUser
227
	 * @throws CircleNotFoundException
228
	 * @throws FederatedUserNotFoundException
229
	 * @throws InvalidIdException
230
	 */
231
	public function getLocalFederatedUser(string $userId): FederatedUser {
232
		$user = $this->userManager->get($userId);
233
		if ($user === null) {
234
			throw new FederatedUserNotFoundException('user ' . $userId . ' not found');
235
		}
236
237
		$federatedUser = new FederatedUser();
238
		$federatedUser->set($user->getUID());
239
		$this->fillSingleCircleId($federatedUser);
240
241
		return $federatedUser;
242
	}
243
244
245
	/**
246
	 * some ./occ commands allows to add an Initiator, or force the PoV from the local circles' owner
247
	 *
248
	 * TODO: manage non-user type ?
249
	 *
250
	 * @param string $userId
251
	 * @param string $circleId
252
	 * @param bool $bypass
253
	 *
254
	 * @throws CircleNotFoundException
255
	 * @throws FederatedUserException
256
	 * @throws FederatedUserNotFoundException
257
	 * @throws InvalidIdException
258
	 * @throws InvalidItemException
259
	 * @throws OwnerNotFoundException
260
	 * @throws RemoteInstanceException
261
	 * @throws RemoteNotFoundException
262
	 * @throws RemoteResourceNotFoundException
263
	 * @throws RequestNetworkException
264
	 * @throws SignatoryException
265
	 * @throws UnknownRemoteException
266
	 * @throws UserTypeNotFoundException
267
	 * @throws MemberNotFoundException
268
	 */
269
	public function commandLineInitiator(string $userId, string $circleId = '', bool $bypass = false): void {
270
		if ($userId !== '') {
271
			$this->setCurrentUser($this->getFederatedUser($userId));
272
273
			return;
274
		}
275
276
		if ($circleId !== '') {
277
			$localCircle = $this->circleRequest->getCircle($circleId);
278
			if ($this->configService->isLocalInstance($localCircle->getInstance())) {
279
				// TODO: manage NO_OWNER circles
280
				$this->setCurrentUser($localCircle->getOwner());
281
282
				return;
283
			}
284
		}
285
286
		if (!$bypass) {
287
			throw new CircleNotFoundException(
288
				'This Circle is not managed from this instance, please use --initiator'
289
			);
290
		}
291
292
		$this->bypassCurrentUserCondition($bypass);
293
	}
294
295
296
	/**
297
	 * Works like getFederatedUser, but returns a member.
298
	 * Allow to specify a level: handle@instance,level
299
	 *
300
	 * Used for filters when searching for Circles
301
	 * TODO: Used outside of ./occ circles:manage:list ?
302
	 *
303
	 * @param string $userId
304
	 * @param int $level
305
	 *
306
	 * @return Member
307
	 * @throws CircleNotFoundException
308
	 * @throws FederatedUserException
309
	 * @throws FederatedUserNotFoundException
310
	 * @throws InvalidItemException
311
	 * @throws MemberNotFoundException
312
	 * @throws OwnerNotFoundException
313
	 * @throws RemoteInstanceException
314
	 * @throws RemoteNotFoundException
315
	 * @throws RemoteResourceNotFoundException
316
	 * @throws RequestNetworkException
317
	 * @throws SignatoryException
318
	 * @throws UnknownRemoteException
319
	 * @throws UserTypeNotFoundException
320
	 */
321
	public function getFederatedMember(string $userId, int $level = Member::LEVEL_MEMBER): Member {
322
		$userId = trim($userId, ',');
323
		if (strpos($userId, ',') !== false) {
324
			list($userId, $level) = explode(',', $userId);
325
		}
326
327
		$federatedUser = $this->getFederatedUser($userId);
328
		$member = new Member();
329
		$member->importFromIFederatedUser($federatedUser);
330
		$member->setLevel((int)$level);
331
332
		return $member;
333
	}
334
335
336
	/**
337
	 * Generate a FederatedUser based on local data.
338
	 * WARNING: There is no confirmation that the returned FederatedUser exists or is valid at this point.
339
	 * Use getFederatedUser() instead if a valid and confirmed FederatedUser is needed.
340
	 *
341
	 * if $federatedId is a known SingleId, will returns data from the local database.
342
	 * if $federatedId is a local username, will returns data from the local database.
343
	 * Otherwise, the FederatedUser will not contains a SingleId.
344
	 *
345
	 * @param string $userId
346
	 * @param int $type
347
	 *
348
	 * @return FederatedUser
349
	 */
350
	public function generateFederatedUser(string $userId, int $type = 0): FederatedUser {
351
		$userId = trim($userId, '@');
352
		if (strpos($userId, '@') === false) {
353
			$instance = '';
354
		} else {
355
			list($userId, $instance) = $this->extractIdAndInstance($userId);
356
		}
357
358
		try {
359
			if (($type === 0 || $type === Member::TYPE_USER)
360
				&& ($instance === '' || $this->configService->isLocalInstance($instance))) {
361
				return $this->getLocalFederatedUser($userId);
362
			}
363
		} catch (CircleNotFoundException | FederatedUserNotFoundException | InvalidIdException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
364
		}
365
366
		try {
367
			if ($type === 0 || $type === Member::TYPE_SINGLE) {
368
				$federatedUser = $this->memberRequest->getFederatedUserBySingleId($userId);
369
				if ($instance === '' || $federatedUser->getInstance() === $instance) {
370
					return $federatedUser;
371
				}
372
			}
373
		} catch (MemberNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
374
		}
375
376
		try {
377
			if ($type === 0 || $type === Member::TYPE_CIRCLE) {
378
				$federatedUser = $this->circleRequest->getFederatedUserByCircleId($userId);
379
				if ($instance === '' || $federatedUser->getInstance() === $instance) {
380
					return $federatedUser;
381
				}
382
			}
383
		} catch (CircleNotFoundException | OwnerNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
384
		}
385
386
		// TODO: search for other possible entries, like mail address
387
388
		if ($type === 0) {
389
			$type = Member::TYPE_USER;
390
		}
391
392
		$federatedUser = new FederatedUser();
393
		$federatedUser->set($userId, $instance, $type);
394
395
		return $federatedUser;
396
	}
397
398
399
	/**
400
	 * get a valid FederatedUser, based on the federatedId (userId@instance) its the type.
401
	 * If instance is local, get the local valid FederatedUser
402
	 * If instance is not local, get the remote valid FederatedUser
403
	 *
404
	 * @param string $federatedId
405
	 * @param int $userType
406
	 *
407
	 * @return FederatedUser
408
	 * @throws CircleNotFoundException
409
	 * @throws FederatedUserException
410
	 * @throws FederatedUserNotFoundException
411
	 * @throws InvalidItemException
412
	 * @throws MemberNotFoundException
413
	 * @throws OwnerNotFoundException
414
	 * @throws RemoteInstanceException
415
	 * @throws RemoteNotFoundException
416
	 * @throws RemoteResourceNotFoundException
417
	 * @throws RequestNetworkException
418
	 * @throws SignatoryException
419
	 * @throws UnknownRemoteException
420
	 * @throws UserTypeNotFoundException
421
	 */
422
	public function getFederatedUser(string $federatedId, int $userType = Member::TYPE_USER): FederatedUser {
423
		list($singleId, $instance) = $this->extractIdAndInstance($federatedId);
424
425
		switch ($userType) {
426
			case Member::TYPE_USER:
427
				try {
428
					return $this->getFederatedUser_User($singleId, $instance);
429
				} catch (RemoteNotFoundException $e) {
430
					throw new RemoteNotFoundException('Instance %s not found', ['instance' => $instance]);
431
				} catch (Exception $e) {
432
				}
433
434
				return $this->getFederatedUser_SingleId($singleId, $instance);
435
			case Member::TYPE_CIRCLE:
436
				return $this->getFederatedUser_Circle($singleId, $instance);
437
			case Member::TYPE_SINGLE:
438
				return $this->getFederatedUser_SingleId($singleId, $instance);
439
		}
440
441
		throw new UserTypeNotFoundException();
442
	}
443
444
445
	/**
446
	 * @param string $singleId
447
	 * @param string $instance
448
	 *
449
	 * @return FederatedUser
450
	 * @throws FederatedUserException
451
	 * @throws FederatedUserNotFoundException
452
	 * @throws InvalidItemException
453
	 * @throws MemberNotFoundException
454
	 * @throws RemoteInstanceException
455
	 * @throws RemoteNotFoundException
456
	 * @throws RemoteResourceNotFoundException
457
	 * @throws RequestNetworkException
458
	 * @throws SignatoryException
459
	 * @throws UnknownRemoteException
460
	 */
461
	private function getFederatedUser_SingleId(string $singleId, string $instance): FederatedUser {
462
		if (strlen($singleId) !== ManagedModel::ID_LENGTH) {
463
			throw new MemberNotFoundException();
464
		}
465
466
		if ($this->configService->isLocalInstance($instance)) {
467
			return $this->memberRequest->getFederatedUserBySingleId($singleId);
468
		} else {
469
			$federatedUser =
470
				$this->remoteService->getFederatedUserFromInstance($singleId, $instance, Member::TYPE_SINGLE);
471
			$this->confirmLocalSingleId($federatedUser);
472
473
			return $federatedUser;
474
		}
475
	}
476
477
478
	/**
479
	 * @param string $userId
480
	 * @param string $instance
481
	 *
482
	 * @return FederatedUser
483
	 * @throws CircleNotFoundException
484
	 * @throws FederatedUserException
485
	 * @throws FederatedUserNotFoundException
486
	 * @throws InvalidIdException
487
	 * @throws InvalidItemException
488
	 * @throws RemoteInstanceException
489
	 * @throws RemoteNotFoundException
490
	 * @throws RemoteResourceNotFoundException
491
	 * @throws RequestNetworkException
492
	 * @throws SignatoryException
493
	 * @throws UnknownRemoteException
494
	 */
495
	private function getFederatedUser_User(string $userId, string $instance): FederatedUser {
496
		if ($this->configService->isLocalInstance($instance)) {
497
			return $this->getLocalFederatedUser($userId);
498
		} else {
499
			$federatedUser =
500
				$this->remoteService->getFederatedUserFromInstance($userId, $instance, Member::TYPE_USER);
501
			$this->confirmLocalSingleId($federatedUser);
502
503
			return $federatedUser;
504
		}
505
	}
506
507
508
	/**
509
	 * // TODO: do we need to have this working on remote instance ?
510
	 *
511
	 * @param string $circleId
512
	 * @param string $instance
513
	 *
514
	 * @return FederatedUser
515
	 * @throws CircleNotFoundException
516
	 * @throws FederatedUserException
517
	 * @throws FederatedUserNotFoundException
518
	 * @throws InvalidItemException
519
	 * @throws OwnerNotFoundException
520
	 * @throws RemoteInstanceException
521
	 * @throws RemoteNotFoundException
522
	 * @throws RemoteResourceNotFoundException
523
	 * @throws RequestNetworkException
524
	 * @throws SignatoryException
525
	 * @throws UnknownRemoteException
526
	 */
527
	private function getFederatedUser_Circle(string $circleId, string $instance): FederatedUser {
528
		// TODO: check remote instance for existing circle
529
		if ($this->configService->isLocalInstance($instance)) {
530
			$circle = $this->circleRequest->getCircle($circleId);
531
			$federatedUser = new FederatedUser();
532
			$federatedUser->set($circleId, $circle->getInstance(), Member::TYPE_CIRCLE);
533
			$federatedUser->setSingleId($circleId);
534
		} else {
535
			$federatedUser =
536
				$this->remoteService->getFederatedUserFromInstance($circleId, $instance, Member::TYPE_CIRCLE);
537
			$this->confirmLocalSingleId($federatedUser);
538
		}
539
540
		return $federatedUser;
541
	}
542
543
544
	/**
545
	 * extract userID and instance from a federatedId
546
	 *
547
	 * @param string $federatedId
548
	 *
549
	 * @return array
550
	 */
551
	private function extractIdAndInstance(string $federatedId): array {
552
		$federatedId = trim($federatedId, '@');
553
		if (strpos($federatedId, '@') === false) {
554
			$userId = $federatedId;
555
			$instance = $this->configService->getLocalInstance();
556
		} else {
557
			list($userId, $instance) = explode('@', $federatedId);
558
		}
559
560
		return [$userId, $instance];
561
	}
562
563
564
	/**
565
	 * @param FederatedUser $federatedUser
566
	 *
567
	 * @throws CircleNotFoundException
568
	 * @throws InvalidIdException
569
	 */
570
	private function fillSingleCircleId(FederatedUser $federatedUser): void {
571
		if ($federatedUser->getSingleId() !== '') {
572
			return;
573
		}
574
575
		$circle = $this->getSingleCircle($federatedUser);
576
		$federatedUser->setSingleId($circle->getId());
577
	}
578
579
580
	/**
581
	 * get the Single Circle from a local user
582
	 *
583
	 * @param FederatedUser $federatedUser
584
	 *
585
	 * @return Circle
586
	 * @throws CircleNotFoundException
587
	 * @throws InvalidIdException
588
	 * @throws FederatedUserException
589
	 */
590
	private function getSingleCircle(FederatedUser $federatedUser): Circle {
591
		if (!$this->configService->isLocalInstance($federatedUser->getInstance())) {
592
			throw new FederatedUserException('FederatedUser must be local');
593
		}
594
595
		try {
596
			return $this->circleRequest->getInitiatorCircle($federatedUser);
597
		} catch (CircleNotFoundException $e) {
598
			$circle = new Circle();
599
			$id = $this->token(ManagedModel::ID_LENGTH);
600
601
			$circle->setName('single:' . $federatedUser->getUserId() . ':' . $id)
602
				   ->setId($id)
603
				   ->setConfig(Circle::CFG_SINGLE);
604
			$this->circleRequest->save($circle);
605
606
			$owner = new Member();
607
			$owner->importFromIFederatedUser($federatedUser);
608
			$owner->setLevel(Member::LEVEL_OWNER)
609
				  ->setCircleId($id)
610
				  ->setSingleId($id)
611
				  ->setId($id)
612
				  ->setCachedName($owner->getUserId())
613
				  ->setStatus('Member');
614
			$this->memberRequest->save($owner);
615
		}
616
617
		return $this->circleRequest->getInitiatorCircle($federatedUser);
618
	}
619
620
621
	/**
622
	 * Confirm that all field of a FederatedUser are filled.
623
	 *
624
	 * @param FederatedUser $federatedUser
625
	 *
626
	 * @throws FederatedUserException
627
	 */
628
	private function confirmFederatedUser(FederatedUser $federatedUser): void {
629
		if ($federatedUser->getUserId() === ''
630
			|| $federatedUser->getSingleId() === ''
631
			|| $federatedUser->getUserType() === ''
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $federatedUser->getUserType() (integer) and '' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
632
			|| $federatedUser->getInstance() === '') {
633
			$this->debug('FederatedUser is not empty', ['federatedUser' => $federatedUser]);
634
			throw new FederatedUserException('FederatedUser is not complete');
635
		}
636
	}
637
638
	/**
639
	 * Confirm that the singleId of a FederatedUser is unique and not used to any other member of the
640
	 * database.
641
	 *
642
	 * @param FederatedUser $federatedUser
643
	 *
644
	 * @throws FederatedUserException
645
	 */
646
	public function confirmLocalSingleId(FederatedUser $federatedUser): void {
647
		$members = $this->memberRequest->getMembersBySingleId($federatedUser->getSingleId());
648
649
		foreach ($members as $member) {
650
			if (!$federatedUser->compareWith($member)) {
651
				$this->debug(
652
					'uniqueness of SingleId could not be confirmed',
653
					['federatedUser' => $federatedUser, 'localMember' => $member]
654
				);
655
				throw new FederatedUserException('uniqueness of SingleId could not be confirmed');
656
			}
657
		}
658
	}
659
660
661
//	/**
662
//	 * @param FederatedUser $federatedUser
663
//	 *
664
//	 * @return Membership[]
665
//	 */
666
//	public function generateMemberships(FederatedUser $federatedUser): array {
667
//		$circles = $this->circleRequest->getCircles(null, $federatedUser);
668
//		$memberships = [];
669
//		foreach ($circles as $circle) {
670
//			$initiator = $circle->getInitiator();
671
//			if (!$initiator->isMember()) {
672
//				continue;
673
//			}
674
//
675
//			$memberships[] = new Membership(
676
//				$initiator->getId(), $circle->getId(), $federatedUser->getSingleId(), $initiator->getLevel()
677
//			);
678
//
679
////			$newUser = new CurrentUser($circle->getId(), Member::TYPE_CIRCLE, '');
680
////			$circles = $this->circleRequest->getCircles(null, $currentUser);
681
//		}
682
//
683
//		return $memberships;
684
//	}
685
//
686
//
687
//	/**
688
//	 * @param FederatedUser|null $federatedUser
689
//	 */
690
//	public function updateMemberships(?FederatedUser $federatedUser = null) {
691
//		if (is_null($federatedUser)) {
692
//			$federatedUser = $this->getCurrentUser();
693
//		} else {
694
//			$federatedUser->setMemberships($this->membershipRequest->getMemberships($federatedUser));
695
//		}
696
//
697
//		if (is_null($federatedUser)) {
698
//			return;
699
//		}
700
//
701
//		$last = $this->generateMemberships($federatedUser);
702
//
703
//		echo 'known: ' . json_encode($federatedUser->getMemberships()) . "\n";
704
//		echo 'last: ' . json_encode($last) . "\n";
705
//
706
////
707
////		$circles = $this->circleRequest->getCircles(null, $viewer);
708
////		foreach ($circles as $circle) {
709
////			$viewer = $circle->getViewer();
710
////			if (!$viewer->isMember()) {
711
////				continue;
712
////			}
713
////
714
////			echo 'new member: ' . json_encode($viewer) . "\n";
715
//////			$this->federatedUserService->updateMembership($circle);
716
////		}
717
//
718
//
719
//	}
720
721
722
}
723
724