diff options
Diffstat (limited to 'apps/files_sharing')
-rw-r--r-- | apps/files_sharing/ajax/list.php | 91 | ||||
-rw-r--r-- | apps/files_sharing/css/public.css | 5 | ||||
-rw-r--r-- | apps/files_sharing/js/public.js | 69 | ||||
-rw-r--r-- | apps/files_sharing/js/share.js | 24 | ||||
-rw-r--r-- | apps/files_sharing/lib/helper.php | 114 | ||||
-rw-r--r-- | apps/files_sharing/public.php | 86 |
6 files changed, 270 insertions, 119 deletions
diff --git a/apps/files_sharing/ajax/list.php b/apps/files_sharing/ajax/list.php new file mode 100644 index 00000000000..4b645496253 --- /dev/null +++ b/apps/files_sharing/ajax/list.php @@ -0,0 +1,91 @@ +<?php +/** + * ownCloud + * + * @author Vincent Petry + * @copyright 2014 Vincent Petry <pvince81@owncloud.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +// only need filesystem apps +$RUNTIME_APPTYPES=array('filesystem'); + +// Init owncloud + +if(!\OC_App::isEnabled('files_sharing')){ + exit; +} + +if(!isset($_GET['t'])){ + \OC_Response::setStatus(400); //400 Bad Request + \OC_Log::write('core-preview', 'No token parameter was passed', \OC_Log::DEBUG); + exit; +} + +$token = $_GET['t']; + +$password = null; +if (isset($_POST['password'])) { + $password = $_POST['password']; +} + +$relativePath = null; +if (isset($_GET['dir'])) { + $relativePath = $_GET['dir']; +} + +$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(404); + \OCP\JSON::error(array('success' => false)); + exit(); +} + +$data = array(); +$baseUrl = OCP\Util::linkTo('files_sharing', 'index.php') . '?t=' . urlencode($token) . '&dir='; + +// make filelist +$files = \OCA\Files\Helper::getFiles($dir); + +$formattedFiles = array(); +foreach ($files as $file) { + $entry = \OCA\Files\Helper::formatFileInfo($file); + unset($entry['directory']); // for now + $entry['permissions'] = \OCP\PERMISSION_READ; + $formattedFiles[] = $entry; +} + +$data['directory'] = $relativePath; +$data['files'] = $formattedFiles; +$data['dirToken'] = $linkItem['token']; + +$permissions = $linkItem['permissions']; + +// if globally disabled +if (OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes') === 'no') { + // only allow reading + $permissions = \OCP\PERMISSION_READ; +} + +$data['permissions'] = $permissions; + +OCP\JSON::success(array('data' => $data)); diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 5246a4b2fec..f0b9b04491f 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -35,6 +35,11 @@ body { background: #fff; text-align: center; margin: 45px auto 0; + min-height: 150px; +} + +#preview .notCreatable { + display: none; } #noPreview { diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index 06c168969de..9ce8985f1fd 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -8,16 +8,7 @@ * */ -/* global OC, FileList, FileActions */ - -// Override download path to files_sharing/public.php -function fileDownloadPath(dir, file) { - var url = $('#downloadURL').val(); - if (url.indexOf('&path=') != -1) { - url += '/'+file; - } - return url; -} +/* global OC, FileActions, FileList, Files */ $(document).ready(function() { @@ -31,31 +22,43 @@ $(document).ready(function() { action($('#filename').val()); } } - FileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function(filename) { - var tr = FileList.findFileEl(filename); - if (tr.length > 0) { - window.location = $(tr).find('a.name').attr('href'); - } - }); + } - // override since the format is different - FileList.getDownloadUrl = function(filename, dir) { - if ($.isArray(filename)) { - filename = JSON.stringify(filename); - } - var path = dir || FileList.getCurrentDirectory(); - var params = { - service: 'files', - t: $('#sharingToken').val(), - path: path, - download: null - }; - if (filename) { - params.files = filename; - } - return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); + // override since the format is different + Files.getDownloadUrl = function(filename, dir) { + if ($.isArray(filename)) { + filename = JSON.stringify(filename); + } + var path = dir || FileList.getCurrentDirectory(); + var params = { + service: 'files', + t: $('#sharingToken').val(), + path: path, + files: filename, + download: null }; - } + return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); + }; + + Files.getAjaxUrl = function(action, params) { + params = params || {}; + params.t = $('#sharingToken').val(); + return OC.filePath('files_sharing', 'ajax', action + '.php') + '?' + OC.buildQueryString(params); + }; + + FileList.linkTo = function(dir) { + var params = { + service: 'files', + t: $('#sharingToken').val(), + dir: dir + }; + return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); + }; + + Files.generatePreviewUrl = function(urlSpec) { + urlSpec.t = $('#dirToken').val(); + return OC.generateUrl('/apps/files_sharing/ajax/publicpreview.php?') + $.param(urlSpec); + }; var file_upload_start = $('#file_upload_start'); file_upload_start.on('fileuploadadd', function(e, data) { diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 9f0ed12f935..ea518f3b70e 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -1,15 +1,35 @@ +/* + * Copyright (c) 2014 + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +/* global OC, t, FileList, FileActions */ $(document).ready(function() { var disableSharing = $('#disableSharing').data('status'), sharesLoaded = false; if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined' && !disableSharing) { + var oldCreateRow = FileList._createRow; + FileList._createRow = function(fileData) { + var tr = oldCreateRow.apply(this, arguments); + if (fileData.shareOwner) { + tr.attr('data-share-owner', fileData.shareOwner); + } + return tr; + }; + $('#fileList').on('fileActionsReady',function(){ - var allShared = $('#fileList').find('[data-share-owner]').find('[data-Action="Share"]'); + var allShared = $('#fileList').find('[data-share-owner] [data-Action="Share"]'); allShared.addClass('permanent'); allShared.find('span').text(function(){ - $owner = $(this).closest('tr').attr('data-share-owner'); + var $owner = $(this).closest('tr').attr('data-share-owner'); return ' ' + t('files_sharing', 'Shared by {owner}', {owner: $owner}); }); diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php new file mode 100644 index 00000000000..b602fe3599d --- /dev/null +++ b/apps/files_sharing/lib/helper.php @@ -0,0 +1,114 @@ +<?php + +namespace OCA\Files_Sharing; + +class Helper { + + /** + * Sets up the filesystem and user for public sharing + * @param string $token string share token + * @param string $relativePath optional path relative to the share + * @param string $password optional password + */ + public static function setupFromToken($token, $relativePath = null, $password = null) { + \OC_User::setIncognitoMode(true); + + $linkItem = \OCP\Share::getShareByToken($token); + if($linkItem === false || ($linkItem['item_type'] !== 'file' && $linkItem['item_type'] !== 'folder')) { + \OC_Response::setStatus(404); + \OC_Log::write('core-preview', 'Passed token parameter is not valid', \OC_Log::DEBUG); + exit; + } + + if(!isset($linkItem['uid_owner']) || !isset($linkItem['file_source'])) { + \OC_Response::setStatus(500); + \OC_Log::write('core-preview', 'Passed token seems to be valid, but it does not contain all necessary information . ("' . $token . '")', \OC_Log::WARN); + exit; + } + + $type = $linkItem['item_type']; + $fileSource = $linkItem['file_source']; + $shareOwner = $linkItem['uid_owner']; + $rootLinkItem = \OCP\Share::resolveReShare($linkItem); + $path = null; + if (isset($rootLinkItem['uid_owner'])) { + \OCP\JSON::checkUserExists($rootLinkItem['uid_owner']); + \OC_Util::tearDownFS(); + \OC_Util::setupFS($rootLinkItem['uid_owner']); + $path = \OC\Files\Filesystem::getPath($linkItem['file_source']); + } + + if ($path === null) { + \OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG); + \OC_Response::setStatus(404); + \OCP\JSON::error(array('success' => 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'])) { + if (!self::authenticate($linkItem, $password)) { + \OC_Response::setStatus(403); + \OCP\JSON::error(array('success' => false)); + exit(); + } + } + + $basePath = $path; + $rootName = basename($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 true if authorized, false otherwise + */ + public static function authenticate($linkItem, $password) { + if ($password !== null) { + if ($linkItem['share_type'] == \OCP\Share::SHARE_TYPE_LINK) { + // Check Password + $forcePortable = (CRYPT_BLOWFISH != 1); + $hasher = new PasswordHash(8, $forcePortable); + if (!($hasher->CheckPassword($password.OC_Config::getValue('passwordsalt', ''), + $linkItem['share_with']))) { + return false; + } else { + // Save item id in session for future requests + \OC::$session->set('public_link_authenticated', $linkItem['id']); + } + } 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::$session->exists('public_link_authenticated') + || \OC::$session->get('public_link_authenticated') !== $linkItem['id']) { + return false; + } + } + return true; + } +} diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index fe61dd4d5a0..ce51eca6ddb 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -11,31 +11,6 @@ if ($appConfig->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { exit(); } -function fileCmp($a, $b) { - if ($a['type'] == 'dir' and $b['type'] != 'dir') { - return -1; - } elseif ($a['type'] != 'dir' and $b['type'] == 'dir') { - return 1; - } else { - return strnatcasecmp($a['name'], $b['name']); - } -} - -function determineIcon($file, $sharingRoot, $sharingToken) { - // for folders we simply reuse the files logic - if($file['type'] == 'dir') { - return \OCA\Files\Helper::determineIcon($file); - } - - $relativePath = substr($file['path'], 6); - $relativePath = substr($relativePath, strlen($sharingRoot)); - if($file['isPreviewAvailable']) { - return OCP\publicPreview_icon($relativePath, $sharingToken) . '&c=' . $file['etag']; - } - $icon = OCP\mimetype_icon($file['mimetype']); - return substr($icon, 0, -3) . 'svg'; -} - if (isset($_GET['t'])) { $token = $_GET['t']; $linkItem = OCP\Share::getShareByToken($token, false); @@ -153,13 +128,6 @@ if (isset($path)) { $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); $tmpl->assign('dirToken', $linkItem['token']); $tmpl->assign('sharingToken', $token); - $allowPublicUploadEnabled = (bool) ($linkItem['permissions'] & OCP\PERMISSION_CREATE); - if ($appConfig->getValue('core', 'shareapi_allow_public_upload', 'yes') === 'no') { - $allowPublicUploadEnabled = false; - } - if ($linkItem['item_type'] !== 'folder') { - $allowPublicUploadEnabled = false; - } $urlLinkIdentifiers= (isset($token)?'&t='.$token:'') .(isset($_GET['dir'])?'&dir='.$_GET['dir']:'') @@ -170,64 +138,18 @@ if (isset($path)) { OCP\Util::addStyle('files', 'files'); OCP\Util::addStyle('files', 'upload'); + OCP\Util::addScript('files', 'breadcrumb'); OCP\Util::addScript('files', 'files'); OCP\Util::addScript('files', 'filelist'); OCP\Util::addscript('files', 'keyboardshortcuts'); $files = array(); $rootLength = strlen($basePath) + 1; - $totalSize = 0; - foreach (\OC\Files\Filesystem::getDirectoryContent($path) as $i) { - $totalSize += $i['size']; - $i['date'] = OCP\Util::formatDate($i['mtime']); - if ($i['type'] == 'file') { - $fileinfo = pathinfo($i['name']); - $i['basename'] = $fileinfo['filename']; - if (!empty($fileinfo['extension'])) { - $i['extension'] = '.' . $fileinfo['extension']; - } else { - $i['extension'] = ''; - } - } - $i['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($i['mimetype']); - $i['directory'] = $getPath; - $i['permissions'] = OCP\PERMISSION_READ; - $i['icon'] = determineIcon($i, $basePath, $token); - $files[] = $i; - } - usort($files, "fileCmp"); - - // Make breadcrumb - $breadcrumb = array(); - $pathtohere = ''; - foreach (explode('/', $getPath) as $i) { - if ($i != '') { - $pathtohere .= '/' . $i; - $breadcrumb[] = array('dir' => $pathtohere, 'name' => $i); - } - } - $list = new OCP\Template('files', 'part.list', ''); - $list->assign('files', $files); - $list->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path='); - $list->assign('downloadURL', - OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path='); - $list->assign('isPublic', true); - $list->assign('sharingtoken', $token); - $list->assign('sharingroot', $basePath); - $breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', ''); - $breadcrumbNav->assign('breadcrumb', $breadcrumb); - $breadcrumbNav->assign('rootBreadCrumb', $rootName); - $breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path='); $maxUploadFilesize=OCP\Util::maxUploadFilesize($path); - $fileHeader = (!isset($files) or count($files) > 0); - $emptyContent = ($allowPublicUploadEnabled and !$fileHeader); $freeSpace=OCP\Util::freeSpace($path); $uploadLimit=OCP\Util::uploadLimit(); $folder = new OCP\Template('files', 'index', ''); - $folder->assign('fileList', $list->fetchPage()); - $folder->assign('breadcrumb', $breadcrumbNav->fetchPage()); $folder->assign('dir', $getPath); - $folder->assign('isCreatable', $allowPublicUploadEnabled); $folder->assign('dirToken', $linkItem['token']); $folder->assign('permissions', OCP\PERMISSION_READ); $folder->assign('isPublic',true); @@ -239,15 +161,11 @@ if (isset($path)) { $folder->assign('uploadLimit', $uploadLimit); // PHP upload limit $folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $folder->assign('usedSpacePercent', 0); - $folder->assign('fileHeader', $fileHeader); $folder->assign('disableSharing', true); $folder->assign('trash', false); - $folder->assign('emptyContent', $emptyContent); - $folder->assign('ajaxLoad', false); $tmpl->assign('folder', $folder->fetchPage()); $maxInputFileSize = OCP\Config::getSystemValue('maxZipInputSize', OCP\Util::computerFileSize('800 MB')); - $allowZip = OCP\Config::getSystemValue('allowZipDownload', true) - && ( $maxInputFileSize === 0 || $totalSize <= $maxInputFileSize); + $allowZip = OCP\Config::getSystemValue('allowZipDownload', true); $tmpl->assign('allowZipDownload', intval($allowZip)); $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path=' . urlencode($getPath)); |