Completed
Pull Request — master (#609)
by Maxence
02:47
created

SyncService::groupMemberRemoved()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 7
Ratio 100 %

Importance

Changes 0
Metric Value
dl 7
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
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\Traits\TStringTools;
36
use Exception;
37
use OCA\Circles\AppInfo\Application;
38
use OCA\Circles\Db\CircleRequest;
39
use OCA\Circles\Db\MemberRequest;
40
use OCA\Circles\Exceptions\CircleNotFoundException;
41
use OCA\Circles\Exceptions\ContactAddressBookNotFoundException;
42
use OCA\Circles\Exceptions\ContactFormatException;
43
use OCA\Circles\Exceptions\ContactNotFoundException;
44
use OCA\Circles\Exceptions\FederatedEventException;
45
use OCA\Circles\Exceptions\FederatedItemException;
46
use OCA\Circles\Exceptions\FederatedUserException;
47
use OCA\Circles\Exceptions\FederatedUserNotFoundException;
48
use OCA\Circles\Exceptions\GroupNotFoundException;
49
use OCA\Circles\Exceptions\InitiatorNotConfirmedException;
50
use OCA\Circles\Exceptions\InvalidIdException;
51
use OCA\Circles\Exceptions\MigrationTo22Exception;
52
use OCA\Circles\Exceptions\OwnerNotFoundException;
53
use OCA\Circles\Exceptions\RemoteInstanceException;
54
use OCA\Circles\Exceptions\RemoteNotFoundException;
55
use OCA\Circles\Exceptions\RemoteResourceNotFoundException;
56
use OCA\Circles\Exceptions\RequestBuilderException;
57
use OCA\Circles\Exceptions\SingleCircleNotFoundException;
58
use OCA\Circles\Exceptions\UnknownRemoteException;
59
use OCA\Circles\FederatedItems\SingleMemberAdd;
60
use OCA\Circles\Model\Circle;
61
use OCA\Circles\Model\Federated\FederatedEvent;
62
use OCA\Circles\Model\FederatedUser;
63
use OCA\Circles\Model\ManagedModel;
64
use OCA\Circles\Model\Member;
65
use OCP\IGroupManager;
66
use OCP\IUserManager;
67
68
69
/**
70
 * Class SyncService
71
 *
72
 * @package OCA\Circles\Service
73
 */
74
class SyncService {
75
76
77
	use TStringTools;
78
79
80
	/** @var IUserManager */
81
	private $userManager;
82
83
	/** @var IGroupManager */
84
	private $groupManager;
85
86
	/** @var CircleRequest */
87
	private $circleRequest;
88
89
	/** @var MemberRequest */
90
	private $memberRequest;
91
92
	/** @var FederatedUserService */
93
	private $federatedUserService;
94
95
	/** @var federatedEventService */
96
	private $federatedEventService;
97
98
	/** @var MemberService */
99
	private $memberService;
100
101
	/** @var MembershipService */
102
	private $membershipService;
103
104
	/** @var ConfigService */
105
	private $configService;
106
107
108
	/**
109
	 * SyncService constructor.
110
	 *
111
	 * @param IUserManager $userManager
112
	 * @param IGroupManager $groupManager
113
	 * @param CircleRequest $circleRequest
114
	 * @param MemberRequest $memberRequest
115
	 * @param FederatedUserService $federatedUserService
116
	 * @param federatedEventService $federatedEventService
117
	 * @param MemberService $memberService
118
	 * @param MembershipService $membershipService
119
	 * @param ConfigService $configService
120
	 */
121 View Code Duplication
	public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
		IUserManager $userManager,
123
		IGroupManager $groupManager,
124
		CircleRequest $circleRequest,
125
		MemberRequest $memberRequest,
126
		FederatedUserService $federatedUserService,
127
		federatedEventService $federatedEventService,
128
		MemberService $memberService,
129
		MembershipService $membershipService,
130
		ConfigService $configService
131
	) {
132
		$this->userManager = $userManager;
133
		$this->groupManager = $groupManager;
134
		$this->circleRequest = $circleRequest;
135
		$this->memberRequest = $memberRequest;
136
		$this->federatedUserService = $federatedUserService;
137
		$this->federatedEventService = $federatedEventService;
138
		$this->memberService = $memberService;
139
		$this->membershipService = $membershipService;
140
		$this->configService = $configService;
141
	}
142
143
144
	/**
145
	 * @return bool
146
	 * @throws MigrationTo22Exception
147
	 */
148
	public function migration(): bool {
149
		if ($this->configService->getAppValueBool(ConfigService::MIGRATION_22)) {
150
			return false;
151
		}
152
153
		$this->migrationTo22();
154
		$this->configService->setAppValue(ConfigService::MIGRATION_22, '1');
155
156
		return true;
157
158
	}
159
160
	/**
161
	 * @return void
162
	 * @throws MigrationTo22Exception
163
	 */
164
	private function migrationTo22(): void {
165
		throw new MigrationTo22Exception('migration failed');
166
	}
167
168
169
	/**
170
	 * @return void
171
	 */
172
	public function syncAll(): void {
173
		$this->syncOcc();
174
		$this->syncNextcloudUsers();
175
		$this->syncGlobalScale();
176
		$this->syncRemote();
177
		$this->syncNextcloudGroups();
178
		$this->syncContacts();
179
	}
180
181
182
	/**
183
	 * @throws FederatedUserException
184
	 * @throws InvalidIdException
185
	 * @throws RequestBuilderException
186
	 * @throws SingleCircleNotFoundException
187
	 * @throws ContactAddressBookNotFoundException
188
	 * @throws ContactFormatException
189
	 * @throws ContactNotFoundException
190
	 */
191
	public function syncOcc(): void {
192
		$this->federatedUserService->getAppInitiator('occ', Member::APP_OCC);
193
	}
194
195
196
	/**
197
	 * @return void
198
	 */
199
	public function syncNextcloudUsers(): void {
200
		foreach ($this->userManager->search('') as $user) {
201
			try {
202
				$this->syncNextcloudUser($user->getUID());
203
			} catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
204
			}
205
		}
206
	}
