Total Complexity | 58 |
Total Lines | 603 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like Manager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Manager, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
48 | class Manager { |
||
49 | const STORAGE = '\OCA\Files_Sharing\External\Storage'; |
||
50 | |||
51 | /** |
||
52 | * @var string |
||
53 | */ |
||
54 | private $uid; |
||
55 | |||
56 | /** |
||
57 | * @var IDBConnection |
||
58 | */ |
||
59 | private $connection; |
||
60 | |||
61 | /** |
||
62 | * @var \OC\Files\Mount\Manager |
||
63 | */ |
||
64 | private $mountManager; |
||
65 | |||
66 | /** |
||
67 | * @var IStorageFactory |
||
68 | */ |
||
69 | private $storageLoader; |
||
70 | |||
71 | /** |
||
72 | * @var IClientService |
||
73 | */ |
||
74 | private $clientService; |
||
75 | |||
76 | /** |
||
77 | * @var IManager |
||
78 | */ |
||
79 | private $notificationManager; |
||
80 | |||
81 | /** |
||
82 | * @var IDiscoveryService |
||
83 | */ |
||
84 | private $discoveryService; |
||
85 | |||
86 | /** @var ICloudFederationProviderManager */ |
||
87 | private $cloudFederationProviderManager; |
||
88 | |||
89 | /** @var ICloudFederationFactory */ |
||
90 | private $cloudFederationFactory; |
||
91 | |||
92 | /** @var IGroupManager */ |
||
93 | private $groupManager; |
||
94 | |||
95 | /** @var IUserManager */ |
||
96 | private $userManager; |
||
97 | |||
98 | /** |
||
99 | * @param IDBConnection $connection |
||
100 | * @param \OC\Files\Mount\Manager $mountManager |
||
101 | * @param IStorageFactory $storageLoader |
||
102 | * @param IClientService $clientService |
||
103 | * @param IManager $notificationManager |
||
104 | * @param IDiscoveryService $discoveryService |
||
105 | * @param ICloudFederationProviderManager $cloudFederationProviderManager |
||
106 | * @param ICloudFederationFactory $cloudFederationFactory |
||
107 | * @param IGroupManager $groupManager |
||
108 | * @param IUserManager $userManager |
||
109 | * @param string $uid |
||
110 | */ |
||
111 | public function __construct(IDBConnection $connection, |
||
112 | \OC\Files\Mount\Manager $mountManager, |
||
113 | IStorageFactory $storageLoader, |
||
114 | IClientService $clientService, |
||
115 | IManager $notificationManager, |
||
116 | IDiscoveryService $discoveryService, |
||
117 | ICloudFederationProviderManager $cloudFederationProviderManager, |
||
118 | ICloudFederationFactory $cloudFederationFactory, |
||
119 | IGroupManager $groupManager, |
||
120 | IUserManager $userManager, |
||
121 | $uid) { |
||
122 | $this->connection = $connection; |
||
123 | $this->mountManager = $mountManager; |
||
124 | $this->storageLoader = $storageLoader; |
||
125 | $this->clientService = $clientService; |
||
126 | $this->uid = $uid; |
||
127 | $this->notificationManager = $notificationManager; |
||
128 | $this->discoveryService = $discoveryService; |
||
129 | $this->cloudFederationProviderManager = $cloudFederationProviderManager; |
||
130 | $this->cloudFederationFactory = $cloudFederationFactory; |
||
131 | $this->groupManager = $groupManager; |
||
132 | $this->userManager = $userManager; |
||
133 | } |
||
134 | |||
135 | /** |
||
136 | * add new server-to-server share |
||
137 | * |
||
138 | * @param string $remote |
||
139 | * @param string $token |
||
140 | * @param string $password |
||
141 | * @param string $name |
||
142 | * @param string $owner |
||
143 | * @param int $shareType |
||
144 | * @param boolean $accepted |
||
145 | * @param string $user |
||
146 | * @param int $remoteId |
||
147 | * @param int $parent |
||
148 | * @return Mount|null |
||
149 | * @throws \Doctrine\DBAL\DBALException |
||
150 | */ |
||
151 | public function addShare($remote, $token, $password, $name, $owner, $shareType, $accepted=false, $user = null, $remoteId = -1, $parent = -1) { |
||
152 | |||
153 | $user = $user ? $user : $this->uid; |
||
154 | $accepted = $accepted ? 1 : 0; |
||
155 | $name = Filesystem::normalizePath('/' . $name); |
||
156 | |||
157 | if (!$accepted) { |
||
158 | // To avoid conflicts with the mount point generation later, |
||
159 | // we only use a temporary mount point name here. The real |
||
160 | // mount point name will be generated when accepting the share, |
||
161 | // using the original share item name. |
||
162 | $tmpMountPointName = '{{TemporaryMountPointName#' . $name . '}}'; |
||
163 | $mountPoint = $tmpMountPointName; |
||
164 | $hash = md5($tmpMountPointName); |
||
165 | $data = [ |
||
166 | 'remote' => $remote, |
||
167 | 'share_token' => $token, |
||
168 | 'password' => $password, |
||
169 | 'name' => $name, |
||
170 | 'owner' => $owner, |
||
171 | 'user' => $user, |
||
172 | 'mountpoint' => $mountPoint, |
||
173 | 'mountpoint_hash' => $hash, |
||
174 | 'accepted' => $accepted, |
||
175 | 'remote_id' => $remoteId, |
||
176 | 'share_type' => $shareType, |
||
177 | ]; |
||
178 | |||
179 | $i = 1; |
||
180 | while (!$this->connection->insertIfNotExist('*PREFIX*share_external', $data, ['user', 'mountpoint_hash'])) { |
||
|
|||
181 | // The external share already exists for the user |
||
182 | $data['mountpoint'] = $tmpMountPointName . '-' . $i; |
||
183 | $data['mountpoint_hash'] = md5($data['mountpoint']); |
||
184 | $i++; |
||
185 | } |
||
186 | return null; |
||
187 | } |
||
188 | |||
189 | $mountPoint = Files::buildNotExistingFileName('/', $name); |
||
190 | $mountPoint = Filesystem::normalizePath('/' . $mountPoint); |
||
191 | $hash = md5($mountPoint); |
||
192 | |||
193 | $this->writeShareToDb($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType); |
||
194 | |||
195 | $options = array( |
||
196 | 'remote' => $remote, |
||
197 | 'token' => $token, |
||
198 | 'password' => $password, |
||
199 | 'mountpoint' => $mountPoint, |
||
200 | 'owner' => $owner |
||
201 | ); |
||
202 | return $this->mountShare($options); |
||
203 | } |
||
204 | |||
205 | /** |
||
206 | * write remote share to the database |
||
207 | * |
||
208 | * @param $remote |
||
209 | * @param $token |
||
210 | * @param $password |
||
211 | * @param $name |
||
212 | * @param $owner |
||
213 | * @param $user |
||
214 | * @param $mountPoint |
||
215 | * @param $hash |
||
216 | * @param $accepted |
||
217 | * @param $remoteId |
||
218 | * @param $parent |
||
219 | * @param $shareType |
||
220 | * @return bool |
||
221 | */ |
||
222 | private function writeShareToDb($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType) { |
||
223 | $query = $this->connection->prepare(' |
||
224 | INSERT INTO `*PREFIX*share_external` |
||
225 | (`remote`, `share_token`, `password`, `name`, `owner`, `user`, `mountpoint`, `mountpoint_hash`, `accepted`, `remote_id`, `parent`, `share_type`) |
||
226 | VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) |
||
227 | '); |
||
228 | return $query->execute(array($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType)); |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * get share |
||
233 | * |
||
234 | * @param int $id share id |
||
235 | * @return mixed share of false |
||
236 | */ |
||
237 | public function getShare($id) { |
||
238 | $getShare = $this->connection->prepare(' |
||
239 | SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted`, `parent`, `share_type`, `password`, `mountpoint_hash` |
||
240 | FROM `*PREFIX*share_external` |
||
241 | WHERE `id` = ?'); |
||
242 | $result = $getShare->execute(array($id)); |
||
243 | |||
244 | $share = $result ? $getShare->fetch() : []; |
||
245 | |||
246 | $validShare = is_array($share) && isset($share['share_type']) && isset($share['user']); |
||
247 | |||
248 | // check if the user is allowed to access it |
||
249 | if ($validShare && (int)$share['share_type'] === Share::SHARE_TYPE_USER && $share['user'] === $this->uid) { |
||
250 | return $share; |
||
251 | } else if ($validShare && (int)$share['share_type'] === Share::SHARE_TYPE_GROUP) { |
||
252 | $user = $this->userManager->get($this->uid); |
||
253 | if ($this->groupManager->get($share['user'])->inGroup($user)) { |
||
254 | return $share; |
||
255 | } |
||
256 | } |
||
257 | |||
258 | return false; |
||
259 | |||
260 | } |
||
261 | |||
262 | /** |
||
263 | * accept server-to-server share |
||
264 | * |
||
265 | * @param int $id |
||
266 | * @return bool True if the share could be accepted, false otherwise |
||
267 | */ |
||
268 | public function acceptShare($id) { |
||
269 | |||
270 | $share = $this->getShare($id); |
||
271 | $result = false; |
||
272 | |||
273 | if ($share) { |
||
274 | \OC_Util::setupFS($this->uid); |
||
275 | $shareFolder = Helper::getShareFolder(); |
||
276 | $mountPoint = Files::buildNotExistingFileName($shareFolder, $share['name']); |
||
277 | $mountPoint = Filesystem::normalizePath($mountPoint); |
||
278 | $hash = md5($mountPoint); |
||
279 | $userShareAccepted = false; |
||
280 | |||
281 | if((int)$share['share_type'] === Share::SHARE_TYPE_USER) { |
||
282 | $acceptShare = $this->connection->prepare(' |
||
283 | UPDATE `*PREFIX*share_external` |
||
284 | SET `accepted` = ?, |
||
285 | `mountpoint` = ?, |
||
286 | `mountpoint_hash` = ? |
||
287 | WHERE `id` = ? AND `user` = ?'); |
||
288 | $userShareAccepted = $acceptShare->execute(array(1, $mountPoint, $hash, $id, $this->uid)); |
||
289 | } else { |
||
290 | $result = $this->writeShareToDb( |
||
291 | $share['remote'], |
||
292 | $share['share_token'], |
||
293 | $share['password'], |
||
294 | $share['name'], |
||
295 | $share['owner'], |
||
296 | $this->uid, |
||
297 | $mountPoint, $hash, 1, |
||
298 | $share['remote_id'], |
||
299 | $id, |
||
300 | $share['share_type']); |
||
301 | } |
||
302 | if ($userShareAccepted === true) { |
||
303 | $this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'accept'); |
||
304 | \OC_Hook::emit(Share::class, 'federated_share_added', ['server' => $share['remote']]); |
||
305 | $result = true; |
||
306 | } |
||
307 | } |
||
308 | |||
309 | // Make sure the user has no notification for something that does not exist anymore. |
||
310 | $this->processNotification($id); |
||
311 | |||
312 | return $result; |
||
313 | } |
||
314 | |||
315 | /** |
||
316 | * decline server-to-server share |
||
317 | * |
||
318 | * @param int $id |
||
319 | * @return bool True if the share could be declined, false otherwise |
||
320 | */ |
||
321 | public function declineShare($id) { |
||
322 | |||
323 | $share = $this->getShare($id); |
||
324 | $result = false; |
||
325 | |||
326 | if ($share && (int)$share['share_type'] === Share::SHARE_TYPE_USER) { |
||
327 | $removeShare = $this->connection->prepare(' |
||
328 | DELETE FROM `*PREFIX*share_external` WHERE `id` = ? AND `user` = ?'); |
||
329 | $removeShare->execute(array($id, $this->uid)); |
||
330 | $this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline'); |
||
331 | |||
332 | $this->processNotification($id); |
||
333 | $result = true; |
||
334 | } else if ($share && (int)$share['share_type'] === Share::SHARE_TYPE_GROUP) { |
||
335 | $result = $this->writeShareToDb( |
||
336 | $share['remote'], |
||
337 | $share['share_token'], |
||
338 | $share['password'], |
||
339 | $share['name'], |
||
340 | $share['owner'], |
||
341 | $this->uid, |
||
342 | $share['mountpoint'], |
||
343 | $share['mountpoint_hash'], |
||
344 | 0, |
||
345 | $share['remote_id'], |
||
346 | $id, |
||
347 | $share['share_type']); |
||
348 | $this->processNotification($id); |
||
349 | } |
||
350 | |||
351 | return $result; |
||
352 | } |
||
353 | |||
354 | /** |
||
355 | * @param int $remoteShare |
||
356 | */ |
||
357 | public function processNotification($remoteShare) { |
||
358 | $filter = $this->notificationManager->createNotification(); |
||
359 | $filter->setApp('files_sharing') |
||
360 | ->setUser($this->uid) |
||
361 | ->setObject('remote_share', (int) $remoteShare); |
||
362 | $this->notificationManager->markProcessed($filter); |
||
363 | } |
||
364 | |||
365 | /** |
||
366 | * inform remote server whether server-to-server share was accepted/declined |
||
367 | * |
||
368 | * @param string $remote |
||
369 | * @param string $token |
||
370 | * @param int $remoteId Share id on the remote host |
||
371 | * @param string $feedback |
||
372 | * @return boolean |
||
373 | */ |
||
374 | private function sendFeedbackToRemote($remote, $token, $remoteId, $feedback) { |
||
375 | |||
376 | $result = $this->tryOCMEndPoint($remote, $token, $remoteId, $feedback); |
||
377 | |||
378 | if($result === true) { |
||
379 | return true; |
||
380 | } |
||
381 | |||
382 | $federationEndpoints = $this->discoveryService->discover($remote, 'FEDERATED_SHARING'); |
||
383 | $endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares'; |
||
384 | |||
385 | $url = rtrim($remote, '/') . $endpoint . '/' . $remoteId . '/' . $feedback . '?format=' . Share::RESPONSE_FORMAT; |
||
386 | $fields = array('token' => $token); |
||
387 | |||
388 | $client = $this->clientService->newClient(); |
||
389 | |||
390 | try { |
||
391 | $response = $client->post( |
||
392 | $url, |
||
393 | [ |
||
394 | 'body' => $fields, |
||
395 | 'connect_timeout' => 10, |
||
396 | ] |
||
397 | ); |
||
398 | } catch (\Exception $e) { |
||
399 | return false; |
||
400 | } |
||
401 | |||
402 | $status = json_decode($response->getBody(), true); |
||
403 | |||
404 | return ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200); |
||
405 | } |
||
406 | |||
407 | /** |
||
408 | * try send accept message to ocm end-point |
||
409 | * |
||
410 | * @param string $remoteDomain |
||
411 | * @param string $token |
||
412 | * @param $remoteId id of the share |
||
413 | * @param string $feedback |
||
414 | * @return bool |
||
415 | */ |
||
416 | protected function tryOCMEndPoint($remoteDomain, $token, $remoteId, $feedback) { |
||
417 | switch ($feedback) { |
||
418 | case 'accept': |
||
419 | $notification = $this->cloudFederationFactory->getCloudFederationNotification(); |
||
420 | $notification->setMessage( |
||
421 | 'SHARE_ACCEPTED', |
||
422 | 'file', |
||
423 | $remoteId, |
||
424 | [ |
||
425 | 'sharedSecret' => $token, |
||
426 | 'message' => 'Recipient accept the share' |
||
427 | ] |
||
428 | |||
429 | ); |
||
430 | return $this->cloudFederationProviderManager->sendNotification($remoteDomain, $notification); |
||
431 | case 'decline': |
||
432 | $notification = $this->cloudFederationFactory->getCloudFederationNotification(); |
||
433 | $notification->setMessage( |
||
434 | 'SHARE_DECLINED', |
||
435 | 'file', |
||
436 | $remoteId, |
||
437 | [ |
||
438 | 'sharedSecret' => $token, |
||
439 | 'message' => 'Recipient declined the share' |
||
440 | ] |
||
441 | |||
442 | ); |
||
443 | return $this->cloudFederationProviderManager->sendNotification($remoteDomain, $notification); |
||
444 | } |
||
445 | |||
446 | return false; |
||
447 | |||
448 | } |
||
449 | |||
450 | |||
451 | /** |
||
452 | * remove '/user/files' from the path and trailing slashes |
||
453 | * |
||
454 | * @param string $path |
||
455 | * @return string |
||
456 | */ |
||
457 | protected function stripPath($path) { |
||
458 | $prefix = '/' . $this->uid . '/files'; |
||
459 | return rtrim(substr($path, strlen($prefix)), '/'); |
||
460 | } |
||
461 | |||
462 | public function getMount($data) { |
||
463 | $data['manager'] = $this; |
||
464 | $mountPoint = '/' . $this->uid . '/files' . $data['mountpoint']; |
||
465 | $data['mountpoint'] = $mountPoint; |
||
466 | $data['certificateManager'] = \OC::$server->getCertificateManager($this->uid); |
||
467 | return new Mount(self::STORAGE, $mountPoint, $data, $this, $this->storageLoader); |
||
468 | } |
||
469 | |||
470 | /** |
||
471 | * @param array $data |
||
472 | * @return Mount |
||
473 | */ |
||
474 | protected function mountShare($data) { |
||
475 | $mount = $this->getMount($data); |
||
476 | $this->mountManager->addMount($mount); |
||
477 | return $mount; |
||
478 | } |
||
479 | |||
480 | /** |
||
481 | * @return \OC\Files\Mount\Manager |
||
482 | */ |
||
483 | public function getMountManager() { |
||
484 | return $this->mountManager; |
||
485 | } |
||
486 | |||
487 | /** |
||
488 | * @param string $source |
||
489 | * @param string $target |
||
490 | * @return bool |
||
491 | */ |
||
492 | public function setMountPoint($source, $target) { |
||
493 | $source = $this->stripPath($source); |
||
494 | $target = $this->stripPath($target); |
||
495 | $sourceHash = md5($source); |
||
496 | $targetHash = md5($target); |
||
497 | |||
498 | $query = $this->connection->prepare(' |
||
499 | UPDATE `*PREFIX*share_external` |
||
500 | SET `mountpoint` = ?, `mountpoint_hash` = ? |
||
501 | WHERE `mountpoint_hash` = ? |
||
502 | AND `user` = ? |
||
503 | '); |
||
504 | $result = (bool)$query->execute(array($target, $targetHash, $sourceHash, $this->uid)); |
||
505 | |||
506 | return $result; |
||
507 | } |
||
508 | |||
509 | public function removeShare($mountPoint) { |
||
510 | |||
511 | $mountPointObj = $this->mountManager->find($mountPoint); |
||
512 | $id = $mountPointObj->getStorage()->getCache()->getId(''); |
||
513 | |||
514 | $mountPoint = $this->stripPath($mountPoint); |
||
515 | $hash = md5($mountPoint); |
||
516 | |||
517 | $getShare = $this->connection->prepare(' |
||
518 | SELECT `remote`, `share_token`, `remote_id`, `share_type`, `id` |
||
519 | FROM `*PREFIX*share_external` |
||
520 | WHERE `mountpoint_hash` = ? AND `user` = ?'); |
||
521 | $result = $getShare->execute(array($hash, $this->uid)); |
||
522 | |||
523 | $share = $getShare->fetch(); |
||
524 | $getShare->closeCursor(); |
||
525 | if ($result && (bool)$share !== false && (int)$share['share_type'] === Share::SHARE_TYPE_USER) { |
||
526 | try { |
||
527 | $this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline'); |
||
528 | } catch (\Exception $e) { |
||
529 | // if we fail to notify the remote (probably cause the remote is down) |
||
530 | // we still want the share to be gone to prevent undeletable remotes |
||
531 | } |
||
532 | |||
533 | $query = $this->connection->prepare(' |
||
534 | DELETE FROM `*PREFIX*share_external` |
||
535 | WHERE `id` = ? |
||
536 | '); |
||
537 | $result = (bool)$query->execute(array((int)$share['id'])); |
||
538 | } else if ($result && (int)$share['share_type'] === Share::SHARE_TYPE_GROUP) { |
||
539 | $query = $this->connection->prepare(' |
||
540 | UPDATE `*PREFIX*share_external` |
||
541 | SET `accepted` = ? |
||
542 | WHERE `id` = ?'); |
||
543 | $result = (bool)$query->execute(array(0, (int)$share['id'])); |
||
544 | } |
||
545 | |||
546 | if($result) { |
||
547 | $this->removeReShares($id); |
||
548 | } |
||
549 | |||
550 | return $result; |
||
551 | } |
||
552 | |||
553 | /** |
||
554 | * remove re-shares from share table and mapping in the federated_reshares table |
||
555 | * |
||
556 | * @param $mountPointId |
||
557 | */ |
||
558 | protected function removeReShares($mountPointId) { |
||
574 | } |
||
575 | |||
576 | /** |
||
577 | * remove all shares for user $uid if the user was deleted |
||
578 | * |
||
579 | * @param string $uid |
||
580 | * @return bool |
||
581 | */ |
||
582 | public function removeUserShares($uid) { |
||
583 | $getShare = $this->connection->prepare(' |
||
584 | SELECT `remote`, `share_token`, `remote_id` |
||
585 | FROM `*PREFIX*share_external` |
||
586 | WHERE `user` = ?'); |
||
587 | $result = $getShare->execute(array($uid)); |
||
588 | |||
589 | if ($result) { |
||
590 | $shares = $getShare->fetchAll(); |
||
591 | foreach($shares as $share) { |
||
592 | $this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline'); |
||
593 | } |
||
594 | } |
||
595 | |||
596 | $query = $this->connection->prepare(' |
||
597 | DELETE FROM `*PREFIX*share_external` |
||
598 | WHERE `user` = ? |
||
599 | '); |
||
600 | return (bool)$query->execute(array($uid)); |
||
601 | } |
||
602 | |||
603 | /** |
||
604 | * return a list of shares which are not yet accepted by the user |
||
605 | * |
||
606 | * @return array list of open server-to-server shares |
||
607 | */ |
||
608 | public function getOpenShares() { |
||
610 | } |
||
611 | |||
612 | /** |
||
613 | * return a list of shares which are accepted by the user |
||
614 | * |
||
615 | * @return array list of accepted server-to-server shares |
||
616 | */ |
||
617 | public function getAcceptedShares() { |
||
619 | } |
||
620 | |||
621 | /** |
||
622 | * return a list of shares for the user |
||
623 | * |
||
624 | * @param bool|null $accepted True for accepted only, |
||
625 | * false for not accepted, |
||
626 | * null for all shares of the user |
||
627 | * @return array list of open server-to-server shares |
||
628 | */ |
||
629 | private function getShares($accepted) { |
||
651 | } |
||
652 | } |
||
653 |
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.