public function testFindByStorageId()
 {
     /** @var \OCA\Files_External\Service\UserStoragesService $storageService */
     $storageService = $this->getMockBuilder('\\OCA\\Files_External\\Service\\UserStoragesService')->disableOriginalConstructor()->getMock();
     $storage = $this->getMockBuilder('\\OC\\Files\\Storage\\Storage')->disableOriginalConstructor()->getMock();
     $storage->expects($this->any())->method('getId')->will($this->returnValue('dummy'));
     $mount = new PersonalMount($storageService, 10, $storage, '/foo');
     $mountManager = new Manager();
     $mountManager->addMount($mount);
     $this->assertEquals([$mount], $mountManager->findByStorageId('dummy'));
 }
Example #2
0
 public function testLong()
 {
     $storage = new LongId(array());
     $mount = new \OC\Files\Mount\MountPoint($storage, '/foo');
     $this->manager->addMount($mount);
     $id = $mount->getStorageId();
     $storageId = $storage->getId();
     $this->assertEquals(array($mount), $this->manager->findByStorageId($id));
     $this->assertEquals(array($mount), $this->manager->findByStorageId($storageId));
     $this->assertEquals(array($mount), $this->manager->findByStorageId(md5($storageId)));
 }
Example #3
0
	/**
	 * mount an \OC\Files\Storage\Storage in our virtual filesystem
	 *
	 * @param \OC\Files\Storage\Storage|string $class
	 * @param array $arguments
	 * @param string $mountpoint
	 */
	static public function mount($class, $arguments, $mountpoint) {
		if (!self::$mounts) {
			\OC_Util::setupFS();
		}
		$mount = new Mount\Mount($class, $mountpoint, $arguments, self::getLoader());
		self::$mounts->addMount($mount);
	}
