false)); exit(); } if (!isset($linkItem['item_type'])) { \OCP\Util::writeLog('share', 'No item type set for share id: ' . $linkItem['id'], \OCP\Util::ERROR); \OC_Response::setStatus(404); \OCP\JSON::error(array('success' => false)); exit(); } if (isset($linkItem['share_with']) && (int)$linkItem['share_type'] === \OCP\Share::SHARE_TYPE_LINK) { if (!self::authenticate($linkItem, $password)) { \OC_Response::setStatus(403); \OCP\JSON::error(array('success' => false)); exit(); } } $basePath = $path; if ($relativePath !== null && \OC\Files\Filesystem::isReadable($basePath . $relativePath)) { $path .= \OC\Files\Filesystem::normalizePath($relativePath); } return array( 'linkItem' => $linkItem, 'basePath' => $basePath, 'realPath' => $path ); } /** * Authenticate link item with the given password * or with the session if no password was given. * @param array $linkItem link item array * @param string $password optional password * * @return boolean true if authorized, false otherwise */ public static function authenticate($linkItem, $password = null) { if ($password !== null) { if ($linkItem['share_type'] == \OCP\Share::SHARE_TYPE_LINK) { // Check Password $newHash = ''; if(\OC::$server->getHasher()->verify($password, $linkItem['share_with'], $newHash)) { // Save item id in session for future requests \OC::$server->getSession()->set('public_link_authenticated', $linkItem['id']); /** * FIXME: Migrate old hashes to new hash format * Due to the fact that there is no reasonable functionality to update the password * of an existing share no migration is yet performed there. * The only possibility is to update the existing share which will result in a new * share ID and is a major hack. * * In the future the migration should be performed once there is a proper method * to update the share's password. (for example `$share->updatePassword($password)` * * @link https://github.com/owncloud/core/issues/10671 */ if(!empty($newHash)) { } } else { return false; } } else { \OCP\Util::writeLog('share', 'Unknown share type '.$linkItem['share_type'] .' for share id '.$linkItem['id'], \OCP\Util::ERROR); return false; } } else { // not authenticated ? if ( ! \OC::$server->getSession()->exists('public_link_authenticated') || \OC::$server->getSession()->get('public_link_authenticated') !== $linkItem['id']) { return false; } } return true; } 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; } 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); } /** * Format a path to be relative to the /user/files/ directory * @param string $path the absolute path * @return string e.g. turns '/admin/files/test.txt' into 'test.txt' */ public static function stripUserFilesPath($path) { $trimmed = ltrim($path, '/'); $split = explode('/', $trimmed); // it is not a file relative to data/user/files if (count($split) < 3 || $split[1] !== 'files') { return false; } $sliced = array_slice($split, 2); $relPath = implode('/', $sliced); return $relPath; } /** * check if file name already exists and generate unique target * * @param string $path * @param array $excludeList * @param \OC\Files\View $view * @return string $path */ public static function generateUniqueTarget($path, $excludeList, $view) { $pathinfo = pathinfo($path); $ext = (isset($pathinfo['extension'])) ? '.'.$pathinfo['extension'] : ''; $name = $pathinfo['filename']; $dir = $pathinfo['dirname']; $i = 2; while ($view->file_exists($path) || in_array($path, $excludeList)) { $path = \OC\Files\Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext); $i++; } return $path; } /** * allow users from other ownCloud instances to mount public links share by this instance * @return bool */ public static function isOutgoingServer2serverShareEnabled() { $appConfig = \OC::$server->getAppConfig(); $result = $appConfig->getValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes'); return ($result === 'yes') ? true : false; } /** * allow user to mount public links from onther ownClouds * @return bool */ public static function isIncomingServer2serverShareEnabled() { $appConfig = \OC::$server->getAppConfig(); $result = $appConfig->getValue('files_sharing', 'incoming_server2server_share_enabled', 'yes'); return ($result === 'yes') ? true : false; } /** * get default share folder * * @return string */ public static function getShareFolder() { $shareFolder = \OC::$server->getConfig()->getSystemValue('share_folder', '/'); return \OC\Files\Filesystem::normalizePath($shareFolder); } /** * set default share folder * * @param string $shareFolder */ public static function setShareFolder($shareFolder) { \OC::$server->getConfig()->setSystemValue('share_folder', $shareFolder); } }