1<?php
2
3declare(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 <maxence@artificial-owl.com>
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
32namespace OCA\Circles;
33
34use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException;
35use OCA\Circles\Exceptions\CircleNotFoundException;
36use OCA\Circles\Exceptions\ContactAddressBookNotFoundException;
37use OCA\Circles\Exceptions\ContactFormatException;
38use OCA\Circles\Exceptions\ContactNotFoundException;
39use OCA\Circles\Exceptions\FederatedEventException;
40use OCA\Circles\Exceptions\FederatedItemException;
41use OCA\Circles\Exceptions\FederatedUserException;
42use OCA\Circles\Exceptions\FederatedUserNotFoundException;
43use OCA\Circles\Exceptions\InitiatorNotConfirmedException;
44use OCA\Circles\Exceptions\InitiatorNotFoundException;
45use OCA\Circles\Exceptions\InvalidIdException;
46use OCA\Circles\Exceptions\MemberNotFoundException;
47use OCA\Circles\Exceptions\MembershipNotFoundException;
48use OCA\Circles\Exceptions\OwnerNotFoundException;
49use OCA\Circles\Exceptions\RemoteInstanceException;
50use OCA\Circles\Exceptions\RemoteNotFoundException;
51use OCA\Circles\Exceptions\RemoteResourceNotFoundException;
52use OCA\Circles\Exceptions\RequestBuilderException;
53use OCA\Circles\Exceptions\SingleCircleNotFoundException;
54use OCA\Circles\Exceptions\UnknownRemoteException;
55use OCA\Circles\Exceptions\UserTypeNotFoundException;
56use OCA\Circles\Model\Circle;
57use OCA\Circles\Model\FederatedUser;
58use OCA\Circles\Model\Member;
59use OCA\Circles\Model\Membership;
60use OCA\Circles\Model\Probes\CircleProbe;
61use OCA\Circles\Service\CircleService;
62use OCA\Circles\Service\FederatedUserService;
63use OCA\Circles\Service\MemberService;
64use OCA\Circles\Service\MembershipService;
65use OCP\IUserSession;
66
67/**
68 * Class CirclesManager
69 *
70 * @package OCA\Circles
71 */
72class CirclesManager {
73
74
75	/** @var CirclesQueryHelper */
76	private $circlesQueryHelper;
77
78	/** @var FederatedUserService */
79	private $federatedUserService;
80
81	/** @var CircleService */
82	private $circleService;
83
84	/** @var MemberService */
85	private $memberService;
86
87	/** @var MembershipService */
88	private $membershipService;
89
90
91	/**
92	 * CirclesManager constructor.
93	 *
94	 * @param IUserSession $userSession
95	 * @param FederatedUserService $federatedUserService
96	 * @param CircleService $circleService
97	 * @param MemberService $memberService
98	 * @param CirclesQueryHelper $circlesQueryHelper
99	 */
100	public function __construct(
101		FederatedUserService $federatedUserService,
102		CircleService $circleService,
103		MemberService $memberService,
104		MembershipService $membershipService,
105		CirclesQueryHelper $circlesQueryHelper
106	) {
107		$this->federatedUserService = $federatedUserService;
108		$this->circleService = $circleService;
109		$this->memberService = $memberService;
110		$this->membershipService = $membershipService;
111		$this->circlesQueryHelper = $circlesQueryHelper;
112	}
113
114
115	/**
116	 * @param string $federatedId
117	 * @param int $type
118	 *
119	 * @return FederatedUser
120	 * @throws CircleNotFoundException
121	 * @throws FederatedItemException
122	 * @throws FederatedUserException
123	 * @throws FederatedUserNotFoundException
124	 * @throws InvalidIdException
125	 * @throws MemberNotFoundException
126	 * @throws OwnerNotFoundException
127	 * @throws RemoteInstanceException
128	 * @throws RemoteNotFoundException
129	 * @throws RemoteResourceNotFoundException
130	 * @throws RequestBuilderException
131	 * @throws SingleCircleNotFoundException
132	 * @throws UnknownRemoteException
133	 * @throws UserTypeNotFoundException
134	 */
135	public function getFederatedUser(string $federatedId, int $type = Member::TYPE_SINGLE): FederatedUser {
136		return $this->federatedUserService->getFederatedUser($federatedId, $type);
137	}
138
139
140	/**
141	 * @throws FederatedUserNotFoundException
142	 * @throws SingleCircleNotFoundException
143	 * @throws RequestBuilderException
144	 * @throws InvalidIdException
145	 * @throws FederatedUserException
146	 */
147	public function startSession(?FederatedUser $federatedUser = null): void {
148		if (is_null($federatedUser)) {
149			$this->federatedUserService->initCurrentUser();
150		} else {
151			$this->federatedUserService->setCurrentUser($federatedUser);
152		}
153	}
154
155	/**
156	 *
157	 */
158	public function startSuperSession(): void {
159		$this->federatedUserService->unsetCurrentUser();
160		$this->federatedUserService->bypassCurrentUserCondition(true);
161	}
162
163
164	/**
165	 * $userId - userId to emulate as initiator (can be empty)
166	 * $userType - specify if userIs not a singleId
167	 * $circleId - if no userId specified, will use the owner of the Circle as initiator
168	 *
169	 * @param string $userId
170	 * @param int $userType
171	 * @param string $circleId
172	 *
173	 * @throws CircleNotFoundException
174	 * @throws FederatedItemException
175	 * @throws FederatedUserException
176	 * @throws FederatedUserNotFoundException
177	 * @throws InvalidIdException
178	 * @throws MemberNotFoundException
179	 * @throws OwnerNotFoundException
180	 * @throws RemoteInstanceException
181	 * @throws RemoteNotFoundException
182	 * @throws RemoteResourceNotFoundException
183	 * @throws RequestBuilderException
184	 * @throws SingleCircleNotFoundException
185	 * @throws UnknownRemoteException
186	 * @throws UserTypeNotFoundException
187	 */
188	public function startOccSession(
189		string $userId,
190		int $userType = Member::TYPE_SINGLE,
191		string $circleId = ''
192	): void {
193		$this->federatedUserService->commandLineInitiator($userId, $userType, $circleId);
194	}
195
196
197	/**
198	 *
199	 */
200	public function stopSession(): void {
201		$this->federatedUserService->unsetCurrentUser();
202		$this->federatedUserService->bypassCurrentUserCondition(false);
203	}
204
205
206	/**
207	 * @return IFederatedUser
208	 */
209	public function getCurrentFederatedUser(): IFederatedUser {
210		return $this->federatedUserService->getCurrentUser();
211	}
212
213
214	/**
215	 * @return CirclesQueryHelper
216	 */
217	public function getQueryHelper(): CirclesQueryHelper {
218		return $this->circlesQueryHelper;
219	}
220
221
222	/**
223	 * @param string $name
224	 * @param FederatedUser|null $owner
225	 * @param bool $personal
226	 * @param bool $local
227	 *
228	 * @return Circle
229	 * @throws FederatedEventException
230	 * @throws InitiatorNotConfirmedException
231	 * @throws FederatedItemException
232	 * @throws InitiatorNotFoundException
233	 * @throws InvalidItemException
234	 * @throws OwnerNotFoundException
235	 * @throws RemoteInstanceException
236	 * @throws RemoteNotFoundException
237	 * @throws RemoteResourceNotFoundException
238	 * @throws RequestBuilderException
239	 * @throws UnknownRemoteException
240	 */
241	public function createCircle(
242		string $name,
243		?FederatedUser $owner = null,
244		bool $personal = false,
245		bool $local = false
246	): Circle {
247		$outcome = $this->circleService->create($name, $owner, $personal, $local);
248		$circle = new Circle();
249		$circle->import($outcome);
250
251		return $circle;
252	}
253
254
255	/**
256	 * @param string $singleId
257	 *
258	 * @throws CircleNotFoundException
259	 * @throws FederatedEventException
260	 * @throws FederatedItemException
261	 * @throws InitiatorNotConfirmedException
262	 * @throws InitiatorNotFoundException
263	 * @throws OwnerNotFoundException
264	 * @throws RemoteInstanceException
265	 * @throws RemoteNotFoundException
266	 * @throws RemoteResourceNotFoundException
267	 * @throws RequestBuilderException
268	 * @throws UnknownRemoteException
269	 */
270	public function destroyCircle(string $singleId): void {
271		$this->circleService->destroy($singleId);
272	}
273
274
275	/**
276	 * returns Circles available, based on current session
277	 *
278	 * @return Circle[]
279	 * @throws InitiatorNotFoundException
280	 * @throws RequestBuilderException
281	 */
282	public function getCircles(?CircleProbe $probe = null): array {
283		if (is_null($probe)) {
284			$probe = new CircleProbe();
285			$probe->filterHiddenCircles()
286				  ->filterBackendCircles();
287		}
288
289		return $this->circleService->getCircles($probe);
290	}
291
292
293	/**
294	 * @param string $singleId
295	 * @param CircleProbe|null $probe
296	 *
297	 * @return Circle
298	 * @throws CircleNotFoundException
299	 * @throws InitiatorNotFoundException
300	 * @throws RequestBuilderException
301	 */
302	public function getCircle(string $singleId, ?CircleProbe $probe = null): Circle {
303		return $this->circleService->getCircle($singleId, $probe);
304	}
305
306
307	/**
308	 * @param string $circleId
309	 * @param FederatedUser $federatedUser
310	 *
311	 * @return Member
312	 * @throws CircleNotFoundException
313	 * @throws ContactAddressBookNotFoundException
314	 * @throws ContactFormatException
315	 * @throws ContactNotFoundException
316	 * @throws FederatedEventException
317	 * @throws FederatedItemException
318	 * @throws FederatedUserException
319	 * @throws InitiatorNotConfirmedException
320	 * @throws InitiatorNotFoundException
321	 * @throws InvalidIdException
322	 * @throws InvalidItemException
323	 * @throws OwnerNotFoundException
324	 * @throws RemoteInstanceException
325	 * @throws RemoteNotFoundException
326	 * @throws RemoteResourceNotFoundException
327	 * @throws RequestBuilderException
328	 * @throws SingleCircleNotFoundException
329	 * @throws UnknownRemoteException
330	 */
331	public function addMember(string $circleId, FederatedUser $federatedUser): Member {
332		$outcome = $this->memberService->addMember($circleId, $federatedUser);
333		$member = new Member();
334		$member->import($outcome);
335
336		return $member;
337	}
338
339
340	/**
341	 * @param string $memberId
342	 * @param int $level
343	 *
344	 * @return Member
345	 * @throws FederatedEventException
346	 * @throws FederatedItemException
347	 * @throws InitiatorNotConfirmedException
348	 * @throws InitiatorNotFoundException
349	 * @throws InvalidItemException
350	 * @throws MemberNotFoundException
351	 * @throws OwnerNotFoundException
352	 * @throws RemoteNotFoundException
353	 * @throws RemoteResourceNotFoundException
354	 * @throws RequestBuilderException
355	 * @throws UnknownRemoteException
356	 */
357	public function levelMember(string $memberId, int $level): Member {
358		$outcome = $this->memberService->memberLevel($memberId, $level);
359		$member = new Member();
360		$member->import($outcome);
361
362		return $member;
363	}
364
365
366	/**
367	 * @param string $memberId
368	 *
369	 * @throws FederatedEventException
370	 * @throws FederatedItemException
371	 * @throws InitiatorNotConfirmedException
372	 * @throws InitiatorNotFoundException
373	 * @throws MemberNotFoundException
374	 * @throws OwnerNotFoundException
375	 * @throws RemoteNotFoundException
376	 * @throws RemoteResourceNotFoundException
377	 * @throws RequestBuilderException
378	 * @throws UnknownRemoteException
379	 */
380	public function removeMember(string $memberId): void {
381		$this->memberService->removeMember($memberId);
382	}
383
384
385	/**
386	 * @param string $circleId
387	 * @param string $singleId
388	 * @param bool $detailed
389	 *
390	 * @return Membership
391	 * @throws MembershipNotFoundException
392	 * @throws RequestBuilderException
393	 */
394	public function getLink(string $circleId, string $singleId, bool $detailed = false): Membership {
395		return $this->membershipService->getMembership($circleId, $singleId, $detailed);
396	}
397
398
399	/**
400	 * @param IEntity $circle
401	 *
402	 * @return string
403	 */
404	public function getDefinition(IEntity $circle): string {
405		return $this->circleService->getDefinition($circle);
406	}
407
408
409	/**
410	 * WIP
411	 *
412	 * @param string $circleId
413	 * @param string $singleId
414	 *
415	 * @return Member
416	 * @throws InitiatorNotFoundException
417	 * @throws MemberNotFoundException
418	 * @throws RequestBuilderException
419	 */
420//	public function getMember(string $circleId, string $singleId): Member {
421//		$this->federatedUserService->bypassCurrentUserCondition(true);
422//		$this->memberService->getMemberById($circleId, $singleId);
423//	}
424
425
426	/**
427	 * WIP
428	 *
429	 * @param string $memberId
430	 *
431	 * @return Member
432	 */
433//	public function getMemberById(string $memberId): Member {
434}
435