Change global sharing variable to be a list of shares in use, indexed by token. This should resolve the issues with multiple shares being accessed in the same session.

This commit is contained in:
nathangray 2021-03-11 17:00:16 -07:00
parent ba84d3170d
commit 1ffde3b692
9 changed files with 80 additions and 26 deletions

View File

@ -1381,6 +1381,7 @@ the mail server returned common en The mail server returned
there already is a system-user with this name. user's should not have the same name as a systemuser common en There already is a system user with this name. Please, select another name. there already is a system-user with this name. user's should not have the same name as a systemuser common en There already is a system user with this name. Please, select another name.
they will be sub-folders in users home (%1 attribute). common en They will be sub-folders in users home (%1 attribute). they will be sub-folders in users home (%1 attribute). common en They will be sub-folders in users home (%1 attribute).
this feature is only available in epl version. common en This feature is only available in EPL version. this feature is only available in epl version. common en This feature is only available in EPL version.
this is your own share. to test it, use an anonymous / incognito window.<br/>%1 common en This is your own share. To test it, use an anonymous / incognito window.<br/>%1
this name has been used already common en This name has been used already! this name has been used already common en This name has been used already!
this text gets displayed if the input-field is empty and has no focus (blur) common en Text gets displayed if the input field is empty and has no focus (blur) this text gets displayed if the input-field is empty and has no focus (blur) common en Text gets displayed if the input field is empty and has no focus (blur)
this will reset toolbar preferences for all users and set them to configured default prefs. common en This will reset toolbar preferences for all users and set them to configured default prefs. this will reset toolbar preferences for all users and set them to configured default prefs. common en This will reset toolbar preferences for all users and set them to configured default prefs.

View File

@ -198,7 +198,7 @@ class Sharing
unset($GLOBALS['egw_info']['flags']['autocreate_session_callback']); unset($GLOBALS['egw_info']['flags']['autocreate_session_callback']);
if (isset($GLOBALS['egw']->session) && $GLOBALS['egw']->session->verify() if (isset($GLOBALS['egw']->session) && $GLOBALS['egw']->session->verify()
&& isset($GLOBALS['egw']->sharing) && $GLOBALS['egw']->sharing->share['share_token'] === $token) && isset($GLOBALS['egw']->sharing) && array_key_exists($token, $GLOBALS['egw']->sharing))
{ {
return $GLOBALS['egw']->session->sessionid; return $GLOBALS['egw']->session->sessionid;
} }
@ -277,11 +277,15 @@ class Sharing
), __LINE__, __FILE__); ), __LINE__, __FILE__);
// store sharing object in egw object and therefore in session // store sharing object in egw object and therefore in session
$GLOBALS['egw']->sharing = static::factory($share); if(!isset($GLOBALS['egw']->sharing))
{
$GLOBALS['egw']->sharing = Array();
}
$GLOBALS['egw']->sharing[$share['share_token']] = static::factory($share);
// we have a session we want to keep, but share owner is different from current user and we need filemanager UI, or no session // we have a session we want to keep, but share owner is different from current user and we need filemanager UI, or no session
// --> create a new anon session // --> create a new anon session
if ($keep_session === false && $GLOBALS['egw']->sharing->need_session() || is_null($keep_session)) if ($keep_session === false && $GLOBALS['egw']->sharing[$share['share_token']]->need_session() || is_null($keep_session))
{ {
$sessionid = static::create_new_session(); $sessionid = static::create_new_session();
@ -513,7 +517,7 @@ class Sharing
self::create_session($GLOBALS['egw']->session->session_flags === 'N' && self::create_session($GLOBALS['egw']->session->session_flags === 'N' &&
$GLOBALS['egw_info']['user']['account_lid'] !== 'anonymous'); $GLOBALS['egw_info']['user']['account_lid'] !== 'anonymous');
return $GLOBALS['egw']->sharing->ServeRequest(); return $GLOBALS['egw']->sharing[static::get_token()]->ServeRequest();
} }
/* No extended ACL for readonly shares, disable eacl by setting session cache /* No extended ACL for readonly shares, disable eacl by setting session cache
@ -526,7 +530,6 @@ class Sharing
}*/ }*/
if($this->use_collabora()) if($this->use_collabora())
{ {
unset($GLOBALS['egw']->sharing);
$ui = new \EGroupware\Collabora\Ui(); $ui = new \EGroupware\Collabora\Ui();
return $ui->editor($this->share['share_path']); return $ui->editor($this->share['share_path']);
} }
@ -543,6 +546,12 @@ class Sharing
// WebDAV always looks at the original request for a single file so make sure the file is found at the root // WebDAV always looks at the original request for a single file so make sure the file is found at the root
Vfs::$is_root = true; Vfs::$is_root = true;
unset($GLOBALS['egw_info']['server']['vfs_fstab']); unset($GLOBALS['egw_info']['server']['vfs_fstab']);
// Make SURE resolve_url is set, otherwise webdav will give full access to /
if(!$this->share['resolve_url'])
{
$this->share['resolve_url'] = Vfs::resolve_url($this->share['share_path'], true, true, true, true);
}
Vfs::mount($this->share['resolve_url'], '/', false, false, true); Vfs::mount($this->share['resolve_url'], '/', false, false, true);
Vfs::clearstatcache(); Vfs::clearstatcache();

