summaryrefslogtreecommitdiffstats
path: root/apps/files_sharing/lib/SharedMount.php
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2016-05-25 15:40:05 +0200
committerVincent Petry <pvince81@owncloud.com>2016-05-25 15:40:05 +0200
commitd22aeb749d22590c4caf630fd390dabca6e2c724 (patch)
tree34ee255a19177a99504b4b5f652b071dc268cf3b /apps/files_sharing/lib/SharedMount.php
parent7f20203006d1a8ac1ba4d367044b9a0613a3fb59 (diff)
parent3f0b2d148d875a2a4961a5b27309d379b9de1329 (diff)
downloadnextcloud-server-d22aeb749d22590c4caf630fd390dabca6e2c724.tar.gz
nextcloud-server-d22aeb749d22590c4caf630fd390dabca6e2c724.zip
Merge pull request #24661 from owncloud/files_sharing-psr4
Move Files_Sharing to PSR-4
Diffstat (limited to 'apps/files_sharing/lib/SharedMount.php')
-rw-r--r--apps/files_sharing/lib/SharedMount.php226
1 files changed, 226 insertions, 0 deletions
diff --git a/apps/files_sharing/lib/SharedMount.php b/apps/files_sharing/lib/SharedMount.php
new file mode 100644
index 00000000000..4aed80b12b2
--- /dev/null
+++ b/apps/files_sharing/lib/SharedMount.php
@@ -0,0 +1,226 @@
+<?php
+/**
+ * @author Björn Schießle <schiessle@owncloud.com>
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Robin Appelman <icewind@owncloud.com>
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_Sharing;
+
+use OC\Files\Filesystem;
+use OC\Files\Mount\MountPoint;
+use OC\Files\Mount\MoveableMount;
+use OC\Files\View;
+
+/**
+ * Shared mount points can be moved by the user
+ */
+class SharedMount extends MountPoint implements MoveableMount {
+ /**
+ * @var \OC\Files\Storage\Shared $storage
+ */
+ protected $storage = null;
+
+ /**
+ * @var \OC\Files\View
+ */
+ private $recipientView;
+
+ /**
+ * @var string
+ */
+ private $user;
+
+ /** @var \OCP\Share\IShare */
+ private $share;
+
+ /**
+ * @param string $storage
+ * @param SharedMount[] $mountpoints
+ * @param array|null $arguments
+ * @param \OCP\Files\Storage\IStorageFactory $loader
+ */
+ public function __construct($storage, array $mountpoints, $arguments = null, $loader = null) {
+ $this->user = $arguments['user'];
+ $this->recipientView = new View('/' . $this->user . '/files');
+ $this->share = $arguments['newShare'];
+ $newMountPoint = $this->verifyMountPoint($this->share, $mountpoints);
+ $absMountPoint = '/' . $this->user . '/files' . $newMountPoint;
+ $arguments['ownerView'] = new View('/' . $this->share->getShareOwner() . '/files');
+ parent::__construct($storage, $absMountPoint, $arguments, $loader);
+ }
+
+ /**
+ * check if the parent folder exists otherwise move the mount point up
+ *
+ * @param \OCP\Share\IShare $share
+ * @param SharedMount[] $mountpoints
+ * @return string
+ */
+ private function verifyMountPoint(\OCP\Share\IShare $share, array $mountpoints) {
+
+ $mountPoint = basename($share->getTarget());
+ $parent = dirname($share->getTarget());
+
+ if (!$this->recipientView->is_dir($parent)) {
+ $parent = Helper::getShareFolder();
+ }
+
+ $newMountPoint = $this->generateUniqueTarget(
+ \OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint),
+ $this->recipientView,
+ $mountpoints
+ );
+
+ if ($newMountPoint !== $share->getTarget()) {
+ $this->updateFileTarget($newMountPoint, $share);
+ }
+
+ return $newMountPoint;
+ }
+
+ /**
+ * update fileTarget in the database if the mount point changed
+ *
+ * @param string $newPath
+ * @param \OCP\Share\IShare $share
+ * @return bool
+ */
+ private function updateFileTarget($newPath, &$share) {
+ $share->setTarget($newPath);
+ \OC::$server->getShareManager()->moveShare($share, $this->user);
+ }
+
+
+ /**
+ * @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()->getTarget() === $path) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ $i = 2;
+ while ($view->file_exists($path) || $mountpointExists($path)) {
+ $path = Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext);
+ $i++;
+ }
+
+ return $path;
+ }
+
+ /**
+ * 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'
+ * @throws \OCA\Files_Sharing\Exceptions\BrokenPath
+ */
+ protected 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::ERROR);
+ throw new \OCA\Files_Sharing\Exceptions\BrokenPath('Path does not start with /user/files', 10);
+ }
+
+ // 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) {
+
+ $relTargetPath = $this->stripUserFilesPath($target);
+ $share = $this->storage->getShare();
+
+ $result = true;
+
+ try {
+ $this->updateFileTarget($relTargetPath, $share);
+ $this->setMountPoint($target);
+ $this->storage->setMountPoint($relTargetPath);
+ } catch (\Exception $e) {
+ \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 bool
+ */
+ public function removeMount() {
+ $mountManager = \OC\Files\Filesystem::getMountManager();
+ /** @var $storage \OC\Files\Storage\Shared */
+ $storage = $this->getStorage();
+ $result = $storage->unshareStorage();
+ $mountManager->removeMount($this->mountPoint);
+
+ return $result;
+ }
+
+ /**
+ * @return \OCP\Share\IShare
+ */
+ public function getShare() {
+ return $this->share;
+ }
+
+ /**
+ * Get the file id of the root of the storage
+ *
+ * @return int
+ */
+ public function getStorageRootId() {
+ return $this->share->getNodeId();
+ }
+}