Example #4
0
    public function removeShare($mountPoint)
    {
        $mountPointObj = $this->mountManager->find($mountPoint);
        $id = $mountPointObj->getStorage()->getCache()->getId('');
        $mountPoint = $this->stripPath($mountPoint);
        $hash = md5($mountPoint);
        $getShare = $this->connection->prepare('
			SELECT `remote`, `share_token`, `remote_id`
			FROM  `*PREFIX*share_external`
			WHERE `mountpoint_hash` = ? AND `user` = ?');
        $result = $getShare->execute(array($hash, $this->uid));
        if ($result) {
            $share = $getShare->fetch();
            $this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline');
        }
        $getShare->closeCursor();
        $query = $this->connection->prepare('
			DELETE FROM `*PREFIX*share_external`
			WHERE `mountpoint_hash` = ?
			AND `user` = ?
		');
        $result = (bool) $query->execute(array($hash, $this->uid));
        if ($result) {
            $this->removeReShares($id);
        }
        return $result;
    }
Example #5
0
 /**
  * @param array $data
  * @return Mount
  */
 protected function mountShare($data)
 {
     $data['manager'] = $this;
     $mountPoint = '/' . $this->userSession->getUser()->getUID() . '/files' . $data['mountpoint'];
     $data['mountpoint'] = $mountPoint;
     $mount = new Mount(self::STORAGE, $mountPoint, $data, $this, $this->storageLoader);
     $this->mountManager->addMount($mount);
     return $mount;
 }
Example #6
0
 /**
  * copy file between two storages
  *
  * @param Storage $sourceStorage
  * @param string $sourceInternalPath
  * @param string $targetInternalPath
  * @param bool $preserveMtime
  * @param bool $isRename
  * @return bool
  */
 private function copyBetweenStorage(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename)
 {
     // first copy the keys that we reuse the existing file key on the target location
     // and don't create a new one which would break versions for example.
     $mount = $this->mountManager->findByStorageId($sourceStorage->getId());
     if (count($mount) === 1) {
         $mountPoint = $mount[0]->getMountPoint();
         $source = $mountPoint . '/' . $sourceInternalPath;
         $target = $this->getFullPath($targetInternalPath);
         $this->copyKeys($source, $target);
     } else {
         $this->logger->error('Could not find mount point, can\'t keep encryption keys');
     }
     if ($sourceStorage->is_dir($sourceInternalPath)) {
         $dh = $sourceStorage->opendir($sourceInternalPath);
         $result = $this->mkdir($targetInternalPath);
         if (is_resource($dh)) {
             while ($result and ($file = readdir($dh)) !== false) {
                 if (!Filesystem::isIgnoredDir($file)) {
                     $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
                 }
             }
         }
     } else {
         try {
             $source = $sourceStorage->fopen($sourceInternalPath, 'r');
             $target = $this->fopen($targetInternalPath, 'w');
             list(, $result) = \OC_Helper::streamCopy($source, $target);
             fclose($source);
             fclose($target);
         } catch (\Exception $e) {
             fclose($source);
             fclose($target);
             throw $e;
         }
         if ($result) {
             if ($preserveMtime) {
                 $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
             }
             $isEncrypted = $this->encryptionManager->isEnabled() && $this->mount->getOption('encrypt', true) ? 1 : 0;
             // in case of a rename we need to manipulate the source cache because
             // this information will be kept for the new target
             if ($isRename) {
                 $sourceStorage->getCache()->put($sourceInternalPath, ['encrypted' => $isEncrypted]);
             } else {
                 $this->getCache()->put($targetInternalPath, ['encrypted' => $isEncrypted]);
             }
         } else {
             // delete partially written target file
             $this->unlink($targetInternalPath);
             // delete cache entry that was created by fopen
             $this->getCache()->remove($targetInternalPath);
         }
     }
     return (bool) $result;
 }
Example #7
0
 /**
  * Moves a file from one location to another
  *
  * @param string $sourcePath The path to the file which should be moved
  * @param string $destinationPath The full destination path, so not just the destination parent node
  * @throws \Sabre\DAV\Exception\BadRequest
  * @throws \Sabre\DAV\Exception\ServiceUnavailable
  * @throws \Sabre\DAV\Exception\Forbidden
  * @return int
  */
 public function move($sourcePath, $destinationPath)
 {
     if (!$this->fileView) {
         throw new \Sabre\DAV\Exception\ServiceUnavailable('filesystem not setup');
     }
     $targetNodeExists = $this->nodeExists($destinationPath);
     $sourceNode = $this->getNodeForPath($sourcePath);
     if ($sourceNode instanceof \Sabre\DAV\ICollection && $targetNodeExists) {
         throw new \Sabre\DAV\Exception\Forbidden('Could not copy directory ' . $sourceNode . ', target exists');
     }
     list($sourceDir, ) = \Sabre\HTTP\URLUtil::splitPath($sourcePath);
     list($destinationDir, ) = \Sabre\HTTP\URLUtil::splitPath($destinationPath);
     $isMovableMount = false;
     $sourceMount = $this->mountManager->find($this->fileView->getAbsolutePath($sourcePath));
     $internalPath = $sourceMount->getInternalPath($this->fileView->getAbsolutePath($sourcePath));
     if ($sourceMount instanceof MoveableMount && $internalPath === '') {
         $isMovableMount = true;
     }
     try {
         $sameFolder = $sourceDir === $destinationDir;
         // if we're overwriting or same folder
         if ($targetNodeExists || $sameFolder) {
             // note that renaming a share mount point is always allowed
             if (!$this->fileView->isUpdatable($destinationDir) && !$isMovableMount) {
                 throw new \Sabre\DAV\Exception\Forbidden();
             }
         } else {
             if (!$this->fileView->isCreatable($destinationDir)) {
                 throw new \Sabre\DAV\Exception\Forbidden();
             }
         }
         if (!$sameFolder) {
             // moving to a different folder, source will be gone, like a deletion
             // note that moving a share mount point is always allowed
             if (!$this->fileView->isDeletable($sourcePath) && !$isMovableMount) {
                 throw new \Sabre\DAV\Exception\Forbidden();
             }
         }
         $fileName = basename($destinationPath);
         try {
             $this->fileView->verifyPath($destinationDir, $fileName);
         } catch (\OCP\Files\InvalidPathException $ex) {
             throw new InvalidPath($ex->getMessage());
         }
         $renameOkay = $this->fileView->rename($sourcePath, $destinationPath);
         if (!$renameOkay) {
             throw new \Sabre\DAV\Exception\Forbidden('');
         }
     } catch (StorageNotAvailableException $e) {
         throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
     } catch (LockedException $e) {
         throw new FileLocked($e->getMessage(), $e->getCode(), $e);
     }
     $this->markDirty($sourceDir);
     $this->markDirty($destinationDir);
 }
Example #8
0
 /**
  * @param array $data
  * @return Mount
  */
 protected function mountShare($data)
 {
     $data['manager'] = $this;
     $mountPoint = '/' . $this->uid . '/files' . $data['mountpoint'];
     $data['mountpoint'] = $mountPoint;
     $data['certificateManager'] = \OC::$server->getCertificateManager($this->uid);
     $mount = new Mount(self::STORAGE, $mountPoint, $data, $this, $this->storageLoader);
     $this->mountManager->addMount($mount);
     return $mount;
 }
 /**
  * Moves a file from one location to another
  *
  * @param string $sourcePath The path to the file which should be moved
  * @param string $destinationPath The full destination path, so not just the destination parent node
  * @throws \Sabre\DAV\Exception\BadRequest
  * @throws \Sabre\DAV\Exception\ServiceUnavailable
  * @throws \Sabre\DAV\Exception\Forbidden
  * @return int
  */
 public function move($sourcePath, $destinationPath)
 {
     if (!$this->fileView) {
         throw new \Sabre\DAV\Exception\ServiceUnavailable('filesystem not setup');
     }
     $targetNodeExists = $this->nodeExists($destinationPath);
     $sourceNode = $this->getNodeForPath($sourcePath);
     if ($sourceNode instanceof \Sabre\DAV\ICollection && $targetNodeExists) {
         throw new \Sabre\DAV\Exception\Forbidden('Could not copy directory ' . $sourceNode . ', target exists');
     }
     list($sourceDir, ) = \Sabre\DAV\URLUtil::splitPath($sourcePath);
     list($destinationDir, ) = \Sabre\DAV\URLUtil::splitPath($destinationPath);
     $isMovableMount = false;
     $sourceMount = $this->mountManager->find($this->fileView->getAbsolutePath($sourcePath));
     $internalPath = $sourceMount->getInternalPath($this->fileView->getAbsolutePath($sourcePath));
     if ($sourceMount instanceof MoveableMount && $internalPath === '') {
         $isMovableMount = true;
     }
     try {
         $sameFolder = $sourceDir === $destinationDir;
         // if we're overwriting or same folder
         if ($targetNodeExists || $sameFolder) {
             // note that renaming a share mount point is always allowed
             if (!$this->fileView->isUpdatable($destinationDir) && !$isMovableMount) {
                 throw new \Sabre\DAV\Exception\Forbidden();
             }
         } else {
             if (!$this->fileView->isCreatable($destinationDir)) {
                 throw new \Sabre\DAV\Exception\Forbidden();
             }
         }
         if (!$sameFolder) {
             // moving to a different folder, source will be gone, like a deletion
             // note that moving a share mount point is always allowed
             if (!$this->fileView->isDeletable($sourcePath) && !$isMovableMount) {
                 throw new \Sabre\DAV\Exception\Forbidden();
             }
         }
         $fileName = basename($destinationPath);
         if (!\OCP\Util::isValidFileName($fileName)) {
             throw new \Sabre\DAV\Exception\BadRequest();
         }
         $renameOkay = $this->fileView->rename($sourcePath, $destinationPath);
         if (!$renameOkay) {
             throw new \Sabre\DAV\Exception\Forbidden('');
         }
     } catch (\OCP\Files\StorageNotAvailableException $e) {
         throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
     }
     // update properties
     $query = \OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertypath` = ?' . ' WHERE `userid` = ? AND `propertypath` = ?');
     $query->execute(array(\OC\Files\Filesystem::normalizePath($destinationPath), \OC_User::getUser(), \OC\Files\Filesystem::normalizePath($sourcePath)));
     $this->markDirty($sourceDir);
     $this->markDirty($destinationDir);
 }
Example #10
0
 private function assertNotMount($mountPoint)
 {
     $mountPoint = rtrim($mountPoint, '/');
     $mount = $this->mountManager->find($this->getFullPath($mountPoint));
     if ($mount) {
         $this->assertInstanceOf('\\OCP\\Files\\Mount\\IMountPoint', $mount);
         $this->assertNotEquals($this->getFullPath($mountPoint), rtrim($mount->getMountPoint(), '/'));
     } else {
         $this->assertNull($mount);
     }
 }
Example #11
0
 /**
  * search file by id
  *
  * An array is returned because in the case where a single storage is mounted in different places the same file
  * can exist in different places
  *
  * @param int $id
  * @throws \OCP\Files\NotFoundException
  * @return Node[]
  */
 public function getById($id)
 {
     $result = Cache::getById($id);
     if (is_null($result)) {
         throw new NotFoundException();
     } else {
         list($storageId, $internalPath) = $result;
         $nodes = array();
         $mounts = $this->mountManager->findByStorageId($storageId);
         foreach ($mounts as $mount) {
             $nodes[] = $this->get($mount->getMountPoint() . $internalPath);
         }
         return $nodes;
     }
 }
 /**
  * Moves a file from one location to another
  *
  * @param string $sourcePath The path to the file which should be moved
  * @param string $destinationPath The full destination path, so not just the destination parent node
  * @throws \Sabre\DAV\Exception\BadRequest
  * @throws \Sabre\DAV\Exception\ServiceUnavailable
  * @throws \Sabre\DAV\Exception\Forbidden
  * @return int
  */
 public function move($sourcePath, $destinationPath)
 {
     if (!$this->fileView) {
         throw new \Sabre\DAV\Exception\ServiceUnavailable('filesystem not setup');
     }
     $sourceNode = $this->getNodeForPath($sourcePath);
     if ($sourceNode instanceof \Sabre\DAV\ICollection and $this->nodeExists($destinationPath)) {
         throw new \Sabre\DAV\Exception\Forbidden('Could not copy directory ' . $sourceNode . ', target exists');
     }
     list($sourceDir, ) = \Sabre\DAV\URLUtil::splitPath($sourcePath);
     list($destinationDir, ) = \Sabre\DAV\URLUtil::splitPath($destinationPath);
     $isMovableMount = false;
     $sourceMount = $this->mountManager->find($this->fileView->getAbsolutePath($sourcePath));
     $internalPath = $sourceMount->getInternalPath($this->fileView->getAbsolutePath($sourcePath));
     if ($sourceMount instanceof MoveableMount && $internalPath === '') {
         $isMovableMount = true;
     }
     try {
         // check update privileges
         if (!$this->fileView->isUpdatable($sourcePath) && !$isMovableMount) {
             throw new \Sabre\DAV\Exception\Forbidden();
         }
         if ($sourceDir !== $destinationDir) {
             if (!$this->fileView->isCreatable($destinationDir)) {
                 throw new \Sabre\DAV\Exception\Forbidden();
             }
             if (!$this->fileView->isDeletable($sourcePath) && !$isMovableMount) {
                 throw new \Sabre\DAV\Exception\Forbidden();
             }
         }
         $fileName = basename($destinationPath);
         if (!\OCP\Util::isValidFileName($fileName)) {
             throw new \Sabre\DAV\Exception\BadRequest();
         }
         $renameOkay = $this->fileView->rename($sourcePath, $destinationPath);
         if (!$renameOkay) {
             throw new \Sabre\DAV\Exception\Forbidden('');
         }
     } catch (\OCP\Files\StorageNotAvailableException $e) {
         throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
     }
     // update properties
     $query = \OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertypath` = ?' . ' WHERE `userid` = ? AND `propertypath` = ?');
     $query->execute(array(\OC\Files\Filesystem::normalizePath($destinationPath), \OC_User::getUser(), \OC\Files\Filesystem::normalizePath($sourcePath)));
     $this->markDirty($sourceDir);
     $this->markDirty($destinationDir);
 }
Example #13
0
 /**
  * update keyfiles and share keys recursively
  *
  * @param int $fileSource file source id
  */
 private function update($fileSource)
 {
     $path = \OC\Files\Filesystem::getPath($fileSource);
     $info = \OC\Files\Filesystem::getFileInfo($path);
     $owner = \OC\Files\Filesystem::getOwner($path);
     $view = new \OC\Files\View('/' . $owner . '/files');
     $ownerPath = $view->getPath($info->getId());
     $absPath = '/' . $owner . '/files' . $ownerPath;
     $mount = $this->mountManager->find($path);
     $mountPoint = $mount->getMountPoint();
     // if a folder was shared, get a list of all (sub-)folders
     if ($this->view->is_dir($absPath)) {
         $allFiles = $this->util->getAllFiles($absPath, $mountPoint);
     } else {
         $allFiles = array($absPath);
     }
     $encryptionModule = $this->encryptionManager->getDefaultEncryptionModule();
     foreach ($allFiles as $path) {
         $usersSharing = $this->file->getAccessList($path);
         $encryptionModule->update($path, $this->uid, $usersSharing);
     }
 }
Example #14
0
 /**
  * @param \OC\Files\Mount\MountPoint $mount
  */
 public function unMount($mount)
 {
     $this->mountManager->remove($mount);
 }
Example #15
0
 /**
  * @param array $data
  * @return Mount
  */
 protected function mountShare($data)
 {
     $mount = $this->getMount($data);
     $this->mountManager->addMount($mount);
     return $mount;
 }
Example #16
0
 /**
  * copy file between two storages
  *
  * @param Storage $sourceStorage
  * @param string $sourceInternalPath
  * @param string $targetInternalPath
  * @param bool $preserveMtime
  * @param bool $isRename
  * @return bool
  * @throws \Exception
  */
 private function copyBetweenStorage(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename)
 {
     // for versions we have nothing to do, because versions should always use the
     // key from the original file. Just create a 1:1 copy and done
     if ($this->isVersion($targetInternalPath) || $this->isVersion($sourceInternalPath)) {
         // remember that we try to create a version so that we can detect it during
         // fopen($sourceInternalPath) and by-pass the encryption in order to
         // create a 1:1 copy of the file
         $this->arrayCache->set('encryption_copy_version_' . $sourceInternalPath, true);
         $result = $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
         $this->arrayCache->remove('encryption_copy_version_' . $sourceInternalPath);
         if ($result) {
             $info = $this->getCache('', $sourceStorage)->get($sourceInternalPath);
             // make sure that we update the unencrypted size for the version
             if (isset($info['encrypted']) && $info['encrypted'] === true) {
                 $this->updateUnencryptedSize($this->getFullPath($targetInternalPath), $info['size']);
             }
             $this->updateEncryptedVersion($sourceStorage, $sourceInternalPath, $targetInternalPath, $isRename);
         }
         return $result;
     }
     // first copy the keys that we reuse the existing file key on the target location
     // and don't create a new one which would break versions for example.
     $mount = $this->mountManager->findByStorageId($sourceStorage->getId());
     if (count($mount) === 1) {
         $mountPoint = $mount[0]->getMountPoint();
         $source = $mountPoint . '/' . $sourceInternalPath;
         $target = $this->getFullPath($targetInternalPath);
         $this->copyKeys($source, $target);
     } else {
         $this->logger->error('Could not find mount point, can\'t keep encryption keys');
     }
     if ($sourceStorage->is_dir($sourceInternalPath)) {
         $dh = $sourceStorage->opendir($sourceInternalPath);
         $result = $this->mkdir($targetInternalPath);
         if (is_resource($dh)) {
             while ($result and ($file = readdir($dh)) !== false) {
                 if (!Filesystem::isIgnoredDir($file)) {
                     $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file, false, $isRename);
                 }
             }
         }
     } else {
         try {
             $source = $sourceStorage->fopen($sourceInternalPath, 'r');
             $target = $this->fopen($targetInternalPath, 'w');
             list(, $result) = \OC_Helper::streamCopy($source, $target);
             fclose($source);
             fclose($target);
         } catch (\Exception $e) {
             fclose($source);
             fclose($target);
             throw $e;
         }
         if ($result) {
             if ($preserveMtime) {
                 $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
             }
             $this->updateEncryptedVersion($sourceStorage, $sourceInternalPath, $targetInternalPath, $isRename);
         } else {
             // delete partially written target file
             $this->unlink($targetInternalPath);
             // delete cache entry that was created by fopen
             $this->getCache()->remove($targetInternalPath);
         }
     }
     return (bool) $result;
 }