Completed
Push — master ( 060fe4...9de15f )
by Maxence
02:41
created

MembersService::getRealUserId()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
/**
3
 * Circles - bring cloud-users closer
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2017
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\Circles\Service;
28
29
30
use OC\User\NoUserException;
31
use OCA\Circles\Db\CirclesRequest;
32
use OCA\Circles\Db\MembersRequest;
33
use OCA\Circles\Exceptions\CircleTypeNotValidException;
34
use OCA\Circles\Exceptions\EmailAccountInvalidFormatException;
35
use OCA\Circles\Exceptions\GroupDoesNotExistException;
36
use OCA\Circles\Exceptions\MemberAlreadyExistsException;
37
use OCA\Circles\Exceptions\MemberDoesNotExistException;
38
use OCA\Circles\Model\Circle;
39
use \OCA\Circles\Model\Member;
40
use OCP\IL10N;
41
use OCP\IUserManager;
42
43
class MembersService {
44
45
	/** @var string */
46
	private $userId;
47
48
	/** @var IL10N */
49
	private $l10n;
50
51
	/** @var IUserManager */
52
	private $userManager;
53
54
	/** @var ConfigService */
55
	private $configService;
56
57
	/** @var CirclesRequest */
58
	private $circlesRequest;
59
60
	/** @var MembersRequest */
61
	private $membersRequest;
62
63
	/** @var EventsService */
64
	private $eventsService;
65
66
	/** @var MiscService */
67
	private $miscService;
68
69
	/**
70
	 * MembersService constructor.
71
	 *
72
	 * @param $userId
73
	 * @param IL10N $l10n
74
	 * @param IUserManager $userManager
75
	 * @param ConfigService $configService
76
	 * @param CirclesRequest $circlesRequest
77
	 * @param MembersRequest $membersRequest
78
	 * @param EventsService $eventsService
79
	 * @param MiscService $miscService
80
	 */
81 View Code Duplication
	public function __construct(
1 ignored issue
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...
82
		$userId,
83
		IL10N $l10n,
84
		IUserManager $userManager,
85
		ConfigService $configService,
86
		CirclesRequest $circlesRequest,
87
		MembersRequest $membersRequest,
88
		EventsService $eventsService,
89
		MiscService $miscService
90
	) {
91
		$this->userId = $userId;
92
		$this->l10n = $l10n;
93
		$this->userManager = $userManager;
94
		$this->configService = $configService;
95
		$this->circlesRequest = $circlesRequest;
96
		$this->membersRequest = $membersRequest;
97
		$this->eventsService = $eventsService;
98
		$this->miscService = $miscService;
99
	}
100
101
102
	/**
103
	 * @param string $circleUniqueId
104
	 * @param string $name
105
	 *
106
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use Member[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
107
	 * @throws \Exception
108
	 */
109 View Code Duplication
	public function addLocalMember($circleUniqueId, $name) {
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...
110
111
		try {
112
			$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
113
			$circle->getHigherViewer()
114
				   ->hasToBeModerator();
115
		} catch (\Exception $e) {
116
			throw $e;
117
		}
118
119
		try {
120
			$member =
121
				$this->membersRequest->getFreshNewMember($circleUniqueId, $name, Member::TYPE_USER);
122
			$member->hasToBeInviteAble();
123
124
		} catch (\Exception $e) {
125
			throw $e;
126
		}
127
128
		$member->inviteToCircle($circle->getType());
129
		$this->membersRequest->updateMember($member);
130
131
		$this->eventsService->onMemberNew($circle, $member);
132
133
		return $this->membersRequest->getMembers(
134
			$circle->getUniqueId(), $circle->getHigherViewer()
135
		);
136
	}
137
138
139
	/**
140
	 * @param string $circleUniqueId
141
	 * @param string $email
142
	 *
143
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use Member[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
144
	 * @throws \Exception
145
	 */
146
	public function addEmailAddress($circleUniqueId, $email) {
147
148
		$this->miscService->log('___' . $email);
149
		if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
150
			throw new EmailAccountInvalidFormatException(
151
				$this->l10n->t('Email format is not valid')
152
			);
153
		}
154
155
		try {
156
			$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
157
			$circle->getHigherViewer()
158
				   ->hasToBeModerator();
159
		} catch (\Exception $e) {
160
			throw $e;
161
		}
162
163
		try {
164
			$member = $this->membersRequest->getFreshNewMember(
165
				$circleUniqueId, $email, Member::TYPE_MAIL
166
			);
167
			$member->hasToBeInviteAble();
168
169
		} catch (\Exception $e) {
170
			throw $e;
171
		}
172
173
		$this->miscService->log('___' . json_encode($member));
174
175
//
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
176
//		$member->inviteToCircle($circle->getType());
177
//		$this->membersRequest->updateMember($member);
178
//
179
//		$this->eventsService->onMemberNew($circle, $member);
180
//
181
		return $this->membersRequest->getMembers(
182
			$circle->getUniqueId(), $circle->getHigherViewer()
183
		);
184
	}
185
186
187
	/**
188
	 * @param string $circleUniqueId
189
	 * @param string $groupId
190
	 *
191
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use Member[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
192
	 * @throws \Exception
193
	 */
