Completed
Pull Request — master (#551)
by Maxence
02:27
created

MemberService   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 12
dl 0
loc 177
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A getMember() 0 18 3
A getMembers() 0 3 1
A addMember() 0 18 2
A memberLevel() 0 12 1
A parseLevelString() 0 12 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\Exceptions\RequestNetworkException;
36
use daita\MySmallPhpTools\Exceptions\SignatoryException;
37
use daita\MySmallPhpTools\Model\SimpleDataStore;
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\Exceptions\CircleNotFoundException;
45
use OCA\Circles\Exceptions\FederatedEventException;
46
use OCA\Circles\Exceptions\FederatedItemException;
47
use OCA\Circles\Exceptions\InitiatorNotConfirmedException;
48
use OCA\Circles\Exceptions\InitiatorNotFoundException;
49
use OCA\Circles\Exceptions\MemberLevelException;
50
use OCA\Circles\Exceptions\MemberNotFoundException;
51
use OCA\Circles\Exceptions\OwnerNotFoundException;
52
use OCA\Circles\Exceptions\RemoteNotFoundException;
53
use OCA\Circles\Exceptions\RemoteResourceNotFoundException;
54
use OCA\Circles\Exceptions\UnknownRemoteException;
55
use OCA\Circles\FederatedItems\MemberAdd;
56
use OCA\Circles\FederatedItems\MemberLevel;
57
use OCA\Circles\IFederatedUser;
58
use OCA\Circles\Model\Federated\FederatedEvent;
59
use OCA\Circles\Model\FederatedUser;
60
use OCA\Circles\Model\Member;
61
62
63
/**
64
 * Class MemberService
65
 *
66
 * @package OCA\Circles\Service
67
 */
68
class MemberService {
69
70
71
	use TArrayTools;
72
	use TStringTools;
73
	use TNC21Logger;
74
75
76
	/** @var CircleRequest */
77
	private $circleRequest;
78
79
	/** @var MemberRequest */
80
	private $memberRequest;
81
82
	/** @var FederatedUserService */
83
	private $federatedUserService;
84
85
	/** @var FederatedEventService */
86
	private $federatedEventService;
87
88
89
	/**
90
	 * MemberService constructor.
91
	 *
92
	 * @param CircleRequest $circleRequest
93
	 * @param MemberRequest $memberRequest
94
	 * @param FederatedUserService $federatedUserService
95
	 * @param FederatedEventService $federatedEventService
96
	 */
97
	public function __construct(
98
		CircleRequest $circleRequest, MemberRequest $memberRequest,
99
		FederatedUserService $federatedUserService,
100
		FederatedEventService $federatedEventService
101
	) {
102
		$this->circleRequest = $circleRequest;
103
		$this->memberRequest = $memberRequest;
104
		$this->federatedUserService = $federatedUserService;
105
		$this->federatedEventService = $federatedEventService;
106
	}
107
108
//
109
//	/**
110
//	 * @param Member $member
111
//	 *
112
//	 * @throws MemberAlreadyExistsException
113
//	 */
114
//	public function saveMember(Member $member) {
115
//		$member->setId($this->token(Member::ID_LENGTH));
116
//		$this->memberRequest->save($member);
117
//	}
118
//
119
120
121
	/**
122
	 * @param string $memberId
123
	 *
124
	 * @return Member
125
	 * @throws InitiatorNotFoundException
126
	 * @throws MemberLevelException
127
	 */
128
	public function getMember(string $memberId): Member {
129
		$this->federatedUserService->mustHaveCurrentUser();
130
131
		try {
132
			$member = $this->memberRequest->getMember($memberId);
133
			$circle = $this->circleRequest->getCircle(
134
				$member->getCircleId(), $this->federatedUserService->getCurrentUser()
135
			);
136
			if (!$circle->getInitiator()->isMember()) {
137
				throw new MemberLevelException();
138
			}
139
140
			return $member;
141
		} catch (Exception $e) {
142
			$this->e($e, ['id' => $memberId, 'initiator' => $this->federatedUserService->getCurrentUser()]);
143
			throw new MemberLevelException('insufficient rights');
144
		}
145
	}
146
147
148
	/**
149
	 * @param string $circleId
150
	 *
151
	 * @return Member[]
152
	 */
153
	public function getMembers(string $circleId): array {
154
		return $this->memberRequest->getMembers($circleId);
155
	}
156
157
158
	/**
159
	 * @param string $circleId
160
	 * @param IFederatedUser $member
161
	 *
162
	 * @return SimpleDataStore
163
	 * @throws CircleNotFoundException
164
	 * @throws FederatedEventException
165
	 * @throws InitiatorNotConfirmedException
166
	 * @throws InitiatorNotFoundException
167
	 * @throws OwnerNotFoundException
168
	 * @throws RemoteNotFoundException
169
	 * @throws RemoteResourceNotFoundException
170
	 * @throws RequestNetworkException
171
	 * @throws SignatoryException
172
	 * @throws UnknownRemoteException
173
	 * @throws FederatedItemException
174
	 */
175
	public function addMember(string $circleId, IFederatedUser $member): SimpleDataStore {
176
		$this->federatedUserService->mustHaveCurrentUser();
177
		$circle = $this->circleRequest->getCircle($circleId, $this->federatedUserService->getCurrentUser());
178
179
		if ($member instanceof FederatedUser) {
180
			$tmp = new Member();
181
			$tmp->importFromIFederatedUser($member);
182
			$member = $tmp;
183
		}
184
185
		$event = new FederatedEvent(MemberAdd::class);
186
		$event->setCircle($circle);
187
		$event->setMember($member);
0 ignored issues
show
Documentation introduced by
$member is of type object<OCA\Circles\IFederatedUser>, but the function expects a object<OCA\Circles\Model\Member>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
188
189
		$this->federatedEventService->newEvent($event);
190
191
		return $event->getOutcome();
192
	}
193
194
195
	/**
196
	 * @param string $memberId
197
	 * @param int $level
198
	 *
199
	 * @throws FederatedEventException
200
	 * @throws InitiatorNotConfirmedException
201
	 * @throws InitiatorNotFoundException
202
	 * @throws MemberNotFoundException
203
	 * @throws OwnerNotFoundException
204
	 * @throws RemoteNotFoundException
205
	 * @throws RemoteResourceNotFoundException
206
	 * @throws RequestNetworkException
207
	 * @throws SignatoryException
208
	 * @throws UnknownRemoteException
209
	 */
210
	public function memberLevel(string $memberId, int $level): void {
211
		$this->federatedUserService->mustHaveCurrentUser();
212
213
		$member = $this->memberRequest->getMember($memberId, $this->federatedUserService->getCurrentUser());
214
		$event = new FederatedEvent(MemberLevel::class);
215
		$event->setCircle($member->getCircle());
216
		$event->setMember($member);
217
		$event->setData(new SimpleDataStore(['level' => $level]));
218
219
		$this->federatedEventService->newEvent($event);
220
221
	}
222
223
224
	/**
225
	 * @param string $levelString
226
	 *
227
	 * @return int
228
	 * @throws MemberLevelException
229
	 */
230
	public function parseLevelString(string $levelString): int {
231
		$levelString = ucfirst(strtolower($levelString));
232
		$level = array_search($levelString, Member::$DEF_LEVEL);
0 ignored issues
show
Bug introduced by
The property DEF_LEVEL cannot be accessed from this context as it is declared private in class OCA\Circles\Model\Member.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
233
234
		if (!$level) {
235
			throw new MemberLevelException(
236
				'Available levels: ' . implode(', ', array_values(Member::$DEF_LEVEL))
0 ignored issues
show
Bug introduced by
The property DEF_LEVEL cannot be accessed from this context as it is declared private in class OCA\Circles\Model\Member.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
237
			);
238
		}
239
240
		return (int)$level;
241
	}
242
243
244
}
245
246