207
208
	/**
209
	 * @param string $userId
210
	 *
211
	 * @return FederatedUser
212
	 * @throws FederatedUserException
213
	 * @throws FederatedUserNotFoundException
214
	 * @throws InvalidIdException
215
	 * @throws SingleCircleNotFoundException
216
	 * @throws RequestBuilderException
217
	 */
218
	public function syncNextcloudUser(string $userId): FederatedUser {
219
		return $this->federatedUserService->getLocalFederatedUser($userId);
220
	}
221
222
223
	/**
224
	 * @return void
225
	 */
226
	public function syncNextcloudGroups(): void {
227
		foreach ($this->groupManager->search('') as $group) {
228
			try {
229
				$this->syncNextcloudGroup($group->getGID());
230
			} catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
231
			}
232
		}
233
	}
234
235
	/**
236
	 * @param string $groupId
237
	 *
238
	 * @return Circle
239
	 * @throws FederatedUserException
240
	 * @throws FederatedUserNotFoundException
241
	 * @throws GroupNotFoundException
242
	 * @throws InvalidIdException
243
	 * @throws SingleCircleNotFoundException
244
	 * @throws FederatedEventException
245
	 * @throws FederatedItemException
246
	 * @throws InitiatorNotConfirmedException
247
	 * @throws OwnerNotFoundException
248
	 * @throws RemoteInstanceException
249
	 * @throws RemoteNotFoundException
250
	 * @throws RemoteResourceNotFoundException
251
	 * @throws UnknownRemoteException
252
	 * @throws RequestBuilderException
253
	 */
254
	public function syncNextcloudGroup(string $groupId): Circle {
255
		$circle = $this->federatedUserService->getGroupCircle($groupId);
256
		$group = $this->groupManager->get($groupId);
257
		foreach ($group->getUsers() as $user) {
258
			$member = $this->generateGroupMember($circle, $user->getUID());
259
			$event = new FederatedEvent(SingleMemberAdd::class);
260
			$event->setCircle($circle);
261
			$event->setMember($member);
262
			$this->federatedEventService->newEvent($event);
263
264
//			$this->memberRequest->insertOrUpdate($member);
265
		}
266
267
//		$this->membershipService->onUpdate($circle->getSingleId());
268
269
		return $circle;
270
	}
271
272
273
	/**
274
	 * @param string $userId
275
	 *
276
	 * @throws FederatedUserException
277
	 * @throws FederatedUserNotFoundException
278
	 * @throws InvalidIdException
279
	 * @throws RequestBuilderException
280
	 * @throws SingleCircleNotFoundException
281
	 */
282 View Code Duplication
	public function userDeleted(string $userId): void {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
283
		$federatedUser = $this->federatedUserService->getLocalFederatedUser($userId);
284
285
		// TODO: check existing circle generated by user !
286
		$this->circleRequest->delete($federatedUser->getBasedOn());
287
		$this->memberRequest->deleteAllFromCircle($federatedUser->getBasedOn());
288
		$this->membershipService->onUpdate($federatedUser->getSingleId());
289
	}
290
291
292
	/**
293
	 * @param string $groupId
294
	 *
295
	 * @throws FederatedUserException
296
	 * @throws InvalidIdException
297
	 * @throws RequestBuilderException
298
	 * @throws SingleCircleNotFoundException
299
	 */
