Esempio n. 1
0
 /**
  * create unique target
  * @param string $filePath
  * @param string $shareWith
  * @param string $exclude
  * @return string
  */
 public function generateTarget($filePath, $shareWith, $exclude = null)
 {
     $shareFolder = \OCA\Files_Sharing\Helper::getShareFolder();
     $target = \OC\Files\Filesystem::normalizePath($shareFolder . '/' . basename($filePath));
     // for group shares we return the target right away
     if ($shareWith === false) {
         return $target;
     }
     \OC\Files\Filesystem::initMountPoints($shareWith);
     $view = new \OC\Files\View('/' . $shareWith . '/files');
     if (!$view->is_dir($shareFolder)) {
         $dir = '';
         $subdirs = explode('/', $shareFolder);
         foreach ($subdirs as $subdir) {
             $dir = $dir . '/' . $subdir;
             if (!$view->is_dir($dir)) {
                 $view->mkdir($dir);
             }
         }
     }
     $excludeList = \OCP\Share::getItemsSharedWithUser('file', $shareWith, self::FORMAT_TARGET_NAMES);
     if (is_array($exclude)) {
         $excludeList = array_merge($excludeList, $exclude);
     }
     return \OCA\Files_Sharing\Helper::generateUniqueTarget($target, $excludeList, $view);
 }
Esempio n. 2
0
 /**
  * rename a file
  *
  * @param string $dir
  * @param string $oldname
  * @param string $newname
  * @return array
  */
 public function rename($dir, $oldname, $newname)
 {
     $result = array('success' => false, 'data' => NULL);
     $normalizedOldPath = \OC\Files\Filesystem::normalizePath($dir . '/' . $oldname);
     $normalizedNewPath = \OC\Files\Filesystem::normalizePath($dir . '/' . $newname);
     // rename to non-existing folder is denied
     if (!$this->view->file_exists($normalizedOldPath)) {
         $result['data'] = array('message' => $this->l10n->t('%s could not be renamed as it has been deleted', array($oldname)), 'code' => 'sourcenotfound', 'oldname' => $oldname, 'newname' => $newname);
     } else {
         if (!$this->view->file_exists($dir)) {
             $result['data'] = array('message' => (string) $this->l10n->t('The target folder has been moved or deleted.', array($dir)), 'code' => 'targetnotfound');
             // rename to existing file is denied
         } else {
             if ($this->view->file_exists($normalizedNewPath)) {
                 $result['data'] = array('message' => $this->l10n->t("The name %s is already used in the folder %s. Please choose a different name.", array($newname, $dir)));
             } else {
                 if ($newname !== '.' and $this->view->rename($normalizedOldPath, $normalizedNewPath)) {
                     // successful rename
                     $meta = $this->view->getFileInfo($normalizedNewPath);
                     $meta = \OCA\Files\Helper::populateTags(array($meta));
                     $fileInfo = \OCA\Files\Helper::formatFileInfo(current($meta));
                     $fileInfo['path'] = dirname($normalizedNewPath);
                     $result['success'] = true;
                     $result['data'] = $fileInfo;
                 } else {
                     // rename failed
                     $result['data'] = array('message' => $this->l10n->t('%s could not be renamed', array($oldname)));
                 }
             }
         }
     }
     return $result;
 }
Esempio n. 3
0
 /**
  * inform encryption module that a file was restored from the trash bin,
  * e.g. to update the encryption keys
  *
  * @param array $params
  */
 public function postRestore($params)
 {
     if ($this->encryptionManager->isEnabled()) {
         $path = Filesystem::normalizePath('/' . $this->uid . '/files/' . $params['filePath']);
         $this->update($path);
     }
 }
Esempio n. 4
0
 /**
  * Deletes the given file by moving it into the trashbin.
  *
  * @param string $path
  */
 public function unlink($path)
 {
     if (self::$disableTrash) {
         return $this->storage->unlink($path);
     }
     $normalized = Filesystem::normalizePath($this->mountPoint . '/' . $path);
     $result = true;
     if (!isset($this->deletedFiles[$normalized])) {
         $view = Filesystem::getView();
         $this->deletedFiles[$normalized] = $normalized;
         if ($filesPath = $view->getRelativePath($normalized)) {
             $filesPath = trim($filesPath, '/');
             $result = \OCA\Files_Trashbin\Trashbin::move2trash($filesPath);
             // in cross-storage cases the file will be copied
             // but not deleted, so we delete it here
             if ($result) {
                 $this->storage->unlink($path);
             }
         } else {
             $result = $this->storage->unlink($path);
         }
         unset($this->deletedFiles[$normalized]);
     } else {
         if ($this->storage->file_exists($path)) {
             $result = $this->storage->unlink($path);
         }
     }
     return $result;
 }
 /**
  * propagate the registered changes to their parent folders
  *
  * @param int $time (optional) the mtime to set for the folders, if not set the current time is used
  */
 public function propagateChanges($time = null)
 {
     $changes = $this->getChanges();
     $this->changedFiles = [];
     if (!$time) {
         $time = time();
     }
     foreach ($changes as $change) {
         /**
          * @var \OC\Files\Storage\Storage $storage
          * @var string $internalPath
          */
         $absolutePath = $this->view->getAbsolutePath($change);
         $mount = $this->view->getMount($change);
         $storage = $mount->getStorage();
         $internalPath = $mount->getInternalPath($absolutePath);
         if ($storage) {
             $propagator = $storage->getPropagator();
             $propagatedEntries = $propagator->propagateChange($internalPath, $time);
             foreach ($propagatedEntries as $entry) {
                 $absolutePath = Filesystem::normalizePath($mount->getMountPoint() . '/' . $entry['path']);
                 $relativePath = $this->view->getRelativePath($absolutePath);
                 $this->emit('\\OC\\Files', 'propagate', [$relativePath, $entry]);
             }
         }
     }
 }
