Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
27 changes: 19 additions & 8 deletions apps/files_sharing/lib/MountProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function getMountsForUser(IUser $user, IStorageFactory $storageFactory) {
return $share->getPermissions() > 0 && $share->getShareOwner() !== $user->getUID();
});

$superShares = $this->buildSuperShares($shares);
$superShares = $this->buildSuperShares($shares, $user);

$mounts = [];
foreach ($superShares as $share) {
Expand Down Expand Up @@ -115,17 +115,22 @@ private function groupShares(array $shares) {
if (!isset($tmp[$share->getNodeId()])) {
$tmp[$share->getNodeId()] = [];
}
$tmp[$share->getNodeId()][$share->getTarget()][] = $share;
$tmp[$share->getNodeId()][] = $share;
}

$result = [];
foreach ($tmp as $tmp2) {
foreach ($tmp2 as $item) {
$result[] = $item;
}
// sort by stime, the super share will be based on the least recent share
foreach ($tmp as &$tmp2) {
@usort($tmp2, function($a, $b) {
if ($a->getShareTime() < $b->getShareTime()) {
return -1;
}
return 1;
});
$result[] = $tmp2;
}

return $result;
return array_values($result);
}

/**
Expand All @@ -135,9 +140,10 @@ private function groupShares(array $shares) {
* of all shares within the group.
*
* @param \OCP\Share\IShare[] $allShares
* @param \OCP\IUser $user user
* @return array Tuple of [superShare, groupedShares]
*/
private function buildSuperShares(array $allShares) {
private function buildSuperShares(array $allShares, \OCP\IUser $user) {
$result = [];

$groupedShares = $this->groupShares($allShares);
Expand All @@ -160,6 +166,11 @@ private function buildSuperShares(array $allShares) {
$permissions = 0;
foreach ($shares as $share) {
$permissions |= $share->getPermissions();
if ($share->getTarget() !== $superShare->getTarget()) {
// adjust target, for database consistency
$share->setTarget($superShare->getTarget());
$this->shareManager->moveShare($share, $user->getUID());
}
}

$superShare->setPermissions($permissions);
Expand Down
36 changes: 34 additions & 2 deletions apps/files_sharing/tests/MountProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ private function makeMockShare($id, $nodeId, $owner = 'user2', $target = null, $
$share->expects($this->any())
->method('getNodeId')
->will($this->returnValue($nodeId));
$share->expects($this->any())
->method('getShareTime')
->will($this->returnValue(
// compute share time based on id, simulating share order
new \DateTime('@' . (1469193980 + 1000 * $id))
));
return $share;
}

Expand All @@ -102,7 +108,7 @@ public function testExcludeShares() {

$groupShares = [
$this->makeMockShare(3, 100, 'user2', '/share2', 0),
$this->makeMockShare(4, 100, 'user2', '/share4', 31),
$this->makeMockShare(4, 101, 'user2', '/share4', 31),
$this->makeMockShare(5, 100, 'user1', '/share4', 31),
];

Expand Down Expand Up @@ -141,7 +147,7 @@ public function testExcludeShares() {
$mountedShare2 = $mounts[1]->getShare();
$this->assertEquals('4', $mountedShare2->getId());
$this->assertEquals('user2', $mountedShare2->getShareOwner());
$this->assertEquals(100, $mountedShare2->getNodeId());
$this->assertEquals(101, $mountedShare2->getNodeId());
$this->assertEquals('/share4', $mountedShare2->getTarget());
$this->assertEquals(31, $mountedShare2->getPermissions());
}
Expand Down Expand Up @@ -236,6 +242,32 @@ public function mergeSharesDataProvider() {
// no received share since "user1" opted out
],
],
// #7: share as outsider with "group1" and "user1" where recipient renamed in between
[
[
[1, 100, 'user2', '/share2-renamed', 31],
],
[
[2, 100, 'user2', '/share2', 31],
],
[
// use target of least recent share
['1', 100, 'user2', '/share2-renamed', 31],
],
],
// #8: share as outsider with "group1" and "user1" where recipient renamed in between
[
[
[2, 100, 'user2', '/share2', 31],
],
[
[1, 100, 'user2', '/share2-renamed', 31],
],
[
// use target of least recent share
['1', 100, 'user2', '/share2-renamed', 31],
],
],
];
}

Expand Down
8 changes: 4 additions & 4 deletions build/integration/features/bootstrap/WebDav.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,25 @@ public function makeDavRequest($user, $method, $path, $headers, $body = null){
}

/**
* @Given /^User "([^"]*)" moved file "([^"]*)" to "([^"]*)"$/
* @Given /^User "([^"]*)" moved (file|folder|entry) "([^"]*)" to "([^"]*)"$/
* @param string $user
* @param string $fileSource
* @param string $fileDestination
*/
public function userMovedFile($user, $fileSource, $fileDestination){
public function userMovedFile($user, $entry, $fileSource, $fileDestination){
$fullUrl = substr($this->baseUrl, 0, -4) . $this->davPath;
$headers['Destination'] = $fullUrl . $fileDestination;
$this->response = $this->makeDavRequest($user, "MOVE", $fileSource, $headers);
PHPUnit_Framework_Assert::assertEquals(201, $this->response->getStatusCode());
}

/**
* @When /^User "([^"]*)" moves file "([^"]*)" to "([^"]*)"$/
* @When /^User "([^"]*)" moves (file|folder|entry) "([^"]*)" to "([^"]*)"$/
* @param string $user
* @param string $fileSource
* @param string $fileDestination
*/
public function userMovesFile($user, $fileSource, $fileDestination){
public function userMovesFile($user, $entry, $fileSource, $fileDestination){
$fullUrl = substr($this->baseUrl, 0, -4) . $this->davPath;
$headers['Destination'] = $fullUrl . $fileDestination;
try {
Expand Down
30 changes: 30 additions & 0 deletions build/integration/features/sharing-v1.feature
Original file line number Diff line number Diff line change
Expand Up @@ -838,3 +838,33 @@ Feature: sharing
And as "user0" the folder "merge-test-inside-twogroups-perms (2)" does not exist
And as "user0" the folder "merge-test-inside-twogroups-perms (3)" does not exist

Scenario: Merging shares for recipient when shared from outside with group then user and recipient renames in between
Given As an "admin"
And user "user0" exists
And user "user1" exists
And group "group1" exists
And user "user1" belongs to group "group1"
And user "user0" created a folder "merge-test-outside-groups-renamebeforesecondshare"
When folder "merge-test-outside-groups-renamebeforesecondshare" of user "user0" is shared with group "group1"
And User "user1" moved folder "/merge-test-outside-groups-renamebeforesecondshare" to "/merge-test-outside-groups-renamebeforesecondshare-renamed"
And folder "merge-test-outside-groups-renamebeforesecondshare" of user "user0" is shared with user "user1"
Then as "user1" gets properties of folder "merge-test-outside-groups-renamebeforesecondshare-renamed" with
|{http://owncloud.org/ns}permissions|
And the single response should contain a property "{http://owncloud.org/ns}permissions" with value "SRDNVCK"
And as "user1" the folder "merge-test-outside-groups-renamebeforesecondshare" does not exist

Scenario: Merging shares for recipient when shared from outside with user then group and recipient renames in between
Given As an "admin"
And user "user0" exists
And user "user1" exists
And group "group1" exists
And user "user1" belongs to group "group1"
And user "user0" created a folder "merge-test-outside-groups-renamebeforesecondshare"
When folder "merge-test-outside-groups-renamebeforesecondshare" of user "user0" is shared with user "user1"
And User "user1" moved folder "/merge-test-outside-groups-renamebeforesecondshare" to "/merge-test-outside-groups-renamebeforesecondshare-renamed"
And folder "merge-test-outside-groups-renamebeforesecondshare" of user "user0" is shared with group "group1"
Then as "user1" gets properties of folder "merge-test-outside-groups-renamebeforesecondshare-renamed" with
|{http://owncloud.org/ns}permissions|
And the single response should contain a property "{http://owncloud.org/ns}permissions" with value "SRDNVCK"
And as "user1" the folder "merge-test-outside-groups-renamebeforesecondshare" does not exist