diff options
author | Roeland Jago Douma <rullzer@users.noreply.github.com> | 2019-11-18 20:11:20 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-18 20:11:20 +0100 |
commit | ccc0a5e0d586c8df25edb1a0f3cef20860d71e4f (patch) | |
tree | 96ffd796964b18c194b6696f653f1d0d2d3f70f5 /lib | |
parent | 5320f08cd2eab3926104a314fb76b2de222d1d7b (diff) | |
parent | e16321368f27f3b9534b3fb835fbe6c6fc85077e (diff) | |
download | nextcloud-server-ccc0a5e0d586c8df25edb1a0f3cef20860d71e4f.tar.gz nextcloud-server-ccc0a5e0d586c8df25edb1a0f3cef20860d71e4f.zip |
Merge pull request #16828 from nextcloud/feature/noid/accept-incoming-shares
🔗☑️ Accept all incoming shares
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/Share20/DefaultShareProvider.php | 130 | ||||
-rw-r--r-- | lib/private/Share20/Manager.php | 24 | ||||
-rw-r--r-- | lib/private/Share20/Share.php | 17 | ||||
-rw-r--r-- | lib/public/Share/IManager.php | 12 | ||||
-rw-r--r-- | lib/public/Share/IShare.php | 40 | ||||
-rw-r--r-- | lib/public/Share/IShareProvider.php | 10 |
6 files changed, 207 insertions, 26 deletions
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php index 05b3094e6a2..7a146bf7890 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -142,6 +142,7 @@ class DefaultShareProvider implements IShareProvider { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { //Set the UID of the user we share with $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith())); + $qb->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_PENDING)); } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { //Set the GID of the group we share with $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith())); @@ -252,6 +253,7 @@ class DefaultShareProvider implements IShareProvider { ->set('file_source', $qb->createNamedParameter($share->getNode()->getId())) ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) ->set('note', $qb->createNamedParameter($share->getNote())) + ->set('accepted', $qb->createNamedParameter($share->getStatus())) ->execute(); } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { $qb = $this->dbConn->getQueryBuilder(); @@ -319,6 +321,72 @@ class DefaultShareProvider implements IShareProvider { } /** + * Accept a share. + * + * @param IShare $share + * @param string $recipient + * @return IShare The share object + * @since 9.0.0 + */ + public function acceptShare(IShare $share, string $recipient): IShare { + if ($share->getShareType() === IShare::TYPE_GROUP) { + $group = $this->groupManager->get($share->getSharedWith()); + $user = $this->userManager->get($recipient); + + if (is_null($group)) { + throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist'); + } + + if (!$group->inGroup($user)) { + throw new ProviderException('Recipient not in receiving group'); + } + + // Try to fetch user specific share + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))) + ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))) + ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId()))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )) + ->execute(); + + $data = $stmt->fetch(); + $stmt->closeCursor(); + + /* + * Check if there already is a user specific group share. + * If there is update it (if required). + */ + if ($data === false) { + $id = $this->createUserSpecificGroupShare($share, $recipient); + } else { + $id = $data['id']; + } + + } else if ($share->getShareType() === IShare::TYPE_USER) { + if ($share->getSharedWith() !== $recipient) { + throw new ProviderException('Recipient does not match'); + } + + $id = $share->getId(); + } else { + throw new ProviderException('Invalid shareType'); + } + + $qb = $this->dbConn->getQueryBuilder(); + $qb->update('share') + ->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED)) + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) + ->execute(); + + return $share; + } + + /** * Get all children of this share * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in * @@ -382,13 +450,13 @@ class DefaultShareProvider implements IShareProvider { * Unshare a share from the recipient. If this is a group share * this means we need a special entry in the share db. * - * @param \OCP\Share\IShare $share + * @param IShare $share * @param string $recipient UserId of recipient * @throws BackendError * @throws ProviderException */ - public function deleteFromSelf(\OCP\Share\IShare $share, $recipient) { - if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { + public function deleteFromSelf(IShare $share, $recipient) { + if ($share->getShareType() === IShare::TYPE_GROUP) { $group = $this->groupManager->get($share->getSharedWith()); $user = $this->userManager->get($recipient); @@ -421,37 +489,23 @@ class DefaultShareProvider implements IShareProvider { * If there is update it (if required). */ if ($data === false) { - $qb = $this->dbConn->getQueryBuilder(); - - $type = $share->getNodeType(); - - //Insert new share - $qb->insert('share') - ->values([ - 'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP), - 'share_with' => $qb->createNamedParameter($recipient), - 'uid_owner' => $qb->createNamedParameter($share->getShareOwner()), - 'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()), - 'parent' => $qb->createNamedParameter($share->getId()), - 'item_type' => $qb->createNamedParameter($type), - 'item_source' => $qb->createNamedParameter($share->getNodeId()), - 'file_source' => $qb->createNamedParameter($share->getNodeId()), - 'file_target' => $qb->createNamedParameter($share->getTarget()), - 'permissions' => $qb->createNamedParameter(0), - 'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()), - ])->execute(); - - } else if ($data['permissions'] !== 0) { + $id = $this->createUserSpecificGroupShare($share, $recipient); + $permissions = $share->getPermissions(); + } else { + $permissions = $data['permissions']; + $id = $data['id']; + } + if ($permissions !== 0) { // Update existing usergroup share $qb = $this->dbConn->getQueryBuilder(); $qb->update('share') ->set('permissions', $qb->createNamedParameter(0)) - ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id']))) + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) ->execute(); } - } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { + } else if ($share->getShareType() === IShare::TYPE_USER) { if ($share->getSharedWith() !== $recipient) { throw new ProviderException('Recipient does not match'); @@ -464,6 +518,28 @@ class DefaultShareProvider implements IShareProvider { } } + protected function createUserSpecificGroupShare(IShare $share, string $recipient): int { + $type = $share->getNodeType(); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP), + 'share_with' => $qb->createNamedParameter($recipient), + 'uid_owner' => $qb->createNamedParameter($share->getShareOwner()), + 'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()), + 'parent' => $qb->createNamedParameter($share->getId()), + 'item_type' => $qb->createNamedParameter($type), + 'item_source' => $qb->createNamedParameter($share->getNodeId()), + 'file_source' => $qb->createNamedParameter($share->getNodeId()), + 'file_target' => $qb->createNamedParameter($share->getTarget()), + 'permissions' => $qb->createNamedParameter($share->getPermissions()), + 'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()), + ])->execute(); + + return $qb->getLastInsertId(); + } + /** * @inheritdoc * @@ -932,6 +1008,7 @@ class DefaultShareProvider implements IShareProvider { ->setTarget($data['file_target']) ->setNote($data['note']) ->setMailSend((bool)$data['mail_send']) + ->setStatus((int)$data['accepted']) ->setLabel($data['label']); $shareTime = new \DateTime(); @@ -1020,6 +1097,7 @@ class DefaultShareProvider implements IShareProvider { while($data = $stmt->fetch()) { $shareMap[$data['parent']]->setPermissions((int)$data['permissions']); + $shareMap[$data['parent']]->setStatus((int)$data['accepted']); $shareMap[$data['parent']]->setTarget($data['file_target']); $shareMap[$data['parent']]->setParent($data['parent']); } diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php index 728dd60e759..298aa6f0f57 100644 --- a/lib/private/Share20/Manager.php +++ b/lib/private/Share20/Manager.php @@ -929,6 +929,30 @@ class Manager implements IManager { } /** + * Accept a share. + * + * @param IShare $share + * @param string $recipientId + * @return IShare The share object + * @throws \InvalidArgumentException + * @since 9.0.0 + */ + public function acceptShare(IShare $share, string $recipientId): IShare { + [$providerId, ] = $this->splitFullId($share->getFullId()); + $provider = $this->factory->getProvider($providerId); + + if (!method_exists($provider, 'acceptShare')) { + // TODO FIX ME + throw new \InvalidArgumentException('Share provider does not support accepting'); + } + $provider->acceptShare($share, $recipientId); + $event = new GenericEvent($share); + $this->eventDispatcher->dispatch('OCP\Share::postAcceptShare', $event); + + return $share; + } + + /** * Updates the password of the given share if it is not the same as the * password of the original share. * diff --git a/lib/private/Share20/Share.php b/lib/private/Share20/Share.php index 9ce88b5af22..57b5304b102 100644 --- a/lib/private/Share20/Share.php +++ b/lib/private/Share20/Share.php @@ -58,6 +58,8 @@ class Share implements \OCP\Share\IShare { private $shareOwner; /** @var int */ private $permissions; + /** @var int */ + private $status; /** @var string */ private $note = ''; /** @var \DateTime */ @@ -321,6 +323,21 @@ class Share implements \OCP\Share\IShare { /** * @inheritdoc */ + public function setStatus(int $status): IShare { + $this->status = $status; + return $this; + } + + /** + * @inheritdoc + */ + public function getStatus(): int { + return $this->status; + } + + /** + * @inheritdoc + */ public function setNote($note) { $this->note = $note; return $this; diff --git a/lib/public/Share/IManager.php b/lib/public/Share/IManager.php index 8bb7291d6ba..3127c74be5e 100644 --- a/lib/public/Share/IManager.php +++ b/lib/public/Share/IManager.php @@ -54,6 +54,7 @@ interface IManager { * Update a share. * The target of the share can't be changed this way: use moveShare * The share can't be removed this way (permission 0): use deleteShare + * The state can't be changed this way: use acceptShare * * @param IShare $share * @return IShare The share object @@ -63,6 +64,17 @@ interface IManager { public function updateShare(IShare $share); /** + * Accept a share. + * + * @param IShare $share + * @param string $recipientId + * @return IShare The share object + * @throws \InvalidArgumentException + * @since 18.0.0 + */ + public function acceptShare(IShare $share, string $recipientId): IShare; + + /** * Delete a share * * @param IShare $share diff --git a/lib/public/Share/IShare.php b/lib/public/Share/IShare.php index 3b16fcaec0f..1064f59e6d5 100644 --- a/lib/public/Share/IShare.php +++ b/lib/public/Share/IShare.php @@ -50,6 +50,12 @@ interface IShare { public const TYPE_GROUP = 1; /** + * @internal + * @since 18.0.0 + */ + public const TYPE_USERGROUP = 2; + + /** * @since 17.0.0 */ public const TYPE_LINK = 3; @@ -97,6 +103,21 @@ interface IShare { // const TYPE_USERROOM = 11; /** + * @since 18.0.0 + */ + public const STATUS_PENDING = 0; + + /** + * @since 18.0.0 + */ + public const STATUS_ACCEPTED = 1; + + /** + * @since 18.0.0 + */ + public const STATUS_REJECTED = 2; + + /** * Set the internal id of the share * It is only allowed to set the internal id of a share once. * Attempts to override the internal id will result in an IllegalIDChangeException @@ -280,6 +301,25 @@ interface IShare { public function getPermissions(); /** + * Set the accepted status + * See self::STATUS_* + * + * @param int $status + * @return IShare The modified object + * @since 18.0.0 + */ + public function setStatus(int $status): IShare; + + /** + * Get the accepted status + * See self::STATUS_* + * + * @return int + * @since 18.0.0 + */ + public function getStatus(): int; + + /** * Attach a note to a share * * @param string $note diff --git a/lib/public/Share/IShareProvider.php b/lib/public/Share/IShareProvider.php index c8815928269..49ab4bef3e6 100644 --- a/lib/public/Share/IShareProvider.php +++ b/lib/public/Share/IShareProvider.php @@ -64,6 +64,16 @@ interface IShareProvider { public function update(\OCP\Share\IShare $share); /** + * Accept a share. + * + * @param IShare $share + * @param string $recipient + * @return IShare The share object + * @since 17.0.0 + */ +// public function acceptShare(IShare $share, string $recipient): IShare; + + /** * Delete a share * * @param \OCP\Share\IShare $share |