Esempio n. 6
0
 public function checkScanWarning($fullPath, OutputInterface $output)
 {
     $normalizedPath = basename(\OC\Files\Filesystem::normalizePath($fullPath));
     $path = basename($fullPath);
     if ($normalizedPath !== $path) {
         $output->writeln("\t<error>Entry \"" . $fullPath . '" will not be accessible due to incompatible encoding</error>');
     }
 }
Esempio n. 7
0
 /**
  * @brief list bookshelf contents
  *
  * @return array of FileInfo[], sorted by time added
  */
 public static function get()
 {
     $files = array();
     if ($bookshelf = json_decode(Config::get('bookshelf', ''), true)) {
         arsort($bookshelf);
         while (list($id, $time) = each($bookshelf)) {
             array_push($files, \OC\Files\Filesystem::getFileInfo(\OC\Files\Filesystem::normalizePath(\OC\Files\Filesystem::getPath($id))));
         }
     }
     return $files;
 }
Esempio n. 8
0
 /**
  * @param array $share
  * @param string $internalPath
  * @param \OC\Files\Cache\ChangePropagator $propagator
  */
 private function propagateForOwner($share, $internalPath, ChangePropagator $propagator)
 {
     // note that we have already set up the filesystem for the owner when mounting the share
     $view = new View('/' . $share['uid_owner'] . '/files');
     $shareRootPath = $view->getPath($share['item_source']);
     if (!is_null($shareRootPath)) {
         $path = $shareRootPath . '/' . $internalPath;
         $path = Filesystem::normalizePath($path);
         $propagator->addChange($path);
         $propagator->propagateChanges();
     }
 }
Esempio n. 9
0
 /**
  * rename mount point from the children if the parent was renamed
  *
  * @param string $oldPath old path relative to data/user/files
  * @param string $newPath new path relative to data/user/files
  */
 private static function renameChildren($oldPath, $newPath)
 {
     $absNewPath = \OC\Files\Filesystem::normalizePath('/' . \OCP\User::getUser() . '/files/' . $newPath);
     $absOldPath = \OC\Files\Filesystem::normalizePath('/' . \OCP\User::getUser() . '/files/' . $oldPath);
     $mountManager = \OC\Files\Filesystem::getMountManager();
     $mountedShares = $mountManager->findIn('/' . \OCP\User::getUser() . '/files/' . $oldPath);
     foreach ($mountedShares as $mount) {
         if ($mount->getStorage()->instanceOfStorage('OCA\\Files_Sharing\\ISharedStorage')) {
             $mountPoint = $mount->getMountPoint();
             $target = str_replace($absOldPath, $absNewPath, $mountPoint);
             $mount->moveMount($target);
         }
     }
 }
Esempio n. 10
0
 /**
  * Release an existing lock
  * @param string $path Path to file, relative to this storage
  * @param integer $lockType The type of lock to release
  * @param bool $releaseAll If true, release all outstanding locks
  * @return bool true on success, false on failure
  */
 protected function releaseLock($path, $lockType, $releaseAll = false)
 {
     $path = Filesystem::normalizePath($this->storage->getLocalFile($path));
     if (is_dir($path)) {
         return false;
     }
     if (isset($this->locks[$path])) {
         if ($releaseAll) {
             return $this->locks[$path]->releaseAll();
         } else {
             return $this->locks[$path]->release($lockType);
         }
     }
     return true;
 }
Esempio n. 11
0
 /**
  * check if the parent folder exists otherwise move the mount point up
  */
 private function verifyMountPoint(&$share, $user)
 {
     $mountPoint = basename($share['file_target']);
     $parent = dirname($share['file_target']);
     if (!\OC\Files\Filesystem::is_dir($parent)) {
         $parent = Helper::getShareFolder();
     }
     $newMountPoint = \OCA\Files_Sharing\Helper::generateUniqueTarget(\OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint), array(), new \OC\Files\View('/' . $user . '/files'));
     if ($newMountPoint !== $share['file_target']) {
         self::updateFileTarget($newMountPoint, $share);
         $share['file_target'] = $newMountPoint;
         $share['unique_name'] = true;
     }
     return $newMountPoint;
 }
Esempio n. 12
0
    public function addShare($remote, $token, $password, $name, $owner)
    {
        if ($this->uid) {
            $query = $this->connection->prepare('
				INSERT INTO `*PREFIX*share_external`
					(`remote`, `share_token`, `password`, `name`, `owner`, `user`, `mountpoint`, `mountpoint_hash`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?)
			');
            $mountPoint = Filesystem::normalizePath('/' . $name);
            $hash = md5($mountPoint);
            $query->execute(array($remote, $token, $password, $name, $owner, $this->uid, $mountPoint, $hash));
            $options = array('remote' => $remote, 'token' => $token, 'password' => $password, 'mountpoint' => $mountPoint, 'owner' => $owner);
            return $this->mountShare($options);
        }
    }
Esempio n. 13
0
 /**
  * check if the parent folder exists otherwise move the mount point up
  *
  * @param array $share
  * @return string
  */
 private function verifyMountPoint(&$share)
 {
     $mountPoint = basename($share['file_target']);
     $parent = dirname($share['file_target']);
     if (!$this->recipientView->is_dir($parent)) {
         $parent = Helper::getShareFolder();
     }
     $newMountPoint = \OCA\Files_Sharing\Helper::generateUniqueTarget(\OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint), [], $this->recipientView);
     if ($newMountPoint !== $share['file_target']) {
         $this->updateFileTarget($newMountPoint, $share);
         $share['file_target'] = $newMountPoint;
         $share['unique_name'] = true;
     }
     return $newMountPoint;
 }
