/** * test moving a shared file out of the Shared folder */ function testRename() { // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // save file with content $cryptedFile = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename, $this->dataShort); // test that data was successfully written $this->assertTrue(is_int($cryptedFile)); // get the file info from previous created file $fileInfo = $this->view->getFileInfo('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); // check if we have a valid file info $this->assertTrue($fileInfo instanceof \OC\Files\FileInfo); // share the file \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, OCP\PERMISSION_ALL); // check if share key for user2 exists $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); // login as user2 \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename)); // get file contents $retrievedCryptedFile = $this->view->file_get_contents('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename); // check if data is the same as we previously written $this->assertEquals($this->dataShort, $retrievedCryptedFile); // move the file to a subfolder $this->view->rename('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename, '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1 . $this->filename); // check if we can read the moved file $retrievedRenamedFile = $this->view->file_get_contents('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1 . $this->filename); // check if data is the same as we previously written $this->assertEquals($this->dataShort, $retrievedRenamedFile); // cleanup \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); }
/** * Test clearing orphaned files */ public function testClearFiles() { $input = $this->getMockBuilder('Symfony\\Component\\Console\\Input\\InputInterface')->disableOriginalConstructor()->getMock(); $output = $this->getMockBuilder('Symfony\\Component\\Console\\Output\\OutputInterface')->disableOriginalConstructor()->getMock(); $this->loginAsUser($this->user1); $view = new \OC\Files\View('/' . $this->user1 . '/'); $view->mkdir('files/test'); $fileInfo = $view->getFileInfo('files/test'); $storageId = $fileInfo->getStorage()->getId(); $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is available'); $this->command->execute($input, $output); $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is still available'); $deletedRows = $this->connection->executeUpdate('DELETE FROM `*PREFIX*storages` WHERE `id` = ?', [$storageId]); $this->assertNotNull($deletedRows, 'Asserts that storage got deleted'); $this->assertSame(1, $deletedRows, 'Asserts that storage got deleted'); // parent folder, `files`, ´test` and `welcome.txt` => 4 elements $output->expects($this->once())->method('writeln')->with('4 orphaned file cache entries deleted'); $this->command->execute($input, $output); $this->assertCount(0, $this->getFile($fileInfo->getId()), 'Asserts that file gets cleaned up'); // since we deleted the storage it might throw a (valid) StorageNotAvailableException try { $view->unlink('files/test'); } catch (StorageNotAvailableException $e) { } }
/** * @param array $share Share with info from the share_external table * @return enriched share info with data from the filecache */ private static function extendShareInfo($share) { $view = new \OC\Files\View('/' . \OC_User::getUser() . '/files/'); $info = $view->getFileInfo($share['mountpoint']); $share['mimetype'] = $info->getMimetype(); $share['mtime'] = $info->getMtime(); $share['permissions'] = $info->getPermissions(); $share['type'] = $info->getType(); $share['file_id'] = $info->getId(); return $share; }
/** * index a file * * @author Jörn Dreyer <*****@*****.**> * * @param string $path the path of the file * * @return bool */ public static function indexFile($path = '', $user = null) { if (!Filesystem::isValidPath($path)) { return; } if ($path === '') { //ignore the empty path element return false; } if (is_null($user)) { $view = Filesystem::getView(); $user = \OCP\User::getUser(); } else { $view = new \OC\Files\View('/' . $user . '/files'); } if (!$view) { Util::writeLog('search_lucene', 'could not resolve filesystem view', Util::WARN); return false; } $root = $view->getRoot(); $pk = md5($root . $path); // the cache already knows mime and other basic stuff $data = $view->getFileInfo($path); if (isset($data['mimetype'])) { $mimetype = $data['mimetype']; if ('text/html' === $mimetype) { $doc = \Zend_Search_Lucene_Document_Html::loadHTML($view->file_get_contents($path)); } else { if ('application/msword' === $mimetype) { // FIXME uses ZipArchive ... make compatible with OC\Files\Filesystem //$doc = Zend_Search_Lucene_Document_Docx::loadDocxFile(OC\Files\Filesystem::file_get_contents($path)); //no special treatment yet $doc = new \Zend_Search_Lucene_Document(); } else { $doc = new \Zend_Search_Lucene_Document(); } } // store fscacheid as unique id to lookup by when deleting $doc->addField(\Zend_Search_Lucene_Field::Keyword('pk', $pk)); // Store document URL to identify it in the search results $doc->addField(\Zend_Search_Lucene_Field::Text('path', $path)); $doc->addField(\Zend_Search_Lucene_Field::unIndexed('size', $data['size'])); $doc->addField(\Zend_Search_Lucene_Field::unIndexed('mimetype', $mimetype)); self::extractMetadata($doc, $path, $view, $mimetype); Lucene::updateFile($doc, $path, $user); return true; } else { Util::writeLog('search_lucene', 'need mimetype for content extraction', Util::ERROR); return false; } }
function testDescryptAllWithBrokenFiles() { $file1 = "/decryptAll1" . uniqid() . ".txt"; $file2 = "/decryptAll2" . uniqid() . ".txt"; $util = new Encryption\Util($this->view, $this->userId); $this->view->file_put_contents($this->userId . '/files/' . $file1, $this->dataShort); $this->view->file_put_contents($this->userId . '/files/' . $file2, $this->dataShort); $fileInfoEncrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); $fileInfoEncrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); $this->assertTrue($fileInfoEncrypted1 instanceof \OC\Files\FileInfo); $this->assertTrue($fileInfoEncrypted2 instanceof \OC\Files\FileInfo); $this->assertEquals($fileInfoEncrypted1['encrypted'], 1); $this->assertEquals($fileInfoEncrypted2['encrypted'], 1); // rename keyfile for file1 so that the decryption for file1 fails // Expected behaviour: decryptAll() returns false, file2 gets decrypted anyway $this->view->rename($this->userId . '/files_encryption/keyfiles/' . $file1 . '.key', $this->userId . '/files_encryption/keyfiles/' . $file1 . '.key.moved'); // decrypt all encrypted files $result = $util->decryptAll(); $this->assertFalse($result); $fileInfoUnencrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); $fileInfoUnencrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); $this->assertTrue($fileInfoUnencrypted1 instanceof \OC\Files\FileInfo); $this->assertTrue($fileInfoUnencrypted2 instanceof \OC\Files\FileInfo); // file1 should be still encrypted; file2 should be decrypted $this->assertEquals(1, $fileInfoUnencrypted1['encrypted']); $this->assertEquals(0, $fileInfoUnencrypted2['encrypted']); // keyfiles and share keys should still exist $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/keyfiles/')); $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/share-keys/')); // rename the keyfile for file1 back $this->view->rename($this->userId . '/files_encryption/keyfiles/' . $file1 . '.key.moved', $this->userId . '/files_encryption/keyfiles/' . $file1 . '.key'); // try again to decrypt all encrypted files $result = $util->decryptAll(); $this->assertTrue($result); $fileInfoUnencrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); $fileInfoUnencrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); $this->assertTrue($fileInfoUnencrypted1 instanceof \OC\Files\FileInfo); $this->assertTrue($fileInfoUnencrypted2 instanceof \OC\Files\FileInfo); // now both files should be decrypted $this->assertEquals(0, $fileInfoUnencrypted1['encrypted']); $this->assertEquals(0, $fileInfoUnencrypted2['encrypted']); // keyfiles and share keys should be deleted $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/keyfiles/')); $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/share-keys/')); //cleanup $this->view->unlink($this->userId . '/files/' . $file1); $this->view->unlink($this->userId . '/files/' . $file2); $this->view->deleteAll($this->userId . '/files_encryption/keyfiles.backup'); $this->view->deleteAll($this->userId . '/files_encryption/share-keys.backup'); }
public static function postAvatar($args) { \OC_JSON::checkLoggedIn(); \OC_JSON::callCheck(); $user = \OC_User::getUser(); if (isset($_POST['path'])) { $path = stripslashes($_POST['path']); $view = new \OC\Files\View('/' . $user . '/files'); $fileInfo = $view->getFileInfo($path); if ($fileInfo['encrypted'] === true) { $fileName = $view->toTmpFile($path); } else { $fileName = $view->getLocalFile($path); } } elseif (!empty($_FILES)) { $files = $_FILES['files']; if ($files['error'][0] === 0 && is_uploaded_file($files['tmp_name'][0]) && !\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0])) { \OC\Cache::set('avatar_upload', file_get_contents($files['tmp_name'][0]), 7200); $view = new \OC\Files\View('/' . $user . '/cache'); $fileName = $view->getLocalFile('avatar_upload'); unlink($files['tmp_name'][0]); } } else { $l = new \OC_L10n('core'); \OC_JSON::error(array("data" => array("message" => $l->t("No image or file provided")))); return; } try { $image = new \OC_Image(); $image->loadFromFile($fileName); $image->fixOrientation(); if ($image->valid()) { \OC\Cache::set('tmpavatar', $image->data(), 7200); \OC_JSON::error(array("data" => "notsquare")); } else { $l = new \OC_L10n('core'); $mimeType = $image->mimeType(); if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') { \OC_JSON::error(array("data" => array("message" => $l->t("Unknown filetype")))); } if (!$image->valid()) { \OC_JSON::error(array("data" => array("message" => $l->t("Invalid image")))); } } } catch (\Exception $e) { \OC_JSON::error(array("data" => array("message" => $e->getMessage()))); } }
/** * get the free space in the path's owner home folder * @param path * @return int */ private function getFreeSpace($path) { /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); $owner = $storage->getOwner($internalPath); if (!$owner) { return -1; } $totalSpace = $this->getQuota($owner); if ($totalSpace == -1) { return -1; } $view = new \OC\Files\View("/" . $owner . "/files"); $rootInfo = $view->getFileInfo('/'); $usedSpace = isset($rootInfo['size']) ? $rootInfo['size'] : 0; return $totalSpace - $usedSpace; }
/** * @brief Erase a file's versions which exceed the set quota */ private static function expire($filename, $versionsSize = null, $offset = 0) { if (\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED) == 'true') { list($uid, $filename) = self::getUidAndFilename($filename); $versionsFileview = new \OC\Files\View('/' . $uid . '/files_versions'); // get available disk space for user $softQuota = true; $quota = \OC_Preferences::getValue($uid, 'files', 'quota'); if ($quota === null || $quota === 'default') { $quota = \OC_Appconfig::getValue('files', 'default_quota'); } if ($quota === null || $quota === 'none') { $quota = \OC\Files\Filesystem::free_space('/'); $softQuota = false; } else { $quota = \OCP\Util::computerFileSize($quota); } // make sure that we have the current size of the version history if ($versionsSize === null) { $versionsSize = self::getVersionsSize($uid); if ($versionsSize === false || $versionsSize < 0) { $versionsSize = self::calculateSize($uid); } } // calculate available space for version history // subtract size of files and current versions size from quota if ($softQuota) { $files_view = new \OC\Files\View('/' . $uid . '/files'); $rootInfo = $files_view->getFileInfo('/'); $free = $quota - $rootInfo['size']; // remaining free space for user if ($free > 0) { $availableSpace = $free * self::DEFAULTMAXSIZE / 100 - ($versionsSize + $offset); // how much space can be used for versions } else { $availableSpace = $free - $versionsSize - $offset; } } else { $availableSpace = $quota - $offset; } // with the probability of 0.1% we reduce the number of all versions not only for the current file $random = rand(0, 1000); if ($random == 0) { $allFiles = true; } else { $allFiles = false; } $allVersions = Storage::getVersions($uid, $filename); $versionsByFile[$filename] = $allVersions; $sizeOfDeletedVersions = self::delOldVersions($versionsByFile, $allVersions, $versionsFileview); $availableSpace = $availableSpace + $sizeOfDeletedVersions; $versionsSize = $versionsSize - $sizeOfDeletedVersions; // if still not enough free space we rearrange the versions from all files if ($availableSpace <= 0 || $allFiles) { $result = Storage::getAllVersions($uid); $versionsByFile = $result['by_file']; $allVersions = $result['all']; $sizeOfDeletedVersions = self::delOldVersions($versionsByFile, $allVersions, $versionsFileview); $availableSpace = $availableSpace + $sizeOfDeletedVersions; $versionsSize = $versionsSize - $sizeOfDeletedVersions; } // Check if enough space is available after versions are rearranged. // If not we delete the oldest versions until we meet the size limit for versions, // but always keep the two latest versions $numOfVersions = count($allVersions) - 2; $i = 0; while ($availableSpace < 0 && $i < $numOfVersions) { $version = current($allVersions); $versionsFileview->unlink($version['path'] . '.v' . $version['version']); $versionsSize -= $version['size']; $availableSpace += $version['size']; next($allVersions); $i++; } return $versionsSize; // finally return the new size of the version history } return false; }
/** * Find which users can access a shared item * @param string $path to the file * @param string $ownerUser owner of the file * @param boolean $includeOwner include owner to the list of users with access to the file * @param boolean $returnUserPaths Return an array with the user => path map * @param boolean $recursive take all parent folders into account (default true) * @return array * @note $path needs to be relative to user data dir, e.g. 'file.txt' * not '/admin/data/file.txt' */ public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false, $recursive = true) { Filesystem::initMountPoints($ownerUser); $shares = $sharePaths = $fileTargets = array(); $publicShare = false; $remoteShare = false; $source = -1; $cache = false; $view = new \OC\Files\View('/' . $ownerUser . '/files'); $meta = $view->getFileInfo($path); if ($meta) { $path = substr($meta->getPath(), strlen('/' . $ownerUser . '/files')); } else { // if the file doesn't exists yet we start with the parent folder $meta = $view->getFileInfo(dirname($path)); } if ($meta !== false) { $source = $meta['fileid']; $cache = new \OC\Files\Cache\Cache($meta['storage']); } while ($source !== -1) { // Fetch all shares with another user if (!$returnUserPaths) { $query = \OC_DB::prepare('SELECT `share_with`, `file_source`, `file_target` FROM `*PREFIX*share` WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'); $result = $query->execute(array($source, self::SHARE_TYPE_USER)); } else { $query = \OC_DB::prepare('SELECT `share_with`, `file_source`, `file_target` FROM `*PREFIX*share` WHERE `item_source` = ? AND `share_type` IN (?, ?) AND `item_type` IN (\'file\', \'folder\')'); $result = $query->execute(array($source, self::SHARE_TYPE_USER, self::$shareTypeGroupUserUnique)); } if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR); } else { while ($row = $result->fetchRow()) { $shares[] = $row['share_with']; if ($returnUserPaths) { $fileTargets[(int) $row['file_source']][$row['share_with']] = $row; } } } // We also need to take group shares into account $query = \OC_DB::prepare('SELECT `share_with`, `file_source`, `file_target` FROM `*PREFIX*share` WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'); $result = $query->execute(array($source, self::SHARE_TYPE_GROUP)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR); } else { while ($row = $result->fetchRow()) { $usersInGroup = \OC_Group::usersInGroup($row['share_with']); $shares = array_merge($shares, $usersInGroup); if ($returnUserPaths) { foreach ($usersInGroup as $user) { if (!isset($fileTargets[(int) $row['file_source']][$user])) { // When the user already has an entry for this file source // the file is either shared directly with him as well, or // he has an exception entry (because of naming conflict). $fileTargets[(int) $row['file_source']][$user] = $row; } } } } } //check for public link shares if (!$publicShare) { $query = \OC_DB::prepare(' SELECT `share_with` FROM `*PREFIX*share` WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')', 1); $result = $query->execute(array($source, self::SHARE_TYPE_LINK)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR); } else { if ($result->fetchRow()) { $publicShare = true; } } } //check for remote share if (!$remoteShare) { $query = \OC_DB::prepare(' SELECT `share_with` FROM `*PREFIX*share` WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')', 1); $result = $query->execute(array($source, self::SHARE_TYPE_REMOTE)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR); } else { if ($result->fetchRow()) { $remoteShare = true; } } } // let's get the parent for the next round $meta = $cache->get((int) $source); if ($recursive === true && $meta !== false) { $source = (int) $meta['parent']; } else { $source = -1; } } // Include owner in list of users, if requested if ($includeOwner) { $shares[] = $ownerUser; } if ($returnUserPaths) { $fileTargetIDs = array_keys($fileTargets); $fileTargetIDs = array_unique($fileTargetIDs); if (!empty($fileTargetIDs)) { $query = \OC_DB::prepare('SELECT `fileid`, `path` FROM `*PREFIX*filecache` WHERE `fileid` IN (' . implode(',', $fileTargetIDs) . ')'); $result = $query->execute(); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR); } else { while ($row = $result->fetchRow()) { foreach ($fileTargets[$row['fileid']] as $uid => $shareData) { $sharedPath = $shareData['file_target']; $sharedPath .= substr($path, strlen($row['path']) - 5); $sharePaths[$uid] = $sharedPath; } } } } if ($includeOwner) { $sharePaths[$ownerUser] = $path; } else { unset($sharePaths[$ownerUser]); } return $sharePaths; } return array('users' => array_unique($shares), 'public' => $publicShare, 'remote' => $remoteShare); }
public function testShareWithOwnerError() { \OC_User::setUserId($this->user1); $view = new \OC\Files\View('/' . $this->user1 . '/'); $view->mkdir('files/folder1'); $fileInfo = $view->getFileInfo('files/folder1'); $this->assertInstanceOf('\\OC\\Files\\FileInfo', $fileInfo); $fileId = $fileInfo->getId(); $this->assertTrue(\OCP\Share::shareItem('folder', $fileId, \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_ALL), 'Failed asserting that user 1 successfully shared "test" with user 2.'); \OC_User::setUserId($this->user2); try { \OCP\Share::shareItem('folder', $fileId, \OCP\Share::SHARE_TYPE_USER, $this->user1, \OCP\Constants::PERMISSION_ALL); $this->fail(); } catch (\Exception $e) { $this->assertEquals('Sharing failed, because the user ' . $this->user1 . ' is the original sharer', $e->getMessage()); } }
public static function getSharesFromItem($target) { $result = array(); $owner = \OC\Files\Filesystem::getOwner($target); \OC\Files\Filesystem::initMountPoints($owner); $info = \OC\Files\Filesystem::getFileInfo($target); $ownerView = new \OC\Files\View('/' . $owner . '/files'); if ($owner != \OCP\User::getUser()) { $path = $ownerView->getPath($info['fileid']); } else { $path = $target; } $ids = array(); while ($path !== dirname($path)) { $info = $ownerView->getFileInfo($path); if ($info instanceof \OC\Files\FileInfo) { $ids[] = $info['fileid']; } else { \OCP\Util::writeLog('sharing', 'No fileinfo available for: ' . $path, \OCP\Util::WARN); } $path = dirname($path); } if (!empty($ids)) { $idList = array_chunk($ids, 99, true); foreach ($idList as $subList) { $statement = "SELECT `share_with`, `share_type`, `file_target` FROM `*PREFIX*share` WHERE `file_source` IN (" . implode(',', $subList) . ") AND `share_type` IN (0, 1, 2)"; $query = \OCP\DB::prepare($statement); $r = $query->execute(); $result = array_merge($result, $r->fetchAll()); } } return $result; }
/** * get file ID from a given path * @param string $path * @return string fileID or null */ private static function getFileId($path) { $view = new \OC\Files\View('/' . \OCP\User::getUser() . '/files'); $fileId = null; $fileInfo = $view->getFileInfo($path); if ($fileInfo) { $fileId = $fileInfo['fileid']; } return $fileId; }
/** * Find which users can access a shared item * @param string $path to the file * @param string $ownerUser owner of the file * @param boolean $includeOwner include owner to the list of users with access to the file * @param boolean $returnUserPaths Return an array with the user => path map * @return array * @note $path needs to be relative to user data dir, e.g. 'file.txt' * not '/admin/data/file.txt' */ public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false) { $shares = $sharePaths = $fileTargets = array(); $publicShare = false; $source = -1; $cache = false; $view = new \OC\Files\View('/' . $ownerUser . '/files'); if ($view->file_exists($path)) { $meta = $view->getFileInfo($path); $path = substr($meta->getPath(), strlen('/' . $ownerUser . '/files')); } else { // if the file doesn't exists yet we start with the parent folder $meta = $view->getFileInfo(dirname($path)); } if ($meta !== false) { $source = $meta['fileid']; $cache = new \OC\Files\Cache\Cache($meta['storage']); } while ($source !== -1) { // Fetch all shares with another user $query = \OC_DB::prepare('SELECT `share_with`, `file_source`, `file_target` FROM `*PREFIX*share` WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'); $result = $query->execute(array($source, self::SHARE_TYPE_USER)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } else { while ($row = $result->fetchRow()) { $shares[] = $row['share_with']; if ($returnUserPaths) { $fileTargets[(int) $row['file_source']][$row['share_with']] = $row; } } } // We also need to take group shares into account $query = \OC_DB::prepare('SELECT `share_with`, `file_source`, `file_target` FROM `*PREFIX*share` WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'); $result = $query->execute(array($source, self::SHARE_TYPE_GROUP)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } else { while ($row = $result->fetchRow()) { $usersInGroup = \OC_Group::usersInGroup($row['share_with']); $shares = array_merge($shares, $usersInGroup); if ($returnUserPaths) { foreach ($usersInGroup as $user) { $fileTargets[(int) $row['file_source']][$user] = $row; } } } } //check for public link shares if (!$publicShare) { $query = \OC_DB::prepare('SELECT `share_with` FROM `*PREFIX*share` WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'); $result = $query->execute(array($source, self::SHARE_TYPE_LINK)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } else { if ($result->fetchRow()) { $publicShare = true; } } } // let's get the parent for the next round $meta = $cache->get((int) $source); if ($meta !== false) { $source = (int) $meta['parent']; } else { $source = -1; } } // Include owner in list of users, if requested if ($includeOwner) { $shares[] = $ownerUser; if ($returnUserPaths) { $sharePaths[$ownerUser] = $path; } } if ($returnUserPaths) { $fileTargetIDs = array_keys($fileTargets); $fileTargetIDs = array_unique($fileTargetIDs); if (!empty($fileTargetIDs)) { $query = \OC_DB::prepare('SELECT `fileid`, `path` FROM `*PREFIX*filecache` WHERE `fileid` IN (' . implode(',', $fileTargetIDs) . ')'); $result = $query->execute(); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } else { while ($row = $result->fetchRow()) { foreach ($fileTargets[$row['fileid']] as $uid => $shareData) { $sharedPath = $shareData['file_target']; $sharedPath .= substr($path, strlen($row['path']) - 5); $sharePaths[$uid] = $sharedPath; } } } } return $sharePaths; } return array("users" => array_unique($shares), "public" => $publicShare); }
<?php $installedVersion = OCP\Config::getAppValue('files_sharing', 'installed_version'); if (version_compare($installedVersion, '0.3', '<')) { $update_error = false; $query = OCP\DB::prepare('SELECT * FROM `*PREFIX*sharing`'); $result = $query->execute(); $groupShares = array(); //we need to set up user backends, otherwise creating the shares will fail with "because user does not exist" OC_User::useBackend(new OC_User_Database()); OC_Group::useBackend(new OC_Group_Database()); OC_App::loadApps(array('authentication')); $rootView = new \OC\Files\View(''); while ($row = $result->fetchRow()) { $meta = $rootView->getFileInfo(${$row}['source']); $itemSource = $meta['fileid']; if ($itemSource != -1) { $file = $meta; if ($file['mimetype'] == 'httpd/unix-directory') { $itemType = 'folder'; } else { $itemType = 'file'; } if ($row['permissions'] == 0) { $permissions = OCP\PERMISSION_READ | OCP\PERMISSION_SHARE; } else { $permissions = OCP\PERMISSION_READ | OCP\PERMISSION_UPDATE | OCP\PERMISSION_SHARE; if ($itemType == 'folder') { $permissions |= OCP\PERMISSION_CREATE; } }
public static function prepare_delete($args, $prefix = '') { $path = $args['path']; if (substr($path, 0, 1) === '/') { $path = substr($path, 1); } $view = new \OC\Files\View('/' . \OC_User::getUser() . '/' . $prefix); $info = $view->getFileInfo($path); \OC\Preview::$deleteFileMapper = array_merge(\OC\Preview::$deleteFileMapper, array(Files\Filesystem::normalizePath($view->getAbsolutePath($path)) => $info)); }
public function testDoNotExpireOtherShares() { $this->loginAsUser($this->user1); $view = new \OC\Files\View('/' . $this->user1 . '/'); $view->mkdir('files/test'); $fileInfo = $view->getFileInfo('files/test'); $this->assertNotNull(\OCP\Share::shareItem('folder', $fileInfo->getId(), \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ), 'Failed asserting that user 1 successfully shared "test" by link with user2.'); $shares = $this->getShares(); $this->assertCount(1, $shares); reset($shares); $share = current($shares); $this->logout(); $this->job->run([]); $shares = $this->getShares(); $this->assertCount(1, $shares); }
/** * @param array $args * @param string $prefix */ public static function prepare_delete($args, $prefix = '') { $path = $args['path']; if (substr($path, 0, 1) === '/') { $path = substr($path, 1); } $view = new \OC\Files\View('/' . \OC_User::getUser() . '/' . $prefix); $absPath = Files\Filesystem::normalizePath($view->getAbsolutePath($path)); self::addPathToDeleteFileMapper($absPath, $view->getFileInfo($path)); if ($view->is_dir($path)) { $children = self::getAllChildren($view, $path); self::$deleteChildrenMapper[$absPath] = $children; } }
public function testSharingAFileInsideAFolderThatIsAlreadyShared() { OC_User::setUserId($this->user1); $view = new \OC\Files\View('/' . $this->user1 . '/'); $view->mkdir('files/test'); $view->mkdir('files/test/sub1'); $view->file_put_contents('files/test/sub1/file.txt', 'abc'); $folderInfo = $view->getFileInfo('files/test/sub1'); $folderId = $folderInfo->getId(); $fileInfo = $view->getFileInfo('files/test/sub1/file.txt'); $fileId = $fileInfo->getId(); $this->assertTrue(OCP\Share::shareItem('folder', $folderId, OCP\Share::SHARE_TYPE_GROUP, $this->group2, \OCP\Constants::PERMISSION_READ + \OCP\Constants::PERMISSION_UPDATE), 'Failed asserting that user 1 successfully shared "test/sub1" with group 2.'); $this->assertTrue(OCP\Share::shareItem('file', $fileId, OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ), 'Failed asserting that user 1 successfully shared "test/sub1/file.txt" with user 2.'); $result = \OCP\Share::getItemsSharedWithUser('file', $this->user2); $this->assertCount(2, $result); foreach ($result as $share) { $itemName = substr($share['path'], strrpos($share['path'], '/')); $this->assertSame($itemName, $share['file_target'], 'Asserting that the file_target is the last segment of the path'); $this->assertSame($share['item_target'], '/' . $share['item_source'], 'Asserting that the item is the item that was shared'); } }
/** * index a file * * @author Jörn Dreyer <*****@*****.**> * * @param string $path the path of the file * * @return bool */ public static function indexFile($path = '', $user = null) { if (!Filesystem::isValidPath($path)) { return; } if ($path === '') { //ignore the empty path element return false; } if (is_null($user)) { $view = Filesystem::getView(); $user = \OCP\User::getUser(); } else { $view = new \OC\Files\View('/' . $user . '/files'); } if (!$view) { Util::writeLog('search_lucene', 'could not resolve filesystem view', Util::WARN); return false; } if (!$view->file_exists($path)) { Util::writeLog('search_lucene', 'file vanished, ignoring', Util::DEBUG); return true; } $root = $view->getRoot(); $pk = md5($root . $path); // the cache already knows mime and other basic stuff $data = $view->getFileInfo($path); if (isset($data['mimetype'])) { $mimeType = $data['mimetype']; // initialize plain lucene document $doc = new \Zend_Search_Lucene_Document(); // index content for local files only $localFile = $view->getLocalFile($path); if ($localFile) { //try to use special lucene document types if ('text/plain' === $mimeType) { $body = $view->file_get_contents($path); if ($body != '') { $doc->addField(\Zend_Search_Lucene_Field::UnStored('body', $body)); } } else { if ('text/html' === $mimeType) { //TODO could be indexed, even if not local $doc = \Zend_Search_Lucene_Document_Html::loadHTML($view->file_get_contents($path)); } else { if ('application/pdf' === $mimeType) { $doc = Pdf::loadPdf($view->file_get_contents($path)); // commented the mimetype checks, as the zend classes only understand docx and not doc files. // FIXME distinguish doc and docx, xls and xlsx, ppt and pptx, in oc core mimetype helper ... //} else if ('application/msword' === $mimeType) { } else { if (strtolower(substr($data['name'], -5)) === '.docx') { $doc = \Zend_Search_Lucene_Document_Docx::loadDocxFile($localFile); //} else if ('application/msexcel' === $mimeType) { } else { if (strtolower(substr($data['name'], -5)) === '.xlsx') { $doc = \Zend_Search_Lucene_Document_Xlsx::loadXlsxFile($localFile); //} else if ('application/mspowerpoint' === $mimeType) { } else { if (strtolower(substr($data['name'], -5)) === '.pptx') { $doc = \Zend_Search_Lucene_Document_Pptx::loadPptxFile($localFile); } else { if (strtolower(substr($data['name'], -4)) === '.odt') { $doc = Odt::loadOdtFile($localFile); } else { if (strtolower(substr($data['name'], -4)) === '.ods') { $doc = Ods::loadOdsFile($localFile); } } } } } } } } } // Store filecache id as unique id to lookup by when deleting $doc->addField(\Zend_Search_Lucene_Field::Keyword('pk', $pk)); // Store filename $doc->addField(\Zend_Search_Lucene_Field::Text('filename', $data['name'], 'UTF-8')); // Store document path to identify it in the search results $doc->addField(\Zend_Search_Lucene_Field::Text('path', $path, 'UTF-8')); $doc->addField(\Zend_Search_Lucene_Field::unIndexed('size', $data['size'])); $doc->addField(\Zend_Search_Lucene_Field::unIndexed('mimetype', $mimeType)); //self::extractMetadata($doc, $path, $view, $mimeType); Lucene::updateFile($doc, $path, $user); return true; } else { Util::writeLog('search_lucene', 'need mimetype for content extraction', Util::ERROR); return false; } }
$root = \OC\Files\Filesystem::getPath($linkItem['file_source']) . '/'; $images = array_map(function ($image) use($root) { return $root . $image; }, $images); } else { $root = ''; OCP\JSON::checkLoggedIn(); $user = OCP\User::getUser(); } session_write_close(); $eventSource = new OC_EventSource(); foreach ($images as $image) { $height = 200 * $scale; if ($square) { $width = 200 * $scale; } else { $width = 400 * $scale; } $userView = new \OC\Files\View('/' . $user); $preview = new \OC\Preview($user, 'files', '/' . $image, $width, $height); $preview->setKeepAspect(!$square); $fileInfo = $userView->getFileInfo('/files/' . $image); // if the thumbnails is already cached, get it directly from the filesystem to avoid decoding and re-encoding the image $imageName = substr($image, strlen($root)); if ($path = $preview->isCached($fileInfo->getId())) { $eventSource->send('preview', array('image' => $imageName, 'preview' => base64_encode($userView->file_get_contents('/' . $path)))); } else { $eventSource->send('preview', array('image' => $imageName, 'preview' => (string) $preview->getPreview())); } } $eventSource->close();
public function testSharingAFolderThatIsSharedWithAGroupOfTheOwner() { OC_User::setUserId($this->user1); $view = new \OC\Files\View('/' . $this->user1 . '/'); $view->mkdir('files/test'); $view->mkdir('files/test/sub1'); $view->mkdir('files/test/sub1/sub2'); $fileInfo = $view->getFileInfo('files/test/sub1'); $fileId = $fileInfo->getId(); $this->assertTrue(OCP\Share::shareItem('folder', $fileId, OCP\Share::SHARE_TYPE_GROUP, $this->group1, \OCP\Constants::PERMISSION_READ + \OCP\Constants::PERMISSION_CREATE), 'Failed asserting that user 1 successfully shared "test/sub1" with group 1.'); $result = OCP\Share::getItemShared('folder', $fileId, Test_Share_Backend::FORMAT_SOURCE); $this->assertNotEmpty($result); $this->assertEquals(\OCP\Constants::PERMISSION_READ + \OCP\Constants::PERMISSION_CREATE, $result['permissions']); $fileInfo = $view->getFileInfo('files/test/sub1/sub2'); $fileId = $fileInfo->getId(); $this->assertTrue(OCP\Share::shareItem('folder', $fileId, OCP\Share::SHARE_TYPE_USER, $this->user4, \OCP\Constants::PERMISSION_READ), 'Failed asserting that user 1 successfully shared "test/sub1/sub2" with user 4.'); $result = OCP\Share::getItemShared('folder', $fileId, Test_Share_Backend::FORMAT_SOURCE); $this->assertNotEmpty($result); $this->assertEquals(\OCP\Constants::PERMISSION_READ, $result['permissions']); }
public function testDeleteGhostFolder() { $storage = new Temporary(array()); $scanner = $storage->getScanner(); $cache = $storage->getCache(); $storage->mkdir('foo'); $storage->file_put_contents('foo/foo.txt', 'bar'); \OC\Files\Filesystem::mount($storage, array(), '/test/'); $scanner->scan(''); $storage->rmdir('foo'); $this->assertTrue($cache->inCache('foo')); $this->assertTrue($cache->inCache('foo/foo.txt')); $view = new \OC\Files\View('/test'); $rootInfo = $view->getFileInfo(''); $this->assertEquals(3, $rootInfo->getSize()); $view->rmdir('foo'); $newInfo = $view->getFileInfo(''); $this->assertFalse($cache->inCache('foo')); $this->assertFalse($cache->inCache('foo/foo.txt')); $this->assertNotEquals($rootInfo->getEtag(), $newInfo->getEtag()); $this->assertEquals(0, $newInfo->getSize()); }
/** * share a folder which contains a share mount point, should be forbidden */ public function testShareFolderWithAMountPoint() { // user 1 shares a folder with user2 \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); $fileInfo = $this->view->getFileInfo($this->folder); $result = \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); $this->assertTrue($result); // user2 shares a file from the folder as link \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); $view = new \OC\Files\View('/' . \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2 . '/files'); $view->mkdir("localDir"); // move mount point to the folder "localDir" $result = $view->rename($this->folder, 'localDir/' . $this->folder); $this->assertTrue($result !== false); // try to share "localDir" $fileInfo2 = $view->getFileInfo('localDir'); $this->assertTrue($fileInfo2 instanceof \OC\Files\FileInfo); try { $result2 = \OCP\Share::shareItem('folder', $fileInfo2['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER3, 31); } catch (\Exception $e) { $result2 = false; } $this->assertFalse($result2); //cleanup $result = $view->rename('localDir/' . $this->folder, $this->folder); $this->assertTrue($result !== false); $view->unlink('localDir'); \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); \OCP\Share::unshare('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); }
public function testTouchNotSupported() { $storage = new TemporaryNoTouch(array()); $scanner = $storage->getScanner(); \OC\Files\Filesystem::mount($storage, array(), '/test/'); $past = time() - 100; $storage->file_put_contents('test', 'foobar'); $scanner->scan(''); $view = new \OC\Files\View(''); $info = $view->getFileInfo('/test/test'); $view->touch('/test/test', $past); $scanner->scanFile('test', \OC\Files\Cache\Scanner::REUSE_ETAG); $info2 = $view->getFileInfo('/test/test'); $this->assertSame($info['etag'], $info2['etag']); }
exit; } $rootLinkItem = OCP\Share::resolveReShare($linkedItem); $userId = $rootLinkItem['uid_owner']; OCP\JSON::checkUserExists($rootLinkItem['uid_owner']); \OC_Util::setupFS($userId); \OC\Files\Filesystem::initMountPoints($userId); $view = new \OC\Files\View('/' . $userId . '/files'); $pathId = $linkedItem['file_source']; $path = $view->getPath($pathId); if ($path === null) { \OC_Response::setStatus(\OC_Response::STATUS_NOT_FOUND); \OCP\Util::writeLog('core-preview', 'Could not resolve file for shared item', \OCP\Util::WARN); exit; } $pathInfo = $view->getFileInfo($path); $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']; }
/** * @param string $path * @param int $size * @return int|bool */ public function postFileSize($path, $size, $fileInfo = null) { $view = new \OC\Files\View('/'); $userId = Helper::getUser($path); $util = new Util($view, $userId); // if encryption is no longer enabled or if the files aren't migrated yet // we return the default file size if (!\OCP\App::isEnabled('files_encryption') || $util->getMigrationStatus() !== Util::MIGRATION_COMPLETED) { return $size; } // if path is a folder do nothing if ($view->is_dir($path)) { $proxyState = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $fileInfo = $view->getFileInfo($path); \OC_FileProxy::$enabled = $proxyState; if (isset($fileInfo['unencrypted_size']) && $fileInfo['unencrypted_size'] > 0) { return $fileInfo['unencrypted_size']; } return $size; } // get relative path $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path); // if path is empty we cannot resolve anything if (empty($relativePath)) { return $size; } // get file info from database/cache if not .part file if (empty($fileInfo) && !Helper::isPartialFilePath($path)) { $proxyState = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $fileInfo = $view->getFileInfo($path); \OC_FileProxy::$enabled = $proxyState; } // if file is encrypted return real file size if (isset($fileInfo['encrypted']) && $fileInfo['encrypted'] === true) { // try to fix unencrypted file size if it doesn't look plausible if ((int) $fileInfo['size'] > 0 && (int) $fileInfo['unencrypted_size'] === 0) { $fixSize = $util->getFileSize($path); $fileInfo['unencrypted_size'] = $fixSize; // put file info if not .part file if (!Helper::isPartialFilePath($relativePath)) { $view->putFileInfo($path, array('unencrypted_size' => $fixSize)); } } $size = $fileInfo['unencrypted_size']; } else { $fileInfoUpdates = array(); $fixSize = $util->getFileSize($path); if ($fixSize > 0) { $size = $fixSize; $fileInfoUpdates['encrypted'] = true; $fileInfoUpdates['unencrypted_size'] = $size; // put file info if not .part file if (!Helper::isPartialFilePath($relativePath)) { $view->putFileInfo($path, $fileInfoUpdates); } } } return $size; }
/** * get uid of the owners of the file and the path to the file * @param string $path Path of the file to check * @throws \Exception * @note $shareFilePath must be relative to data/UID/files. Files * relative to /Shared are also acceptable * @return array */ public function getUidAndFilename($path) { $pathinfo = pathinfo($path); $partfile = false; $parentFolder = false; if (array_key_exists('extension', $pathinfo) && $pathinfo['extension'] === 'part') { // if the real file exists we check this file $filePath = $this->userFilesDir . '/' . $pathinfo['dirname'] . '/' . $pathinfo['filename']; if ($this->view->file_exists($filePath)) { $pathToCheck = $pathinfo['dirname'] . '/' . $pathinfo['filename']; } else { // otherwise we look for the parent $pathToCheck = $pathinfo['dirname']; $parentFolder = true; } $partfile = true; } else { $pathToCheck = $path; } $view = new \OC\Files\View($this->userFilesDir); $fileOwnerUid = $view->getOwner($pathToCheck); // handle public access if ($this->isPublic) { return array($this->userId, $path); } else { // Check that UID is valid if (!\OCP\User::userExists($fileOwnerUid)) { throw new \Exception('Could not find owner (UID = "' . var_export($fileOwnerUid, 1) . '") of file "' . $path . '"'); } // NOTE: Bah, this dependency should be elsewhere \OC\Files\Filesystem::initMountPoints($fileOwnerUid); // If the file owner is the currently logged in user if ($fileOwnerUid === $this->userId) { // Assume the path supplied is correct $filename = $path; } else { $info = $view->getFileInfo($pathToCheck); $ownerView = new \OC\Files\View('/' . $fileOwnerUid . '/files'); // Fetch real file path from DB $filename = $ownerView->getPath($info['fileid']); if ($parentFolder) { $filename = $filename . '/' . $pathinfo['filename']; } if ($partfile) { $filename = $filename . '.' . $pathinfo['extension']; } } return array($fileOwnerUid, \OC\Files\Filesystem::normalizePath($filename)); } }
/** * get current size of trash bin from a given user * * @param string $user user who owns the trash bin * @return integer trash bin size */ private static function getTrashbinSize($user) { $view = new \OC\Files\View('/' . $user); $fileInfo = $view->getFileInfo('/files_trashbin'); return isset($fileInfo['size']) ? $fileInfo['size'] : 0; }
public function testWatcherEtagCrossStorage() { $storage1 = new Temporary(array()); $storage2 = new Temporary(array()); $scanner1 = $storage1->getScanner(); $scanner2 = $storage2->getScanner(); $storage1->mkdir('sub'); \OC\Files\Filesystem::mount($storage1, array(), '/test/'); \OC\Files\Filesystem::mount($storage2, array(), '/test/sub/storage'); $past = time() - 100; $storage2->file_put_contents('test.txt', 'foobar'); $scanner1->scan(''); $scanner2->scan(''); $view = new \OC\Files\View(''); $storage2->getWatcher('')->setPolicy(Watcher::CHECK_ALWAYS); $oldFileInfo = $view->getFileInfo('/test/sub/storage/test.txt'); $oldFolderInfo = $view->getFileInfo('/test'); $storage2->getCache()->update($oldFileInfo->getId(), array('storage_mtime' => $past)); $view->getFileInfo('/test/sub/storage/test.txt'); $newFolderInfo = $view->getFileInfo('/test'); $this->assertNotEquals($newFolderInfo->getEtag(), $oldFolderInfo->getEtag()); }
$server->addPlugin(new OC_Connector_Sabre_ExceptionLoggerPlugin('webdav')); // wait with registering these until auth is handled and the filesystem is setup $server->subscribeEvent('beforeMethod', function () use($server, $objectTree, $authBackend) { $share = $authBackend->getShare(); $rootShare = \OCP\Share::resolveReShare($share); $owner = $rootShare['uid_owner']; $isWritable = $share['permissions'] & (\OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_CREATE); $fileId = $share['file_source']; if (!$isWritable) { \OC\Files\Filesystem::addStorageWrapper('readonly', function ($mountPoint, $storage) { return new \OCA\Files_Sharing\ReadOnlyWrapper(array('storage' => $storage)); }); } OC_Util::setupFS($owner); $ownerView = \OC\Files\Filesystem::getView(); $path = $ownerView->getPath($fileId); $view = new \OC\Files\View($ownerView->getAbsolutePath($path)); $rootInfo = $view->getFileInfo(''); // Create ownCloud Dir if ($rootInfo->getType() === 'dir') { $root = new OC_Connector_Sabre_Directory($view, $rootInfo); } else { $root = new OC_Connector_Sabre_File($view, $rootInfo); } $mountManager = \OC\Files\Filesystem::getMountManager(); $objectTree->init($root, $view, $mountManager); $server->addPlugin(new OC_Connector_Sabre_QuotaPlugin($view)); }, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request // And off we go! $server->exec();