From fb4e6c0dfe935c71b4c5e85dfa3b5d71d145c83e Mon Sep 17 00:00:00 2001 From: nathangray Date: Fri, 3 Apr 2020 16:20:47 -0600 Subject: [PATCH] Some improvements to sharing when multiple shares are involved --- api/src/Vfs/HiddenUploadSharing.php | 27 ++++++++++++++++---- api/src/Vfs/Sharing.php | 38 ++++++++++++++++++++++++++--- composer.lock | 8 +++--- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/api/src/Vfs/HiddenUploadSharing.php b/api/src/Vfs/HiddenUploadSharing.php index 417474d3a7..75810f5825 100644 --- a/api/src/Vfs/HiddenUploadSharing.php +++ b/api/src/Vfs/HiddenUploadSharing.php @@ -57,16 +57,21 @@ class HiddenUploadSharing extends Sharing */ public static function setup_share($keep_session, &$share) { - // Get these before root is mounted readonly + // Get these before parent is mounted to make sure we get the right path + unset($GLOBALS['egw_info']['server']['vfs_fstab']); // triggers reset of fstab in mount() + $GLOBALS['egw_info']['server']['vfs_fstab'] = Vfs::mount(); + Vfs::clearstatcache(); $resolve_url = Vfs::resolve_url($share['share_path'], true, true, true, true); $upload_dir = Vfs::concat($resolve_url, self::HIDDEN_UPLOAD_DIR); // Parent mounts the root read-only - parent::setup_share($keep_session, $share); + parent::setup_share(true, $share); + + $upload_mount = Vfs::concat($share['share_root'], self::HIDDEN_UPLOAD_DIR); // Mounting upload dir, has original share owner access (write) Vfs::$is_root = true; - if (!Vfs::mount($upload_dir, Vfs::concat($share['share_root'], self::HIDDEN_UPLOAD_DIR), false, false, false)) + if (!Vfs::mount($upload_dir, $upload_mount, false, false, false)) { sleep(1); return static::share_fail( @@ -74,6 +79,7 @@ class HiddenUploadSharing extends Sharing "Requested resource '/" . htmlspecialchars($share['share_token']) . "' does NOT exist!\n" ); } + static::session_mount($upload_mount, $upload_dir); Vfs::$is_root = false; Vfs::clearstatcache(); @@ -192,6 +198,11 @@ class HiddenUploadSharing extends Sharing { return (int)$this->share['share_writable'] == self::HIDDEN_UPLOAD; } + + public function redo() + { + static::setup_share(true, $this->share); + } } if (file_exists(__DIR__.'/../../../filemanager/inc/class.filemanager_ui.inc.php')) @@ -258,6 +269,8 @@ if (file_exists(__DIR__.'/../../../filemanager/inc/class.filemanager_ui.inc.php' protected static function handle_upload_action(string $action, $selected, $dir, $props, &$arr) { Api\Translation::add_app('filemanager'); + $vfs = Vfs::mount(); + $GLOBALS['egw']->sharing->redo(); parent::handle_upload_action($action, $selected, $dir, $props, $arr); $arr['msg'] .= "\n" . lang("The uploaded file is only visible to the person sharing these files with you, not to yourself or other people knowing this sharing link."); $arr['type'] = 'notice'; @@ -266,7 +279,10 @@ if (file_exists(__DIR__.'/../../../filemanager/inc/class.filemanager_ui.inc.php' protected function is_hidden_upload_dir($directory) { if (!isset($GLOBALS['egw']->sharing)) return false; - return Vfs::is_dir($directory) && $directory == Vfs::concat( $GLOBALS['egw']->sharing->get_root(), Sharing::HIDDEN_UPLOAD_DIR ); + // Just hide anything that is 'Upload' mounted where we expect, not just this share, to avoid exposing when + // more than one share is used + $mounts = Vfs::mount(); + return Vfs::is_dir($directory) && '/'.Vfs::basename($directory) == Sharing::HIDDEN_UPLOAD_DIR && $mounts[$directory]; } /** @@ -283,7 +299,8 @@ if (file_exists(__DIR__.'/../../../filemanager/inc/class.filemanager_ui.inc.php' $hidden_upload = (isset($GLOBALS['egw']->sharing) && $GLOBALS['egw']->sharing->has_hidden_upload()); // Not allowed in hidden upload dir - if($hidden_upload && strpos($query['path'], Sharing::HIDDEN_UPLOAD_DIR) === 0) + $check_path = Sharing::HIDDEN_UPLOAD_DIR . (substr($query['path'], -1) == '/' ? '/' : ''); + if(($length = strlen($check_path)) && (substr($query['path'], -$length) === $check_path)) { // only redirect, if it would be to some other location, gives redirect-loop otherwise if ($query['path'] != ($path = static::get_home_dir())) diff --git a/api/src/Vfs/Sharing.php b/api/src/Vfs/Sharing.php index 17e658f6d2..73f3a7d906 100644 --- a/api/src/Vfs/Sharing.php +++ b/api/src/Vfs/Sharing.php @@ -106,10 +106,9 @@ class Sharing extends \EGroupware\Api\Sharing } //_debug_array($share); + $share['share_root'] = '/'.Vfs::basename($share['share_path']); if ($keep_session) // add share to existing session { - $share['share_root'] = '/'.$share['share_token']; - // if current user is not the share owner, we cant just mount share if (Vfs::$user != $share['share_owner']) { @@ -127,7 +126,6 @@ class Sharing extends \EGroupware\Api\Sharing 'collabora' => $GLOBALS['egw_info']['apps']['collabora'] || $apps['collabora'] ); - $share['share_root'] = '/'; Vfs::$user = $share['share_owner']; // Need to re-init stream wrapper, as some of them look at @@ -141,7 +139,8 @@ class Sharing extends \EGroupware\Api\Sharing // mounting share Vfs::$is_root = true; - if (!Vfs::mount($share['resolve_url'], $share['share_root'], false, false, !$keep_session)) + $clear_fstab = !$GLOBALS['egw_info']['user']['account_lid'] || $GLOBALS['egw_info']['user']['account_lid'] == 'anonymous'; + if (!Vfs::mount($share['resolve_url'], $share['share_root'], false, false, $clear_fstab)) { sleep(1); return static::share_fail( @@ -149,12 +148,43 @@ class Sharing extends \EGroupware\Api\Sharing "Requested resource '/".htmlspecialchars($share['share_token'])."' does NOT exist!\n" ); } + + $session_fstab =& Api\Cache::getSession('api', 'fstab'); + if(!$session_fstab) + { + $session_fstab = array(); + } + foreach($session_fstab as $mount => $info) + { + Vfs::mount($info['mount'], $mount, false, false); + } + static::session_mount($share['share_root'], $share['resolve_url']); + + Vfs::$is_root = false; Vfs::clearstatcache(); // clear link-cache and load link registry without permission check to access /apps Api\Link::init_static(true); } + /** + * Just temporary until we get the share streamwrapper in + * @param $target + * @param $mount + */ + protected static function session_mount($target, $mount) + { + $session_fstab =& Api\Cache::getSession('api', 'fstab'); + if(!$session_fstab) + { + $session_fstab = array(); + } + $session_fstab[$target] = array( + 'mount' => $mount, + 'class' => get_called_class() + ); + } + protected function after_login() { // only allow filemanager app (gets overwritten by session::create) diff --git a/composer.lock b/composer.lock index 146c456ba6..816d8f3e23 100644 --- a/composer.lock +++ b/composer.lock @@ -774,12 +774,12 @@ "source": { "type": "git", "url": "https://github.com/EGroupware/collabora.git", - "reference": "547ab7518955c58ef0d637570cd97c47e1b499c2" + "reference": "53fc64d4d7a7b20bdce8c830dcd32880f6599364" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/EGroupware/collabora/zipball/547ab7518955c58ef0d637570cd97c47e1b499c2", - "reference": "547ab7518955c58ef0d637570cd97c47e1b499c2", + "url": "https://api.github.com/repos/EGroupware/collabora/zipball/53fc64d4d7a7b20bdce8c830dcd32880f6599364", + "reference": "53fc64d4d7a7b20bdce8c830dcd32880f6599364", "shasum": "" }, "require": { @@ -806,7 +806,7 @@ ], "description": "EGroupware integration for Collabora Online Office", "homepage": "https://www.egroupware.org/", - "time": "2020-03-30T21:57:55+00:00" + "time": "2020-04-02T16:36:02+00:00" }, { "name": "egroupware/icalendar",