Esempio n. 14
0
    public function addShare($remote, $token, $password, $name, $owner, $accepted = false, $user = null, $remoteId = -1)
    {
        $user = $user ? $user : $this->userSession->getUser()->getUID();
        $accepted = $accepted ? 1 : 0;
        $mountPoint = Filesystem::normalizePath('/' . $name);
        $query = $this->connection->prepare('
				INSERT INTO `*PREFIX*share_external`
					(`remote`, `share_token`, `password`, `name`, `owner`, `user`, `mountpoint`, `mountpoint_hash`, `accepted`, `remote_id`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
			');
        $hash = md5($mountPoint);
        $query->execute(array($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId));
        if ($accepted) {
            $options = array('remote' => $remote, 'token' => $token, 'password' => $password, 'mountpoint' => $mountPoint, 'owner' => $owner);
            return $this->mountShare($options);
        }
    }
Esempio n. 15
0
 /**
  * attach listeners to the scanner
  *
  * @param \OC\Files\Mount\MountPoint $mount
  */
 protected function attachListener($mount)
 {
     $scanner = $mount->getStorage()->getScanner();
     $emitter = $this;
     $scanner->listen('\\OC\\Files\\Cache\\Scanner', 'scanFile', function ($path) use($mount, $emitter) {
         $emitter->emit('\\OC\\Files\\Utils\\Scanner', 'scanFile', array($mount->getMountPoint() . $path));
     });
     $scanner->listen('\\OC\\Files\\Cache\\Scanner', 'scanFolder', function ($path) use($mount, $emitter) {
         $emitter->emit('\\OC\\Files\\Utils\\Scanner', 'scanFolder', array($mount->getMountPoint() . $path));
     });
     // propagate etag and mtimes when files are changed or removed
     $propagator = $this->propagator;
     $propagatorListener = function ($path) use($mount, $propagator) {
         $fullPath = Filesystem::normalizePath($mount->getMountPoint() . $path);
         $propagator->addChange($fullPath);
     };
     $scanner->listen('\\OC\\Files\\Cache\\Scanner', 'addToCache', $propagatorListener);
     $scanner->listen('\\OC\\Files\\Cache\\Scanner', 'removeFromCache', $propagatorListener);
 }
Esempio n. 16
0
 public function __construct($AppName, IRequest $request, $UserId)
 {
     parent::__construct($AppName, $request);
     $this->userId = $UserId;
     $path = self::PROJECTKIT_PREFIX . DIRECTORY_SEPARATOR;
     if (isset($_GET['containerId'])) {
         $path .= self::PROJECT_PREFIX . (string) $_GET['containerId'] . DIRECTORY_SEPARATOR;
         if (isset($_GET['targetType']) && isset($_GET['targetId'])) {
             switch ($_GET['targetType']) {
                 case TargetType::TASK:
                     $path .= self::TASK_PREFIX;
                     break;
                 case TargetType::ISSUE:
                     $path .= self::ISSUE_PREFIX;
                     break;
                 default:
                     break;
             }
             $path .= (string) $_GET['targetId'] . DIRECTORY_SEPARATOR;
             $_SESSION['targetType'] = $_GET['targetType'];
         } elseif (!isset($_GET['targetType']) && !isset($_GET['targetId'])) {
             $_SESSION['targetType'] = TargetType::PROJECT;
         }
         //use session to save targetType
         $path = Filesystem::normalizePath($path);
         //Create folder for path
         if (!Filesystem::file_exists($path)) {
             try {
                 Filesystem::mkdir($path);
             } catch (\Exception $e) {
                 $result = ['success' => false, 'data' => ['message' => $e->getMessage()]];
                 \OCP\JSON::error($result);
                 exit;
             }
         }
         if (!isset($_GET['dir'])) {
             $params = array_merge($_GET, ["dir" => $path]);
             $url = $_SERVER['PHP_SELF'] . '?' . http_build_query($params);
             header('Location: ' . $url, true, 302);
             exit;
         }
     }
 }
Esempio n. 17
0
 /**
  * go recursively through a dir and collect all files and sub files.
  * @param string $dir relative to the users files folder
  * @return array with list of files relative to the users files folder
  */
 public function getAllFiles($dir, $mountPoint = '')
 {
     $result = array();
     $dirList = array($dir);
     while ($dirList) {
         $dir = array_pop($dirList);
         $content = $this->view->getDirectoryContent(\OC\Files\Filesystem::normalizePath($this->userFilesDir . '/' . $dir));
         foreach ($content as $c) {
             // getDirectoryContent() returns the paths relative to the mount points, so we need
             // to re-construct the complete path
             $path = $mountPoint !== '' ? $mountPoint . '/' . $c['path'] : $c['path'];
             $path = \OC\Files\Filesystem::normalizePath($path);
             if ($c['type'] === 'dir') {
                 $dirList[] = substr($path, strlen('/' . \OCP\User::getUser() . "/files"));
             } else {
                 $result[] = substr($path, strlen('/' . \OCP\User::getUser() . "/files"));
             }
         }
     }
     return $result;
 }
Esempio n. 18
0
$sharedFile = null;
if ($linkedItem['item_type'] === 'folder') {
    $isValid = \OC\Files\Filesystem::isValidPath($file);
    if (!$isValid) {
        \OC_Response::setStatus(\OC_Response::STATUS_BAD_REQUEST);
        \OCP\Util::writeLog('core-preview', 'Passed filename is not valid, might be malicious (file:"' . $file . '";ip:"' . \OC::$server->getRequest()->getRemoteAddress() . '")', \OCP\Util::WARN);
        exit;
    }
    $sharedFile = \OC\Files\Filesystem::normalizePath($file);
}
if ($linkedItem['item_type'] === 'file') {
    $parent = $pathInfo['parent'];
    $path = $view->getPath($parent);
    $sharedFile = $pathInfo['name'];
}
$path = \OC\Files\Filesystem::normalizePath($path, false);
if (substr($path, 0, 1) === '/') {
    $path = substr($path, 1);
}
if ($maxX === 0 || $maxY === 0) {
    \OC_Response::setStatus(\OC_Response::STATUS_BAD_REQUEST);
    \OCP\Util::writeLog('core-preview', 'x and/or y set to 0', \OCP\Util::DEBUG);
    exit;
}
$root = 'files/' . $path;
try {
    $preview = new \OC\Preview($userId, $root);
    $preview->setFile($sharedFile);
    $preview->setMaxX($maxX);
    $preview->setMaxY($maxY);
    $preview->setScalingUp($scalingUp);
Esempio n. 19
0
$token = $_GET['t'];
$password = null;
if (isset($_POST['password'])) {
    $password = $_POST['password'];
}
$relativePath = null;
if (isset($_GET['dir'])) {
    $relativePath = $_GET['dir'];
}
$sortAttribute = isset($_GET['sort']) ? $_GET['sort'] : 'name';
$sortDirection = isset($_GET['sortdirection']) ? $_GET['sortdirection'] === 'desc' : false;
$data = \OCA\Files_Sharing\Helper::setupFromToken($token, $relativePath, $password);
$linkItem = $data['linkItem'];
// Load the files
$dir = $data['realPath'];
$dir = \OC\Files\Filesystem::normalizePath($dir);
if (!\OC\Files\Filesystem::is_dir($dir . '/')) {
    \OC_Response::setStatus(\OC_Response::STATUS_NOT_FOUND);
    \OCP\JSON::error(array('success' => false));
    exit;
}
$data = array();
// make filelist
$files = \OCA\Files\Helper::getFiles($dir, $sortAttribute, $sortDirection);
$formattedFiles = array();
foreach ($files as $file) {
    $entry = \OCA\Files\Helper::formatFileInfo($file);
    unset($entry['directory']);
    // for now
    $entry['permissions'] = \OCP\PERMISSION_READ;
    $formattedFiles[] = $entry;
Esempio n. 20
0
 /**
  *
  * @param string $mountPoint Mount point
  * @param string $mountType MOUNT_TYPE_GROUP | MOUNT_TYPE_USER
  * @param string $applicable User or group to remove mount from
  * @param bool $isPersonal Personal or system mount point
  * @return bool
  */
 public static function removeMountPoint($mountPoint, $mountType, $applicable, $isPersonal = false)
 {
     // Verify that the mount point applies for the current user
     $relMountPoints = $mountPoint;
     if ($isPersonal) {
         if ($applicable != OCP\User::getUser()) {
             return false;
         }
         $mountPoint = '/' . $applicable . '/files/' . ltrim($mountPoint, '/');
     } else {
         $mountPoint = '/$user/files/' . ltrim($mountPoint, '/');
     }
     $mountPoint = \OC\Files\Filesystem::normalizePath($mountPoint);
     $mountPoints = self::readData($isPersonal ? OCP\User::getUser() : NULL);
     // Remove mount point
     unset($mountPoints[$mountType][$applicable][$mountPoint]);
     // Unset parent arrays if empty
     if (empty($mountPoints[$mountType][$applicable])) {
         unset($mountPoints[$mountType][$applicable]);
         if (empty($mountPoints[$mountType])) {
             unset($mountPoints[$mountType]);
         }
     }
     self::writeData($isPersonal ? OCP\User::getUser() : NULL, $mountPoints);
     \OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_delete_mount, array(\OC\Files\Filesystem::signal_param_path => $relMountPoints, \OC\Files\Filesystem::signal_param_mount_type => $mountType, \OC\Files\Filesystem::signal_param_users => $applicable));
     return true;
 }
Esempio n. 21
0
 /**
  * @PublicPage
  * @NoCSRFRequired
  *
  * @param string $token
  * @param string $files
  * @param string $path
  * @return void|RedirectResponse
  */
 public function downloadShare($token, $files = null, $path = '')
 {
     \OC_User::setIncognitoMode(true);
     $linkItem = OCP\Share::getShareByToken($token, false);
     // Share is password protected - check whether the user is permitted to access the share
     if (isset($linkItem['share_with'])) {
         if (!Helper::authenticate($linkItem)) {
             return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate', array('token' => $token)));
         }
     }
     $originalSharePath = self::getPath($token);
     if (isset($originalSharePath) && Filesystem::isReadable($originalSharePath . $path)) {
         $originalSharePath = Filesystem::normalizePath($originalSharePath . $path);
         $type = \OC\Files\Filesystem::is_dir($originalSharePath) ? 'folder' : 'file';
         $args = $type === 'folder' ? array('dir' => $originalSharePath) : array('dir' => dirname($originalSharePath), 'scrollto' => basename($originalSharePath));
         $linkToFile = \OCP\Util::linkToAbsolute('files', 'index.php', $args);
         $subject = $type === 'folder' ? Activity::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED : Activity::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED;
         $this->activityManager->publishActivity('files_sharing', $subject, array($originalSharePath), '', array(), $originalSharePath, $linkToFile, $linkItem['uid_owner'], Activity::TYPE_PUBLIC_LINKS, Activity::PRIORITY_MEDIUM);
     }
     if (!is_null($files)) {
         // download selected files
         $files_list = json_decode($files);
         // in case we get only a single file
         if ($files_list === NULL) {
             $files_list = array($files);
         }
         // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
         // after dispatching the request which results in a "Cannot modify header information" notice.
         OC_Files::get($originalSharePath, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD');
         exit;
     } else {
         // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
         // after dispatching the request which results in a "Cannot modify header information" notice.
         OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $_SERVER['REQUEST_METHOD'] == 'HEAD');
         exit;
     }
 }
Esempio n. 22
0
 /**
  * get default share folder
  *
  * @param \OC\Files\View
  * @return string
  */
 public static function getShareFolder($view = null)
 {
     if ($view === null) {
         $view = Filesystem::getView();
     }
     $shareFolder = \OC::$server->getConfig()->getSystemValue('share_folder', '/');
     $shareFolder = Filesystem::normalizePath($shareFolder);
     if (!$view->file_exists($shareFolder)) {
         $dir = '';
         $subdirs = explode('/', $shareFolder);
         foreach ($subdirs as $subdir) {
             $dir = $dir . '/' . $subdir;
             if (!$view->is_dir($dir)) {
                 $view->mkdir($dir);
             }
         }
     }
     return $shareFolder;
 }
Esempio n. 23
0
 /**
  * get default share folder
  *
  * @return string
  */
 public static function getShareFolder()
 {
     $shareFolder = \OC::$server->getConfig()->getSystemValue('share_folder', '/');
     $shareFolder = Filesystem::normalizePath($shareFolder);
     if (!Filesystem::file_exists($shareFolder)) {
         $dir = '';
         $subdirs = explode('/', $shareFolder);
         foreach ($subdirs as $subdir) {
             $dir = $dir . '/' . $subdir;
             if (!Filesystem::is_dir($dir)) {
                 Filesystem::mkdir($dir);
             }
         }
     }
     return $shareFolder;
 }
Esempio n. 24
0
 /**
  * Get the lock file associated to a file
  *
  * @param string $filename The filename of the file to create a lock file for
  * @return string The filename of the lock file
  */
 public static function getLockFile($filename)
 {
     if (!self::$locksDir) {
         $dataDir = \OC::$server->getConfig()->getSystemValue('datadirectory');
         self::$locksDir = $dataDir . '/.locks';
     }
     if (!file_exists(self::$locksDir)) {
         mkdir(self::$locksDir);
     }
     $filename = Filesystem::normalizePath($filename);
     return self::$locksDir . '/' . sha1($filename) . '.lock';
 }
Esempio n. 25
0
 /**
  * change file metadata
  *
  * @param string $path
  * @param array|\OCP\Files\FileInfo $data
  * @return int
  *
  * returns the fileid of the updated file
  */
 public function putFileInfo($path, $data)
 {
     $this->assertPathLength($path);
     if ($data instanceof FileInfo) {
         $data = $data->getData();
     }
     $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
     /**
      * @var \OC\Files\Storage\Storage $storage
      * @var string $internalPath
      */
     list($storage, $internalPath) = Filesystem::resolvePath($path);
     if ($storage) {
         $cache = $storage->getCache($path);
         if (!$cache->inCache($internalPath)) {
             $scanner = $storage->getScanner($internalPath);
             $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
         }
         return $cache->put($internalPath, $data);
     } else {
         return -1;
     }
 }
Esempio n. 26
0
 /**
  * @param string $path
  * @return string
  */
 public function cleanPath($path)
 {
     if ($path === '') {
         return $path;
     }
     $path = Filesystem::normalizePath($path);
     // remove leading slash
     return substr($path, 1);
 }
Esempio n. 27
0
 /**
  * after a file is renamed/copied, rename/copy its keyfile and share-keys also fix the file size and fix also the sharing
  *
  * @param array $params array with oldpath and newpath
  */
 public static function postRenameOrCopy($params)
 {
     if (\OCP\App::isEnabled('files_encryption') === false) {
         return true;
     }
     // Disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $view = new \OC_FilesystemView('/');
     $userId = \OCP\User::getUser();
     $util = new Util($view, $userId);
     if (isset(self::$renamedFiles[$params['oldpath']]['uid']) && isset(self::$renamedFiles[$params['oldpath']]['path'])) {
         $ownerOld = self::$renamedFiles[$params['oldpath']]['uid'];
         $pathOld = self::$renamedFiles[$params['oldpath']]['path'];
         $type = self::$renamedFiles[$params['oldpath']]['type'];
         $operation = self::$renamedFiles[$params['oldpath']]['operation'];
         unset(self::$renamedFiles[$params['oldpath']]);
     } else {
         \OCP\Util::writeLog('Encryption library', "can't get path and owner from the file before it was renamed", \OCP\Util::DEBUG);
         \OC_FileProxy::$enabled = $proxyStatus;
         return false;
     }
     list($ownerNew, $pathNew) = $util->getUidAndFilename($params['newpath']);
     // Format paths to be relative to user files dir
     if ($util->isSystemWideMountPoint($pathOld)) {
         $oldKeyfilePath = 'files_encryption/keyfiles/' . $pathOld;
         $oldShareKeyPath = 'files_encryption/share-keys/' . $pathOld;
     } else {
         $oldKeyfilePath = $ownerOld . '/' . 'files_encryption/keyfiles/' . $pathOld;
         $oldShareKeyPath = $ownerOld . '/' . 'files_encryption/share-keys/' . $pathOld;
     }
     if ($util->isSystemWideMountPoint($pathNew)) {
         $newKeyfilePath = 'files_encryption/keyfiles/' . $pathNew;
         $newShareKeyPath = 'files_encryption/share-keys/' . $pathNew;
     } else {
         $newKeyfilePath = $ownerNew . '/files_encryption/keyfiles/' . $pathNew;
         $newShareKeyPath = $ownerNew . '/files_encryption/share-keys/' . $pathNew;
     }
     // add key ext if this is not an folder
     if ($type === 'file') {
         $oldKeyfilePath .= '.key';
         $newKeyfilePath .= '.key';
         // create destination folder if not exists
         $localKeyPath = $view->getLocalFile($oldShareKeyPath);
         $newLocalKeyPath = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $localKeyPath));
         if (!file_exists(dirname($newLocalKeyPath))) {
             mkdir(dirname($newLocalKeyPath), 0750, true);
         }
         // handle share-keys
         $matches = Helper::findShareKeys($pathOld, $oldShareKeyPath, $view);
         if (count($matches) === 0) {
             \OC_Log::write('Encryption library', 'No share keys found for "' . $pathOld . '"', \OC_Log::WARN);
         }
         foreach ($matches as $src) {
             $dst = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $src));
             $view->{$operation}($src, $dst);
         }
     } else {
         // handle share-keys folders
         // create destination folder if not exists
         if (!$view->file_exists(dirname($newShareKeyPath))) {
             mkdir($view->getLocalFile($newShareKeyPath), 0750, true);
         }
         $view->{$operation}($oldShareKeyPath, $newShareKeyPath);
     }
     // Rename keyfile so it isn't orphaned
     if ($view->file_exists($oldKeyfilePath)) {
         // create destination folder if not exists
         if (!$view->file_exists(dirname($newKeyfilePath))) {
             mkdir(dirname($view->getLocalFile($newKeyfilePath)), 0750, true);
         }
         $view->{$operation}($oldKeyfilePath, $newKeyfilePath);
     }
     // build the path to the file
     $newPath = '/' . $ownerNew . '/files' . $pathNew;
     // update sharing-keys
     self::updateKeyfiles($params['newpath'], $type);
     \OC_FileProxy::$enabled = $proxyStatus;
 }
