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:
parent
3aaa33d9d4
commit
b6192c39d8
|
@ -63,24 +63,25 @@ class MountProvider implements IMountProvider {
|
|||
$shares = array_filter($shares, function ($share) {
|
||||
return $share['permissions'] > 0;
|
||||
});
|
||||
$shares = array_map(function ($share) use ($user, $storageFactory) {
|
||||
|
||||
$mounts = [];
|
||||
foreach ($shares as $share) {
|
||||
try {
|
||||
return new SharedMount(
|
||||
$mounts[] = new SharedMount(
|
||||
'\OC\Files\Storage\Shared',
|
||||
'/' . $user->getUID() . '/' . $share['file_target'],
|
||||
array(
|
||||
$mounts,
|
||||
[
|
||||
'share' => $share,
|
||||
'user' => $user->getUID()
|
||||
),
|
||||
],
|
||||
$storageFactory
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->logException($e);
|
||||
$this->logger->error('Error while trying to create shared mount');
|
||||
}
|
||||
}, $shares);
|
||||
}
|
||||
|
||||
// array_filter removes the null values from the array
|
||||
return array_filter($shares);
|
||||
return array_filter($mounts);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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($this->recipientView);
|
||||
}
|
||||
|
||||
$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
|
||||
*
|
||||
|
|
|
@ -566,3 +566,16 @@ Feature: sharing
|
|||
| path | welcome.txt |
|
||||
| shareType | 3 |
|
||||
Then share ids should match
|
||||
|
||||
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)/ |
|
||||
|
||||
|
|
Loading…
Reference in New Issue