300
	public function groupDeleted(string $groupId): void {
301
		$circle = new Circle();
302
		$circle->setName('group:' . $groupId)
303
			   ->setConfig(Circle::CFG_SYSTEM | Circle::CFG_NO_OWNER | Circle::CFG_HIDDEN)
304
			   ->setSource(Member::TYPE_GROUP);
305
306
		$owner = $this->federatedUserService->getAppInitiator(Application::APP_ID, Member::APP_CIRCLES);
307
308
		$member = new Member();
309
		$member->importFromIFederatedUser($owner);
310
		$member->setLevel(Member::LEVEL_OWNER)
311
			   ->setStatus(Member::STATUS_MEMBER);
312
		$circle->setOwner($member);
313
314
		try {
315
			$circle = $this->circleRequest->searchCircle($circle);
316
		} catch (CircleNotFoundException $e) {
317
			return;
318
		}
319
320
		$this->circleRequest->delete($circle);
321
		$this->memberRequest->deleteAllFromCircle($circle);
322
323
		$this->membershipService->onUpdate($circle->getSingleId());
324
	}
325
326
327
	/**
328
	 * @param Circle $circle
329
	 * @param string $userId
330
	 *
331
	 * @return Member
332
	 * @throws FederatedUserException
333
	 * @throws FederatedUserNotFoundException
334
	 * @throws InvalidIdException
335
	 * @throws RequestBuilderException
336
	 * @throws SingleCircleNotFoundException
337
	 */
338
	private function generateGroupMember(Circle $circle, string $userId): Member {
339
		$federatedUser = $this->federatedUserService->getLocalFederatedUser($userId);
340
341
		$member = new Member();
342
		$member->importFromIFederatedUser($federatedUser);
343
		$member->setId($this->uuid(ManagedModel::ID_LENGTH));
344
		$member->setCircleId($circle->getSingleId());
345
		$member->setLevel(Member::LEVEL_MEMBER);
346
		$member->setStatus(Member::STATUS_MEMBER);
347
		$member->setInvitedBy($this->federatedUserService->getCurrentApp());
0 ignored issues
show
Bug introduced by
It seems like $this->federatedUserService->getCurrentApp() can be null; however, setInvitedBy() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
348
349
		return $member;
350
	}
351
352
353
	/**
354
	 * @param string $groupId
355
	 * @param string $userId
356
	 *
357
	 * @return Member
358
	 * @throws FederatedEventException
359
	 * @throws FederatedItemException
360
	 * @throws FederatedUserException
361
	 * @throws FederatedUserNotFoundException
362
	 * @throws GroupNotFoundException
363
	 * @throws InitiatorNotConfirmedException
364
	 * @throws InvalidIdException
365
	 * @throws OwnerNotFoundException
366
	 * @throws RemoteInstanceException
367
	 * @throws RemoteNotFoundException
368
	 * @throws RemoteResourceNotFoundException
369
	 * @throws RequestBuilderException
370
	 * @throws SingleCircleNotFoundException
371
	 * @throws UnknownRemoteException
372
	 */
373
	public function groupMemberAdded(string $groupId, string $userId): void {
374
		$circle = $this->federatedUserService->getGroupCircle($groupId);
375
		$member = $this->generateGroupMember($circle, $userId);
376
377
		$event = new FederatedEvent(SingleMemberAdd::class);
378
		$event->setCircle($circle);
379
		$event->setMember($member);
380
		$this->federatedEventService->newEvent($event);
381
382
//		$this->memberRequest->insertOrUpdate($member);
383
384
//		$this->membershipService->onUpdate($member->getSingleId());
385
	}
386
387
388
	/**
389
	 * @param string $groupId
390
	 * @param string $userId
391
	 *
392
	 * @throws FederatedEventException
393
	 * @throws FederatedItemException
394
	 * @throws FederatedUserException
395
	 * @throws FederatedUserNotFoundException
396
	 * @throws GroupNotFoundException
397
	 * @throws InitiatorNotConfirmedException
398
	 * @throws InvalidIdException
399
	 * @throws OwnerNotFoundException
400
	 * @throws RemoteInstanceException
401
	 * @throws RemoteNotFoundException
402
	 * @throws RemoteResourceNotFoundException
403
	 * @throws RequestBuilderException
404
	 * @throws SingleCircleNotFoundException
405
	 * @throws UnknownRemoteException
406
	 */
407 View Code Duplication
	public function groupMemberRemoved(string $groupId, string $userId): void {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
408
		$circle = $this->federatedUserService->getGroupCircle($groupId);
409
		$federatedUser = $this->federatedUserService->getLocalFederatedUser($userId);
410
411
		$this->memberRequest->deleteFederatedUserFromCircle($federatedUser, $circle);
412
		$this->membershipService->onUpdate($federatedUser->getSingleId());
413
	}
414
415
416
	/**
417
	 * @return void
418
	 */
419
	public function syncContacts(): void {
420
	}
421
422
423
	/**
424
	 * @return void
425
	 */
426
	public function syncGlobalScale(): void {
427
	}
428
429
430
	/**
431
	 * @return void
432
	 */
433
	public function syncRemote(): void {
434
	}
435
436
437
	/**
438
	 * @param string $circleId
439
	 *
440
	 * @return void
441
	 */
442
	public function syncRemoteCircle(string $circleId): void {
0 ignored issues
show
Unused Code introduced by
The parameter $circleId is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
443
	}
444
445
446
}
447
448