Completed
Push — federated-circles ( 66c054...80cab6 )
by Maxence
02:37
created

FederatedService   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 173
Duplicated Lines 10.98 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 13
lcom 1
cbo 10
dl 19
loc 173
c 1
b 0
f 1
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 19 19 1
B linkCircle() 0 27 4
A generateLinkRemoteURL() 0 7 2
B requestLinkWithCircle() 0 28 2
A requestLinkStatus() 0 20 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Circles - Bring cloud-users closer together.
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 Exception;
31
use OC\Http\Client\ClientService;
32
use OCA\Circles\Db\CirclesMapper;
33
use OCA\Circles\Db\MembersMapper;
34
use OCA\Circles\Exceptions\FederatedCircleLinkFormatException;
35
use OCA\Circles\Exceptions\FederatedCircleNotAllowedException;
36
use OCA\Circles\Exceptions\CircleTypeNotValid;
37
use OCA\Circles\Exceptions\FederatedRemoteCircleDoesNotExistException;
38
use OCA\Circles\Exceptions\FederatedRemoteDoesNotAllowException;
39
use OCA\Circles\Exceptions\MemberIsNotAdminException;
40
use OCA\Circles\Model\Circle;
41
use OCP\IL10N;
42
use Sabre\HTTP\ClientException;
43
44
class FederatedService {
45
46
	/** @var string */
47
	private $userId;
48
49
	/** @var IL10N */
50
	private $l10n;
51
52
	/** @var ConfigService */
53
	private $configService;
54
55
	/** @var CirclesService */
56
	private $circlesService;
57
58
	/** @var CirclesMapper */
59
	private $dbCircles;
60
61
	/** @var MembersMapper */
62
	private $dbMembers;
63
64
	/** @var ClientService */
65
	private $clientService;
66
67
	/** @var MiscService */
68
	private $miscService;
69
70
71
	/**
72
	 * CirclesService constructor.
73
	 *
74
	 * @param $userId
75
	 * @param IL10N $l10n
76
	 * @param ConfigService $configService
77
	 * @param DatabaseService $databaseService
78
	 * @param CirclesService $circlesService
79
	 * @param ClientService $clientService
80
	 * @param MiscService $miscService
81
	 */
82 View Code Duplication
	public function __construct(
83
		$userId,
84
		IL10N $l10n,
85
		ConfigService $configService,
86
		DatabaseService $databaseService,
87
		CirclesService $circlesService,
88
		ClientService $clientService,
89
		MiscService $miscService
90
	) {
91
		$this->userId = $userId;
92
		$this->l10n = $l10n;
93
		$this->configService = $configService;
94
		$this->circlesService = $circlesService;
95
		$this->clientService = $clientService;
96
		$this->miscService = $miscService;
97
98
		$this->dbCircles = $databaseService->getCirclesMapper();
99
		$this->dbMembers = $databaseService->getMembersMapper();
100
	}
101
102
103
	/**
104
	 * link to a circle.
105
	 *
106
	 * @param int $circleId
107
	 * @param string $link
108
	 *
109
	 * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
110
	 * @throws Exception
111
	 * @throws FederatedCircleLinkFormatException
112
	 * @throws CircleTypeNotValid
113
	 * @throws MemberIsNotAdminException
114
	 */
115
	public function linkCircle($circleId, $link) {
116
117
		if (!$this->configService->isFederatedAllowed()) {
118
			throw new FederatedCircleNotAllowedException(
119
				$this->l10n->t("Federated circles are not allowed on this Nextcloud")
120
			);
121
		}
122
123
		if (strpos($link, '@') === false) {
124
			throw new FederatedCircleLinkFormatException(
125
				$this->l10n->t("Federated link does not have a valid format")
126
			);
127
		}
128
129
		list($remoteCircle, $remoteAddress) = explode('@', $link, 2);
130
		try {
131
132
			$circle = $this->circlesService->detailsCircle($circleId);
133
			$circle->getUser()
134
				   ->hasToBeAdmin();
135
			$circle->cantBePersonal();
136
137
			return $this->requestLinkWithCircle($circle, $remoteAddress, $remoteCircle);
138
		} catch (Exception $e) {
139
			throw $e;
140
		}
141
	}
142
143
	/**
144
	 * @param string $remote
145
	 *
146
	 * @return string
147
	 */
148
	private function generateLinkRemoteURL($remote) {
149
		if (strpos($remote, 'http') !== 0) {
150
			$remote = 'https://' . $remote;
151
		}
152
153
		return rtrim($remote, '/') . '/index.php/apps/circles/circles/link/';
154
	}
155
156
157
	/**
158
	 * @param Circle $circle
159
	 * @param $remoteAddress
160
	 * @param $remoteCircle
161
	 *
162
	 * @return integer
163
	 * @throws Exception
164
	 */
165
	private function requestLinkWithCircle(Circle $circle, $remoteAddress, $remoteCircle) {
166
		$this->miscService->log(
167
			"create link : " . $remoteCircle . ' - ' . $remoteAddress . ' - ' . $circle->getId()
168
		);
169
170
		$args = [
171
			'source'     => $circle->getId(),
172
			'circleName' => $remoteCircle
173
		];
174
175
		$client = $this->clientService->newClient();
176
		try {
177
			$request = $client->put(
178
				$this->generateLinkRemoteURL($remoteAddress), [
179
																'body'            => $args,
180
																'timeout'         => 10,
181
																'connect_timeout' => 10,
182
															]
183
			);
184
185
			$result = json_decode($request->getBody(), true);
186
			$this->requestLinkStatus($result);
187
188
			return 1;
189
		} catch (Exception $e) {
190
			throw $e;
191
		}
192
	}
193
194
195
	private function requestLinkStatus($result) {
196
197
		if ($result['status'] === 1) {
198
			return;
199
		}
200
201
		if ($result['reason'] === 'federated_not_allowed') {
202
			throw new FederatedRemoteDoesNotAllowException(
203
				$this->l10n->t('Federated circles are not allowed on the remote Nextcloud')
204
			);
205
		}
206
207
		if ($result['reason'] === 'circle_does_not_exist') {
208
			throw new FederatedRemoteCircleDoesNotExistException(
209
				$this->l10n->t('The requested remote circle does not exist')
210
			);
211
		}
212
213
		throw new Exception();
214
	}
215
216
}