]> source.dussan.org Git - nextcloud-server.git/commitdiff
Refactor file sharing public link handling
authorLukas Reschke <lukas@owncloud.com>
Wed, 15 Oct 2014 09:58:44 +0000 (11:58 +0200)
committerLukas Reschke <lukas@owncloud.com>
Fri, 14 Nov 2014 15:26:59 +0000 (16:26 +0100)
fixes download issue introduced by #10755

Conflicts:
apps/files_sharing/public.php

14 files changed:
apps/files_sharing/appinfo/routes.php
apps/files_sharing/application.php [new file with mode: 0644]
apps/files_sharing/js/public.js
apps/files_sharing/lib/controllers/sharecontroller.php [new file with mode: 0644]
apps/files_sharing/lib/helper.php
apps/files_sharing/lib/middleware/sharingcheckmiddleware.php [new file with mode: 0644]
apps/files_sharing/public.php
apps/files_sharing/templates/authenticate.php
apps/files_sharing/templates/public.php
apps/files_sharing/tests/controller/sharecontroller.php [new file with mode: 0644]
apps/files_sharing/tests/middleware/sharingcheckmiddleware.php [new file with mode: 0644]
apps/files_sharing/tests/testcase.php
core/routes.php
core/share/controller.php [deleted file]

index d58a97e295617953fb8855929920fd57f3f50745..68f33d94995bdec65b735eba7677826a67ace7ff 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 /** @var $this \OCP\Route\IRouter */
 $this->create('core_ajax_public_preview', '/publicpreview')->action(
        function() {
diff --git a/apps/files_sharing/application.php b/apps/files_sharing/application.php
new file mode 100644 (file)
index 0000000..089ed6a
--- /dev/null
@@ -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');
+       }
+
+}
index 52679a7158d09c1ccd722c723f059c5a23198d0d..0627ed6ab54dbcaabf45e7148bd654d9e7fed476 100644 (file)
@@ -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
                });
diff --git a/apps/files_sharing/lib/controllers/sharecontroller.php b/apps/files_sharing/lib/controllers/sharecontroller.php
new file mode 100644 (file)
index 0000000..ec99b93
--- /dev/null
@@ -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;
+       }
+}
index e7ca4fcccd4e25f9e765af3ba561b0b2ffd36f1a..3a2d51cddb7f21b1900ed5b4cc717ef0be4cb162 100644 (file)
@@ -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
diff --git a/apps/files_sharing/lib/middleware/sharingcheckmiddleware.php b/apps/files_sharing/lib/middleware/sharingcheckmiddleware.php
new file mode 100644 (file)
index 0000000..af79cd9
--- /dev/null
@@ -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;
+       }
+
+}
index 4320c105103c48662acf1da234bb1e0821127d19..d9b8f0f4f303b69928467be958839b476d358169 100644 (file)
 <?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)));
index 0c4ac6ca44537975961f459f8d9250ee0834a1ab..e3aa62b9eced716b8ac338be40ecec7b5d4cf255 100644 (file)
@@ -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"
index 46bf90b1b4128e587f0378528ff2248c86334f4c..6b875d3c2b76df0abfce4a8879755853b15ba9fe 100644 (file)
@@ -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'])): ?>
diff --git a/apps/files_sharing/tests/controller/sharecontroller.php b/apps/files_sharing/tests/controller/sharecontroller.php
new file mode 100644 (file)
index 0000000..357184b
--- /dev/null
@@ -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);
+       }
+}
diff --git a/apps/files_sharing/tests/middleware/sharingcheckmiddleware.php b/apps/files_sharing/tests/middleware/sharingcheckmiddleware.php
new file mode 100644 (file)
index 0000000..90c9a7b
--- /dev/null
@@ -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'));
+       }
+}
index 78277dc907f0512adf8696eab37dd1dee626c4cc..034baa785da218e20ac3de9539ed4785f7959365 100644 (file)
@@ -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();
        }
 
        /**
index 92545d0322ee5fa39ba2c72047b4e967c1a6320e..ced70898f501ce973d239aacf40e446b6d7bfdfe 100644 (file)
@@ -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(){
diff --git a/core/share/controller.php b/core/share/controller.php
deleted file mode 100644 (file)
index c1741af..0000000
+++ /dev/null
@@ -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';
-       }
-}
-?>