On mount make sure multiple shares with same target map to unique ones (#23937)

Scenario:
user0 shares a folder 'foo' with user2
user1 shares a folder 'foo' with user2
user2 logs in

Before: show only the 'foo' from user1

After: show both.

* Added intergration tests
This commit is contained in:
Roeland Douma 2016-04-14 11:50:27 +02:00 committed by Thomas Müller
parent 25fff15487
commit 411fac892a
3 changed files with 61 additions and 15 deletions

View File

@ -55,19 +55,20 @@ class MountProvider implements IMountProvider {
$shares = array_filter($shares, function ($share) {
return $share['permissions'] > 0;
});
$shares = array_map(function ($share) use ($user, $storageFactory) {
return new SharedMount(
$mounts = [];
foreach ($shares as $share) {
$mounts[] = new SharedMount(
'\OC\Files\Storage\Shared',
'/' . $user->getUID() . '/' . $share['file_target'],
array(
$mounts,
[
'share' => $share,
'user' => $user->getUID()
),
],
$storageFactory
);
}, $shares);
}
// array_filter removes the null values from the array
return array_filter($shares);
return array_filter($mounts);
}
}

View File

@ -25,6 +25,7 @@
namespace OCA\Files_Sharing;
use OC\Files\Filesystem;
use OC\Files\Mount\MountPoint;
use OC\Files\Mount\MoveableMount;
use OC\Files\View;
@ -50,14 +51,14 @@ class SharedMount extends MountPoint implements MoveableMount {
/**
* @param string $storage
* @param string $mountpoint
* @param SharedMount[] $mountpoints
* @param array|null $arguments
* @param \OCP\Files\Storage\IStorageFactory $loader
*/
public function __construct($storage, $mountpoint, $arguments = null, $loader = null) {
public function __construct($storage, array $mountpoints, $arguments = null, $loader = null) {
$this->user = $arguments['user'];
$this->recipientView = new View('/' . $this->user . '/files');
$newMountPoint = $this->verifyMountPoint($arguments['share']);
$newMountPoint = $this->verifyMountPoint($arguments['share'], $mountpoints);
$absMountPoint = '/' . $this->user . '/files' . $newMountPoint;
$arguments['ownerView'] = new View('/' . $arguments['share']['uid_owner'] . '/files');
parent::__construct($storage, $absMountPoint, $arguments, $loader);
@ -67,9 +68,10 @@ class SharedMount extends MountPoint implements MoveableMount {
* check if the parent folder exists otherwise move the mount point up
*
* @param array $share
* @param SharedMount[] $mountpoints
* @return string
*/
private function verifyMountPoint(&$share) {
private function verifyMountPoint(&$share, array $mountpoints) {
$mountPoint = basename($share['file_target']);
$parent = dirname($share['file_target']);
@ -78,10 +80,10 @@ class SharedMount extends MountPoint implements MoveableMount {
$parent = Helper::getShareFolder();
}
$newMountPoint = \OCA\Files_Sharing\Helper::generateUniqueTarget(
$newMountPoint = $this->generateUniqueTarget(
\OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint),
[],
$this->recipientView
$this->recipientView,
$mountpoints
);
if ($newMountPoint !== $share['file_target']) {
@ -93,6 +95,37 @@ class SharedMount extends MountPoint implements MoveableMount {
return $newMountPoint;
}
/**
* @param string $path
* @param View $view
* @param SharedMount[] $mountpoints
* @return mixed
*/
private function generateUniqueTarget($path, $view, array $mountpoints) {
$pathinfo = pathinfo($path);
$ext = (isset($pathinfo['extension'])) ? '.'.$pathinfo['extension'] : '';
$name = $pathinfo['filename'];
$dir = $pathinfo['dirname'];
// Helper function to find existing mount points
$mountpointExists = function($path) use ($mountpoints) {
foreach ($mountpoints as $mountpoint) {
if ($mountpoint->getShare()['file_target'] === $path) {
return true;
}
}
return false;
};
$i = 2;
while ($view->file_exists($path) || $mountpointExists($path)) {
$path = Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext);
$i++;
}
return $path;
}
/**
* update fileTarget in the database if the mount point changed
*

View File

@ -670,3 +670,15 @@ Feature: sharing
When as "user1" gets properties of folder "/tmp" with
|{http://owncloud.org/ns}share-permissions|
Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "15"
Scenario: unique target names for incomming shares
Given user "user0" exists
And user "user1" exists
And user "user2" exists
And user "user0" created a folder "/foo"
And user "user1" created a folder "/foo"
When file "/foo" of user "user0" is shared with user "user2"
And file "/foo" of user "user1" is shared with user "user2"
Then user "user2" should see following elements
| /foo/ |
| /foo%20(2)/ |