Group shares with same source and target
Fixes #24575 Note that this is a very limited solution and eventually we want smarter merging!
This commit is contained in:
parent
f4f43dddf5
commit
39ebf120c2
|
@ -75,16 +75,21 @@ class MountProvider implements IMountProvider {
|
||||||
return $share->getPermissions() > 0 && $share->getShareOwner() !== $user->getUID();
|
return $share->getPermissions() > 0 && $share->getShareOwner() !== $user->getUID();
|
||||||
});
|
});
|
||||||
|
|
||||||
$mounts = [];
|
$groupedShares = $this->groupShares($shares);
|
||||||
foreach ($shares as $share) {
|
|
||||||
|
|
||||||
|
$superShares = $this->superShares($groupedShares);
|
||||||
|
|
||||||
|
|
||||||
|
$mounts = [];
|
||||||
|
foreach ($superShares as $share) {
|
||||||
try {
|
try {
|
||||||
$mounts[] = new SharedMount(
|
$mounts[] = new SharedMount(
|
||||||
'\OC\Files\Storage\Shared',
|
'\OC\Files\Storage\Shared',
|
||||||
$mounts,
|
$mounts,
|
||||||
[
|
[
|
||||||
'user' => $user->getUID(),
|
'user' => $user->getUID(),
|
||||||
'newShare' => $share,
|
'superShare' => $share[0],
|
||||||
|
'groupedShares' => $share[1],
|
||||||
],
|
],
|
||||||
$storageFactory
|
$storageFactory
|
||||||
);
|
);
|
||||||
|
@ -97,4 +102,63 @@ class MountProvider implements IMountProvider {
|
||||||
// array_filter removes the null values from the array
|
// array_filter removes the null values from the array
|
||||||
return array_filter($mounts);
|
return array_filter($mounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \OCP\Share\IShare[] $shares
|
||||||
|
* @return \OCP\Share\IShare[]
|
||||||
|
*/
|
||||||
|
private function groupShares(array $shares) {
|
||||||
|
$tmp = [];
|
||||||
|
|
||||||
|
foreach ($shares as $share) {
|
||||||
|
if (!isset($tmp[$share->getNodeId()])) {
|
||||||
|
$tmp[$share->getNodeId()] = [];
|
||||||
|
}
|
||||||
|
$tmp[$share->getNodeId()][$share->getTarget()][] = $share;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
foreach ($tmp as $tmp2) {
|
||||||
|
foreach ($tmp2 as $item) {
|
||||||
|
$result[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract super shares
|
||||||
|
*
|
||||||
|
* @param array $shares Array of \OCP\Share\IShare[]
|
||||||
|
* @return array Tuple of [superShare, groupedShares]
|
||||||
|
*/
|
||||||
|
private function superShares(array $groupedShares) {
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
/** @var \OCP\Share\IShare[] $shares */
|
||||||
|
foreach ($groupedShares as $shares) {
|
||||||
|
if (count($shares) === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$superShare = $this->shareManager->newShare();
|
||||||
|
|
||||||
|
$superShare->setId($shares[0]->getId())
|
||||||
|
->setShareOwner($shares[0]->getShareOwner())
|
||||||
|
->setNodeId($shares[0]->getNodeId())
|
||||||
|
->setTarget($shares[0]->getTarget());
|
||||||
|
|
||||||
|
$permissions = 0;
|
||||||
|
foreach ($shares as $share) {
|
||||||
|
$permissions |= $share->getPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
$superShare->setPermissions($permissions);
|
||||||
|
|
||||||
|
$result[] = [$superShare, $shares];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,10 @@ class SharedMount extends MountPoint implements MoveableMount {
|
||||||
private $user;
|
private $user;
|
||||||
|
|
||||||
/** @var \OCP\Share\IShare */
|
/** @var \OCP\Share\IShare */
|
||||||
private $share;
|
private $superShare;
|
||||||
|
|
||||||
|
/** @var \OCP\Share\IShare[] */
|
||||||
|
private $groupedShares;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $storage
|
* @param string $storage
|
||||||
|
@ -63,10 +66,13 @@ class SharedMount extends MountPoint implements MoveableMount {
|
||||||
public function __construct($storage, array $mountpoints, $arguments = null, $loader = null) {
|
public function __construct($storage, array $mountpoints, $arguments = null, $loader = null) {
|
||||||
$this->user = $arguments['user'];
|
$this->user = $arguments['user'];
|
||||||
$this->recipientView = new View('/' . $this->user . '/files');
|
$this->recipientView = new View('/' . $this->user . '/files');
|
||||||
$this->share = $arguments['newShare'];
|
|
||||||
$newMountPoint = $this->verifyMountPoint($this->share, $mountpoints);
|
$this->superShare = $arguments['superShare'];
|
||||||
|
$this->groupedShares = $arguments['groupedShares'];
|
||||||
|
|
||||||
|
$newMountPoint = $this->verifyMountPoint($this->superShare, $mountpoints);
|
||||||
$absMountPoint = '/' . $this->user . '/files' . $newMountPoint;
|
$absMountPoint = '/' . $this->user . '/files' . $newMountPoint;
|
||||||
$arguments['ownerView'] = new View('/' . $this->share->getShareOwner() . '/files');
|
$arguments['ownerView'] = new View('/' . $this->superShare->getShareOwner() . '/files');
|
||||||
parent::__construct($storage, $absMountPoint, $arguments, $loader);
|
parent::__construct($storage, $absMountPoint, $arguments, $loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +114,12 @@ class SharedMount extends MountPoint implements MoveableMount {
|
||||||
*/
|
*/
|
||||||
private function updateFileTarget($newPath, &$share) {
|
private function updateFileTarget($newPath, &$share) {
|
||||||
$share->setTarget($newPath);
|
$share->setTarget($newPath);
|
||||||
|
|
||||||
|
foreach ($this->groupedShares as $share) {
|
||||||
|
$share->setTarget($newPath);
|
||||||
\OC::$server->getShareManager()->moveShare($share, $this->user);
|
\OC::$server->getShareManager()->moveShare($share, $this->user);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -214,7 +224,7 @@ class SharedMount extends MountPoint implements MoveableMount {
|
||||||
* @return \OCP\Share\IShare
|
* @return \OCP\Share\IShare
|
||||||
*/
|
*/
|
||||||
public function getShare() {
|
public function getShare() {
|
||||||
return $this->share;
|
return $this->superShare;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -223,6 +233,6 @@ class SharedMount extends MountPoint implements MoveableMount {
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getStorageRootId() {
|
public function getStorageRootId() {
|
||||||
return $this->share->getNodeId();
|
return $this->getShare()->getNodeId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,11 +43,11 @@ use OCP\Lock\ILockingProvider;
|
||||||
* Convert target path to source path and pass the function call to the correct storage provider
|
* Convert target path to source path and pass the function call to the correct storage provider
|
||||||
*/
|
*/
|
||||||
class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
|
|
||||||
private $share; // the shared resource
|
|
||||||
|
|
||||||
/** @var \OCP\Share\IShare */
|
/** @var \OCP\Share\IShare */
|
||||||
private $newShare;
|
private $superShare;
|
||||||
|
|
||||||
|
/** @var \OCP\Share\IShare[] */
|
||||||
|
private $groupedShares;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \OC\Files\View
|
* @var \OC\Files\View
|
||||||
|
@ -77,11 +77,14 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
public function __construct($arguments) {
|
public function __construct($arguments) {
|
||||||
$this->ownerView = $arguments['ownerView'];
|
$this->ownerView = $arguments['ownerView'];
|
||||||
$this->logger = \OC::$server->getLogger();
|
$this->logger = \OC::$server->getLogger();
|
||||||
$this->newShare = $arguments['newShare'];
|
|
||||||
|
$this->superShare = $arguments['superShare'];
|
||||||
|
$this->groupedShares = $arguments['groupedShares'];
|
||||||
|
|
||||||
$this->user = $arguments['user'];
|
$this->user = $arguments['user'];
|
||||||
|
|
||||||
Filesystem::initMountPoints($this->newShare->getShareOwner());
|
Filesystem::initMountPoints($this->superShare->getShareOwner());
|
||||||
$sourcePath = $this->ownerView->getPath($this->newShare->getNodeId());
|
$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
|
||||||
list($storage, $internalPath) = $this->ownerView->resolvePath($sourcePath);
|
list($storage, $internalPath) = $this->ownerView->resolvePath($sourcePath);
|
||||||
|
|
||||||
parent::__construct([
|
parent::__construct([
|
||||||
|
@ -96,8 +99,8 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
}
|
}
|
||||||
$this->initialized = true;
|
$this->initialized = true;
|
||||||
try {
|
try {
|
||||||
Filesystem::initMountPoints($this->newShare->getShareOwner());
|
Filesystem::initMountPoints($this->superShare->getShareOwner());
|
||||||
$sourcePath = $this->ownerView->getPath($this->newShare->getNodeId());
|
$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
|
||||||
list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath);
|
list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath);
|
||||||
$this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath);
|
$this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
@ -105,6 +108,13 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getShareId() {
|
||||||
|
return $this->superShare->getId();
|
||||||
|
}
|
||||||
|
|
||||||
private function isValid() {
|
private function isValid() {
|
||||||
$this->init();
|
$this->init();
|
||||||
return $this->sourceRootInfo && ($this->sourceRootInfo->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE;
|
return $this->sourceRootInfo && ($this->sourceRootInfo->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE;
|
||||||
|
@ -119,15 +129,6 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
return 'shared::' . $this->getMountPoint();
|
return 'shared::' . $this->getMountPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* get file cache of the shared item source
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getSourceId() {
|
|
||||||
return $this->newShare->getNodeId();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the permissions granted for a shared file
|
* Get the permissions granted for a shared file
|
||||||
*
|
*
|
||||||
|
@ -138,7 +139,7 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
if (!$this->isValid()) {
|
if (!$this->isValid()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
$permissions = $this->newShare->getPermissions();
|
$permissions = $this->superShare->getPermissions();
|
||||||
// part files and the mount point always have delete permissions
|
// part files and the mount point always have delete permissions
|
||||||
if ($target === '' || pathinfo($target, PATHINFO_EXTENSION) === 'part') {
|
if ($target === '' || pathinfo($target, PATHINFO_EXTENSION) === 'part') {
|
||||||
$permissions |= \OCP\Constants::PERMISSION_DELETE;
|
$permissions |= \OCP\Constants::PERMISSION_DELETE;
|
||||||
|
@ -260,30 +261,18 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getMountPoint() {
|
public function getMountPoint() {
|
||||||
return $this->newShare->getTarget();
|
return $this->superShare->getTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
* @param string $path
|
||||||
*/
|
*/
|
||||||
public function setMountPoint($path) {
|
public function setMountPoint($path) {
|
||||||
$this->newShare->setTarget($path);
|
$this->superShare->setTarget($path);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
foreach ($this->groupedShares as $share) {
|
||||||
* @return int
|
$share->setTarget($path);
|
||||||
*/
|
|
||||||
public function getShareType() {
|
|
||||||
return $this->newShare->getShareType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* get share ID
|
|
||||||
*
|
|
||||||
* @return integer unique share ID
|
|
||||||
*/
|
|
||||||
public function getShareId() {
|
|
||||||
return $this->newShare->getId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -292,14 +281,14 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getSharedFrom() {
|
public function getSharedFrom() {
|
||||||
return $this->newShare->getShareOwner();
|
return $this->superShare->getShareOwner();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \OCP\Share\IShare
|
* @return \OCP\Share\IShare
|
||||||
*/
|
*/
|
||||||
public function getShare() {
|
public function getShare() {
|
||||||
return $this->newShare;
|
return $this->superShare;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -308,7 +297,7 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getItemType() {
|
public function getItemType() {
|
||||||
return $this->newShare->getNodeType();
|
return $this->superShare->getNodeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCache($path = '', $storage = null) {
|
public function getCache($path = '', $storage = null) {
|
||||||
|
@ -337,7 +326,7 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOwner($path) {
|
public function getOwner($path) {
|
||||||
return $this->newShare->getShareOwner();
|
return $this->superShare->getShareOwner();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -346,7 +335,9 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function unshareStorage() {
|
public function unshareStorage() {
|
||||||
\OC::$server->getShareManager()->deleteFromSelf($this->newShare, $this->user);
|
foreach ($this->groupedShares as $share) {
|
||||||
|
\OC::$server->getShareManager()->deleteFromSelf($share, $this->user);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +353,7 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
$targetStorage->acquireLock($targetInternalPath, $type, $provider);
|
$targetStorage->acquireLock($targetInternalPath, $type, $provider);
|
||||||
// lock the parent folders of the owner when locking the share as recipient
|
// lock the parent folders of the owner when locking the share as recipient
|
||||||
if ($path === '') {
|
if ($path === '') {
|
||||||
$sourcePath = $this->ownerView->getPath($this->newShare->getNodeId());
|
$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
|
||||||
$this->ownerView->lockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
|
$this->ownerView->lockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -378,7 +369,7 @@ class Shared extends \OC\Files\Storage\Wrapper\Jail implements ISharedStorage {
|
||||||
$targetStorage->releaseLock($targetInternalPath, $type, $provider);
|
$targetStorage->releaseLock($targetInternalPath, $type, $provider);
|
||||||
// unlock the parent folders of the owner when unlocking the share as recipient
|
// unlock the parent folders of the owner when unlocking the share as recipient
|
||||||
if ($path === '') {
|
if ($path === '') {
|
||||||
$sourcePath = $this->ownerView->getPath($this->newShare->getNodeId());
|
$sourcePath = $this->ownerView->getPath($this->superShare->getNodeId());
|
||||||
$this->ownerView->unlockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
|
$this->ownerView->unlockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue