Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix received federated group shares
Fix pending shares endpoint to consider user-specific sub-entries
for group shares whenever a share was accepted or declined.

Added unit test for adding remote group shares.

Fixed "removeUserShares" to not send a remote request as we never send
remote requests for group shares.

Signed-off-by: Vincent Petry <[email protected]>
  • Loading branch information
PVince81 committed Aug 10, 2021
commit 08ab5d97dab170d642d98c0be20adf6757908315
50 changes: 41 additions & 9 deletions apps/files_sharing/lib/External/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -571,15 +571,21 @@ protected function removeReShares($mountPointId) {
*/
public function removeUserShares($uid): bool {
try {
// TODO: use query builder
$getShare = $this->connection->prepare('
SELECT `remote`, `share_token`, `remote_id`
SELECT `id`, `remote`, `share_type`, `share_token`, `remote_id`
FROM `*PREFIX*share_external`
WHERE `user` = ?');
$result = $getShare->execute([$uid]);
$shares = $result->fetchAll();
$result->closeCursor();
$deletedGroupShares = [];
foreach ($shares as $share) {
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline');
if ((int)$share['share_type'] === IShare::TYPE_GROUP) {
$deletedGroupShares[] = $share['id'];
} else {
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline');
}
}

$query = $this->connection->prepare('
Expand All @@ -588,6 +594,17 @@ public function removeUserShares($uid): bool {
');
$deleteResult = $query->execute([$uid]);
$deleteResult->closeCursor();

// delete sub-entries from deleted parents
foreach ($deletedGroupShares as $deletedId) {
// TODO: batch this with query builder
$query = $this->connection->prepare('
DELETE FROM `*PREFIX*share_external`
WHERE `parent` = ?
');
$deleteResult = $query->execute([$deletedId]);
$deleteResult->closeCursor();
}
} catch (\Doctrine\DBAL\Exception $ex) {
return false;
}
Expand Down Expand Up @@ -629,23 +646,38 @@ private function getShares($accepted) {
$userGroups[] = $group->getGID();
}

$query = 'SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted`
// FIXME: use query builder
$query = 'SELECT `id`, `share_type`, `parent`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted`
FROM `*PREFIX*share_external`
WHERE (`user` = ? OR `user` IN (?))';
$parameters = [$this->uid, implode(',',$userGroups)];
if (!is_null($accepted)) {
$query .= ' AND `accepted` = ?';
$parameters[] = (int) $accepted;
}
$parameters = [$this->uid, implode(',', $userGroups)];
$query .= ' ORDER BY `id` ASC';

$sharesQuery = $this->connection->prepare($query);
try {
$result = $sharesQuery->execute($parameters);
$shares = $result->fetchAll();
$result->closeCursor();
return $shares;

// remove parent group share entry if we have a specific user share entry for the user
$toRemove = [];
foreach ($shares as $share) {
if ((int)$share['share_type'] === IShare::TYPE_GROUP && (int)$share['parent'] > 0) {
$toRemove[] = $share['parent'];
}
}
$shares = array_filter($shares, function ($share) use ($toRemove) {
return !in_array($share['id'], $toRemove, true);
});

if (!is_null($accepted)) {
$shares = array_filter($shares, function ($share) use ($accepted) {
return (bool)$share['accepted'] === $accepted;
});
}
return array_values($shares);
} catch (\Doctrine\DBAL\Exception $e) {
// FIXME
return [];
}
}
Expand Down
Loading