Esempio n. 28
0
 public static function post_delete($args, $prefix = '')
 {
     $path = Files\Filesystem::normalizePath($args['path']);
     $preview = new Preview(\OC_User::getUser(), $prefix, $path);
     $preview->deleteAllPreviews();
 }
Esempio n. 29
0
 /**
  * @medium
  */
 function testSearch()
 {
     $storage1 = $this->getTestStorage();
     $storage2 = $this->getTestStorage();
     $storage3 = $this->getTestStorage();
     \OC\Files\Filesystem::mount($storage1, array(), '/');
     \OC\Files\Filesystem::mount($storage2, array(), '/substorage');
     \OC\Files\Filesystem::mount($storage3, array(), '/folder/anotherstorage');
     $rootView = new \OC\Files\View('');
     $results = $rootView->search('foo');
     $this->assertEquals(6, count($results));
     $paths = array();
     foreach ($results as $result) {
         $this->assertEquals($result['path'], \OC\Files\Filesystem::normalizePath($result['path']));
         $paths[] = $result['path'];
     }
     $this->assertContains('/foo.txt', $paths);
     $this->assertContains('/foo.png', $paths);
     $this->assertContains('/substorage/foo.txt', $paths);
     $this->assertContains('/substorage/foo.png', $paths);
     $this->assertContains('/folder/anotherstorage/foo.txt', $paths);
     $this->assertContains('/folder/anotherstorage/foo.png', $paths);
     $folderView = new \OC\Files\View('/folder');
     $results = $folderView->search('bar');
     $this->assertEquals(2, count($results));
     $paths = array();
     foreach ($results as $result) {
         $paths[] = $result['path'];
     }
     $this->assertContains('/anotherstorage/folder/bar.txt', $paths);
     $this->assertContains('/bar.txt', $paths);
     $results = $folderView->search('foo');
     $this->assertEquals(2, count($results));
     $paths = array();
     foreach ($results as $result) {
         $paths[] = $result['path'];
     }
     $this->assertContains('/anotherstorage/foo.txt', $paths);
     $this->assertContains('/anotherstorage/foo.png', $paths);
     $this->assertEquals(6, count($rootView->searchByMime('text')));
     $this->assertEquals(3, count($folderView->searchByMime('text')));
 }