194
	public function importMembersFromGroup($circleUniqueId, $groupId) {
195
196
		try {
197
			$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
198
			$circle->getHigherViewer()
199
				   ->hasToBeModerator();
200
		} catch (\Exception $e) {
201
			throw $e;
202
		}
203
204
		$group = \OC::$server->getGroupManager()
205
							 ->get($groupId);
206
		if ($group === null) {
207
			throw new GroupDoesNotExistException($this->l10n->t('This group does not exist'));
208
		}
209
210
		foreach ($group->getUsers() as $user) {
211
			try {
212
				$member =
213
					$this->membersRequest->getFreshNewMember(
214
						$circleUniqueId, $user->getUID(), Member::TYPE_USER
215
					);
216
				$member->hasToBeInviteAble();
217
218
				$member->inviteToCircle($circle->getType());
219
				$this->membersRequest->updateMember($member);
220
221
				$this->eventsService->onMemberNew($circle, $member);
222
			} catch (MemberAlreadyExistsException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
223
			} catch (\Exception $e) {
224
				throw $e;
225
			}
226
		}
227
228
		return $this->membersRequest->getMembers(
229
			$circle->getUniqueId(), $circle->getHigherViewer()
230
		);
231
	}
232
233
234
	/**
235
	 * getMember();
236
	 *
237
	 * Will return any data of a user related to a circle (as a Member). User can be a 'non-member'
238
	 * Viewer needs to be at least Member of the Circle
239
	 *
240
	 * @param $circleId
241
	 * @param $userId
242
	 * @param $type
243
	 *
244
	 * @return Member
245
	 * @throws \Exception
246
	 */
247
	public function getMember($circleId, $userId, $type) {
248
249
		try {
250
			$this->circlesRequest->getCircle($circleId, $this->userId)
251
								 ->getHigherViewer()
252
								 ->hasToBeMember();
253
254
			$member = $this->membersRequest->forceGetMember($circleId, $userId, $type);
255
			$member->setNote('');
256
257
			return $member;
258
		} catch (\Exception $e) {
259
			throw $e;
260
		}
261
	}
262
263
264
	/**
265
	 * @param string $circleUniqueId
266
	 * @param string $name
267
	 * @param int $level
268
	 *
269
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use Member[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
270
	 * @throws \Exception
271
	 */
272
	public function levelLocalMember($circleUniqueId, $name, $level) {
273
274
		$level = (int)$level;
275
		try {
276
			$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
277
			if ($circle->getType() === Circle::CIRCLES_PERSONAL) {
278
				throw new CircleTypeNotValidException(
279
					$this->l10n->t('You cannot edit level in a personal circle')
280
				);
281
			}
282
283
			$member = $this->membersRequest->forceGetMember(
284
				$circle->getUniqueId(), $name, Member::TYPE_USER
285
			);
286
			if ($member->getLevel() !== $level) {
287
				if ($level === Member::LEVEL_OWNER) {
288
					$this->switchOwner($circle, $member);
289
				} else {
290
					$this->editMemberLevel($circle, $member, $level);
291
				}
292
293
				$this->eventsService->onMemberLevel($circle, $member);
294
			}
295
296
			return $this->membersRequest->getMembers(
297
				$circle->getUniqueId(), $circle->getHigherViewer()
298
			);
299
		} catch (\Exception $e) {
300
			throw $e;
301
		}
302
303
	}
304
305
306
	/**
307
	 * @param Circle $circle
308
	 * @param Member $member
309
	 * @param $level
310
	 *
311
	 * @throws \Exception
312
	 */
313
	private function editMemberLevel(Circle $circle, Member &$member, $level) {
314
		try {
315
			$isMod = $circle->getHigherViewer();
316
			$isMod->hasToBeModerator();
317
			$isMod->hasToBeHigherLevel($level);
318
319
			$member->hasToBeMember();
320
			$member->cantBeOwner();
321
			$isMod->hasToBeHigherLevel($member->getLevel());
322
323
			$member->setLevel($level);
324
			$this->membersRequest->updateMember($member);
325
		} catch (\Exception $e) {
326
			throw $e;
327
		}
328
329
	}
330
331
	/**
332
	 * @param Circle $circle
333
	 * @param Member $member
334
	 *
335
	 * @throws \Exception
336
	 */
337
	private function switchOwner(Circle $circle, Member &$member) {
338
		try {
339
			$isMod = $circle->getHigherViewer();
340
			$isMod->hasToBeOwner();
341
342
			$member->hasToBeMember();
343
			$member->cantBeOwner();
344
345
			$member->setLevel(Member::LEVEL_OWNER);
346
			$this->membersRequest->updateMember($member);
347
348
			$isMod->setLevel(Member::LEVEL_ADMIN);
349
			$this->membersRequest->updateMember($isMod);
350
351
		} catch (\Exception $e) {
352
			throw $e;
353
		}
354
	}
355
356
357
	/**
358
	 * @param string $circleUniqueId
359
	 * @param string $name
360
	 * @param $type
361
	 *
362
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use Member[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
363
	 * @throws \Exception
364
	 */
365
	public function removeMember($circleUniqueId, $name, $type) {
366
367
		try {
368
			$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
369
			$circle->getHigherViewer()
370
				   ->hasToBeModerator();
371
372
			$member = $this->membersRequest->forceGetMember($circleUniqueId, $name, $type);
373
			$member->hasToBeMemberOrAlmost();
374
			$member->cantBeOwner();
375
376
			$circle->getHigherViewer()
377
				   ->hasToBeHigherLevel($member->getLevel());
378
		} catch (\Exception $e) {
379
			throw $e;
380
		}
381
382
		$this->eventsService->onMemberLeaving($circle, $member);
383
384
		$member->setStatus(Member::STATUS_NONMEMBER);
385
		$member->setLevel(Member::LEVEL_NONE);
386
		$this->membersRequest->updateMember($member);
387
388
		return $this->membersRequest->getMembers(
389
			$circle->getUniqueId(), $circle->getHigherViewer()
390
		);
391
	}
392
393
394
	/**
395
	 * When a user is removed, remove him from all Circles
396
	 *
397
	 * @param $userId
398
	 */
399
	public function onUserRemoved($userId) {
400
		$this->membersRequest->removeAllFromUser($userId);
401
	}
402
403
404
}