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:
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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
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 |
||
52 | class Manager implements IManager { |
||
53 | |||
54 | /** @var IProviderFactory */ |
||
55 | private $factory; |
||
56 | /** @var ILogger */ |
||
57 | private $logger; |
||
58 | /** @var IConfig */ |
||
59 | private $config; |
||
60 | /** @var ISecureRandom */ |
||
61 | private $secureRandom; |
||
62 | /** @var IHasher */ |
||
63 | private $hasher; |
||
64 | /** @var IMountManager */ |
||
65 | private $mountManager; |
||
66 | /** @var IGroupManager */ |
||
67 | private $groupManager; |
||
68 | /** @var IL10N */ |
||
69 | private $l; |
||
70 | /** @var IUserManager */ |
||
71 | private $userManager; |
||
72 | /** @var IRootFolder */ |
||
73 | private $rootFolder; |
||
74 | /** @var CappedMemoryCache */ |
||
75 | private $sharingDisabledForUsersCache; |
||
76 | |||
77 | |||
78 | /** |
||
79 | * Manager constructor. |
||
80 | * |
||
81 | * @param ILogger $logger |
||
82 | * @param IConfig $config |
||
83 | * @param ISecureRandom $secureRandom |
||
84 | * @param IHasher $hasher |
||
85 | * @param IMountManager $mountManager |
||
86 | * @param IGroupManager $groupManager |
||
87 | * @param IL10N $l |
||
88 | * @param IProviderFactory $factory |
||
89 | * @param IUserManager $userManager |
||
90 | * @param IRootFolder $rootFolder |
||
91 | */ |
||
92 | public function __construct( |
||
93 | ILogger $logger, |
||
94 | IConfig $config, |
||
95 | ISecureRandom $secureRandom, |
||
96 | IHasher $hasher, |
||
97 | IMountManager $mountManager, |
||
98 | IGroupManager $groupManager, |
||
99 | IL10N $l, |
||
100 | IProviderFactory $factory, |
||
101 | IUserManager $userManager, |
||
102 | IRootFolder $rootFolder |
||
103 | ) { |
||
104 | $this->logger = $logger; |
||
105 | $this->config = $config; |
||
106 | $this->secureRandom = $secureRandom; |
||
107 | $this->hasher = $hasher; |
||
108 | $this->mountManager = $mountManager; |
||
109 | $this->groupManager = $groupManager; |
||
110 | $this->l = $l; |
||
111 | $this->factory = $factory; |
||
112 | $this->userManager = $userManager; |
||
113 | $this->rootFolder = $rootFolder; |
||
114 | $this->sharingDisabledForUsersCache = new CappedMemoryCache(); |
||
115 | } |
||
116 | |||
117 | /** |
||
118 | * Convert from a full share id to a tuple (providerId, shareId) |
||
119 | * |
||
120 | * @param string $id |
||
121 | * @return string[] |
||
122 | */ |
||
123 | private function splitFullId($id) { |
||
124 | return explode(':', $id, 2); |
||
125 | } |
||
126 | |||
127 | /** |
||
128 | * Verify if a password meets all requirements |
||
129 | * |
||
130 | * @param string $password |
||
131 | * @throws \Exception |
||
132 | */ |
||
133 | protected function verifyPassword($password) { |
||
134 | if ($password === null) { |
||
135 | // No password is set, check if this is allowed. |
||
136 | if ($this->shareApiLinkEnforcePassword()) { |
||
137 | throw new \InvalidArgumentException('Passwords are enforced for link shares'); |
||
138 | } |
||
139 | |||
140 | return; |
||
141 | } |
||
142 | |||
143 | // Let others verify the password |
||
144 | $accepted = true; |
||
145 | $message = ''; |
||
146 | \OCP\Util::emitHook('\OC\Share', 'verifyPassword', [ |
||
147 | 'password' => $password, |
||
148 | 'accepted' => &$accepted, |
||
149 | 'message' => &$message |
||
150 | ]); |
||
151 | |||
152 | if (!$accepted) { |
||
153 | throw new \Exception($message); |
||
154 | } |
||
155 | |||
156 | \OC::$server->getEventDispatcher()->dispatch( |
||
157 | 'OCP\Share::validatePassword', |
||
158 | new GenericEvent(null, ['password' => $password]) |
||
159 | ); |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * Check for generic requirements before creating a share |
||
164 | * |
||
165 | * @param \OCP\Share\IShare $share |
||
166 | * @throws \InvalidArgumentException |
||
167 | * @throws GenericShareException |
||
168 | */ |
||
169 | protected function generalCreateChecks(\OCP\Share\IShare $share) { |
||
170 | if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { |
||
171 | // We expect a valid user as sharedWith for user shares |
||
172 | if (!$this->userManager->userExists($share->getSharedWith())) { |
||
173 | throw new \InvalidArgumentException('SharedWith is not a valid user'); |
||
174 | } |
||
175 | } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { |
||
176 | // We expect a valid group as sharedWith for group shares |
||
177 | if (!$this->groupManager->groupExists($share->getSharedWith())) { |
||
178 | throw new \InvalidArgumentException('SharedWith is not a valid group'); |
||
179 | } |
||
180 | } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { |
||
181 | if ($share->getSharedWith() !== null) { |
||
182 | throw new \InvalidArgumentException('SharedWith should be empty'); |
||
183 | } |
||
184 | } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) { |
||
185 | if ($share->getSharedWith() === null) { |
||
186 | throw new \InvalidArgumentException('SharedWith should not be empty'); |
||
187 | } |
||
188 | } else { |
||
189 | // We can't handle other types yet |
||
190 | throw new \InvalidArgumentException('unkown share type'); |
||
191 | } |
||
192 | |||
193 | // Verify the initiator of the share is set |
||
194 | if ($share->getSharedBy() === null) { |
||
195 | throw new \InvalidArgumentException('SharedBy should be set'); |
||
196 | } |
||
197 | |||
198 | // Cannot share with yourself |
||
199 | View Code Duplication | if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && |
|
|
|||
200 | $share->getSharedWith() === $share->getSharedBy()) { |
||
201 | throw new \InvalidArgumentException('Can\'t share with yourself'); |
||
202 | } |
||
203 | |||
204 | // The path should be set |
||
205 | if ($share->getNode() === null) { |
||
206 | throw new \InvalidArgumentException('Path should be set'); |
||
207 | } |
||
208 | |||
209 | // And it should be a file or a folder |
||
210 | if (!($share->getNode() instanceof \OCP\Files\File) && |
||
211 | !($share->getNode() instanceof \OCP\Files\Folder)) { |
||
212 | throw new \InvalidArgumentException('Path should be either a file or a folder'); |
||
213 | } |
||
214 | |||
215 | // And you can't share your rootfolder |
||
216 | if ($this->userManager->userExists($share->getSharedBy())) { |
||
217 | $sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath(); |
||
218 | } else { |
||
219 | $sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath(); |
||
220 | } |
||
221 | if ($sharedPath === $share->getNode()->getPath()) { |
||
222 | throw new \InvalidArgumentException('You can\'t share your root folder'); |
||
223 | } |
||
224 | |||
225 | // Check if we actually have share permissions |
||
226 | View Code Duplication | if (!$share->getNode()->isShareable()) { |
|
227 | $message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]); |
||
228 | throw new GenericShareException($message_t, $message_t, 404); |
||
229 | } |
||
230 | |||
231 | // Permissions should be set |
||
232 | if ($share->getPermissions() === null) { |
||
233 | throw new \InvalidArgumentException('A share requires permissions'); |
||
234 | } |
||
235 | |||
236 | /* |
||
237 | * Quick fix for #23536 |
||
238 | * Non moveable mount points do not have update and delete permissions |
||
239 | * while we 'most likely' do have that on the storage. |
||
240 | */ |
||
241 | $permissions = $share->getNode()->getPermissions(); |
||
242 | $mount = $share->getNode()->getMountPoint(); |
||
243 | if (!($mount instanceof MoveableMount)) { |
||
244 | $permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE; |
||
245 | } |
||
246 | |||
247 | // Check that we do not share with more permissions than we have |
||
248 | View Code Duplication | if ($share->getPermissions() & ~$permissions) { |
|
249 | $message_t = $this->l->t('Cannot increase permissions of %s', [$share->getNode()->getPath()]); |
||
250 | throw new GenericShareException($message_t, $message_t, 404); |
||
251 | } |
||
252 | |||
253 | if ($share->getNode() instanceof \OCP\Files\File) { |
||
254 | View Code Duplication | if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) { |
|
255 | $message_t = $this->l->t('Files can\'t be shared with delete permissions'); |
||
256 | throw new GenericShareException($message_t); |
||
257 | } |
||
258 | View Code Duplication | if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) { |
|
259 | $message_t = $this->l->t('Files can\'t be shared with create permissions'); |
||
260 | throw new GenericShareException($message_t); |
||
261 | } |
||
262 | } |
||
263 | } |
||
264 | |||
265 | /** |
||
266 | * Validate if the expiration date fits the system settings |
||
267 | * |
||
268 | * @param \OCP\Share\IShare $share The share to validate the expiration date of |
||
269 | * @return \OCP\Share\IShare The modified share object |
||
270 | * @throws GenericShareException |
||
271 | * @throws \InvalidArgumentException |
||
272 | * @throws \Exception |
||
273 | */ |
||
274 | protected function validateExpirationDate(\OCP\Share\IShare $share) { |
||
275 | |||
276 | $expirationDate = $share->getExpirationDate(); |
||
277 | |||
278 | if ($expirationDate !== null) { |
||
279 | //Make sure the expiration date is a date |
||
280 | $expirationDate->setTime(0, 0, 0); |
||
281 | |||
282 | $date = new \DateTime(); |
||
283 | $date->setTime(0, 0, 0); |
||
284 | View Code Duplication | if ($date >= $expirationDate) { |
|
285 | $message = $this->l->t('Expiration date is in the past'); |
||
286 | throw new GenericShareException($message, $message, 404); |
||
287 | } |
||
288 | } |
||
289 | |||
290 | // If expiredate is empty set a default one if there is a default |
||
291 | $fullId = null; |
||
292 | try { |
||
293 | $fullId = $share->getFullId(); |
||
294 | } catch (\UnexpectedValueException $e) { |
||
295 | // This is a new share |
||
296 | } |
||
297 | |||
298 | if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) { |
||
299 | $expirationDate = new \DateTime(); |
||
300 | $expirationDate->setTime(0,0,0); |
||
301 | $expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D')); |
||
302 | } |
||
303 | |||
304 | // If we enforce the expiration date check that is does not exceed |
||
305 | if ($this->shareApiLinkDefaultExpireDateEnforced()) { |
||
306 | if ($expirationDate === null) { |
||
307 | throw new \InvalidArgumentException('Expiration date is enforced'); |
||
308 | } |
||
309 | |||
310 | $date = new \DateTime(); |
||
311 | $date->setTime(0, 0, 0); |
||
312 | $date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D')); |
||
313 | View Code Duplication | if ($date < $expirationDate) { |
|
314 | $message = $this->l->t('Cannot set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]); |
||
315 | throw new GenericShareException($message, $message, 404); |
||
316 | } |
||
317 | } |
||
318 | |||
319 | $accepted = true; |
||
320 | $message = ''; |
||
321 | \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [ |
||
322 | 'expirationDate' => &$expirationDate, |
||
323 | 'accepted' => &$accepted, |
||
324 | 'message' => &$message, |
||
325 | 'passwordSet' => $share->getPassword() !== null, |
||
326 | ]); |
||
327 | |||
328 | if (!$accepted) { |
||
329 | throw new \Exception($message); |
||
330 | } |
||
331 | |||
332 | $share->setExpirationDate($expirationDate); |
||
333 | |||
334 | return $share; |
||
335 | } |
||
336 | |||
337 | /** |
||
338 | * Check for pre share requirements for user shares |
||
339 | * |
||
340 | * @param \OCP\Share\IShare $share |
||
341 | * @throws \Exception |
||
342 | */ |
||
343 | protected function userCreateChecks(\OCP\Share\IShare $share) { |
||
344 | // Check if we can share with group members only |
||
345 | if ($this->shareWithGroupMembersOnly()) { |
||
346 | $sharedBy = $this->userManager->get($share->getSharedBy()); |
||
347 | $sharedWith = $this->userManager->get($share->getSharedWith()); |
||
348 | // Verify we can share with this user |
||
349 | $groups = array_intersect( |
||
350 | $this->groupManager->getUserGroupIds($sharedBy), |
||
351 | $this->groupManager->getUserGroupIds($sharedWith) |
||
352 | ); |
||
353 | if (empty($groups)) { |
||
354 | throw new \Exception('Only sharing with group members is allowed'); |
||
355 | } |
||
356 | } |
||
357 | |||
358 | /* |
||
359 | * TODO: Could be costly, fix |
||
360 | * |
||
361 | * Also this is not what we want in the future.. then we want to squash identical shares. |
||
362 | */ |
||
363 | $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER); |
||
364 | $existingShares = $provider->getSharesByPath($share->getNode()); |
||
365 | foreach($existingShares as $existingShare) { |
||
366 | // Ignore if it is the same share |
||
367 | try { |
||
368 | if ($existingShare->getFullId() === $share->getFullId()) { |
||
369 | continue; |
||
370 | } |
||
371 | } catch (\UnexpectedValueException $e) { |
||
372 | //Shares are not identical |
||
373 | } |
||
374 | |||
375 | // Identical share already existst |
||
376 | if ($existingShare->getSharedWith() === $share->getSharedWith()) { |
||
377 | throw new \Exception('Path already shared with this user'); |
||
378 | } |
||
379 | |||
380 | // The share is already shared with this user via a group share |
||
381 | if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { |
||
382 | $group = $this->groupManager->get($existingShare->getSharedWith()); |
||
383 | if (!is_null($group)) { |
||
384 | $user = $this->userManager->get($share->getSharedWith()); |
||
385 | |||
386 | if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) { |
||
387 | throw new \Exception('Path already shared with this user'); |
||
388 | } |
||
389 | } |
||
390 | } |
||
391 | } |
||
392 | } |
||
393 | |||
394 | /** |
||
395 | * Check for pre share requirements for group shares |
||
396 | * |
||
397 | * @param \OCP\Share\IShare $share |
||
398 | * @throws \Exception |
||
399 | */ |
||
400 | protected function groupCreateChecks(\OCP\Share\IShare $share) { |
||
401 | // Verify group shares are allowed |
||
402 | if (!$this->allowGroupSharing()) { |
||
403 | throw new \Exception('Group sharing is now allowed'); |
||
404 | } |
||
405 | |||
406 | // Verify if the user can share with this group |
||
407 | if ($this->shareWithGroupMembersOnly()) { |
||
408 | $sharedBy = $this->userManager->get($share->getSharedBy()); |
||
409 | $sharedWith = $this->groupManager->get($share->getSharedWith()); |
||
410 | if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) { |
||
411 | throw new \Exception('Only sharing within your own groups is allowed'); |
||
412 | } |
||
413 | } |
||
414 | |||
415 | /* |
||
416 | * TODO: Could be costly, fix |
||
417 | * |
||
418 | * Also this is not what we want in the future.. then we want to squash identical shares. |
||
419 | */ |
||
420 | $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP); |
||
421 | $existingShares = $provider->getSharesByPath($share->getNode()); |
||
422 | foreach($existingShares as $existingShare) { |
||
423 | try { |
||
424 | if ($existingShare->getFullId() === $share->getFullId()) { |
||
425 | continue; |
||
426 | } |
||
427 | } catch (\UnexpectedValueException $e) { |
||
428 | //It is a new share so just continue |
||
429 | } |
||
430 | |||
431 | if ($existingShare->getSharedWith() === $share->getSharedWith()) { |
||
432 | throw new \Exception('Path already shared with this group'); |
||
433 | } |
||
434 | } |
||
435 | } |
||
436 | |||
437 | /** |
||
438 | * Check for pre share requirements for link shares |
||
439 | * |
||
440 | * @param \OCP\Share\IShare $share |
||
441 | * @throws \Exception |
||
442 | */ |
||
443 | protected function linkCreateChecks(\OCP\Share\IShare $share) { |
||
444 | // Are link shares allowed? |
||
445 | if (!$this->shareApiAllowLinks()) { |
||
446 | throw new \Exception('Link sharing not allowed'); |
||
447 | } |
||
448 | |||
449 | // Link shares by definition can't have share permissions |
||
450 | if ($share->getPermissions() & \OCP\Constants::PERMISSION_SHARE) { |
||
451 | throw new \InvalidArgumentException('Link shares can\'t have reshare permissions'); |
||
452 | } |
||
453 | |||
454 | // Check if public upload is allowed |
||
455 | if (!$this->shareApiLinkAllowPublicUpload() && |
||
456 | ($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) { |
||
457 | throw new \InvalidArgumentException('Public upload not allowed'); |
||
458 | } |
||
459 | } |
||
460 | |||
461 | /** |
||
462 | * To make sure we don't get invisible link shares we set the parent |
||
463 | * of a link if it is a reshare. This is a quick word around |
||
464 | * until we can properly display multiple link shares in the UI |
||
465 | * |
||
466 | * See: https://github.com/owncloud/core/issues/22295 |
||
467 | * |
||
468 | * FIXME: Remove once multiple link shares can be properly displayed |
||
469 | * |
||
470 | * @param \OCP\Share\IShare $share |
||
471 | */ |
||
472 | protected function setLinkParent(\OCP\Share\IShare $share) { |
||
482 | |||
483 | /** |
||
484 | * @param File|Folder $path |
||
485 | */ |
||
486 | protected function pathCreateChecks($path) { |
||
497 | |||
498 | /** |
||
499 | * Check if the user that is sharing can actually share |
||
500 | * |
||
501 | * @param \OCP\Share\IShare $share |
||
502 | * @throws \Exception |
||
503 | */ |
||
504 | protected function canShare(\OCP\Share\IShare $share) { |
||
513 | |||
514 | /** |
||
515 | * Share a path |
||
516 | * |
||
517 | * @param \OCP\Share\IShare $share |
||
518 | * @return Share The share object |
||
519 | * @throws \Exception |
||
520 | * |
||
521 | * TODO: handle link share permissions or check them |
||
522 | */ |
||
523 | public function createShare(\OCP\Share\IShare $share) { |
||
636 | |||
637 | /** |
||
638 | * Update a share |
||
639 | * |
||
640 | * @param \OCP\Share\IShare $share |
||
641 | * @return \OCP\Share\IShare The share object |
||
642 | * @throws \InvalidArgumentException |
||
643 | */ |
||
644 | public function updateShare(\OCP\Share\IShare $share) { |
||
645 | $expirationDateUpdated = false; |
||
646 | |||
647 | $this->canShare($share); |
||
648 | |||
649 | try { |
||
650 | $originalShare = $this->getShareById($share->getFullId()); |
||
651 | } catch (\UnexpectedValueException $e) { |
||
652 | throw new \InvalidArgumentException('Share does not have a full id'); |
||
653 | } |
||
654 | |||
655 | // We can't change the share type! |
||
656 | if ($share->getShareType() !== $originalShare->getShareType()) { |
||
657 | throw new \InvalidArgumentException('Can\'t change share type'); |
||
658 | } |
||
659 | |||
660 | // We can only change the recipient on user shares |
||
661 | if ($share->getSharedWith() !== $originalShare->getSharedWith() && |
||
662 | $share->getShareType() !== \OCP\Share::SHARE_TYPE_USER) { |
||
663 | throw new \InvalidArgumentException('Can only update recipient on user shares'); |
||
664 | } |
||
665 | |||
666 | // Cannot share with the owner |
||
667 | View Code Duplication | if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && |
|
668 | $share->getSharedWith() === $share->getShareOwner()) { |
||
669 | throw new \InvalidArgumentException('Can\'t share with the share owner'); |
||
670 | } |
||
671 | |||
672 | $this->generalCreateChecks($share); |
||
673 | |||
674 | if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { |
||
675 | $this->userCreateChecks($share); |
||
676 | } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { |
||
677 | $this->groupCreateChecks($share); |
||
678 | } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { |
||
679 | $this->linkCreateChecks($share); |
||
680 | |||
681 | // Password updated. |
||
682 | if ($share->getPassword() !== $originalShare->getPassword()) { |
||
683 | //Verify the password |
||
684 | $this->verifyPassword($share->getPassword()); |
||
685 | |||
686 | // If a password is set. Hash it! |
||
687 | if ($share->getPassword() !== null) { |
||
688 | $share->setPassword($this->hasher->hash($share->getPassword())); |
||
689 | } |
||
690 | } |
||
691 | |||
692 | if ($share->getExpirationDate() != $originalShare->getExpirationDate()) { |
||
693 | //Verify the expiration date |
||
694 | $this->validateExpirationDate($share); |
||
695 | $expirationDateUpdated = true; |
||
696 | } |
||
697 | } |
||
698 | |||
699 | $this->pathCreateChecks($share->getNode()); |
||
700 | |||
701 | // Now update the share! |
||
702 | $provider = $this->factory->getProviderForType($share->getShareType()); |
||
703 | $share = $provider->update($share); |
||
704 | |||
705 | if ($expirationDateUpdated === true) { |
||
706 | \OC_Hook::emit('OCP\Share', 'post_set_expiration_date', [ |
||
707 | 'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder', |
||
708 | 'itemSource' => $share->getNode()->getId(), |
||
709 | 'date' => $share->getExpirationDate(), |
||
710 | 'uidOwner' => $share->getSharedBy(), |
||
711 | ]); |
||
712 | } |
||
713 | |||
714 | if ($share->getPassword() !== $originalShare->getPassword()) { |
||
715 | \OC_Hook::emit('OCP\Share', 'post_update_password', [ |
||
716 | 'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder', |
||
717 | 'itemSource' => $share->getNode()->getId(), |
||
718 | 'uidOwner' => $share->getSharedBy(), |
||
719 | 'token' => $share->getToken(), |
||
720 | 'disabled' => is_null($share->getPassword()), |
||
721 | ]); |
||
722 | } |
||
723 | |||
724 | if ($share->getPermissions() !== $originalShare->getPermissions()) { |
||
725 | if ($this->userManager->userExists($share->getShareOwner())) { |
||
726 | $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner()); |
||
727 | } else { |
||
728 | $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy()); |
||
729 | } |
||
730 | \OC_Hook::emit('OCP\Share', 'post_update_permissions', [ |
||
731 | 'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder', |
||
732 | 'itemSource' => $share->getNode()->getId(), |
||
733 | 'shareType' => $share->getShareType(), |
||
734 | 'shareWith' => $share->getSharedWith(), |
||
735 | 'uidOwner' => $share->getSharedBy(), |
||
736 | 'permissions' => $share->getPermissions(), |
||
737 | 'path' => $userFolder->getRelativePath($share->getNode()->getPath()), |
||
738 | ]); |
||
739 | } |
||
740 | |||
741 | return $share; |
||
742 | } |
||
743 | |||
744 | /** |
||
745 | * Delete all the children of this share |
||
746 | * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in |
||
747 | * |
||
748 | * @param \OCP\Share\IShare $share |
||
749 | * @return \OCP\Share\IShare[] List of deleted shares |
||
750 | */ |
||
751 | protected function deleteChildren(\OCP\Share\IShare $share) { |
||
766 | |||
767 | protected static function formatUnshareHookParams(\OCP\Share\IShare $share) { |
||
768 | // Prepare hook |
||
769 | $shareType = $share->getShareType(); |
||
770 | $sharedWith = ''; |
||
771 | if ($shareType === \OCP\Share::SHARE_TYPE_USER) { |
||
772 | $sharedWith = $share->getSharedWith(); |
||
773 | } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) { |
||
774 | $sharedWith = $share->getSharedWith(); |
||
775 | } else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) { |
||
792 | |||
793 | /** |
||
794 | * Delete a share |
||
795 | * |
||
796 | * @param \OCP\Share\IShare $share |
||
797 | * @throws ShareNotFound |
||
798 | * @throws \InvalidArgumentException |
||
799 | */ |
||
800 | public function deleteShare(\OCP\Share\IShare $share) { |
||
831 | |||
832 | |||
833 | /** |
||
834 | * Unshare a file as the recipient. |
||
835 | * This can be different from a regular delete for example when one of |
||
836 | * the users in a groups deletes that share. But the provider should |
||
837 | * handle this. |
||
838 | * |
||
839 | * @param \OCP\Share\IShare $share |
||
840 | * @param string $recipientId |
||
841 | */ |
||
842 | public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) { |
||
857 | |||
858 | /** |
||
859 | * @inheritdoc |
||
860 | */ |
||
861 | public function moveShare(\OCP\Share\IShare $share, $recipientId) { |
||
886 | |||
887 | |||
888 | /** |
||
889 | * @inheritdoc |
||
890 | */ |
||
891 | public function getAllSharesBy($userId, $shareTypes, $nodeIDs, $reshares = false) { |
||
934 | |||
935 | /** |
||
936 | * @inheritdoc |
||
937 | */ |
||
938 | public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) { |
||
1004 | |||
1005 | /** |
||
1006 | * @inheritdoc |
||
1007 | */ |
||
1008 | public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) { |
||
1013 | |||
1014 | /** |
||
1015 | * @inheritdoc |
||
1016 | */ |
||
1017 | public function getShareById($id, $recipient = null) { |
||
1037 | |||
1038 | /** |
||
1039 | * Get all the shares for a given path |
||
1040 | * |
||
1041 | * @param \OCP\Files\Node $path |
||
1042 | * @param int $page |
||
1043 | * @param int $perPage |
||
1044 | * |
||
1045 | * @return Share[] |
||
1046 | */ |
||
1047 | public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) { |
||
1064 | |||
1065 | /** |
||
1066 | * Get the share by token possible with password |
||
1067 | * |
||
1068 | * @param string $token |
||
1069 | * @return Share |
||
1070 | * |
||
1071 | * @throws ShareNotFound |
||
1072 | */ |
||
1073 | public function getShareByToken($token) { |
||
1104 | |||
1105 | /** |
||
1106 | * Verify the password of a public share |
||
1107 | * |
||
1108 | * @param \OCP\Share\IShare $share |
||
1109 | * @param string $password |
||
1110 | * @return bool |
||
1111 | */ |
||
1112 | public function checkPassword(\OCP\Share\IShare $share, $password) { |
||
1135 | |||
1136 | /** |
||
1137 | * @inheritdoc |
||
1138 | */ |
||
1139 | public function userDeleted($uid) { |
||
1147 | |||
1148 | /** |
||
1149 | * @inheritdoc |
||
1150 | */ |
||
1151 | public function groupDeleted($gid) { |
||
1155 | |||
1156 | /** |
||
1157 | * @inheritdoc |
||
1158 | */ |
||
1159 | public function userDeletedFromGroup($uid, $gid) { |
||
1163 | |||
1164 | /** |
||
1165 | * Get access list to a path. This means |
||
1166 | * all the users and groups that can access a given path. |
||
1167 | * |
||
1168 | * Consider: |
||
1169 | * -root |
||
1170 | * |-folder1 |
||
1171 | * |-folder2 |
||
1172 | * |-fileA |
||
1173 | * |
||
1174 | * fileA is shared with user1 |
||
1175 | * folder2 is shared with group2 |
||
1176 | * folder1 is shared with user2 |
||
1177 | * |
||
1178 | * Then the access list will to '/folder1/folder2/fileA' is: |
||
1179 | * [ |
||
1180 | * 'users' => ['user1', 'user2'], |
||
1181 | * 'groups' => ['group2'] |
||
1182 | * ] |
||
1183 | * |
||
1184 | * This is required for encryption |
||
1185 | * |
||
1186 | * @param \OCP\Files\Node $path |
||
1187 | */ |
||
1188 | public function getAccessList(\OCP\Files\Node $path) { |
||
1190 | |||
1191 | /** |
||
1192 | * Create a new share |
||
1193 | * @return \OCP\Share\IShare; |
||
1194 | */ |
||
1195 | public function newShare() { |
||
1198 | |||
1199 | /** |
||
1200 | * Is the share API enabled |
||
1201 | * |
||
1202 | * @return bool |
||
1203 | */ |
||
1204 | public function shareApiEnabled() { |
||
1207 | |||
1208 | /** |
||
1209 | * Is public link sharing enabled |
||
1210 | * |
||
1211 | * @return bool |
||
1212 | */ |
||
1213 | public function shareApiAllowLinks() { |
||
1216 | |||
1217 | /** |
||
1218 | * Is password on public link requires |
||
1219 | * |
||
1220 | * @return bool |
||
1221 | */ |
||
1222 | public function shareApiLinkEnforcePassword() { |
||
1225 | |||
1226 | /** |
||
1227 | * Is default expire date enabled |
||
1228 | * |
||
1229 | * @return bool |
||
1230 | */ |
||
1231 | public function shareApiLinkDefaultExpireDate() { |
||
1234 | |||
1235 | /** |
||
1236 | * Is default expire date enforced |
||
1237 | *` |
||
1238 | * @return bool |
||
1239 | */ |
||
1240 | public function shareApiLinkDefaultExpireDateEnforced() { |
||
1244 | |||
1245 | /** |
||
1246 | * Number of default expire days |
||
1247 | *shareApiLinkAllowPublicUpload |
||
1248 | * @return int |
||
1249 | */ |
||
1250 | public function shareApiLinkDefaultExpireDays() { |
||
1253 | |||
1254 | /** |
||
1255 | * Allow public upload on link shares |
||
1256 | * |
||
1257 | * @return bool |
||
1258 | */ |
||
1259 | public function shareApiLinkAllowPublicUpload() { |
||
1262 | |||
1263 | /** |
||
1264 | * check if user can only share with group members |
||
1265 | * @return bool |
||
1266 | */ |
||
1267 | public function shareWithGroupMembersOnly() { |
||
1270 | |||
1271 | /** |
||
1272 | * Check if users can share with groups |
||
1273 | * @return bool |
||
1274 | */ |
||
1275 | public function allowGroupSharing() { |
||
1278 | |||
1279 | /** |
||
1280 | * Copied from \OC_Util::isSharingDisabledForUser |
||
1281 | * |
||
1282 | * TODO: Deprecate fuction from OC_Util |
||
1283 | * |
||
1284 | * @param string $userId |
||
1285 | * @return bool |
||
1286 | */ |
||
1287 | public function sharingDisabledForUser($userId) { |
||
1320 | |||
1321 | /** |
||
1322 | * @inheritdoc |
||
1323 | */ |
||
1324 | public function outgoingServer2ServerSharesAllowed() { |
||
1327 | |||
1328 | } |
||
1329 |
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.