Esempio n. 30
0
 /**
  * Get shared items from the database
  * @param string $itemType
  * @param string $item Item source or target (optional)
  * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique
  * @param string $shareWith User or group the item is being shared with
  * @param string $uidOwner User that is the owner of shared items (optional)
  * @param int $format Format to convert items to with formatItems() (optional)
  * @param mixed $parameters to pass to formatItems() (optional)
  * @param int $limit Number of items to return, -1 to return all matches (optional)
  * @param boolean $includeCollections Include collection item types (optional)
  * @param boolean $itemShareWithBySource (optional)
  * @param boolean $checkExpireDate
  * @return array
  *
  * See public functions getItem(s)... for parameter usage
  *
  */
 public static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, $includeCollections = false, $itemShareWithBySource = false, $checkExpireDate = true)
 {
     if (!self::isEnabled()) {
         return array();
     }
     $backend = self::getBackend($itemType);
     $collectionTypes = false;
     // Get filesystem root to add it to the file target and remove from the
     // file source, match file_source with the file cache
     if ($itemType == 'file' || $itemType == 'folder') {
         if (!is_null($uidOwner)) {
             $root = \OC\Files\Filesystem::getRoot();
         } else {
             $root = '';
         }
         $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ';
         if (!isset($item)) {
             $where .= ' AND `file_target` IS NOT NULL ';
         }
         $where .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` ';
         $fileDependent = true;
         $queryArgs = array();
     } else {
         $fileDependent = false;
         $root = '';
         $collectionTypes = self::getCollectionItemTypes($itemType);
         if ($includeCollections && !isset($item) && $collectionTypes) {
             // If includeCollections is true, find collections of this item type, e.g. a music album contains songs
             if (!in_array($itemType, $collectionTypes)) {
                 $itemTypes = array_merge(array($itemType), $collectionTypes);
             } else {
                 $itemTypes = $collectionTypes;
             }
             $placeholders = join(',', array_fill(0, count($itemTypes), '?'));
             $where = ' WHERE `item_type` IN (' . $placeholders . '))';
             $queryArgs = $itemTypes;
         } else {
             $where = ' WHERE `item_type` = ?';
             $queryArgs = array($itemType);
         }
     }
     if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') {
         $where .= ' AND `share_type` != ?';
         $queryArgs[] = self::SHARE_TYPE_LINK;
     }
     if (isset($shareType)) {
         // Include all user and group items
         if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) {
             $where .= ' AND ((`share_type` in (?, ?) AND `share_with` = ?) ';
             $queryArgs[] = self::SHARE_TYPE_USER;
             $queryArgs[] = self::$shareTypeGroupUserUnique;
             $queryArgs[] = $shareWith;
             $groups = \OC_Group::getUserGroups($shareWith);
             if (!empty($groups)) {
                 $placeholders = join(',', array_fill(0, count($groups), '?'));
                 $where .= ' OR (`share_type` = ? AND `share_with` IN (' . $placeholders . ')) ';
                 $queryArgs[] = self::SHARE_TYPE_GROUP;
                 $queryArgs = array_merge($queryArgs, $groups);
             }
             $where .= ')';
             // Don't include own group shares
             $where .= ' AND `uid_owner` != ?';
             $queryArgs[] = $shareWith;
         } else {
             $where .= ' AND `share_type` = ?';
             $queryArgs[] = $shareType;
             if (isset($shareWith)) {
                 $where .= ' AND `share_with` = ?';
                 $queryArgs[] = $shareWith;
             }
         }
     }
     if (isset($uidOwner)) {
         $where .= ' AND `uid_owner` = ?';
         $queryArgs[] = $uidOwner;
         if (!isset($shareType)) {
             // Prevent unique user targets for group shares from being selected
             $where .= ' AND `share_type` != ?';
             $queryArgs[] = self::$shareTypeGroupUserUnique;
         }
         if ($fileDependent) {
             $column = 'file_source';
         } else {
             $column = 'item_source';
         }
     } else {
         if ($fileDependent) {
             $column = 'file_target';
         } else {
             $column = 'item_target';
         }
     }
     if (isset($item)) {
         $collectionTypes = self::getCollectionItemTypes($itemType);
         if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) {
             $where .= ' AND (';
         } else {
             $where .= ' AND';
         }
         // If looking for own shared items, check item_source else check item_target
         if (isset($uidOwner) || $itemShareWithBySource) {
             // If item type is a file, file source needs to be checked in case the item was converted
             if ($fileDependent) {
                 $where .= ' `file_source` = ?';
                 $column = 'file_source';
             } else {
                 $where .= ' `item_source` = ?';
                 $column = 'item_source';
             }
         } else {
             if ($fileDependent) {
                 $where .= ' `file_target` = ?';
                 $item = \OC\Files\Filesystem::normalizePath($item);
             } else {
                 $where .= ' `item_target` = ?';
             }
         }
         $queryArgs[] = $item;
         if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) {
             $placeholders = join(',', array_fill(0, count($collectionTypes), '?'));
             $where .= ' OR `item_type` IN (' . $placeholders . '))';
             $queryArgs = array_merge($queryArgs, $collectionTypes);
         }
     }
     if ($shareType == self::$shareTypeUserAndGroups && $limit === 1) {
         // Make sure the unique user target is returned if it exists,
         // unique targets should follow the group share in the database
         // If the limit is not 1, the filtering can be done later
         $where .= ' ORDER BY `*PREFIX*share`.`id` DESC';
     } else {
         $where .= ' ORDER BY `*PREFIX*share`.`id` ASC';
     }
     if ($limit != -1 && !$includeCollections) {
         // The limit must be at least 3, because filtering needs to be done
         if ($limit < 3) {
             $queryLimit = 3;
         } else {
             $queryLimit = $limit;
         }
     } else {
         $queryLimit = null;
     }
     $select = self::createSelectStatement($format, $fileDependent, $uidOwner);
     $root = strlen($root);
     $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where, $queryLimit);
     $result = $query->execute($queryArgs);
     if (\OC_DB::isError($result)) {
         \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage() . ', select=' . $select . ' where=', \OCP\Util::ERROR);
     }
     $items = array();
     $targets = array();
     $switchedItems = array();
     $mounts = array();
     while ($row = $result->fetchRow()) {
         self::transformDBResults($row);
         // Filter out duplicate group shares for users with unique targets
         if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
             continue;
         }
         if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) {
             $row['share_type'] = self::SHARE_TYPE_GROUP;
             $row['unique_name'] = true;
             // remember that we use a unique name for this user
             $row['share_with'] = $items[$row['parent']]['share_with'];
             // if the group share was unshared from the user we keep the permission, otherwise
             // we take the permission from the parent because this is always the up-to-date
             // permission for the group share
             if ($row['permissions'] > 0) {
                 $row['permissions'] = $items[$row['parent']]['permissions'];
             }
             // Remove the parent group share
             unset($items[$row['parent']]);
             if ($row['permissions'] == 0) {
                 continue;
             }
         } else {
             if (!isset($uidOwner)) {
                 // Check if the same target already exists
                 if (isset($targets[$row['id']])) {
                     // Check if the same owner shared with the user twice
                     // through a group and user share - this is allowed
                     $id = $targets[$row['id']];
                     if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) {
                         // Switch to group share type to ensure resharing conditions aren't bypassed
                         if ($items[$id]['share_type'] != self::SHARE_TYPE_GROUP) {
                             $items[$id]['share_type'] = self::SHARE_TYPE_GROUP;
                             $items[$id]['share_with'] = $row['share_with'];
                         }
                         // Switch ids if sharing permission is granted on only
                         // one share to ensure correct parent is used if resharing
                         if (~(int) $items[$id]['permissions'] & \OCP\Constants::PERMISSION_SHARE && (int) $row['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
                             $items[$row['id']] = $items[$id];
                             $switchedItems[$id] = $row['id'];
                             unset($items[$id]);
                             $id = $row['id'];
                         }
                         $items[$id]['permissions'] |= (int) $row['permissions'];
                     }
                     continue;
                 } elseif (!empty($row['parent'])) {
                     $targets[$row['parent']] = $row['id'];
                 }
             }
         }
         // Remove root from file source paths if retrieving own shared items
         if (isset($uidOwner) && isset($row['path'])) {
             if (isset($row['parent'])) {
                 $query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?');
                 $parentResult = $query->execute(array($row['parent']));
                 if (\OC_DB::isError($result)) {
                     \OCP\Util::writeLog('OCP\\Share', 'Can\'t select parent: ' . \OC_DB::getErrorMessage() . ', select=' . $select . ' where=' . $where, \OCP\Util::ERROR);
                 } else {
                     $parentRow = $parentResult->fetchRow();
                     $tmpPath = $parentRow['file_target'];
                     // find the right position where the row path continues from the target path
                     $pos = strrpos($row['path'], $parentRow['file_target']);
                     $subPath = substr($row['path'], $pos);
                     $splitPath = explode('/', $subPath);
                     foreach (array_slice($splitPath, 2) as $pathPart) {
                         $tmpPath = $tmpPath . '/' . $pathPart;
                     }
                     $row['path'] = $tmpPath;
                 }
             } else {
                 if (!isset($mounts[$row['storage']])) {
                     $mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']);
                     if (is_array($mountPoints) && !empty($mountPoints)) {
                         $mounts[$row['storage']] = current($mountPoints);
                     }
                 }
                 if (!empty($mounts[$row['storage']])) {
                     $path = $mounts[$row['storage']]->getMountPoint() . $row['path'];
                     $relPath = substr($path, $root);
                     // path relative to data/user
                     $row['path'] = rtrim($relPath, '/');
                 }
             }
         }
         if ($checkExpireDate) {
             if (self::expireItem($row)) {
                 continue;
             }
         }
         // Check if resharing is allowed, if not remove share permission
         if (isset($row['permissions']) && !self::isResharingAllowed() | \OCP\Util::isSharingDisabledForUser()) {
             $row['permissions'] &= ~\OCP\Constants::PERMISSION_SHARE;
         }
         // Add display names to result
         $row['share_with_displayname'] = $row['share_with'];
         if (isset($row['share_with']) && $row['share_with'] != '' && $row['share_type'] === self::SHARE_TYPE_USER) {
             $row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']);
         } else {
             if (isset($row['share_with']) && $row['share_with'] != '' && $row['share_type'] === self::SHARE_TYPE_REMOTE) {
                 $addressBookEntries = \OC::$server->getContactsManager()->search($row['share_with'], ['CLOUD']);
                 foreach ($addressBookEntries as $entry) {
                     foreach ($entry['CLOUD'] as $cloudID) {
                         if ($cloudID === $row['share_with']) {
                             $row['share_with_displayname'] = $entry['FN'];
                         }
                     }
                 }
             }
         }
         if (isset($row['uid_owner']) && $row['uid_owner'] != '') {
             $row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']);
         }
         if ($row['permissions'] > 0) {
             $items[$row['id']] = $row;
         }
     }
     // group items if we are looking for items shared with the current user
     if (isset($shareWith) && $shareWith === \OCP\User::getUser()) {
         $items = self::groupItems($items, $itemType);
     }
     if (!empty($items)) {
         $collectionItems = array();
         foreach ($items as &$row) {
             // Return only the item instead of a 2-dimensional array
             if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) {
                 if ($format == self::FORMAT_NONE) {
                     return $row;
                 } else {
                     break;
                 }
             }
             // Check if this is a collection of the requested item type
             if ($includeCollections && $collectionTypes && $row['item_type'] !== 'folder' && in_array($row['item_type'], $collectionTypes)) {
                 if (($collectionBackend = self::getBackend($row['item_type'])) && $collectionBackend instanceof \OCP\Share_Backend_Collection) {
                     // Collections can be inside collections, check if the item is a collection
                     if (isset($item) && $row['item_type'] == $itemType && $row[$column] == $item) {
                         $collectionItems[] = $row;
                     } else {
                         $collection = array();
                         $collection['item_type'] = $row['item_type'];
                         if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
                             $collection['path'] = basename($row['path']);
                         }
                         $row['collection'] = $collection;
                         // Fetch all of the children sources
                         $children = $collectionBackend->getChildren($row[$column]);
                         foreach ($children as $child) {
                             $childItem = $row;
                             $childItem['item_type'] = $itemType;
                             if ($row['item_type'] != 'file' && $row['item_type'] != 'folder') {
                                 $childItem['item_source'] = $child['source'];
                                 $childItem['item_target'] = $child['target'];
                             }
                             if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
                                 if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
                                     $childItem['file_source'] = $child['source'];
                                 } else {
                                     // TODO is this really needed if we already know that we use the file backend?
                                     $meta = \OC\Files\Filesystem::getFileInfo($child['file_path']);
                                     $childItem['file_source'] = $meta['fileid'];
                                 }
                                 $childItem['file_target'] = \OC\Files\Filesystem::normalizePath($child['file_path']);
                             }
                             if (isset($item)) {
                                 if ($childItem[$column] == $item) {
                                     // Return only the item instead of a 2-dimensional array
                                     if ($limit == 1) {
                                         if ($format == self::FORMAT_NONE) {
                                             return $childItem;
                                         } else {
                                             // Unset the items array and break out of both loops
                                             $items = array();
                                             $items[] = $childItem;
                                             break 2;
                                         }
                                     } else {
                                         $collectionItems[] = $childItem;
                                     }
                                 }
                             } else {
                                 $collectionItems[] = $childItem;
                             }
                         }
                     }
                 }
                 // Remove collection item
                 $toRemove = $row['id'];
                 if (array_key_exists($toRemove, $switchedItems)) {
                     $toRemove = $switchedItems[$toRemove];
                 }
                 unset($items[$toRemove]);
             } elseif ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) {
                 // FIXME: Thats a dirty hack to improve file sharing performance,
                 // see github issue #10588 for more details
                 // Need to find a solution which works for all back-ends
                 $collectionBackend = self::getBackend($row['item_type']);
                 $sharedParents = $collectionBackend->getParents($row['item_source']);
                 foreach ($sharedParents as $parent) {
                     $collectionItems[] = $parent;
                 }
             }
         }
         if (!empty($collectionItems)) {
             $collectionItems = array_unique($collectionItems, SORT_REGULAR);
             $items = array_merge($items, $collectionItems);
         }
         // filter out invalid items, these can appear when subshare entries exist
         // for a group in which the requested user isn't a member any more
         $items = array_filter($items, function ($item) {
             return $item['share_type'] !== self::$shareTypeGroupUserUnique;
         });
         return self::formatResult($items, $column, $backend, $format, $parameters);
     } elseif ($includeCollections && $collectionTypes && in_array('folder', $collectionTypes)) {
         // FIXME: Thats a dirty hack to improve file sharing performance,
         // see github issue #10588 for more details
         // Need to find a solution which works for all back-ends
         $collectionItems = array();
         $collectionBackend = self::getBackend('folder');
         $sharedParents = $collectionBackend->getParents($item, $shareWith, $uidOwner);
         foreach ($sharedParents as $parent) {
             $collectionItems[] = $parent;
         }
         if ($limit === 1) {
             return reset($collectionItems);
         }
         return self::formatResult($collectionItems, $column, $backend, $format, $parameters);
     }
     return array();
 }