protected function execute(InputInterface $input, OutputInterface $output) { $this->sourceUser = $input->getArgument('source-user'); $this->destinationUser = $input->getArgument('destination-user'); if (!$this->userManager->userExists($this->sourceUser)) { $output->writeln("<error>Unknown source user {$this->sourceUser}</error>"); return; } if (!$this->userManager->userExists($this->destinationUser)) { $output->writeln("<error>Unknown destination user {$this->destinationUser}</error>"); return; } $date = date('c'); $this->finalTarget = "{$this->destinationUser}/files/transferred from {$this->sourceUser} on {$date}"; // setup filesystem Filesystem::initMountPoints($this->sourceUser); Filesystem::initMountPoints($this->destinationUser); // analyse source folder $this->analyse($output); // collect all the shares $this->collectUsersShares($output); // transfer the files $this->transfer($output); // restore the shares $this->restoreShares($output); }
/** * Get the source cache of a shared file or folder * * @param string $target Shared target file path * @return \OC\Files\Cache\Cache */ private function getSourceCache($target) { if ($target === false || $target === $this->storage->getMountPoint()) { $target = ''; } $source = \OC_Share_Backend_File::getSource($target, $this->storage->getMountPoint(), $this->storage->getItemType()); if (isset($source['path']) && isset($source['fileOwner'])) { try { \OC\Files\Filesystem::initMountPoints($source['fileOwner']); } catch (NoUserException $e) { \OC::$server->getLogger()->warning('The user \'' . $source['uid_owner'] . '\' of a share can\'t be retrieved.', array('app' => 'files_sharing')); return false; } $mounts = \OC\Files\Filesystem::getMountByNumericId($source['storage']); if (is_array($mounts) and !empty($mounts)) { $fullPath = $mounts[0]->getMountPoint() . $source['path']; list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath); if ($storage) { $this->files[$target] = $internalPath; $cache = $storage->getCache(); $this->storageId = $storage->getId(); $this->numericId = $cache->getNumericStorageId(); return $cache; } } } return false; }
private static function checkUpdate($id) { $cacheItem = Cache::getById($id); if (is_null($cacheItem)) { return; } list($storageId, $internalPath) = $cacheItem; $mounts = Filesystem::getMountByStorageId($storageId); if (count($mounts) === 0) { //if the storage we need isn't mounted on default, try to find a user that has access to the storage $permissionsCache = new Permissions($storageId); $users = $permissionsCache->getUsers($id); if (count($users) === 0) { return; } Filesystem::initMountPoints($users[0]); $mounts = Filesystem::getMountByStorageId($storageId); if (count($mounts) === 0) { return; } } $storage = $mounts[0]->getStorage(); $watcher = new Watcher($storage); $watcher->checkUpdate($internalPath); }
/** * Correct the parent folders' ETags for all users shared the file at $target * * @param string $target */ public static function correctFolders($target) { $uid = \OCP\User::getUser(); $uidOwner = \OC\Files\Filesystem::getOwner($target); $info = \OC\Files\Filesystem::getFileInfo($target); // Correct Shared folders of other users shared with $users = \OCP\Share::getUsersItemShared('file', $info['fileid'], $uidOwner, true); if (!empty($users)) { while (!empty($users)) { $reshareUsers = array(); foreach ($users as $user) { if ($user !== $uidOwner) { $etag = \OC\Files\Filesystem::getETag(''); \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag); // Look for reshares $reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $info['fileid'], $user, true)); } } $users = $reshareUsers; } // Correct folders of shared file owner $target = substr($target, 8); if ($uidOwner !== $uid && ($source = \OC_Share_Backend_File::getSource($target))) { \OC\Files\Filesystem::initMountPoints($uidOwner); $source = '/' . $uidOwner . '/' . $source['path']; \OC\Files\Cache\Updater::correctFolder($source, $info['mtime']); } } }
/** * get the UID of the owner of the file and the path to the file relative to * owners files folder * * @param string $filename * @return array * @throws \OC\User\NoUserException */ public static function getUidAndFilename($filename) { $uid = Filesystem::getOwner($filename); $userManager = \OC::$server->getUserManager(); // if the user with the UID doesn't exists, e.g. because the UID points // to a remote user with a federated cloud ID we use the current logged-in // user. We need a valid local user to create the versions if (!$userManager->userExists($uid)) { $uid = User::getUser(); } Filesystem::initMountPoints($uid); if ($uid != User::getUser()) { $info = Filesystem::getFileInfo($filename); $ownerView = new View('/' . $uid . '/files'); try { $filename = $ownerView->getPath($info['fileid']); // make sure that the file name doesn't end with a trailing slash // can for example happen single files shared across servers $filename = rtrim($filename, '/'); } catch (NotFoundException $e) { $filename = null; } } return [$uid, $filename]; }
/** * 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); }
/** * update script for the removal of the logical "Shared" folder, we create physical "Shared" folder and * update the users file_target so that it doesn't make any difference for the user * @note parameters are just for testing, please ignore them */ function removeSharedFolder($mkdirs = true, $chunkSize = 99) { $query = OCP\DB::prepare('SELECT * FROM `*PREFIX*share`'); $result = $query->execute(); $view = new \OC\Files\View('/'); $users = array(); $shares = array(); //we need to set up user backends OC_User::useBackend(new OC_User_Database()); OC_Group::useBackend(new OC_Group_Database()); OC_App::loadApps(array('authentication')); //we need to set up user backends, otherwise creating the shares will fail with "because user does not exist" while ($row = $result->fetchRow()) { //collect all user shares if ((int) $row['share_type'] === 0 && ($row['item_type'] === 'file' || $row['item_type'] === 'folder')) { $users[] = $row['share_with']; $shares[$row['id']] = $row['file_target']; } else { if ((int) $row['share_type'] === 1 && ($row['item_type'] === 'file' || $row['item_type'] === 'folder')) { //collect all group shares $users = array_merge($users, \OC_group::usersInGroup($row['share_with'])); $shares[$row['id']] = $row['file_target']; } else { if ((int) $row['share_type'] === 2) { $shares[$row['id']] = $row['file_target']; } } } } $unique_users = array_unique($users); if (!empty($unique_users) && !empty($shares)) { // create folder Shared for each user if ($mkdirs) { foreach ($unique_users as $user) { \OC\Files\Filesystem::initMountPoints($user); if (!$view->file_exists('/' . $user . '/files/Shared')) { $view->mkdir('/' . $user . '/files/Shared'); } } } $chunkedShareList = array_chunk($shares, $chunkSize, true); $connection = \OC_DB::getConnection(); foreach ($chunkedShareList as $subList) { $statement = "UPDATE `*PREFIX*share` SET `file_target` = CASE `id` "; //update share table $ids = implode(',', array_keys($subList)); foreach ($subList as $id => $target) { $statement .= "WHEN " . $connection->quote($id, \PDO::PARAM_INT) . " THEN " . $connection->quote('/Shared' . $target, \PDO::PARAM_STR); } $statement .= ' END WHERE `id` IN (' . $ids . ')'; $query = OCP\DB::prepare($statement); $query->execute(array()); } // set config to keep the Shared folder as the default location for new shares \OCA\Files_Sharing\Helper::setShareFolder('/Shared'); } }
public function testChangeLock() { Filesystem::initMountPoints($this->recipientUid); $recipientView = new View('/' . $this->recipientUid . '/files'); $recipientView->lockFile('bar.txt', ILockingProvider::LOCK_SHARED); $recipientView->changeLock('bar.txt', ILockingProvider::LOCK_EXCLUSIVE); $recipientView->unlockFile('bar.txt', ILockingProvider::LOCK_EXCLUSIVE); $this->assertTrue(true); }
/** * @param IRequest $request * @param string $user * @param string $path */ public function __construct(IRequest $request, $user, $path) { $this->request = $request; $this->user = $user; $this->path = $path; Filesystem::initMountPoints($user); $this->view = new View('/' . $user); if (!$this->view->file_exists($path)) { $this->setStatus(Http::STATUS_NOT_FOUND); } }
public static function getUidAndFilename($filename) { $uid = \OC\Files\Filesystem::getOwner($filename); \OC\Files\Filesystem::initMountPoints($uid); if ($uid != \OCP\User::getUser()) { $info = \OC\Files\Filesystem::getFileInfo($filename); $ownerView = new \OC\Files\View('/' . $uid . '/files'); $filename = $ownerView->getPath($info['fileid']); } return array($uid, $filename); }
/** * @return Directory */ private function impl() { $rootView = new View(); $user = \OC::$server->getUserSession()->getUser(); Filesystem::initMountPoints($user->getUID()); if (!$rootView->file_exists('/' . $user->getUID() . '/uploads')) { $rootView->mkdir('/' . $user->getUID() . '/uploads'); } $view = new View('/' . $user->getUID() . '/uploads'); $rootInfo = $view->getFileInfo(''); $impl = new Directory($view, $rootInfo); return $impl; }
/** * Returns the cache storage for the logged in user * @return \OC\Files\View cache storage */ protected function getStorage() { if (isset($this->storage)) { return $this->storage; } if (\OC_User::isLoggedIn()) { \OC\Files\Filesystem::initMountPoints(\OC_User::getUser()); $this->storage = new \OC\Files\View('/' . \OC_User::getUser() . '/cache'); return $this->storage; } else { \OC_Log::write('core', 'Can\'t get cache storage, user not logged in', \OC_Log::ERROR); throw new \OC\ForbiddenException('Can\\t get cache storage, user not logged in'); } }
private function init() { if ($this->initialized) { return; } $this->initialized = true; try { Filesystem::initMountPoints($this->newShare->getShareOwner()); $sourcePath = $this->ownerView->getPath($this->newShare->getNodeId()); list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath); $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); } catch (\Exception $e) { $this->logger->logException($e); } }
/** * @param string $filename * @return array * @throws \OC\User\NoUserException */ public static function getUidAndFilename($filename) { $uid = \OC\Files\Filesystem::getOwner($filename); \OC\Files\Filesystem::initMountPoints($uid); if ($uid != \OCP\User::getUser()) { $info = \OC\Files\Filesystem::getFileInfo($filename); $ownerView = new \OC\Files\View('/' . $uid . '/files'); try { $filename = $ownerView->getPath($info['fileid']); } catch (NotFoundException $e) { $filename = null; } } return [$uid, $filename]; }
/** * create unique target * @param string $filePath * @param string $shareWith * @param string $exclude * @return string */ public function generateTarget($filePath, $shareWith, $exclude = null) { $target = '/' . 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'); $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); }
/** * return a user specific instance of \OCP\IAvatar * @see \OCP\IAvatar * @param string $userId the ownCloud user id * @return \OCP\IAvatar * @throws \Exception In case the username is potentially dangerous * @throws NotFoundException In case there is no user folder yet */ public function getAvatar($userId) { $user = $this->userManager->get($userId); if (is_null($user)) { throw new \Exception('user does not exist'); } /* * Fix for #22119 * Basically we do not want to copy the skeleton folder */ \OC\Files\Filesystem::initMountPoints($userId); $dir = '/' . $userId; /** @var Folder $folder */ $folder = $this->rootFolder->get($dir); return new Avatar($folder, $this->l, $user, $this->logger); }
/** * walk up the users file tree and update the etags * @param string $user * @param string $path */ private static function correctUsersFolder($user, $path) { // $path points to the mount point which is a virtual folder, so we start with // the parent $path = '/files' . dirname($path); \OC\Files\Filesystem::initMountPoints($user); $view = new \OC\Files\View('/' . $user); if ($view->file_exists($path)) { while ($path !== dirname($path)) { $etag = $view->getETag($path); $view->putFileInfo($path, array('etag' => $etag)); $path = dirname($path); } } else { \OCP\Util::writeLog('files_sharing', 'can not update etags on ' . $path . ' for user ' . $user . '. Path does not exists', \OCP\Util::DEBUG); } }
/** * @brief Get the source file path for a shared file * @param string Shared target file path * @return string source file path or false if not found */ private function getSourcePath($target) { $source = $this->getFile($target); if ($source) { if (!isset($source['fullPath'])) { \OC\Files\Filesystem::initMountPoints($source['fileOwner']); $mount = \OC\Files\Mount::findByNumericId($source['storage']); if ($mount) { $this->files[$target]['fullPath'] = $mount->getMountPoint() . $source['path']; } else { $this->files[$target]['fullPath'] = false; } } return $this->files[$target]['fullPath']; } return false; }
/** * Get all mountpoints applicable for the user and check for shares where we need to update the etags * * @param \OCP\IUser $user * @param \OCP\Files\Storage\IStorageFactory $storageFactory * @return \OCP\Files\Mount\IMountPoint[] */ public function getMountsForUser(IUser $user, IStorageFactory $storageFactory) { $shares = \OCP\Share::getItemsSharedWithUser('file', $user->getUID()); $propagator = $this->propagationManager->getSharePropagator($user->getUID()); $propagator->propagateDirtyMountPoints($shares); $shares = array_filter($shares, function ($share) { return $share['permissions'] > 0; }); return array_map(function ($share) use($user, $storageFactory) { Filesystem::initMountPoints($share['uid_owner']); // for updating etags for the share owner when we make changes to this share. $ownerPropagator = $this->propagationManager->getChangePropagator($share['uid_owner']); // for updating our etags when changes are made to the share from the owners side (probably indirectly by us trough another share) $this->propagationManager->listenToOwnerChanges($share['uid_owner'], $user->getUID()); return new SharedMount('\\OC\\Files\\Storage\\Shared', '/' . $user->getUID() . '/' . $share['file_target'], array('propagator' => $ownerPropagator, 'share' => $share, 'user' => $user->getUID()), $storageFactory); }, $shares); }
/** * Get the source file path for a shared file * * @param string $target Shared target file path * @return string|false source file path or false if not found */ public function getSourcePath($target) { $source = $this->getFile($target); if ($source) { if (!isset($source['fullPath'])) { \OC\Files\Filesystem::initMountPoints($source['fileOwner']); $mount = \OC\Files\Filesystem::getMountByNumericId($source['storage']); if (is_array($mount) && !empty($mount)) { $this->files[$target]['fullPath'] = $mount[key($mount)]->getMountPoint() . $source['path']; } else { $this->files[$target]['fullPath'] = false; \OCP\Util::writeLog('files_sharing', "Unable to get mount for shared storage '" . $source['storage'] . "' user '" . $source['fileOwner'] . "'", \OCP\Util::ERROR); } } return $this->files[$target]['fullPath']; } return false; }
/** * Returns the cache storage for the logged in user * * @return \OC\Files\View cache storage * @throws \OC\ForbiddenException * @throws \OC\User\NoUserException */ protected function getStorage() { if (isset($this->storage)) { return $this->storage; } if (\OC_User::isLoggedIn()) { $rootView = new View(); $user = \OC::$server->getUserSession()->getUser(); Filesystem::initMountPoints($user->getUID()); if (!$rootView->file_exists('/' . $user->getUID() . '/cache')) { $rootView->mkdir('/' . $user->getUID() . '/cache'); } $this->storage = new View('/' . $user->getUID() . '/cache'); return $this->storage; } else { \OCP\Util::writeLog('core', 'Can\'t get cache storage, user not logged in', \OCP\Util::ERROR); throw new \OC\ForbiddenException('Can\t get cache storage, user not logged in'); } }
protected function getStorage() { if (isset($this->storage)) { return $this->storage; } if (\OC_User::isLoggedIn()) { \OC\Files\Filesystem::initMountPoints(\OC_User::getUser()); $subdir = 'cache'; $view = new \OC\Files\View('/' . \OC_User::getUser()); if (!$view->file_exists($subdir)) { $view->mkdir($subdir); } $this->storage = new \OC\Files\View('/' . \OC_User::getUser() . '/' . $subdir); return $this->storage; } else { \OC_Log::write('core', 'Can\'t get cache storage, user not logged in', \OC_Log::ERROR); return false; } }
/** * @brief Get the source cache of a shared file or folder * @param string $target Shared target file path * @return \OC\Files\Cache\Cache */ private function getSourceCache($target) { $source = \OC_Share_Backend_File::getSource($target); if (isset($source['path']) && isset($source['fileOwner'])) { \OC\Files\Filesystem::initMountPoints($source['fileOwner']); $mount = \OC\Files\Mount::findByNumericId($source['storage']); if ($mount) { $fullPath = $mount->getMountPoint() . $source['path']; list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath); if ($storage) { $this->files[$target] = $internalPath; $cache = $storage->getCache(); $this->storageId = $storage->getId(); $this->numericId = $cache->getNumericStorageId(); return $cache; } } } return false; }
/** * Get the source cache of a shared file or folder * * @param string $target Shared target file path * @return \OC\Files\Cache\Cache */ private function getSourceCache($target) { if ($target === false || $target === $this->storage->getMountPoint()) { $target = ''; } $source = \OC_Share_Backend_File::getSource($target, $this->storage->getMountPoint(), $this->storage->getItemType()); if (isset($source['path']) && isset($source['fileOwner'])) { \OC\Files\Filesystem::initMountPoints($source['fileOwner']); $mounts = \OC\Files\Filesystem::getMountByNumericId($source['storage']); if (is_array($mounts) and !empty($mounts)) { $fullPath = $mounts[0]->getMountPoint() . $source['path']; list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath); if ($storage) { $this->files[$target] = $internalPath; $cache = $storage->getCache(); $this->storageId = $storage->getId(); $this->numericId = $cache->getNumericStorageId(); return $cache; } } } return false; }
/** * The FileCache Upgrade routine * * @param UpdateWatcher $watcher */ function __doFileCacheUpgrade($watcher) { try { $query = \OC_DB::prepare(' SELECT DISTINCT `user` FROM `*PREFIX*fscache` '); $result = $query->execute(); } catch (\Exception $e) { return; } $users = $result->fetchAll(); if (count($users) == 0) { return; } $step = 100 / count($users); $percentCompleted = 0; $lastPercentCompletedOutput = 0; $startInfoShown = false; foreach ($users as $userRow) { $user = $userRow['user']; \OC\Files\Filesystem::initMountPoints($user); \OC\Files\Cache\Upgrade::doSilentUpgrade($user); if (!$startInfoShown) { //We show it only now, because otherwise Info about upgraded apps //will appear between this and progress info $watcher->success('Updating filecache, this may take really long...'); $startInfoShown = true; } $percentCompleted += $step; $out = floor($percentCompleted); if ($out != $lastPercentCompletedOutput) { $watcher->success('... ' . $out . '% done ...'); $lastPercentCompletedOutput = $out; } } $watcher->success('Updated filecache'); }
/** * Get all mountpoints applicable for the user and check for shares where we need to update the etags * * @param \OCP\IUser $user * @param \OCP\Files\Storage\IStorageFactory $storageFactory * @return \OCP\Files\Mount\IMountPoint[] */ public function getMountsForUser(IUser $user, IStorageFactory $storageFactory) { $shares = \OCP\Share::getItemsSharedWithUser('file', $user->getUID()); $propagator = $this->propagationManager->getSharePropagator($user->getUID()); $propagator->propagateDirtyMountPoints($shares); $shares = array_filter($shares, function ($share) { return $share['permissions'] > 0; }); $shares = array_map(function ($share) use($user, $storageFactory) { try { Filesystem::initMountPoints($share['uid_owner']); } catch (NoUserException $e) { \OC::$server->getLogger()->warning('The user \'' . $share['uid_owner'] . '\' of share with ID \'' . $share['id'] . '\' can\'t be retrieved.', array('app' => 'files_sharing')); return null; } // for updating etags for the share owner when we make changes to this share. $ownerPropagator = $this->propagationManager->getChangePropagator($share['uid_owner']); // for updating our etags when changes are made to the share from the owners side (probably indirectly by us trough another share) $this->propagationManager->listenToOwnerChanges($share['uid_owner'], $user->getUID()); return new SharedMount('\\OC\\Files\\Storage\\Shared', '/' . $user->getUID() . '/' . $share['file_target'], array('propagator' => $ownerPropagator, 'share' => $share, 'user' => $user->getUID()), $storageFactory); }, $shares); // array_filter removes the null values from the array return array_filter($shares); }
/** * 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)); } }
$linkedItem = \OCP\Share::getShareByToken($token); if ($linkedItem === false || $linkedItem['item_type'] !== 'file' && $linkedItem['item_type'] !== 'folder') { \OC_Response::setStatus(\OC_Response::STATUS_NOT_FOUND); \OCP\Util::writeLog('core-preview', 'Passed token parameter is not valid', \OCP\Util::DEBUG); exit; } if (!isset($linkedItem['uid_owner']) || !isset($linkedItem['file_source'])) { \OC_Response::setStatus(\OC_Response::STATUS_INTERNAL_SERVER_ERROR); \OCP\Util::writeLog('core-preview', 'Passed token seems to be valid, but it does not contain all necessary information . ("' . $token . '")', \OCP\Util::WARN); 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);
/** * @brief Change a user's encryption passphrase * @param array $params keys: uid, password */ public static function setPassphrase($params) { if (\OCP\App::isEnabled('files_encryption') === false) { return true; } // Only attempt to change passphrase if server-side encryption // is in use (client-side encryption does not have access to // the necessary keys) if (Crypt::mode() === 'server') { $view = new \OC_FilesystemView('/'); $session = new \OCA\Encryption\Session($view); // Get existing decrypted private key $privateKey = $session->getPrivateKey(); if ($params['uid'] === \OCP\User::getUser() && $privateKey) { // Encrypt private key with new user pwd as passphrase $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($privateKey, $params['password']); // Save private key if ($encryptedPrivateKey) { Keymanager::setPrivateKey($encryptedPrivateKey); } else { \OCP\Util::writeLog('files_encryption', 'Could not update users encryption password', \OCP\Util::ERROR); } // NOTE: Session does not need to be updated as the // private key has not changed, only the passphrase // used to decrypt it has changed } else { // admin changed the password for a different user, create new keys and reencrypt file keys $user = $params['uid']; $util = new Util($view, $user); $recoveryPassword = isset($params['recoveryPassword']) ? $params['recoveryPassword'] : null; // we generate new keys if... // ...we have a recovery password and the user enabled the recovery key // ...encryption was activated for the first time (no keys exists) // ...the user doesn't have any files if ($util->recoveryEnabledForUser() && $recoveryPassword || !$util->userKeysExists() || !$view->file_exists($user . '/files')) { // backup old keys $util->backupAllKeys('recovery'); $newUserPassword = $params['password']; // make sure that the users home is mounted \OC\Files\Filesystem::initMountPoints($user); $keypair = Crypt::createKeypair(); // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; // Save public key $view->file_put_contents('/public-keys/' . $user . '.public.key', $keypair['publicKey']); // Encrypt private key empty passphrase $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], $newUserPassword); // Save private key $view->file_put_contents('/' . $user . '/files_encryption/' . $user . '.private.key', $encryptedPrivateKey); if ($recoveryPassword) { // if recovery key is set we can re-encrypt the key files $util = new Util($view, $user); $util->recoverUsersFiles($recoveryPassword); } \OC_FileProxy::$enabled = $proxyStatus; } } } }
/** * 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); }