fixes download issue introduced by #10755 Conflicts: apps/files_sharing/public.phptags/v8.0.0alpha1
@@ -1,4 +1,5 @@ | |||
<?php | |||
/** @var $this \OCP\Route\IRouter */ | |||
$this->create('core_ajax_public_preview', '/publicpreview')->action( | |||
function() { |
@@ -0,0 +1,73 @@ | |||
<?php | |||
/** | |||
* @author Lukas Reschke | |||
* @copyright 2014 Lukas Reschke lukas@owncloud.com | |||
* | |||
* This file is licensed under the Affero General Public License version 3 or | |||
* later. | |||
* See the COPYING-README file. | |||
*/ | |||
namespace OCA\Files_Sharing; | |||
use OC\AppFramework\Utility\SimpleContainer; | |||
use OCA\Files_Sharing\Controllers\ShareController; | |||
use OCA\Files_Sharing\Middleware\SharingCheckMiddleware; | |||
use \OCP\AppFramework\App; | |||
/** | |||
* @package OCA\Files_Sharing | |||
*/ | |||
class Application extends App { | |||
/** | |||
* @param array $urlParams | |||
*/ | |||
public function __construct(array $urlParams=array()){ | |||
parent::__construct('files_sharing', $urlParams); | |||
$container = $this->getContainer(); | |||
/** | |||
* Controllers | |||
*/ | |||
$container->registerService('ShareController', function(SimpleContainer $c) { | |||
return new ShareController( | |||
$c->query('AppName'), | |||
$c->query('Request'), | |||
$c->query('UserSession'), | |||
$c->query('ServerContainer')->getAppConfig(), | |||
$c->query('ServerContainer')->getConfig(), | |||
$c->query('URLGenerator'), | |||
$c->query('ServerContainer')->getUserManager(), | |||
$c->query('ServerContainer')->getLogger() | |||
); | |||
}); | |||
/** | |||
* Core class wrappers | |||
*/ | |||
$container->registerService('UserSession', function(SimpleContainer $c) { | |||
return $c->query('ServerContainer')->getUserSession(); | |||
}); | |||
$container->registerService('URLGenerator', function(SimpleContainer $c) { | |||
return $c->query('ServerContainer')->getUrlGenerator(); | |||
}); | |||
/** | |||
* Middleware | |||
*/ | |||
$container->registerService('SharingCheckMiddleware', function(SimpleContainer $c){ | |||
return new SharingCheckMiddleware( | |||
$c->query('AppName'), | |||
$c->query('ServerContainer')->getAppConfig(), | |||
$c->getCoreApi() | |||
); | |||
}); | |||
// Execute middlewares | |||
$container->registerMiddleware('SharingCheckMiddleware'); | |||
} | |||
} |
@@ -109,14 +109,12 @@ OCA.Sharing.PublicApp = { | |||
filename = JSON.stringify(filename); | |||
} | |||
var path = dir || FileList.getCurrentDirectory(); | |||
var token = $('#sharingToken').val(); | |||
var params = { | |||
service: 'files', | |||
t: $('#sharingToken').val(), | |||
path: path, | |||
files: filename, | |||
download: null | |||
files: filename | |||
}; | |||
return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); | |||
return OC.generateUrl('/s/'+token+'/download') + '?' + OC.buildQueryString(params); | |||
}; | |||
this.fileList.getAjaxUrl = function (action, params) { | |||
@@ -126,12 +124,11 @@ OCA.Sharing.PublicApp = { | |||
}; | |||
this.fileList.linkTo = function (dir) { | |||
var token = $('#sharingToken').val(); | |||
var params = { | |||
service: 'files', | |||
t: $('#sharingToken').val(), | |||
dir: dir | |||
}; | |||
return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); | |||
return OC.generateUrl('/s/'+token+'') + '?' + OC.buildQueryString(params); | |||
}; | |||
this.fileList.generatePreviewUrl = function (urlSpec) { | |||
@@ -193,8 +190,6 @@ OCA.Sharing.PublicApp = { | |||
_onDirectoryChanged: function (e) { | |||
OC.Util.History.pushState({ | |||
service: 'files', | |||
t: $('#sharingToken').val(), | |||
// arghhhh, why is this not called "dir" !? | |||
path: e.dir | |||
}); |
@@ -0,0 +1,271 @@ | |||
<?php | |||
/** | |||
* @author Clark Tomlinson <clark@owncloud.com> | |||
* @author Lukas Reschke <lukas@owncloud.com> | |||
* @copyright 2014 Clark Tomlinson & Lukas Reschke | |||
* | |||
* This file is licensed under the Affero General Public License version 3 or | |||
* later. | |||
* See the COPYING-README file. | |||
*/ | |||
namespace OCA\Files_Sharing\Controllers; | |||
use OC; | |||
use OC\Files\Filesystem; | |||
use OC_Files; | |||
use OC_Util; | |||
use OCP; | |||
use OCP\Template; | |||
use OCP\JSON; | |||
use OCP\Share; | |||
use OCP\AppFramework\Controller; | |||
use OCP\IRequest; | |||
use OCP\AppFramework\Http\TemplateResponse; | |||
use OCP\AppFramework\Http\RedirectResponse; | |||
use OCP\AppFramework\IApi; | |||
use OC\URLGenerator; | |||
use OC\AppConfig; | |||
use OCP\ILogger; | |||
use OCA\Files_Sharing\Helper; | |||
use OCP\User; | |||
use OCP\Util; | |||
/** | |||
* Class ShareController | |||
* | |||
* @package OCA\Files_Sharing\Controllers | |||
*/ | |||
class ShareController extends Controller { | |||
/** @var \OC\User\Session */ | |||
protected $userSession; | |||
/** @var \OC\AppConfig */ | |||
protected $appConfig; | |||
/** @var \OCP\IConfig */ | |||
protected $config; | |||
/** @var \OC\URLGenerator */ | |||
protected $urlGenerator; | |||
/** @var \OC\User\Manager */ | |||
protected $userManager; | |||
/** @var \OCP\ILogger */ | |||
protected $logger; | |||
/** | |||
* @param string $appName | |||
* @param IRequest $request | |||
* @param OC\User\Session $userSession | |||
* @param AppConfig $appConfig | |||
* @param OCP\IConfig $config | |||
* @param URLGenerator $urlGenerator | |||
* @param OC\User\Manager $userManager | |||
* @param ILogger $logger | |||
*/ | |||
public function __construct($appName, | |||
IRequest $request, | |||
OC\User\Session $userSession, | |||
AppConfig $appConfig, | |||
OCP\IConfig $config, | |||
URLGenerator $urlGenerator, | |||
OC\User\Manager $userManager, | |||
ILogger $logger) { | |||
parent::__construct($appName, $request); | |||
$this->userSession = $userSession; | |||
$this->appConfig = $appConfig; | |||
$this->config = $config; | |||
$this->urlGenerator = $urlGenerator; | |||
$this->userManager = $userManager; | |||
$this->logger = $logger; | |||
} | |||
/** | |||
* @PublicPage | |||
* @NoCSRFRequired | |||
* | |||
* @param string $token | |||
* | |||
* @return TemplateResponse|RedirectResponse | |||
*/ | |||
public function showAuthenticate($token) { | |||
$linkItem = Share::getShareByToken($token, false); | |||
if(Helper::authenticate($linkItem)) { | |||
return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token))); | |||
} | |||
return new TemplateResponse($this->appName, 'authenticate', array(), 'guest'); | |||
} | |||
/** | |||
* @PublicPage | |||
* | |||
* Authenticates against password-protected shares | |||
* @param $token | |||
* @param string $password | |||
* @return RedirectResponse|TemplateResponse | |||
*/ | |||
public function authenticate($token, $password = '') { | |||
$linkItem = Share::getShareByToken($token, false); | |||
if($linkItem === false) { | |||
return new TemplateResponse('core', '404', array(), 'guest'); | |||
} | |||
$authenticate = Helper::authenticate($linkItem, $password); | |||
if($authenticate === true) { | |||
return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token))); | |||
} | |||
return new TemplateResponse($this->appName, 'authenticate', array('wrongpw' => true), 'guest'); | |||
} | |||
/** | |||
* @PublicPage | |||
* @NoCSRFRequired | |||
* | |||
* @param string $token | |||
* @param string $path | |||
* | |||
* @return TemplateResponse | |||
*/ | |||
public function showShare($token, $path = '') { | |||
\OC_User::setIncognitoMode(true); | |||
// Check whether share exists | |||
$linkItem = Share::getShareByToken($token, false); | |||
if($linkItem === false) { | |||
return new TemplateResponse('core', '404', array(), 'guest'); | |||
} | |||
$linkItem = OCP\Share::getShareByToken($token, false); | |||
$shareOwner = $linkItem['uid_owner']; | |||
$originalSharePath = null; | |||
$rootLinkItem = OCP\Share::resolveReShare($linkItem); | |||
if (isset($rootLinkItem['uid_owner'])) { | |||
OCP\JSON::checkUserExists($rootLinkItem['uid_owner']); | |||
OC_Util::tearDownFS(); | |||
OC_Util::setupFS($rootLinkItem['uid_owner']); | |||
$originalSharePath = Filesystem::getPath($linkItem['file_source']); | |||
} | |||
// Share is password protected - check whether the user is permitted to access the share | |||
if (isset($linkItem['share_with']) && !Helper::authenticate($linkItem)) { | |||
return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate', | |||
array('token' => $token))); | |||
} | |||
if (Filesystem::isReadable($originalSharePath . $path)) { | |||
$getPath = Filesystem::normalizePath($path); | |||
$originalSharePath .= $path; | |||
} | |||
$dir = dirname($originalSharePath); | |||
$file = basename($originalSharePath); | |||
$shareTmpl = array(); | |||
$shareTmpl['displayName'] = User::getDisplayName($shareOwner); | |||
$shareTmpl['filename'] = $file; | |||
$shareTmpl['directory_path'] = $linkItem['file_target']; | |||
$shareTmpl['mimetype'] = Filesystem::getMimeType($originalSharePath); | |||
$shareTmpl['dirToken'] = $linkItem['token']; | |||
$shareTmpl['sharingToken'] = $token; | |||
$shareTmpl['server2serversharing'] = Helper::isOutgoingServer2serverShareEnabled(); | |||
$shareTmpl['protected'] = isset($linkItem['share_with']) ? 'true' : 'false'; | |||
$shareTmpl['dir'] = $dir; | |||
// Show file list | |||
if (Filesystem::is_dir($originalSharePath)) { | |||
$shareTmpl['dir'] = $getPath; | |||
$files = array(); | |||
$maxUploadFilesize = Util::maxUploadFilesize($originalSharePath); | |||
$freeSpace = Util::freeSpace($originalSharePath); | |||
$uploadLimit = Util::uploadLimit(); | |||
$folder = new Template('files', 'list', ''); | |||
$folder->assign('dir', $getPath); | |||
$folder->assign('dirToken', $linkItem['token']); | |||
$folder->assign('permissions', OCP\PERMISSION_READ); | |||
$folder->assign('isPublic', true); | |||
$folder->assign('publicUploadEnabled', 'no'); | |||
$folder->assign('files', $files); | |||
$folder->assign('uploadMaxFilesize', $maxUploadFilesize); | |||
$folder->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); | |||
$folder->assign('freeSpace', $freeSpace); | |||
$folder->assign('uploadLimit', $uploadLimit); // PHP upload limit | |||
$folder->assign('usedSpacePercent', 0); | |||
$folder->assign('trash', false); | |||
$shareTmpl['folder'] = $folder->fetchPage(); | |||
} | |||
$shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', array('token' => $token)); | |||
return new TemplateResponse($this->appName, 'public', $shareTmpl, 'base'); | |||
} | |||
/** | |||
* @PublicPage | |||
* @NoCSRFRequired | |||
* @param string $token | |||
* @param string $files | |||
* @param string $path | |||
* @return void|RedirectResponse | |||
*/ | |||
public function downloadShare($token, $files = null, $path = '') { | |||
\OC_User::setIncognitoMode(true); | |||
$linkItem = OCP\Share::getShareByToken($token, false); | |||
// Share is password protected - check whether the user is permitted to access the share | |||
if (isset($linkItem['share_with'])) { | |||
if(!Helper::authenticate($linkItem)) { | |||
return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate', | |||
array('token' => $token))); | |||
} | |||
} | |||
$originalSharePath = self::getPath($token); | |||
if (isset($originalSharePath) && Filesystem::isReadable($originalSharePath . $path)) { | |||
$getPath = Filesystem::normalizePath($path); | |||
$originalSharePath .= $getPath; | |||
} | |||
if (!is_null($files)) { // download selected files | |||
$files_list = json_decode($files); | |||
// in case we get only a single file | |||
if ($files_list === NULL ) { | |||
$files_list = array($files); | |||
} | |||
// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well | |||
// after dispatching the request which results in a "Cannot modify header information" notice. | |||
OC_Files::get($originalSharePath, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD'); | |||
exit(); | |||
} else { | |||
// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well | |||
// after dispatching the request which results in a "Cannot modify header information" notice. | |||
OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $_SERVER['REQUEST_METHOD'] == 'HEAD'); | |||
exit(); | |||
} | |||
} | |||
/** | |||
* @param $token | |||
* @return null|string | |||
*/ | |||
private function getPath($token) { | |||
$linkItem = Share::getShareByToken($token, false); | |||
$path = null; | |||
if (is_array($linkItem) && isset($linkItem['uid_owner'])) { | |||
// seems to be a valid share | |||
$rootLinkItem = Share::resolveReShare($linkItem); | |||
if (isset($rootLinkItem['uid_owner'])) { | |||
JSON::checkUserExists($rootLinkItem['uid_owner']); | |||
OC_Util::tearDownFS(); | |||
OC_Util::setupFS($rootLinkItem['uid_owner']); | |||
$path = Filesystem::getPath($linkItem['file_source']); | |||
} | |||
} | |||
return $path; | |||
} | |||
} |
@@ -95,7 +95,7 @@ class Helper { | |||
* | |||
* @return boolean true if authorized, false otherwise | |||
*/ | |||
public static function authenticate($linkItem, $password) { | |||
public static function authenticate($linkItem, $password = null) { | |||
if ($password !== null) { | |||
if ($linkItem['share_type'] == \OCP\Share::SHARE_TYPE_LINK) { | |||
// Check Password |
@@ -0,0 +1,84 @@ | |||
<?php | |||
/** | |||
* @author Lukas Reschke | |||
* @copyright 2014 Lukas Reschke lukas@owncloud.com | |||
* | |||
* This file is licensed under the Affero General Public License version 3 or | |||
* later. | |||
* See the COPYING-README file. | |||
*/ | |||
namespace OCA\Files_Sharing\Middleware; | |||
use OCP\AppFramework\IApi; | |||
use \OCP\AppFramework\Middleware; | |||
use OCP\AppFramework\Http\TemplateResponse; | |||
use OCP\IAppConfig; | |||
/** | |||
* Checks whether the "sharing check" is enabled | |||
* | |||
* @package OCA\Files_Sharing\Middleware | |||
*/ | |||
class SharingCheckMiddleware extends Middleware { | |||
/** @var string */ | |||
protected $appName; | |||
/** @var IAppConfig */ | |||
protected $appConfig; | |||
/** @var IApi */ | |||
protected $api; | |||
/*** | |||
* @param string $appName | |||
* @param IAppConfig $appConfig | |||
* @param IApi $api | |||
*/ | |||
public function __construct($appName, | |||
IAppConfig $appConfig, | |||
IApi $api) { | |||
$this->appName = $appName; | |||
$this->appConfig = $appConfig; | |||
$this->api = $api; | |||
} | |||
/** | |||
* Check if sharing is enabled before the controllers is executed | |||
*/ | |||
public function beforeController($controller, $methodName) { | |||
if(!$this->isSharingEnabled()) { | |||
throw new \Exception('Sharing is disabled.'); | |||
} | |||
} | |||
/** | |||
* Return 404 page in case of an exception | |||
* @param \OCP\AppFramework\Controller $controller | |||
* @param string $methodName | |||
* @param \Exception $exception | |||
* @return TemplateResponse | |||
*/ | |||
public function afterException($controller, $methodName, \Exception $exception){ | |||
return new TemplateResponse('core', '404', array(), 'guest'); | |||
} | |||
/** | |||
* Check whether sharing is enabled | |||
* @return bool | |||
*/ | |||
private function isSharingEnabled() { | |||
// FIXME: This check is done here since the route is globally defined and not inside the files_sharing app | |||
// Check whether the sharing application is enabled | |||
if(!$this->api->isAppEnabled($this->appName)) { | |||
return false; | |||
} | |||
// Check whether public sharing is enabled | |||
if($this->appConfig->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { | |||
return false; | |||
} | |||
return true; | |||
} | |||
} |
@@ -1,205 +1,17 @@ | |||
<?php | |||
// Load other apps for file previews | |||
use OCA\Files_Sharing\Helper; | |||
OC_App::loadApps(); | |||
$appConfig = \OC::$server->getAppConfig(); | |||
if ($appConfig->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { | |||
header('HTTP/1.0 404 Not Found'); | |||
$tmpl = new OCP\Template('', '404', 'guest'); | |||
$tmpl->printPage(); | |||
exit(); | |||
} | |||
// Legacy sharing links via public.php have the token in $GET['t'] | |||
if (isset($_GET['t'])) { | |||
$token = $_GET['t']; | |||
} | |||
if (isset($token)) { | |||
$linkItem = OCP\Share::getShareByToken($token, false); | |||
if (is_array($linkItem) && isset($linkItem['uid_owner'])) { | |||
// seems to be a valid share | |||
$type = $linkItem['item_type']; | |||
$fileSource = $linkItem['file_source']; | |||
$shareOwner = $linkItem['uid_owner']; | |||
$path = null; | |||
$rootLinkItem = OCP\Share::resolveReShare($linkItem); | |||
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 (isset($path)) { | |||
if (!isset($linkItem['item_type'])) { | |||
OCP\Util::writeLog('share', 'No item type set for share id: ' . $linkItem['id'], \OCP\Util::ERROR); | |||
header('HTTP/1.0 404 Not Found'); | |||
$tmpl = new OCP\Template('', '404', 'guest'); | |||
$tmpl->printPage(); | |||
exit(); | |||
} | |||
if (isset($linkItem['share_with'])) { | |||
// Authenticate share_with | |||
$url = OCP\Util::linkToPublic('files') . '&t=' . $token; | |||
if (isset($_GET['file'])) { | |||
$url .= '&file=' . urlencode($_GET['file']); | |||
} else { | |||
if (isset($_GET['dir'])) { | |||
$url .= '&dir=' . urlencode($_GET['dir']); | |||
} | |||
} | |||
if (isset($_POST['password'])) { | |||
$password = $_POST['password']; | |||
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']))) { | |||
OCP\Util::addStyle('files_sharing', 'authenticate'); | |||
$tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); | |||
$tmpl->assign('URL', $url); | |||
$tmpl->assign('wrongpw', true); | |||
$tmpl->printPage(); | |||
exit(); | |||
} else { | |||
// Save item id in session for future requests | |||
\OC::$server->getSession()->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); | |||
header('HTTP/1.0 404 Not Found'); | |||
$tmpl = new OCP\Template('', '404', 'guest'); | |||
$tmpl->printPage(); | |||
exit(); | |||
} | |||
} else { | |||
// Check if item id is set in session | |||
if ( ! \OC::$server->getSession()->exists('public_link_authenticated') | |||
|| \OC::$server->getSession()->get('public_link_authenticated') !== $linkItem['id'] | |||
) { | |||
// Prompt for password | |||
OCP\Util::addStyle('files_sharing', 'authenticate'); | |||
$tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); | |||
$tmpl->assign('URL', $url); | |||
$tmpl->printPage(); | |||
exit(); | |||
} | |||
} | |||
} | |||
$basePath = $path; | |||
$rootName = \OC_Util::basename($path); | |||
if (isset($_GET['path']) && \OC\Files\Filesystem::isReadable($basePath . $_GET['path'])) { | |||
$getPath = \OC\Files\Filesystem::normalizePath($_GET['path']); | |||
$path .= $getPath; | |||
} else { | |||
$getPath = ''; | |||
} | |||
$dir = dirname($path); | |||
$file = basename($path); | |||
// Download the file | |||
if (isset($_GET['download'])) { | |||
if (!\OCP\App::isEnabled('files_encryption')) { | |||
// encryption app requires the session to store the keys in | |||
\OC::$server->getSession()->close(); | |||
} | |||
if (isset($_GET['files'])) { // download selected files | |||
$files = $_GET['files']; | |||
$files_list = json_decode($files); | |||
// in case we get only a single file | |||
if (!is_array($files_list)) { | |||
$files_list = array($files); | |||
} | |||
OC_Files::get($path, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD'); | |||
} else { | |||
OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD'); | |||
} | |||
exit(); | |||
} else { | |||
OCP\Util::addScript('files', 'file-upload'); | |||
OCP\Util::addStyle('files_sharing', 'public'); | |||
OCP\Util::addStyle('files_sharing', 'mobile'); | |||
OCP\Util::addScript('files_sharing', 'public'); | |||
OCP\Util::addScript('files', 'fileactions'); | |||
OCP\Util::addScript('files', 'jquery.iframe-transport'); | |||
OCP\Util::addScript('files', 'jquery.fileupload'); | |||
$maxUploadFilesize=OCP\Util::maxUploadFilesize($path); | |||
$tmpl = new OCP\Template('files_sharing', 'public', 'base'); | |||
$tmpl->assign('displayName', \OCP\User::getDisplayName($shareOwner)); | |||
$tmpl->assign('filename', $file); | |||
$tmpl->assign('directory_path', $linkItem['file_target']); | |||
$tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); | |||
$tmpl->assign('dirToken', $linkItem['token']); | |||
$tmpl->assign('sharingToken', $token); | |||
$tmpl->assign('server2serversharing', Helper::isOutgoingServer2serverShareEnabled()); | |||
$tmpl->assign('protected', isset($linkItem['share_with']) ? 'true' : 'false'); | |||
$urlLinkIdentifiers= (isset($token)?'&t='.$token:'') | |||
.(isset($_GET['dir'])?'&dir='.$_GET['dir']:'') | |||
.(isset($_GET['file'])?'&file='.$_GET['file']:''); | |||
// Show file list | |||
if (\OC\Files\Filesystem::is_dir($path)) { | |||
$tmpl->assign('dir', $getPath); | |||
OCP\Util::addStyle('files', 'files'); | |||
OCP\Util::addStyle('files', 'upload'); | |||
OCP\Util::addScript('files', 'filesummary'); | |||
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; | |||
$maxUploadFilesize=OCP\Util::maxUploadFilesize($path); | |||
$freeSpace=OCP\Util::freeSpace($path); | |||
$uploadLimit=OCP\Util::uploadLimit(); | |||
$folder = new OCP\Template('files', 'list', ''); | |||
$folder->assign('dir', $getPath); | |||
$folder->assign('dirToken', $linkItem['token']); | |||
$folder->assign('permissions', OCP\PERMISSION_READ); | |||
$folder->assign('isPublic', true); | |||
$folder->assign('publicUploadEnabled', 'no'); | |||
$folder->assign('files', $files); | |||
$folder->assign('uploadMaxFilesize', $maxUploadFilesize); | |||
$folder->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); | |||
$folder->assign('freeSpace', $freeSpace); | |||
$folder->assign('uploadLimit', $uploadLimit); // PHP upload limit | |||
$folder->assign('usedSpacePercent', 0); | |||
$folder->assign('trash', false); | |||
$tmpl->assign('folder', $folder->fetchPage()); | |||
$tmpl->assign('downloadURL', | |||
OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path=' . urlencode($getPath)); | |||
} else { | |||
$tmpl->assign('dir', $dir); | |||
// Show file preview if viewer is available | |||
if ($type == 'file') { | |||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download'); | |||
} else { | |||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') | |||
.$urlLinkIdentifiers.'&download&path='.urlencode($getPath)); | |||
} | |||
} | |||
$tmpl->printPage(); | |||
} | |||
exit(); | |||
} else { | |||
OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG); | |||
} | |||
$errorTemplate = new OCP\Template('files_sharing', 'part.404', ''); | |||
$errorContent = $errorTemplate->fetchPage(); | |||
header('HTTP/1.0 404 Not Found'); | |||
OCP\Util::addStyle('files_sharing', '404'); | |||
$tmpl = new OCP\Template('', '404', 'guest'); | |||
$tmpl->assign('content', $errorContent); | |||
$tmpl->printPage(); | |||
/** | |||
* @author Lukas Reschke | |||
* @copyright 2014 Lukas Reschke lukas@owncloud.com | |||
* | |||
* This file is licensed under the Affero General Public License version 3 or | |||
* later. | |||
* See the COPYING-README file. | |||
*/ | |||
// This file is just used to redirect the legacy sharing URLs (< ownCloud 8) to the new ones | |||
$urlGenerator = new \OC\URLGenerator(\OC::$server->getConfig()); | |||
$token = isset($_GET['t']) ? $_GET['t'] : ''; | |||
$route = isset($_GET['download']) ? 'files_sharing.sharecontroller.downloadshare' : 'files_sharing.sharecontroller.showshare'; | |||
OC_Response::redirect($urlGenerator->linkToRoute($route, array('token' => $token))); |
@@ -1,4 +1,9 @@ | |||
<form action="<?php p($_['URL']); ?>" method="post"> | |||
<?php | |||
/** @var $_ array */ | |||
/** @var $l OC_L10N */ | |||
style('files_sharing', 'authenticate'); | |||
?> | |||
<form method="post"> | |||
<fieldset> | |||
<?php if (!isset($_['wrongpw'])): ?> | |||
<div class="warning-info"><?php p($l->t('This share is password-protected')); ?></div> | |||
@@ -8,6 +13,7 @@ | |||
<?php endif; ?> | |||
<p> | |||
<label for="password" class="infield"><?php p($l->t('Password')); ?></label> | |||
<input type="hidden" name="requesttoken" value="<?php p($_['requesttoken']) ?>" /> | |||
<input type="password" name="password" id="password" | |||
placeholder="<?php p($l->t('Password')); ?>" value="" | |||
autocomplete="off" autocapitalize="off" autocorrect="off" |
@@ -1,8 +1,28 @@ | |||
<?php /** @var $l OC_L10N */ ?> | |||
<?php | |||
/** @var $l OC_L10N */ | |||
/** @var $_ array */ | |||
OCP\Util::addScript('files', 'file-upload'); | |||
OCP\Util::addStyle('files_sharing', 'public'); | |||
OCP\Util::addStyle('files_sharing', 'mobile'); | |||
OCP\Util::addScript('files_sharing', 'public'); | |||
OCP\Util::addScript('files', 'fileactions'); | |||
OCP\Util::addScript('files', 'jquery.iframe-transport'); | |||
OCP\Util::addScript('files', 'jquery.fileupload'); | |||
// JS required for folders | |||
OCP\Util::addStyle('files', 'files'); | |||
OCP\Util::addStyle('files', 'upload'); | |||
OCP\Util::addScript('files', 'filesummary'); | |||
OCP\Util::addScript('files', 'breadcrumb'); | |||
OCP\Util::addScript('files', 'files'); | |||
OCP\Util::addScript('files', 'filelist'); | |||
OCP\Util::addscript('files', 'keyboardshortcuts'); | |||
$thumbSize=1024; | |||
$previewSupported = OC\Preview::isMimeSupported($_['mimetype']) ? 'true' : 'false'; | |||
?> | |||
<?php if ( \OC\Preview::isMimeSupported($_['mimetype'])): /* This enables preview images for links (e.g. on Facebook, Google+, ...)*/?> | |||
<link rel="image_src" href="<?php p(OCP\Util::linkToRoute( 'core_ajax_public_preview', array('x' => $thumbSize, 'y' => $thumbSize, 'file' => $_['directory_path'], 't' => $_['dirToken']))); ?>" /> | |||
<?php endif; ?> | |||
@@ -24,7 +44,7 @@ $previewSupported = OC\Preview::isMimeSupported($_['mimetype']) ? 'true' : 'fals | |||
<header><div id="header" class="<?php p((isset($_['folder']) ? 'share-folder' : 'share-file')) ?>"> | |||
<a href="<?php print_unescaped(link_to('', 'index.php')); ?>" | |||
title="" id="owncloud"> | |||
title="" id="owncloud"> | |||
<div class="logo-wide svg"></div> | |||
</a> | |||
<div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div> | |||
@@ -48,7 +68,7 @@ $previewSupported = OC\Preview::isMimeSupported($_['mimetype']) ? 'true' : 'fals | |||
</a> | |||
</span> | |||
</div> | |||
</div></header> | |||
</div></header> | |||
<div id="content"> | |||
<div id="preview"> | |||
<?php if (isset($_['folder'])): ?> |
@@ -0,0 +1,170 @@ | |||
<?php | |||
/** | |||
* @author Lukas Reschke <lukas@owncloud.com> | |||
* @copyright 2014 Lukas Reschke | |||
* | |||
* This file is licensed under the Affero General Public License version 3 or | |||
* later. | |||
* See the COPYING-README file. | |||
*/ | |||
namespace OCA\Files_Sharing\Controllers; | |||
use OC\Files\Filesystem; | |||
use OCA\Files_Sharing\Application; | |||
use OCP\AppFramework\IAppContainer; | |||
use OCP\Files; | |||
use OCP\AppFramework\Http\RedirectResponse; | |||
use OCP\AppFramework\Http\TemplateResponse; | |||
use OCP\Security\ISecureRandom; | |||
use OC\Files\View; | |||
use OCP\Share; | |||
use OC\URLGenerator; | |||
/** | |||
* @package OCA\Files_Sharing\Controllers | |||
*/ | |||
class ShareControllerTest extends \PHPUnit_Framework_TestCase { | |||
/** @var IAppContainer */ | |||
private $container; | |||
/** @var string */ | |||
private $user; | |||
/** @var string */ | |||
private $token; | |||
/** @var string */ | |||
private $oldUser; | |||
/** @var ShareController */ | |||
private $shareController; | |||
/** @var URLGenerator */ | |||
private $urlGenerator; | |||
protected function setUp() { | |||
$app = new Application(); | |||
$this->container = $app->getContainer(); | |||
$this->container['Config'] = $this->getMockBuilder('\OCP\IConfig') | |||
->disableOriginalConstructor()->getMock(); | |||
$this->container['AppName'] = 'files_sharing'; | |||
$this->container['UserSession'] = $this->getMockBuilder('\OC\User\Session') | |||
->disableOriginalConstructor()->getMock(); | |||
$this->container['URLGenerator'] = $this->getMockBuilder('\OC\URLGenerator') | |||
->disableOriginalConstructor()->getMock(); | |||
$this->urlGenerator = $this->container['URLGenerator']; | |||
$this->shareController = $this->container['ShareController']; | |||
// Store current user | |||
$this->oldUser = \OC_User::getUser(); | |||
// Create a dummy user | |||
$this->user = \OC::$server->getSecureRandom()->getLowStrengthGenerator()->generate(12, ISecureRandom::CHAR_LOWER); | |||
\OC_User::createUser($this->user, $this->user); | |||
\OC_Util::tearDownFS(); | |||
\OC_User::setUserId(''); | |||
Filesystem::tearDown(); | |||
\OC_User::setUserId($this->user); | |||
\OC_Util::setupFS($this->user); | |||
// Create a dummy shared file | |||
$view = new View('/'. $this->user . '/files'); | |||
$view->file_put_contents('file1.txt', 'I am such an awesome shared file!'); | |||
$this->token = \OCP\Share::shareItem( | |||
Filesystem::getFileInfo('file1.txt')->getType(), | |||
Filesystem::getFileInfo('file1.txt')->getId(), | |||
\OCP\Share::SHARE_TYPE_LINK, | |||
'IAmPasswordProtected!', | |||
1 | |||
); | |||
} | |||
protected function tearDown() { | |||
\OC_Util::tearDownFS(); | |||
\OC_User::setUserId(''); | |||
Filesystem::tearDown(); | |||
\OC_User::deleteUser($this->user); | |||
\OC_User::setIncognitoMode(false); | |||
\OC::$server->getSession()->set('public_link_authenticated', ''); | |||
// Set old user | |||
\OC_User::setUserId($this->oldUser); | |||
\OC_Util::setupFS($this->oldUser); | |||
} | |||
public function testShowAuthenticate() { | |||
$linkItem = \OCP\Share::getShareByToken($this->token, false); | |||
// Test without being authenticated | |||
$response = $this->shareController->showAuthenticate($this->token); | |||
$expectedResponse = new TemplateResponse($this->container['AppName'], 'authenticate', array(), 'guest'); | |||
$this->assertEquals($expectedResponse, $response); | |||
// Test with being authenticated for another file | |||
\OC::$server->getSession()->set('public_link_authenticated', $linkItem['id']-1); | |||
$response = $this->shareController->showAuthenticate($this->token); | |||
$expectedResponse = new TemplateResponse($this->container['AppName'], 'authenticate', array(), 'guest'); | |||
$this->assertEquals($expectedResponse, $response); | |||
// Test with being authenticated for the correct file | |||
\OC::$server->getSession()->set('public_link_authenticated', $linkItem['id']); | |||
$response = $this->shareController->showAuthenticate($this->token); | |||
$expectedResponse = new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $this->token))); | |||
$this->assertEquals($expectedResponse, $response); | |||
} | |||
public function testAuthenticate() { | |||
// Test without a not existing token | |||
$response = $this->shareController->authenticate('ThisTokenShouldHopefullyNeverExistSoThatTheUnitTestWillAlwaysPass :)'); | |||
$expectedResponse = new TemplateResponse('core', '404', array(), 'guest'); | |||
$this->assertEquals($expectedResponse, $response); | |||
// Test with a valid password | |||
$response = $this->shareController->authenticate($this->token, 'IAmPasswordProtected!'); | |||
$expectedResponse = new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $this->token))); | |||
$this->assertEquals($expectedResponse, $response); | |||
// Test with a invalid password | |||
$response = $this->shareController->authenticate($this->token, 'WrongPw!'); | |||
$expectedResponse = new TemplateResponse($this->container['AppName'], 'authenticate', array('wrongpw' => true), 'guest'); | |||
$this->assertEquals($expectedResponse, $response); | |||
} | |||
public function testShowShare() { | |||
// Test without a not existing token | |||
$response = $this->shareController->showShare('ThisTokenShouldHopefullyNeverExistSoThatTheUnitTestWillAlwaysPass :)'); | |||
$expectedResponse = new TemplateResponse('core', '404', array(), 'guest'); | |||
$this->assertEquals($expectedResponse, $response); | |||
// Test with a password protected share and no authentication | |||
$response = $this->shareController->showShare($this->token); | |||
$expectedResponse = new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate', array('token' => $this->token))); | |||
$this->assertEquals($expectedResponse, $response); | |||
// Test with password protected share and authentication | |||
$linkItem = Share::getShareByToken($this->token, false); | |||
\OC::$server->getSession()->set('public_link_authenticated', $linkItem['id']); | |||
$response = $this->shareController->showShare($this->token); | |||
$sharedTmplParams = array( | |||
'displayName' => $this->user, | |||
'filename' => 'file1.txt', | |||
'directory_path' => '/file1.txt', | |||
'mimetype' => 'text/plain', | |||
'dirToken' => $this->token, | |||
'sharingToken' => $this->token, | |||
'server2serversharing' => true, | |||
'protected' => 'true', | |||
'dir' => '/', | |||
'downloadURL' => null | |||
); | |||
$expectedResponse = new TemplateResponse($this->container['AppName'], 'public', $sharedTmplParams, 'base'); | |||
$this->assertEquals($expectedResponse, $response); | |||
} | |||
public function testDownloadShare() { | |||
// Test with a password protected share and no authentication | |||
$response = $this->shareController->downloadShare($this->token); | |||
$expectedResponse = new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate', | |||
array('token' => $this->token))); | |||
$this->assertEquals($expectedResponse, $response); | |||
} | |||
} |
@@ -0,0 +1,76 @@ | |||
<?php | |||
/** | |||
* @author Lukas Reschke <lukas@owncloud.com> | |||
* @copyright 2014 Lukas Reschke | |||
* | |||
* This file is licensed under the Affero General Public License version 3 or | |||
* later. | |||
* See the COPYING-README file. | |||
*/ | |||
namespace OCA\Files_Sharing\Middleware; | |||
/** | |||
* @package OCA\Files_Sharing\Middleware\SharingCheckMiddleware | |||
*/ | |||
class SharingCheckMiddlewareTest extends \PHPUnit_Framework_TestCase { | |||
/** @var \OCP\IAppConfig */ | |||
private $appConfig; | |||
/** @var \OCP\AppFramework\IApi */ | |||
private $api; | |||
/** @var SharingCheckMiddleware */ | |||
private $sharingCheckMiddleware; | |||
protected function setUp() { | |||
$this->appConfig = $this->getMockBuilder('\OCP\IAppConfig') | |||
->disableOriginalConstructor()->getMock(); | |||
$this->api = $this->getMockBuilder('\OCP\AppFramework\IApi') | |||
->disableOriginalConstructor()->getMock(); | |||
$this->sharingCheckMiddleware = new SharingCheckMiddleware('files_sharing', $this->appConfig, $this->api); | |||
} | |||
public function testIsSharingEnabledWithEverythingEnabled() { | |||
$this->api | |||
->expects($this->once()) | |||
->method('isAppEnabled') | |||
->with('files_sharing') | |||
->will($this->returnValue(true)); | |||
$this->appConfig | |||
->expects($this->once()) | |||
->method('getValue') | |||
->with('core', 'shareapi_allow_links', 'yes') | |||
->will($this->returnValue('yes')); | |||
$this->assertTrue(\Test_Helper::invokePrivate($this->sharingCheckMiddleware, 'isSharingEnabled')); | |||
} | |||
public function testIsSharingEnabledWithAppDisabled() { | |||
$this->api | |||
->expects($this->once()) | |||
->method('isAppEnabled') | |||
->with('files_sharing') | |||
->will($this->returnValue(false)); | |||
$this->assertFalse(\Test_Helper::invokePrivate($this->sharingCheckMiddleware, 'isSharingEnabled')); | |||
} | |||
public function testIsSharingEnabledWithSharingDisabled() { | |||
$this->api | |||
->expects($this->once()) | |||
->method('isAppEnabled') | |||
->with('files_sharing') | |||
->will($this->returnValue(true)); | |||
$this->appConfig | |||
->expects($this->once()) | |||
->method('getValue') | |||
->with('core', 'shareapi_allow_links', 'yes') | |||
->will($this->returnValue('no')); | |||
$this->assertFalse(\Test_Helper::invokePrivate($this->sharingCheckMiddleware, 'isSharingEnabled')); | |||
} | |||
} |
@@ -22,6 +22,7 @@ | |||
namespace OCA\Files_Sharing\Tests; | |||
use OC\Files\Filesystem; | |||
use OCA\Files\Share; | |||
/** | |||
@@ -115,6 +116,10 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase { | |||
} else { | |||
\OC_App::disable('files_encryption'); | |||
} | |||
\OC_Util::tearDownFS(); | |||
\OC_User::setUserId(''); | |||
Filesystem::tearDown(); | |||
} | |||
/** |
@@ -95,9 +95,22 @@ $this->create('core_avatar_post_cropped', '/avatar/cropped') | |||
->action('OC\Core\Avatar\Controller', 'postCroppedAvatar'); | |||
// Sharing routes | |||
$this->create('core_share_show_share', '/s/{token}') | |||
->get() | |||
->action('OC\Core\Share\Controller', 'showShare'); | |||
$this->create('files_sharing.sharecontroller.showShare', '/s/{token}')->action(function($urlParams) { | |||
$app = new \OCA\Files_Sharing\Application($urlParams); | |||
$app->dispatch('ShareController', 'showShare'); | |||
}); | |||
$this->create('files_sharing.sharecontroller.authenticate', '/s/{token}/authenticate')->post()->action(function($urlParams) { | |||
$app = new \OCA\Files_Sharing\Application($urlParams); | |||
$app->dispatch('ShareController', 'authenticate'); | |||
}); | |||
$this->create('files_sharing.sharecontroller.showAuthenticate', '/s/{token}/authenticate')->get()->action(function($urlParams) { | |||
$app = new \OCA\Files_Sharing\Application($urlParams); | |||
$app->dispatch('ShareController', 'showAuthenticate'); | |||
}); | |||
$this->create('files_sharing.sharecontroller.downloadShare', '/s/{token}/download')->get()->action(function($urlParams) { | |||
$app = new \OCA\Files_Sharing\Application($urlParams); | |||
$app->dispatch('ShareController', 'downloadShare'); | |||
}); | |||
// used for heartbeat | |||
$this->create('heartbeat', '/heartbeat')->action(function(){ |
@@ -1,23 +0,0 @@ | |||
<?php | |||
/** | |||
* Copyright (c) 2014 Christopher Schäpers <christopher@schaepers.it> | |||
* This file is licensed under the Affero General Public License version 3 or | |||
* later. | |||
* See the COPYING-README file. | |||
*/ | |||
namespace OC\Core\Share; | |||
class Controller { | |||
public static function showShare($args) { | |||
\OC_Util::checkAppEnabled('files_sharing'); | |||
$token = $args['token']; | |||
\OC_App::loadApp('files_sharing'); | |||
\OC_User::setIncognitoMode(true); | |||
require_once \OC_App::getAppPath('files_sharing') .'/public.php'; | |||
} | |||
} | |||
?> |