View File

@ -125,6 +125,11 @@ class History
{ {
if ($new_value != $old_value) if ($new_value != $old_value)
{ {
$share_with = '';
foreach(isset($GLOBALS['egw']->sharing) ? $GLOBALS['egw']->sharing : [] as $token => $share_obj)
{
$share_with .= $share_obj->get_share_with();
}
$this->db->insert(self::TABLE,array( $this->db->insert(self::TABLE,array(
'history_record_id' => $record_id, 'history_record_id' => $record_id,
'history_appname' => $this->appname, 'history_appname' => $this->appname,
@ -134,7 +139,7 @@ class History
'history_old_value' => $old_value, 'history_old_value' => $old_value,
'history_timestamp' => time(), 'history_timestamp' => time(),
'sessionid' => $GLOBALS['egw']->session->sessionid_access_log, 'sessionid' => $GLOBALS['egw']->session->sessionid_access_log,
'share_email' => isset($GLOBALS['egw']->sharing) ? $GLOBALS['egw']->sharing->get_share_with() : '', 'share_email' => $share_with,
),false,__LINE__,__FILE__); ),false,__LINE__,__FILE__);
} }
} }
@ -146,6 +151,11 @@ class History
{ {
if ($new_value != $old_value) if ($new_value != $old_value)
{ {
$share_with = '';
foreach(isset($GLOBALS['egw']->sharing) ? $GLOBALS['egw']->sharing : [] as $token => $share_obj)
{
$share_with .= $share_obj->get_share_with();
}
$GLOBALS['egw']->db->insert(self::TABLE,array( $GLOBALS['egw']->db->insert(self::TABLE,array(
'history_record_id' => $id, 'history_record_id' => $id,
'history_appname' => $appname, 'history_appname' => $appname,
@ -155,7 +165,7 @@ class History
'history_old_value' => $old_value, 'history_old_value' => $old_value,
'history_timestamp' => time(), 'history_timestamp' => time(),
'sessionid' => $GLOBALS['egw']->session->sessionid_access_log, 'sessionid' => $GLOBALS['egw']->session->sessionid_access_log,
'share_email' => isset($GLOBALS['egw']->sharing) ? $GLOBALS['egw']->sharing->get_share_with() : '', 'share_email' => $share_with,
),false,__LINE__,__FILE__); ),false,__LINE__,__FILE__);
} }
} }

View File

