summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRoeland Jago Douma <rullzer@users.noreply.github.com>2019-11-18 20:11:20 +0100
committerGitHub <noreply@github.com>2019-11-18 20:11:20 +0100
commitccc0a5e0d586c8df25edb1a0f3cef20860d71e4f (patch)
tree96ffd796964b18c194b6696f653f1d0d2d3f70f5 /lib
parent5320f08cd2eab3926104a314fb76b2de222d1d7b (diff)
parente16321368f27f3b9534b3fb835fbe6c6fc85077e (diff)
downloadnextcloud-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.php130
-rw-r--r--lib/private/Share20/Manager.php24
-rw-r--r--lib/private/Share20/Share.php17
-rw-r--r--lib/public/Share/IManager.php12
-rw-r--r--lib/public/Share/IShare.php40
-rw-r--r--lib/public/Share/IShareProvider.php10
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