Browse Source
Refactor file sharing public link handling
Refactor file sharing public link handling
fixes download issue introduced by #10755 Conflicts: apps/files_sharing/public.phpremotes/origin/fix-10825
14 changed files with 748 additions and 245 deletions
-
1apps/files_sharing/appinfo/routes.php
-
73apps/files_sharing/application.php
-
15apps/files_sharing/js/public.js
-
271apps/files_sharing/lib/controllers/sharecontroller.php
-
2apps/files_sharing/lib/helper.php
-
84apps/files_sharing/lib/middleware/sharingcheckmiddleware.php
-
220apps/files_sharing/public.php
-
8apps/files_sharing/templates/authenticate.php
-
26apps/files_sharing/templates/public.php
-
170apps/files_sharing/tests/controller/sharecontroller.php
-
76apps/files_sharing/tests/middleware/sharingcheckmiddleware.php
-
5apps/files_sharing/tests/testcase.php
-
19core/routes.php
-
23core/share/controller.php
@ -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'); |
|||
} |
|||
|
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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))); |
@ -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')); |
|||
} |
|||
} |
@ -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'; |
|||
} |
|||
} |
|||
?>
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue