|
30 | 30 | use OCP\IUserManager; |
31 | 31 | use OCP\Security\ISecureRandom; |
32 | 32 | use OCP\Server; |
| 33 | +use OCP\Share\Exceptions\AlreadySharedException; |
33 | 34 | use OCP\Share\Exceptions\GenericShareException; |
34 | 35 | use OCP\Share\Exceptions\ShareNotFound; |
35 | 36 | use OCP\Share\IShare; |
@@ -101,20 +102,25 @@ public function create(IShare $share): IShare { |
101 | 102 | throw new \Exception($message_t); |
102 | 103 | } |
103 | 104 |
|
| 105 | + $cloudId = $this->cloudIdManager->resolveCloudId($shareWith); |
| 106 | + |
104 | 107 | /* |
105 | | - * Check if file is not already shared with the remote user |
| 108 | + * Check if file is not already shared with the remote user. |
| 109 | + * Has to be looked up by the normalized cloud ID, because that is what |
| 110 | + * gets stored below. Otherwise spellings like "user@server.com/" slip |
| 111 | + * past this check and create a duplicate share. |
106 | 112 | */ |
107 | | - $alreadyShared = $this->getSharedWith($shareWith, IShare::TYPE_REMOTE, $share->getNode(), 1, 0); |
108 | | - $alreadySharedGroup = $this->getSharedWith($shareWith, IShare::TYPE_REMOTE_GROUP, $share->getNode(), 1, 0); |
109 | | - if (!empty($alreadyShared) || !empty($alreadySharedGroup)) { |
| 113 | + // getSharedWith() ignores its $shareType argument and always |
| 114 | + // queries all supported remote types, so a single lookup covers both. |
| 115 | + $alreadyShared = $this->getSharedWith($cloudId->getId(), IShare::TYPE_REMOTE, $share->getNode(), 1, 0); |
| 116 | + if (!empty($alreadyShared)) { |
110 | 117 | $message = 'Sharing %1$s failed, because this item is already shared with %2$s'; |
111 | 118 | $message_t = $this->l->t('Sharing %1$s failed, because this item is already shared with the account %2$s', [$share->getNode()->getName(), $shareWith]); |
112 | 119 | $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']); |
113 | | - throw new \Exception($message_t); |
| 120 | + throw new AlreadySharedException($message_t, $alreadyShared[0]); |
114 | 121 | } |
115 | 122 |
|
116 | 123 | // don't allow federated shares if source and target server are the same |
117 | | - $cloudId = $this->cloudIdManager->resolveCloudId($shareWith); |
118 | 124 | $currentServer = $this->addressHandler->generateRemoteURL(); |
119 | 125 | $currentUser = $sharedBy; |
120 | 126 | if ($this->addressHandler->compareAddresses($cloudId->getUser(), $cloudId->getRemote(), $currentUser, $currentServer)) { |
|
0 commit comments