|
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 OCA\Circles\Api\v1\Circles; |
|
32
|
|
|
use OCA\Circles\AppInfo\Application; |
|
33
|
|
|
use OCA\Circles\Db\CirclesRequest; |
|
34
|
|
|
use OCA\Circles\Db\FederatedLinksRequest; |
|
35
|
|
|
use OCA\Circles\Db\SharingFrameRequest; |
|
36
|
|
|
use OCA\Circles\Exceptions\CircleDoesNotExistException; |
|
37
|
|
|
use OCA\Circles\Exceptions\MemberDoesNotExistException; |
|
38
|
|
|
use OCA\Circles\Exceptions\PayloadDeliveryException; |
|
39
|
|
|
use OCA\Circles\Exceptions\SharingFrameAlreadyDeliveredException; |
|
40
|
|
|
use OCA\Circles\Exceptions\SharingFrameAlreadyExistException; |
|
41
|
|
|
use OCA\Circles\Exceptions\SharingFrameDoesNotExistException; |
|
42
|
|
|
use OCA\Circles\Model\Circle; |
|
43
|
|
|
use OCA\Circles\Model\FederatedLink; |
|
44
|
|
|
use OCA\Circles\Model\SharingFrame; |
|
45
|
|
|
use OCP\Http\Client\IClientService; |
|
46
|
|
|
|
|
47
|
|
|
|
|
48
|
|
|
class SharingFrameService { |
|
49
|
|
|
|
|
50
|
|
|
/** @var string */ |
|
51
|
|
|
private $userId; |
|
52
|
|
|
|
|
53
|
|
|
/** @var ConfigService */ |
|
54
|
|
|
private $configService; |
|
55
|
|
|
|
|
56
|
|
|
/** @var SharingFrameRequest */ |
|
57
|
|
|
private $sharingFrameRequest; |
|
58
|
|
|
|
|
59
|
|
|
/** @var CirclesRequest */ |
|
60
|
|
|
private $circlesRequest; |
|
61
|
|
|
|
|
62
|
|
|
/** @var FederatedLinksRequest */ |
|
63
|
|
|
private $federatedLinksRequest; |
|
64
|
|
|
|
|
65
|
|
|
/** @var BroadcastService */ |
|
66
|
|
|
private $broadcastService; |
|
67
|
|
|
|
|
68
|
|
|
/** @var FederatedLinkService */ |
|
69
|
|
|
private $federatedLinkService; |
|
70
|
|
|
|
|
71
|
|
|
/** @var IClientService */ |
|
72
|
|
|
private $clientService; |
|
73
|
|
|
|
|
74
|
|
|
/** @var MiscService */ |
|
75
|
|
|
private $miscService; |
|
76
|
|
|
|
|
77
|
|
|
|
|
78
|
|
|
/** |
|
79
|
|
|
* SharingFrameService constructor. |
|
80
|
|
|
* |
|
81
|
|
|
* @param string $userId |
|
82
|
|
|
* @param ConfigService $configService |
|
83
|
|
|
* @param SharingFrameRequest $sharingFrameRequest |
|
84
|
|
|
* @param CirclesRequest $circlesRequest |
|
85
|
|
|
* @param FederatedLinksRequest $federatedLinksRequest |
|
86
|
|
|
* @param BroadcastService $broadcastService |
|
87
|
|
|
* @param FederatedLinkService $federatedLinkService |
|
88
|
|
|
* @param IClientService $clientService |
|
89
|
|
|
* @param MiscService $miscService |
|
90
|
|
|
*/ |
|
91
|
|
View Code Duplication |
public function __construct( |
|
|
|
|
|
|
92
|
|
|
$userId, |
|
93
|
|
|
ConfigService $configService, |
|
94
|
|
|
SharingFrameRequest $sharingFrameRequest, |
|
95
|
|
|
CirclesRequest $circlesRequest, |
|
96
|
|
|
FederatedLinksRequest $federatedLinksRequest, |
|
97
|
|
|
BroadcastService $broadcastService, |
|
98
|
|
|
FederatedLinkService $federatedLinkService, |
|
99
|
|
|
IClientService $clientService, |
|
100
|
|
|
MiscService $miscService |
|
101
|
|
|
) { |
|
102
|
|
|
$this->userId = $userId; |
|
103
|
|
|
$this->configService = $configService; |
|
104
|
|
|
$this->sharingFrameRequest = $sharingFrameRequest; |
|
105
|
|
|
$this->circlesRequest = $circlesRequest; |
|
106
|
|
|
$this->federatedLinksRequest = $federatedLinksRequest; |
|
107
|
|
|
$this->broadcastService = $broadcastService; |
|
108
|
|
|
$this->federatedLinkService = $federatedLinkService; |
|
109
|
|
|
$this->clientService = $clientService; |
|
110
|
|
|
$this->miscService = $miscService; |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
|
|
114
|
|
|
/** |
|
115
|
|
|
* createFrame() |
|
116
|
|
|
* |
|
117
|
|
|
* Save the Frame containing the Payload. |
|
118
|
|
|
* The Payload will be shared locally, and spread it live if a Broadcaster is set. |
|
119
|
|
|
* Function will also initiate the federated broadcast to linked circles. |
|
120
|
|
|
* |
|
121
|
|
|
* @param string $circleUniqueId |
|
122
|
|
|
* @param SharingFrame $frame |
|
123
|
|
|
* @param string|null $broadcast |
|
124
|
|
|
* |
|
125
|
|
|
* @throws Exception |
|
126
|
|
|
* @throws MemberDoesNotExistException |
|
127
|
|
|
*/ |
|
128
|
|
View Code Duplication |
public function createFrame($circleUniqueId, SharingFrame $frame, $broadcast = null) { |
|
|
|
|
|
|
129
|
|
|
|
|
130
|
|
|
try { |
|
131
|
|
|
$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId); |
|
132
|
|
|
$circle->getHigherViewer() |
|
133
|
|
|
->hasToBeMember(); |
|
134
|
|
|
|
|
135
|
|
|
$frame->setCircle($circle); |
|
136
|
|
|
|
|
137
|
|
|
$this->generateHeaders($frame, $circle, $broadcast); |
|
138
|
|
|
$this->sharingFrameRequest->saveSharingFrame($frame); |
|
139
|
|
|
|
|
140
|
|
|
$this->initiateShare($circle->getUniqueId(), $frame->getUniqueId()); |
|
141
|
|
|
} catch (Exception $e) { |
|
142
|
|
|
throw $e; |
|
143
|
|
|
} |
|
144
|
|
|
} |
|
145
|
|
|
|
|
146
|
|
|
|
|
147
|
|
|
/** |
|
148
|
|
|
* Generate Headers and few more thing like UniqueId and Author. |
|
149
|
|
|
* Check if the source is NOT Circles. |
|
150
|
|
|
* |
|
151
|
|
|
* @param SharingFrame $frame |
|
152
|
|
|
* @param Circle $circle |
|
153
|
|
|
* @param $broadcast |
|
154
|
|
|
*/ |
|
155
|
|
|
private function generateHeaders(SharingFrame $frame, Circle $circle, $broadcast) { |
|
156
|
|
|
|
|
157
|
|
|
try { |
|
158
|
|
|
$frame->cannotBeFromCircles(); |
|
159
|
|
|
|
|
160
|
|
|
$frame->setAuthor($this->userId); |
|
161
|
|
|
$frame->setHeader('author', $this->userId); |
|
162
|
|
|
$frame->setHeader('circleName', $circle->getName()); |
|
163
|
|
|
$frame->setHeader('circleUniqueId', $circle->getUniqueId()); |
|
164
|
|
|
$frame->setHeader('broadcast', (string)$broadcast); |
|
165
|
|
|
$frame->generateUniqueId(); |
|
166
|
|
|
|
|
167
|
|
|
} catch (Exception $e) { |
|
168
|
|
|
throw new $e; |
|
169
|
|
|
} |
|
170
|
|
|
} |
|
171
|
|
|
|
|
172
|
|
|
|
|
173
|
|
|
/** |
|
174
|
|
|
* return all SharingFrame from a circle regarding a userId. |
|
175
|
|
|
* |
|
176
|
|
|
* @param string $circleUniqueId |
|
177
|
|
|
* |
|
178
|
|
|
* @return SharingFrame[] |
|
179
|
|
|
*/ |
|
180
|
|
|
public function getFrameFromCircle($circleUniqueId) { |
|
181
|
|
|
return $this->forceGetFrameFromCircle($circleUniqueId, $this->userId); |
|
182
|
|
|
} |
|
183
|
|
|
|
|
184
|
|
|
|
|
185
|
|
|
/** |
|
186
|
|
|
* return all SharingFrame from a circle. |
|
187
|
|
|
* |
|
188
|
|
|
* Warning, result won't be filtered regarding current user session. |
|
189
|
|
|
* Please use getFrameFromCircle(); |
|
190
|
|
|
* |
|
191
|
|
|
* @param string $circleUniqueId |
|
192
|
|
|
* @param $viewerId |
|
193
|
|
|
* |
|
194
|
|
|
* @return SharingFrame[] |
|
195
|
|
|
*/ |
|
196
|
|
|
public function forceGetFrameFromCircle($circleUniqueId, $viewerId) { |
|
197
|
|
|
|
|
198
|
|
|
if ($viewerId !== '') { |
|
199
|
|
|
$circle = $this->circlesRequest->getCircle($circleUniqueId, $viewerId); |
|
200
|
|
|
$circle->getViewer() |
|
201
|
|
|
->hasToBeMember(); |
|
202
|
|
|
} |
|
203
|
|
|
|
|
204
|
|
|
return $this->sharingFrameRequest->getSharingFramesFromCircle($circleUniqueId); |
|
205
|
|
|
} |
|
206
|
|
|
|
|
207
|
|
|
|
|
208
|
|
|
/** |
|
209
|
|
|
* @param string $circleUniqueId |
|
210
|
|
|
* @param string $frameUniqueId |
|
211
|
|
|
* |
|
212
|
|
|
* @return null|SharingFrame |
|
213
|
|
|
* @throws SharingFrameAlreadyDeliveredException |
|
214
|
|
|
* @throws SharingFrameDoesNotExistException |
|
215
|
|
|
*/ |
|
216
|
|
|
public function getFrameFromUniqueId($circleUniqueId, $frameUniqueId) { |
|
217
|
|
|
if ($frameUniqueId === '') { |
|
218
|
|
|
throw new SharingFrameDoesNotExistException('unknown_share'); |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
try { |
|
222
|
|
|
$frame = $this->sharingFrameRequest->getSharingFrame($circleUniqueId, $frameUniqueId); |
|
223
|
|
|
if ($frame->getCloudId() !== null) { |
|
224
|
|
|
throw new SharingFrameAlreadyDeliveredException('share_already_delivered'); |
|
225
|
|
|
} |
|
226
|
|
|
} catch (SharingFrameDoesNotExistException $e) { |
|
227
|
|
|
throw new SharingFrameDoesNotExistException('unknown_share'); |
|
228
|
|
|
} |
|
229
|
|
|
|
|
230
|
|
|
return $frame; |
|
231
|
|
|
} |
|
232
|
|
|
|
|
233
|
|
|
|
|
234
|
|
|
/** |
|
235
|
|
|
* @param string $token |
|
236
|
|
|
* @param string $uniqueId |
|
237
|
|
|
* @param SharingFrame $frame |
|
238
|
|
|
* |
|
239
|
|
|
* @return bool |
|
240
|
|
|
* @throws Exception |
|
241
|
|
|
*/ |
|
242
|
|
|
public function receiveFrame($token, $uniqueId, SharingFrame &$frame) { |
|
243
|
|
|
try { |
|
244
|
|
|
$link = $this->federatedLinksRequest->getLinkFromToken((string)$token, (string)$uniqueId); |
|
245
|
|
|
$circle = $this->circlesRequest->forceGetCircle($link->getCircleId()); |
|
246
|
|
|
} catch (CircleDoesNotExistException $e) { |
|
247
|
|
|
throw new CircleDoesNotExistException('unknown_circle'); |
|
248
|
|
|
} catch (Exception $e) { |
|
249
|
|
|
throw $e; |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
try { |
|
253
|
|
|
$this->sharingFrameRequest->getSharingFrame($link->getCircleId(), $frame->getUniqueId()); |
|
254
|
|
|
throw new SharingFrameAlreadyExistException('shares_is_already_known'); |
|
255
|
|
|
} catch (SharingFrameDoesNotExistException $e) { |
|
|
|
|
|
|
256
|
|
|
} |
|
257
|
|
|
|
|
258
|
|
|
$frame->setCircle($circle); |
|
259
|
|
|
$this->sharingFrameRequest->saveSharingFrame($frame); |
|
260
|
|
|
|
|
261
|
|
|
return true; |
|
262
|
|
|
} |
|
263
|
|
|
|
|
264
|
|
|
|
|
265
|
|
|
/** |
|
266
|
|
|
* @param string $circleUniqueId |
|
267
|
|
|
* @param string $frameUniqueId |
|
268
|
|
|
* |
|
269
|
|
|
* @return bool |
|
270
|
|
|
* @throws Exception |
|
271
|
|
|
*/ |
|
272
|
|
|
public function initiateShare($circleUniqueId, $frameUniqueId) { |
|
273
|
|
|
$args = [ |
|
274
|
|
|
'circleId' => $circleUniqueId, |
|
275
|
|
|
'frameId' => $frameUniqueId |
|
276
|
|
|
]; |
|
277
|
|
|
|
|
278
|
|
|
$client = $this->clientService->newClient(); |
|
279
|
|
|
try { |
|
280
|
|
|
$client->post( |
|
281
|
|
|
$this->generatePayloadDeliveryURL($this->configService->getLocalAddress()), [ |
|
282
|
|
|
'body' => $args, |
|
283
|
|
|
'timeout' => Application::CLIENT_TIMEOUT, |
|
284
|
|
|
'connect_timeout' => Application::CLIENT_TIMEOUT, |
|
285
|
|
|
] |
|
286
|
|
|
); |
|
287
|
|
|
|
|
288
|
|
|
return true; |
|
289
|
|
|
} catch (Exception $e) { |
|
290
|
|
|
throw $e; |
|
291
|
|
|
} |
|
292
|
|
|
} |
|
293
|
|
|
|
|
294
|
|
|
|
|
295
|
|
|
/** |
|
296
|
|
|
* @param string $remote |
|
297
|
|
|
* |
|
298
|
|
|
* @return string |
|
299
|
|
|
*/ |
|
300
|
|
|
private function generatePayloadDeliveryURL($remote) { |
|
301
|
|
|
return $this->configService->generateRemoteHost($remote) . Application::REMOTE_URL_PAYLOAD; |
|
302
|
|
|
} |
|
303
|
|
|
|
|
304
|
|
|
|
|
305
|
|
|
/** |
|
306
|
|
|
* @param SharingFrame $frame |
|
307
|
|
|
* |
|
308
|
|
|
* @throws Exception |
|
309
|
|
|
*/ |
|
310
|
|
|
public function forwardSharingFrame(SharingFrame $frame) { |
|
311
|
|
|
|
|
312
|
|
|
try { |
|
313
|
|
|
$circle = $this->circlesRequest->forceGetCircle( |
|
314
|
|
|
$frame->getCircle() |
|
315
|
|
|
->getUniqueId() |
|
316
|
|
|
); |
|
317
|
|
|
} catch (CircleDoesNotExistException $e) { |
|
318
|
|
|
throw new CircleDoesNotExistException('unknown_circle'); |
|
319
|
|
|
} |
|
320
|
|
|
|
|
321
|
|
|
$links = $this->federatedLinksRequest->getLinksFromCircle( |
|
322
|
|
|
$frame->getCircle() |
|
323
|
|
|
->getUniqueId(), FederatedLink::STATUS_LINK_UP |
|
324
|
|
|
); |
|
325
|
|
|
|
|
326
|
|
|
$this->forwardSharingFrameToFederatedLinks($circle, $frame, $links); |
|
327
|
|
|
} |
|
328
|
|
|
|
|
329
|
|
|
|
|
330
|
|
|
/** |
|
331
|
|
|
* @param Circle $circle |
|
332
|
|
|
* @param SharingFrame $frame |
|
333
|
|
|
* @param FederatedLink[] $links |
|
334
|
|
|
*/ |
|
335
|
|
|
private function forwardSharingFrameToFederatedLinks(Circle $circle, SharingFrame $frame, $links) { |
|
336
|
|
|
|
|
337
|
|
|
$args = [ |
|
338
|
|
|
'apiVersion' => Circles::version(), |
|
339
|
|
|
'uniqueId' => $circle->getUniqueId(true), |
|
340
|
|
|
'item' => json_encode($frame) |
|
341
|
|
|
]; |
|
342
|
|
|
|
|
343
|
|
|
foreach ($links AS $link) { |
|
344
|
|
|
$args['token'] = $link->getToken(true); |
|
345
|
|
|
$this->deliverSharingFrameToLink($link, $args); |
|
346
|
|
|
} |
|
347
|
|
|
} |
|
348
|
|
|
|
|
349
|
|
|
|
|
350
|
|
|
/** |
|
351
|
|
|
* sendRemoteShareToLinks(); |
|
352
|
|
|
* |
|
353
|
|
|
* @param FederatedLink $link |
|
354
|
|
|
* @param array $args |
|
355
|
|
|
*/ |
|
356
|
|
|
private function deliverSharingFrameToLink($link, $args) { |
|
357
|
|
|
|
|
358
|
|
|
$client = $this->clientService->newClient(); |
|
359
|
|
|
try { |
|
360
|
|
|
$request = $client->put( |
|
361
|
|
|
$this->generatePayloadDeliveryURL($link->getAddress()), [ |
|
362
|
|
|
'body' => $args, |
|
363
|
|
|
'timeout' => 10, |
|
364
|
|
|
'connect_timeout' => 10, |
|
365
|
|
|
] |
|
366
|
|
|
); |
|
367
|
|
|
|
|
368
|
|
|
$result = json_decode($request->getBody(), true); |
|
369
|
|
|
if ($result['status'] === -1) { |
|
370
|
|
|
throw new PayloadDeliveryException($result['reason']); |
|
371
|
|
|
} |
|
372
|
|
|
|
|
373
|
|
|
} catch (Exception $e) { |
|
374
|
|
|
$this->miscService->log( |
|
375
|
|
|
'fail to send frame to ' . $link->getAddress() . ' - ' . $e->getMessage() |
|
376
|
|
|
); |
|
377
|
|
|
} |
|
378
|
|
|
} |
|
379
|
|
|
|
|
380
|
|
|
|
|
381
|
|
|
/** |
|
382
|
|
|
* @param SharingFrame $frame |
|
383
|
|
|
*/ |
|
384
|
|
|
public function updateFrameWithCloudId(SharingFrame $frame) { |
|
385
|
|
|
$frame->setCloudId($this->configService->getLocalAddress()); |
|
386
|
|
|
$this->sharingFrameRequest->updateSharingFrame($frame); |
|
387
|
|
|
} |
|
388
|
|
|
|
|
389
|
|
|
|
|
390
|
|
|
} |
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.