Skip to content
Snippets Groups Projects
Commit 14ce44ac authored by Robin Appelman's avatar Robin Appelman
Browse files

Move shared mount moving from the storage to the mount

parent cabe2873
Branches
No related tags found
No related merge requests found
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Sharing;
use OC\Files\Filesystem;
use OC\Files\Mount\Mount;
use OC\Files\Mount\MoveableMount;
use OC\Files\Storage\Shared;
/**
* Person mount points can be moved by the user
*/
class SharedMount extends Mount implements MoveableMount {
/**
* @var \OC\Files\Storage\Shared $storage
*/
protected $storage = null;
/**
* Format a path to be relative to the /user/files/ directory
*
* @param string $path the absolute path
* @return string e.g. turns '/admin/files/test.txt' into '/test.txt'
*/
private function stripUserFilesPath($path) {
$trimmed = ltrim($path, '/');
$split = explode('/', $trimmed);
// it is not a file relative to data/user/files
if (count($split) < 3 || $split[1] !== 'files') {
\OCP\Util::writeLog('file sharing',
'Can not strip userid and "files/" from path: ' . $path,
\OCP\Util::DEBUG);
return false;
}
// skip 'user' and 'files'
$sliced = array_slice($split, 2);
$relPath = implode('/', $sliced);
return '/' . $relPath;
}
/**
* Move the mount point to $target
*
* @param string $target the target mount point
* @return bool
*/
public function moveMount($target) {
// it shouldn't be possible to move a Shared storage into another one
list($targetStorage,) = Filesystem::resolvePath($target);
if ($targetStorage instanceof Shared) {
\OCP\Util::writeLog('file sharing',
'It is not allowed to move one mount point into another one',
\OCP\Util::DEBUG);
return false;
}
$relTargetPath = $this->stripUserFilesPath($target);
$share = $this->storage->getShare();
// if the user renames a mount point from a group share we need to create a new db entry
// for the unique name
if ($this->storage->getShareType() === \OCP\Share::SHARE_TYPE_GROUP && $this->storage->uniqueNameSet() === false) {
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,'
. ' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
. ' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)');
$arguments = array($share['item_type'], $share['item_source'], $share['item_target'],
2, \OCP\User::getUser(), $share['uid_owner'], $share['permissions'], $share['stime'], $share['file_source'],
$relTargetPath, $share['token'], $share['id']);
} else {
// rename mount point
$query = \OC_DB::prepare(
'UPDATE `*PREFIX*share`
SET `file_target` = ?
WHERE `id` = ?'
);
$arguments = array($relTargetPath, $this->storage->getShareId());
}
$result = $query->execute($arguments);
if ($result) {
$this->setMountPoint($target);
$this->storage->setUniqueName();
$this->storage->setMountPoint($relTargetPath);
} else {
\OCP\Util::writeLog('file sharing',
'Could not rename mount point for shared folder "' . $this->getMountPoint() . '" to "' . $target . '"',
\OCP\Util::ERROR);
}
return $result;
}
/**
* Remove the mount points
*
* @return mixed
* @return bool
*/
public function removeMount() {
}
}
......@@ -22,6 +22,8 @@
*/
namespace OC\Files\Storage;
use OC\Files\Filesystem;
use OCA\Files_Sharing\SharedMount;
/**
* Convert target path to source path and pass the function call to the correct storage provider
......@@ -266,124 +268,12 @@ class Shared extends \OC\Files\Storage\Common {
return false;
}
/**
* Format a path to be relative to the /user/files/ directory
* @param string $path the absolute path
* @return string e.g. turns '/admin/files/test.txt' into '/test.txt'
*/
private static function stripUserFilesPath($path) {
$trimmed = ltrim($path, '/');
$split = explode('/', $trimmed);
// it is not a file relative to data/user/files
if (count($split) < 3 || $split[1] !== 'files') {
\OCP\Util::writeLog('file sharing',
'Can not strip userid and "files/" from path: ' . $path,
\OCP\Util::DEBUG);
return false;
}
// skip 'user' and 'files'
$sliced = array_slice($split, 2);
$relPath = implode('/', $sliced);
return '/' . $relPath;
}
/**
* rename a shared folder/file
* @param string $sourcePath
* @param string $targetPath
* @return bool
*/
private function renameMountPoint($sourcePath, $targetPath) {
// it shouldn't be possible to move a Shared storage into another one
list($targetStorage, ) = \OC\Files\Filesystem::resolvePath($targetPath);
if ($targetStorage->instanceOfStorage('\OC\Files\Storage\Shared')) {
\OCP\Util::writeLog('file sharing',
'It is not allowed to move one mount point into another one',
\OCP\Util::DEBUG);
return false;
}
$relTargetPath = $this->stripUserFilesPath($targetPath);
if ($relTargetPath === false) {
\OCP\Util::writeLog('file sharing', 'Wrong target path given: ' . $targetPath, \OCP\Util::ERROR);
return false;
}
$result = self::updateFileTarget($relTargetPath, $this->share);
if ($result) {
// update the mount manager with the new paths
$mountManager = \OC\Files\Filesystem::getMountManager();
$mount = $mountManager->find($sourcePath);
$mount->setMountPoint($targetPath . '/');
$mountManager->addMount($mount);
$mountManager->removeMount($sourcePath . '/');
$this->setUniqueName();
$this->setMountPoint($relTargetPath);
} else {
\OCP\Util::writeLog('file sharing',
'Could not rename mount point for shared folder "' . $sourcePath . '" to "' . $targetPath . '"',
\OCP\Util::ERROR);
}
return (bool)$result;
}
/**
* @update fileTarget in the database if the mount point changed
* @param string $newPath
* @param array $share reference to the share which should be modified
* @return type
*/
private static function updateFileTarget($newPath, &$share) {
// if the user renames a mount point from a group share we need to create a new db entry
// for the unique name
if ($share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP &&
(isset($share['unique_name']) && $share['unique_name'])) {
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,'
.' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
.' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)');
$arguments = array($share['item_type'], $share['item_source'], $share['item_target'],
2, \OCP\User::getUser(), $share['uid_owner'], $share['permissions'], $share['stime'], $share['file_source'],
$newPath, $share['token'], $share['id']);
} else {
// rename mount point
$query = \OC_DB::prepare(
'Update `*PREFIX*share`
SET `file_target` = ?
WHERE `id` = ?'
);
$arguments = array($newPath, $share['id']);
}
return $query->execute($arguments);
}
public function rename($path1, $path2) {
$sourceMountPoint = \OC\Files\Filesystem::getMountPoint($path1);
$targetMountPoint = \OC\Files\Filesystem::getMountPoint($path2);
$relPath1 = \OCA\Files_Sharing\Helper::stripUserFilesPath($path1);
$relPath2 = \OCA\Files_Sharing\Helper::stripUserFilesPath($path2);
// if we renamed the mount point we need to adjust the file_target in the
// database
if (\OC\Files\Filesystem::normalizePath($sourceMountPoint) === \OC\Files\Filesystem::normalizePath($path1)) {
return $this->renameMountPoint($path1, $path2);
}
if ( // Within the same mount point, we only need UPDATE permissions
($sourceMountPoint === $targetMountPoint && $this->isUpdatable($sourceMountPoint)) ||
// otherwise DELETE and CREATE permissions required
($this->isDeletable($path1) && $this->isCreatable(dirname($path2)))) {
if ($this->isUpdatable('')) {
$pathinfo = pathinfo($relPath1);
// for part files we need to ask for the owner and path from the parent directory because
......@@ -486,16 +376,22 @@ class Shared extends \OC\Files\Storage\Common {
public static function setup($options) {
$shares = \OCP\Share::getItemsSharedWith('file');
$manager = Filesystem::getMountManager();
$loader = Filesystem::getLoader();
if (!\OCP\User::isLoggedIn() || \OCP\User::getUser() != $options['user']
|| $shares
) {
foreach ($shares as $share) {
self::verifyMountPoint($share);
\OC\Files\Filesystem::mount('\OC\Files\Storage\Shared',
$mount = new SharedMount(
'\OC\Files\Storage\Shared',
$options['user_dir'] . '/' . $share['file_target'],
array(
'share' => $share,
),
$options['user_dir'] . '/' . $share['file_target']);
$loader
);
$manager->addMount($mount);
}
}
}
......@@ -536,28 +432,54 @@ class Shared extends \OC\Files\Storage\Common {
return $this->share['file_target'];
}
private function setMountPoint($path) {
public function setMountPoint($path) {
$this->share['file_target'] = $path;
}
public function getShareType() {
return $this->share['share_type'];
}
/**
* does the group share already has a user specific unique name
* @return bool
*/
public function uniqueNameSet() {
return (isset($this->share['unique_name']) && $this->share['unique_name']);
}
/**
* the share now uses a unique name of this user
*
* @brief the share now uses a unique name of this user
*/
private function setUniqueName() {
public function setUniqueName() {
$this->share['unique_name'] = true;
}
/**
* @brief get the user who shared the file
*
* get share ID
* @return integer unique share ID
*/
public function getShareId() {
return $this->share['id'];
}
/**
* get the user who shared the file
* @return string
*/
public function getSharedFrom() {
return $this->share['uid_owner'];
}
/**
* @return array
*/
public function getShare() {
return $this->share;
}
/**
* return share type, can be "file" or "folder"
* @return string
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment