|
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\Controller; |
|
28
|
|
|
|
|
29
|
|
|
use Exception; |
|
30
|
|
|
use OC\AppFramework\Http; |
|
31
|
|
|
use OCA\Circles\Api\v1\Circles; |
|
32
|
|
|
use OCA\Circles\Exceptions\CircleDoesNotExistException; |
|
33
|
|
|
use OCA\Circles\Exceptions\SharingFrameAlreadyExistException; |
|
34
|
|
|
use OCA\Circles\Model\FederatedLink; |
|
35
|
|
|
use OCA\Circles\Model\SharingFrame; |
|
36
|
|
|
use OCA\Circles\Service\BroadcastService; |
|
37
|
|
|
use OCA\Circles\Service\CirclesService; |
|
38
|
|
|
use OCA\Circles\Service\ConfigService; |
|
39
|
|
|
use OCA\Circles\Service\FederatedLinkCreationService; |
|
40
|
|
|
use OCA\Circles\Service\FederatedLinkService; |
|
41
|
|
|
use OCA\Circles\Service\MembersService; |
|
42
|
|
|
use OCA\Circles\Service\MiscService; |
|
43
|
|
|
use OCA\Circles\Service\SharingFrameService; |
|
44
|
|
|
use OCP\AppFramework\Controller; |
|
45
|
|
|
use OCP\AppFramework\Http\DataResponse; |
|
46
|
|
|
use OCP\IRequest; |
|
47
|
|
|
|
|
48
|
|
|
class FederatedController extends Controller { |
|
49
|
|
|
|
|
50
|
|
|
/** @var ConfigService */ |
|
51
|
|
|
protected $configService; |
|
52
|
|
|
|
|
53
|
|
|
/** @var CirclesService */ |
|
54
|
|
|
protected $circlesService; |
|
55
|
|
|
|
|
56
|
|
|
/** @var MembersService */ |
|
57
|
|
|
protected $membersService; |
|
58
|
|
|
|
|
59
|
|
|
/** @var SharingFrameService */ |
|
60
|
|
|
protected $sharingFrameService; |
|
61
|
|
|
|
|
62
|
|
|
/** @var BroadcastService */ |
|
63
|
|
|
protected $broadcastService; |
|
64
|
|
|
|
|
65
|
|
|
/** @var FederatedLinkService */ |
|
66
|
|
|
protected $federatedLinkService; |
|
67
|
|
|
|
|
68
|
|
|
/** @var FederatedLinkCreationService */ |
|
69
|
|
|
protected $federatedLinkCreationService; |
|
70
|
|
|
|
|
71
|
|
|
/** @var MiscService */ |
|
72
|
|
|
protected $miscService; |
|
73
|
|
|
|
|
74
|
|
|
|
|
75
|
|
|
/** |
|
76
|
|
|
* BaseController constructor. |
|
77
|
|
|
* |
|
78
|
|
|
* @param string $appName |
|
79
|
|
|
* @param IRequest $request |
|
80
|
|
|
* @param ConfigService $configService |
|
81
|
|
|
* @param CirclesService $circlesService |
|
82
|
|
|
* @param SharingFrameService $sharingFrameService |
|
83
|
|
|
* @param BroadcastService $broadcastService |
|
84
|
|
|
* @param FederatedLinkService $federatedLinkService |
|
85
|
|
|
* @param FederatedLinkCreationService $federatedLinkCreationService |
|
86
|
|
|
* @param MiscService $miscService |
|
87
|
|
|
*/ |
|
88
|
|
View Code Duplication |
public function __construct( |
|
|
|
|
|
|
89
|
|
|
$appName, IRequest $request, ConfigService $configService, CirclesService $circlesService, |
|
90
|
|
|
SharingFrameService $sharingFrameService, BroadcastService $broadcastService, |
|
91
|
|
|
FederatedLinkService $federatedLinkService, |
|
92
|
|
|
FederatedLinkCreationService $federatedLinkCreationService, MiscService $miscService |
|
93
|
|
|
) { |
|
94
|
|
|
parent::__construct($appName, $request); |
|
95
|
|
|
$this->configService = $configService; |
|
96
|
|
|
$this->circlesService = $circlesService; |
|
97
|
|
|
$this->sharingFrameService = $sharingFrameService; |
|
98
|
|
|
$this->broadcastService = $broadcastService; |
|
99
|
|
|
$this->federatedLinkService = $federatedLinkService; |
|
100
|
|
|
$this->federatedLinkCreationService = $federatedLinkCreationService; |
|
101
|
|
|
$this->miscService = $miscService; |
|
102
|
|
|
} |
|
103
|
|
|
|
|
104
|
|
|
|
|
105
|
|
|
/** |
|
106
|
|
|
* requestedLink() |
|
107
|
|
|
* |
|
108
|
|
|
* Called when a remote circle want to create a link. |
|
109
|
|
|
* The function check if it is possible first; then create a link-object |
|
110
|
|
|
* and sent it to be saved in the database. |
|
111
|
|
|
* |
|
112
|
|
|
* @PublicPage |
|
113
|
|
|
* @NoCSRFRequired |
|
114
|
|
|
* |
|
115
|
|
|
* @param $data |
|
116
|
|
|
* |
|
117
|
|
|
* @return DataResponse |
|
118
|
|
|
*/ |
|
119
|
|
|
public function requestedLink($data) { |
|
120
|
|
View Code Duplication |
if (MiscService::get($data, 'uniqueId') === '' |
|
|
|
|
|
|
121
|
|
|
|| !$this->configService->isFederatedCirclesAllowed()) { |
|
122
|
|
|
return $this->federatedFail('federated_not_allowed'); |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
try { |
|
126
|
|
|
Circles::compareVersion(MiscService::get($data, 'apiVersion')); |
|
|
|
|
|
|
127
|
|
|
$circle = $this->circlesService->infoCircleByName(MiscService::get($data, 'linkTo')); |
|
128
|
|
|
$link = $this->generateNewLink($data); |
|
129
|
|
|
|
|
130
|
|
|
$this->federatedLinkCreationService->requestedLinkFromRemoteCircle($circle, $link); |
|
|
|
|
|
|
131
|
|
|
|
|
132
|
|
|
return $this->federatedSuccess( |
|
133
|
|
|
['status' => $link->getStatus(), 'uniqueId' => $circle->getUniqueId(true)], $link |
|
134
|
|
|
); |
|
135
|
|
|
} catch (CircleDoesNotExistException $e) { |
|
136
|
|
|
return $this->federatedFail('circle_does_not_exist'); |
|
137
|
|
|
} catch (Exception $e) { |
|
138
|
|
|
return $this->federatedFail($e->getMessage()); |
|
139
|
|
|
} |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
|
|
143
|
|
|
/** |
|
144
|
|
|
* @param $data |
|
145
|
|
|
* |
|
146
|
|
|
* @return FederatedLink |
|
147
|
|
|
*/ |
|
148
|
|
|
private function generateNewLink($data) { |
|
149
|
|
|
MiscService::mustContains($data, ['token', 'uniqueId', 'sourceName', 'address']); |
|
150
|
|
|
$link = new FederatedLink(); |
|
151
|
|
|
|
|
152
|
|
|
$link->setToken(MiscService::get($data, 'token')) |
|
153
|
|
|
->setUniqueId(MiscService::get($data, 'uniqueId')) |
|
|
|
|
|
|
154
|
|
|
->setRemoteCircleName(MiscService::get($data, 'sourceName')) |
|
|
|
|
|
|
155
|
|
|
->setAddress(MiscService::get($data, 'address')); |
|
|
|
|
|
|
156
|
|
|
|
|
157
|
|
|
return $link; |
|
158
|
|
|
} |
|
159
|
|
|
|
|
160
|
|
|
/** |
|
161
|
|
|
* receiveFederatedDelivery() |
|
162
|
|
|
* |
|
163
|
|
|
* Note: this function will close the request mid-run from the client but will still |
|
164
|
|
|
* running its process. |
|
165
|
|
|
* |
|
166
|
|
|
* Called by a remote circle to broadcast a Share item, the function will save the item |
|
167
|
|
|
* in the database and broadcast it locally. A status response is sent to the remote to free |
|
168
|
|
|
* the remote process before starting to broadcast the item to other federated links. |
|
169
|
|
|
* |
|
170
|
|
|
* @PublicPage |
|
171
|
|
|
* @NoCSRFRequired |
|
172
|
|
|
* |
|
173
|
|
|
* @param array $apiVersion |
|
174
|
|
|
* @param string $token |
|
175
|
|
|
* @param string $uniqueId |
|
176
|
|
|
* @param string $item |
|
177
|
|
|
* |
|
178
|
|
|
* @return DataResponse |
|
|
|
|
|
|
179
|
|
|
*/ |
|
180
|
|
|
public function receiveFederatedDelivery($apiVersion, $token, $uniqueId, $item) { |
|
181
|
|
|
|
|
182
|
|
|
if ($uniqueId === '' || !$this->configService->isFederatedCirclesAllowed()) { |
|
183
|
|
|
return $this->federatedFail('federated_not_allowed'); |
|
184
|
|
|
} |
|
185
|
|
|
|
|
186
|
|
|
try { |
|
187
|
|
|
Circles::compareVersion($apiVersion); |
|
188
|
|
|
$frame = SharingFrame::fromJSON($item); |
|
189
|
|
|
$this->sharingFrameService->receiveFrame($token, $uniqueId, $frame); |
|
|
|
|
|
|
190
|
|
|
} catch (SharingFrameAlreadyExistException $e) { |
|
191
|
|
|
return $this->federatedSuccess(); |
|
192
|
|
|
} catch (Exception $e) { |
|
193
|
|
|
return $this->federatedFail($e->getMessage()); |
|
194
|
|
|
} |
|
195
|
|
|
|
|
196
|
|
|
$this->miscService->asyncAndLeaveClientOutOfThis('done'); |
|
197
|
|
|
$this->broadcastService->broadcastFrame($frame); |
|
198
|
|
|
$this->sharingFrameService->forwardSharingFrame($frame); |
|
199
|
|
|
exit(); |
|
|
|
|
|
|
200
|
|
|
} |
|
201
|
|
|
|
|
202
|
|
|
|
|
203
|
|
|
/** |
|
204
|
|
|
* updateLink(); |
|
205
|
|
|
* |
|
206
|
|
|
* Update the current status of a link, based on UniqueId and Token. |
|
207
|
|
|
* |
|
208
|
|
|
* @PublicPage |
|
209
|
|
|
* @NoCSRFRequired |
|
210
|
|
|
* |
|
211
|
|
|
* @param $data |
|
212
|
|
|
* |
|
213
|
|
|
* @return DataResponse |
|
214
|
|
|
*/ |
|
215
|
|
|
public function updateLink($data) { |
|
216
|
|
View Code Duplication |
if (MiscService::get($data, 'uniqueId') === '' |
|
|
|
|
|
|
217
|
|
|
|| !$this->configService->isFederatedCirclesAllowed()) { |
|
218
|
|
|
return $this->federatedFail('federated_not_allowed'); |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
try { |
|
222
|
|
|
Circles::compareVersion(MiscService::get($data, 'apiVersion')); |
|
|
|
|
|
|
223
|
|
|
$link = $this->federatedLinkService->updateLinkFromRemote( |
|
224
|
|
|
MiscService::get($data, 'token'), MiscService::get($data, 'uniqueId'), |
|
|
|
|
|
|
225
|
|
|
MiscService::get($data, 'status') |
|
|
|
|
|
|
226
|
|
|
); |
|
227
|
|
|
} catch (Exception $e) { |
|
228
|
|
|
return $this->federatedFail($e->getMessage()); |
|
229
|
|
|
} |
|
230
|
|
|
|
|
231
|
|
|
return $this->federatedSuccess( |
|
232
|
|
|
['status' => 1, 'link' => $link], $link |
|
233
|
|
|
); |
|
234
|
|
|
} |
|
235
|
|
|
|
|
236
|
|
|
|
|
237
|
|
|
/** |
|
238
|
|
|
* send a positive response to a request with an array of data, and confirm |
|
239
|
|
|
* the identity of the link with a token |
|
240
|
|
|
* |
|
241
|
|
|
* @param array $data |
|
242
|
|
|
* @param FederatedLink $link |
|
|
|
|
|
|
243
|
|
|
* |
|
244
|
|
|
* @return DataResponse |
|
245
|
|
|
*/ |
|
246
|
|
|
private function federatedSuccess(array $data = array(), FederatedLink $link = null) { |
|
247
|
|
|
|
|
248
|
|
|
if (!key_exists('status', $data)) { |
|
249
|
|
|
$data['status'] = 1; |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
if ($link !== null) { |
|
253
|
|
|
$data = array_merge($data, ['token' => $link->getToken(true)]); |
|
254
|
|
|
} |
|
255
|
|
|
|
|
256
|
|
|
return new DataResponse($data, Http::STATUS_OK); |
|
257
|
|
|
} |
|
258
|
|
|
|
|
259
|
|
|
|
|
260
|
|
|
/** |
|
261
|
|
|
* send a negative response to a request, with a reason of the failure. |
|
262
|
|
|
* |
|
263
|
|
|
* @param string $reason |
|
264
|
|
|
* |
|
265
|
|
|
* @return DataResponse |
|
266
|
|
|
*/ |
|
267
|
|
|
private function federatedFail($reason) { |
|
268
|
|
|
$this->miscService->log(2, 'federated fail: ' . $reason); |
|
269
|
|
|
|
|
270
|
|
|
return new DataResponse( |
|
271
|
|
|
[ |
|
272
|
|
|
'status' => FederatedLink::STATUS_ERROR, |
|
273
|
|
|
'reason' => $reason |
|
274
|
|
|
], |
|
275
|
|
|
Http::STATUS_OK |
|
276
|
|
|
); |
|
277
|
|
|
} |
|
278
|
|
|
} |
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.