@ -14,6 +14,7 @@
namespace EGroupware\Api\Vfs; namespace EGroupware\Api\Vfs;
use EGroupware\Api; use EGroupware\Api;
use EGroupware\Api\Json\Response;
use EGroupware\Api\Vfs; use EGroupware\Api\Vfs;
use EGroupware\Filemanager\Sharing\AnonymousList; use EGroupware\Filemanager\Sharing\AnonymousList;
use EGroupware\Filemanager\Sharing\Ui; use EGroupware\Filemanager\Sharing\Ui;
@ -233,15 +234,39 @@ class Sharing extends \EGroupware\Api\Sharing
*/ */
public function get_ui() public function get_ui()
{ {
// Ask about the share, if the user is not anonymous.
// * Link has already been opened in a new tab by this point * // * Link has already been opened in a new tab by this point *
if($GLOBALS['egw_info']['user']['account_lid'] !== 'anonymous' && $GLOBALS['egw_info']['user']['account_id'] !== $this->share['owner'])
// User testing their own share?
if($GLOBALS['egw_info']['user']['account_id'] == $this->share['share_owner'])
{
Api\Framework::message(lang(
"This is your own share. To test it, use an anonymous / incognito window.\n%1",
'<a href="'.$_SERVER['REQUEST_URI'].'">' . $this->share['share_root'] . '</a>'
),'info');
}
// Opened within EGroupware. Ask about the share, if the user is not anonymous.
if($GLOBALS['egw_info']['user']['account_lid'] !== 'anonymous' && $GLOBALS['egw_info']['user']['account_id'] != $this->share['share_owner'])
{ {
// Check to see if this is already permanent mounted share // Check to see if this is already permanent mounted share
$mount_target = Vfs\Sharing\StreamWrapper::share2url($this->share); $mount_target = Vfs\Sharing\StreamWrapper::share2url($this->share);
// Logged in user opening someone else's share, but they've opened the URL in its own tab
if (!Response::isJSONResponse())
{
Api\Framework::message(lang(
"Share mounted. To test it, use an anonymous / incognito window.\n%1",
'<a href="'.$_SERVER['REQUEST_URI'].'">' . $this->share['share_root'] . '</a>'
),'info');
Api\Framework::redirect(Api\Framework::link('/index.php',[
'menuaction' => 'filemanager.EGroupware\\Filemanager\\Sharing\\Ui.share_received',
'token' => $this->share['share_token']
]));
}
if(($mounted = array_search($mount_target,$GLOBALS['egw_info']['user']['preferences']['common']['vfs_fstab']))) if(($mounted = array_search($mount_target,$GLOBALS['egw_info']['user']['preferences']['common']['vfs_fstab'])))
{ {
Api\Json\Response::get()->apply('window.opener.egw.open_link',[ Response::get()->apply('window.opener.egw.open_link',[
Api\Framework::link('/index.php',[ Api\Framework::link('/index.php',[
'menuaction' => 'filemanager.filemanager_ui.index', 'menuaction' => 'filemanager.filemanager_ui.index',
'path' => $mounted 'path' => $mounted
@ -251,7 +276,7 @@ class Sharing extends \EGroupware\Api\Sharing
else else
{ {
// New share, ask about it // New share, ask about it
Api\Json\Response::get()->apply('window.opener.egw.open_link',[ Response::get()->apply('window.opener.egw.open_link',[
Api\Framework::link('/index.php',[ Api\Framework::link('/index.php',[
'menuaction' => 'filemanager.EGroupware\\Filemanager\\Sharing\\Ui.share_received', 'menuaction' => 'filemanager.EGroupware\\Filemanager\\Sharing\\Ui.share_received',
'token' => $this->share['share_token'] 'token' => $this->share['share_token']
@ -259,7 +284,7 @@ class Sharing extends \EGroupware\Api\Sharing
]); ]);
} }
Api\Json\Response::get()->apply('window.close'); Response::get()->apply('window.close');
// Still need to load the list after though, since loading it processes what we just added // Still need to load the list after though, since loading it processes what we just added
$ui = new \filemanager_ui(); $ui = new \filemanager_ui();
return $ui->index(); return $ui->index();
@ -403,12 +428,14 @@ class Sharing extends \EGroupware\Api\Sharing
if (($exists = ($stat = Vfs::stat($path)) && Vfs::check_access($path, Vfs::READABLE, $stat))) if (($exists = ($stat = Vfs::stat($path)) && Vfs::check_access($path, Vfs::READABLE, $stat)))
{ {
// Make sure we get the correct path if sharing from a share // Not sure why stat puts a / on the end of files, but remove it
if(isset($GLOBALS['egw']->sharing) && $exists) if(substr($stat['url'],-1) == '/' && !Vfs::is_dir($stat['url']))
{
$stat['url'] = substr($stat['url'],0,strlen($stat['url'])-1);
}
// Make sure we get the correct path if sharing from a share
if(isset($GLOBALS['egw']->sharing) && array_key_exists(static::get_token(), $GLOBALS['egw']->sharing) && $exists)
{ {
/* Why not use $stat['url']
$resolved_stat = Vfs::parse_url($stat['url']);
$path = 'vfs://default'. $resolved_stat['path'];*/
$path = $stat['url']; $path = $stat['url'];
} }
} }

View File

@ -259,6 +259,7 @@ setting for document merge saved. filemanager en Setting for document merge save
share files filemanager en Share files share files filemanager en Share files
share link copied into clipboard filemanager en Share link copied into clipboard share link copied into clipboard filemanager en Share link copied into clipboard
shared files filemanager en Shared files shared files filemanager en Shared files
share mounted at %1.<br/>please close this tab. filemanager en Share mounted at %1.<br/>Please close this tab.
shared with filemanager en Shared with shared with filemanager en Shared with
show filemanager en Show show filemanager en Show
show hidden files filemanager en Show hidden files show hidden files filemanager en Show hidden files

View File

@ -65,9 +65,9 @@ class AnonymousList extends filemanager_ui
*/ */
static function get_home_dir() static function get_home_dir()
{ {
if(isset($GLOBALS['egw']->sharing)) if(isset($GLOBALS['egw']->sharing) && array_key_exists(Vfs\Sharing::get_token(), $GLOBALS['egw']->sharing))
{ {
return $GLOBALS['egw']->sharing->get_root(); return $GLOBALS['egw']->sharing[Vfs\Sharing::get_token()]->get_root();
} }
return '/'; return '/';
} }
@ -83,7 +83,8 @@ class AnonymousList extends filemanager_ui
$group = 1; $group = 1;
// do not add edit setting action when we are in sharing // do not add edit setting action when we are in sharing
unset($actions['edit']); unset($actions['edit']);
if (isset($GLOBALS['egw']->sharing) && Vfs::is_writable($GLOBALS['egw']->sharing->get_root())) if (isset($GLOBALS['egw']->sharing) && array_key_exists(Vfs\Sharing::get_token(), $GLOBALS['egw']->sharing) &&
Vfs::is_writable($GLOBALS['egw']->sharing[Vfs\Sharing::get_token()]->get_root()))
{ {
return $actions; return $actions;
} }

View File

@ -37,7 +37,8 @@ class HiddenUpload extends AnonymousList
{ {
$this->etemplate = $this->etemplate ? $this->etemplate : new Etemplate(static::LIST_TEMPLATE); $this->etemplate = $this->etemplate ? $this->etemplate : new Etemplate(static::LIST_TEMPLATE);
if (isset($GLOBALS['egw']->sharing) && $GLOBALS['egw']->sharing->has_hidden_upload()) if (isset($GLOBALS['egw']->sharing) && array_key_exists(Vfs\Sharing::get_token(), $GLOBALS['egw']->sharing) &&
$GLOBALS['egw']->sharing[Vfs\Sharing::get_token()]->has_hidden_upload())
{ {
// Tell client side that the path is actually writable // Tell client side that the path is actually writable
$content['initial_path_readonly'] = false; $content['initial_path_readonly'] = false;
@ -71,7 +72,7 @@ class HiddenUpload extends AnonymousList
{ {
Translation::add_app('filemanager'); Translation::add_app('filemanager');
$vfs = Vfs::mount(); $vfs = Vfs::mount();
$GLOBALS['egw']->sharing->redo(); $GLOBALS['egw']->sharing[Sharing::get_token()]->redo();
parent::handle_upload_action($action, $selected, $dir, $props, $arr); 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['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'; $arr['type'] = 'notice';
@ -97,7 +98,8 @@ class HiddenUpload extends AnonymousList
*/ */
function get_rows(&$query, &$rows) function get_rows(&$query, &$rows)
{ {
$hidden_upload = (isset($GLOBALS['egw']->sharing) && $GLOBALS['egw']->sharing->has_hidden_upload()); $hidden_upload = (isset($GLOBALS['egw']->sharing) && array_key_exists(Vfs\Sharing::get_token(), $GLOBALS['egw']->sharing) &&
$GLOBALS['egw']->sharing[Sharing::get_token()]->has_hidden_upload());
// Not allowed in hidden upload dir // Not allowed in hidden upload dir
$check_path = Sharing::HIDDEN_UPLOAD_DIR . (substr($query['path'], -1) == '/' ? '/' : ''); $check_path = Sharing::HIDDEN_UPLOAD_DIR . (substr($query['path'], -1) == '/' ? '/' : '');

View File

@ -63,7 +63,7 @@ class Ui
$preserve = $content; $preserve = $content;
$preserve['url'] = Vfs\Sharing\StreamWrapper::share2url($share); $preserve['url'] = Vfs\Sharing\StreamWrapper::share2url($share);
$template->exec('filemanager.'.__CLASS__.'.'.__FUNCTION__, $content, $sel_options, $readonlys, $preserve); $template->exec('filemanager.'.__CLASS__.'.'.__FUNCTION__, $content, $sel_options, $readonlys, $preserve,2);
} }
/** /**
@ -100,6 +100,9 @@ class Ui
'path' => $content['share_root'] 'path' => $content['share_root']
]), 'filemanager',false,'filemanager' ]), 'filemanager',false,'filemanager'
]); ]);
// This should only be seen if they pasted the link into a new tab since we can't close the tab in that case
Framework::message(lang("Share mounted at %1.<br/>Please close this tab.", $content['share_root']),"info");
Api\Framework::window_close(); Api\Framework::window_close();
} }
} }

View File

@ -27,8 +27,8 @@ $GLOBALS['egw_info'] = array(
include('./header.inc.php'); include('./header.inc.php');
if (!isset($GLOBALS['egw']->sharing) || \EGroupware\Api\Sharing::get_token() !== $GLOBALS['egw']->sharing->get_token()) if (!isset($GLOBALS['egw']->sharing) || !array_key_exists(Sharing::get_token(), $GLOBALS['egw']->sharing))
{ {
Sharing::create_session(true); // true = mount into existing session Sharing::create_session(true); // true = mount into existing session
} }
$GLOBALS['egw']->sharing->ServeRequest(); $GLOBALS['egw']->sharing[Sharing::get_token()]->ServeRequest();