mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-26 00:29:18 +01:00
WIP on sharing prompt to ask about mounting new share
This commit is contained in:
parent
7c9e1c98ec
commit
5bf4d4866f
@ -334,7 +334,7 @@
|
||||
et2.load(data.name,data.url,data.data);
|
||||
if (typeof data.response != 'undefined')
|
||||
{
|
||||
var json_request = egw(window).json();
|
||||
var json_request = egw(window).json("");
|
||||
json_request.handleResponse({response: data.response});
|
||||
}
|
||||
});
|
||||
|
@ -180,6 +180,14 @@ class Base
|
||||
}
|
||||
unset(self::$fstab[$path], $GLOBALS['egw_info']['server']['vfs_fstab'][$path]);
|
||||
Config::save_value('vfs_fstab', $GLOBALS['egw_info']['server']['vfs_fstab'],'phpgwapi');
|
||||
|
||||
unset($GLOBALS['egw_info']['user']['preferences']['common']['vfs_fstab'][$path]);
|
||||
unset($_SESSION[Api\Session::EGW_INFO_CACHE]['user']['preferences']['common']['vfs_fstab'][$path]);
|
||||
$prefs = new Api\Preferences();
|
||||
$prefs->read_repository();
|
||||
unset($prefs->user['common']['vfs_fstab'][$path]);
|
||||
$prefs->save_repository();
|
||||
|
||||
// invalidate session cache
|
||||
if (method_exists($GLOBALS['egw'],'invalidate_session_cache')) // egw object in setup is limited
|
||||
{
|
||||
|
@ -14,6 +14,7 @@ namespace EGroupware\Api\Vfs;
|
||||
|
||||
use EGroupware\Api;
|
||||
use EGroupware\Api\Vfs;
|
||||
use EGroupware\Filemanager\Sharing\HiddenUpload;
|
||||
|
||||
/**
|
||||
* VFS sharing for a folder, but always read-only. A /Upload directory is used to receive uploads without allowing any
|
||||
@ -187,7 +188,7 @@ class HiddenUploadSharing extends Sharing
|
||||
$GLOBALS['egw_info']['flags']['currentapp'] = 'filemanager';
|
||||
Api\Framework::includeCSS('filemanager', 'sharing');
|
||||
|
||||
$ui = new UploadSharingUi();
|
||||
$ui = new HiddenUpload();
|
||||
$ui->index();
|
||||
}
|
||||
|
||||
@ -203,139 +204,4 @@ class HiddenUploadSharing extends Sharing
|
||||
{
|
||||
static::setup_share(true, $this->share);
|
||||
}
|
||||
}
|
||||
|
||||
if (file_exists(__DIR__.'/../../../filemanager/inc/class.filemanager_ui.inc.php'))
|
||||
{
|
||||
require_once __DIR__.'/../../../filemanager/inc/class.filemanager_ui.inc.php';
|
||||
|
||||
class UploadSharingUi extends SharingUi
|
||||
{
|
||||
|
||||
/**
|
||||
* Get active view - override so it points to this class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_view()
|
||||
{
|
||||
return array(new UploadSharingUi(), 'listview');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filemanager listview
|
||||
*
|
||||
* Override to customize for sharing with a hidden upload directory.
|
||||
* Everything not in the upload directory is readonly, but we make it look like you can upload.
|
||||
* The upload directory is not shown.
|
||||
*
|
||||
* @param array $content
|
||||
* @param string $msg
|
||||
*/
|
||||
function listview(array $content=null,$msg=null)
|
||||
{
|
||||
$this->etemplate = $this->etemplate ? $this->etemplate : new Api\Etemplate(static::LIST_TEMPLATE);
|
||||
|
||||
if (isset($GLOBALS['egw']->sharing) && $GLOBALS['egw']->sharing->has_hidden_upload())
|
||||
{
|
||||
// Tell client side that the path is actually writable
|
||||
$content['initial_path_readonly'] = false;
|
||||
|
||||
// No new anything
|
||||
$this->etemplate->disableElement('nm[new]');
|
||||
$this->etemplate->setElementAttribute('nm[button][createdir]', 'readonly', true);
|
||||
|
||||
// Take over upload, change target and conflict strategy
|
||||
$path = Vfs::concat(self::get_home_dir(), Sharing::HIDDEN_UPLOAD_DIR);
|
||||
$target = str_replace('\\', '\\\\', __CLASS__);
|
||||
$this->etemplate->setElementAttribute('nm[upload]', 'onFinishOne', "app.filemanager.upload(ev, 1, '$path', 'rename', '{$target}::ajax_action')");
|
||||
}
|
||||
|
||||
return parent::listview($content, $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deal with an uploaded file.
|
||||
* Overridden from the parent to change the message and message type
|
||||
*
|
||||
* @param string $action Should be 'upload'
|
||||
* @param $selected Array of file information
|
||||
* @param string $dir Target directory
|
||||
* @param $props
|
||||
* @param string[] $arr Result
|
||||
*
|
||||
* @throws Api\Exception\AssertionFailed
|
||||
*/
|
||||
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';
|
||||
}
|
||||
|
||||
protected function is_hidden_upload_dir($directory)
|
||||
{
|
||||
if (!isset($GLOBALS['egw']->sharing)) return false;
|
||||
// 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];
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to fetch the rows for the nextmatch widget
|
||||
*
|
||||
* @param array $query
|
||||
* @param array &$rows
|
||||
* @return int
|
||||
*
|
||||
* @throws Api\Json\Exception
|
||||
*/
|
||||
function get_rows(&$query, &$rows)
|
||||
{
|
||||
$hidden_upload = (isset($GLOBALS['egw']->sharing) && $GLOBALS['egw']->sharing->has_hidden_upload());
|
||||
|
||||
// Not allowed in hidden upload dir
|
||||
$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()))
|
||||
{
|
||||
// we will leave here, since we are not allowed, go back to root
|
||||
// TODO: Give message about it, redirect to home dir
|
||||
}
|
||||
$rows = array();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get file list from parent
|
||||
$total = parent::get_rows($query, $rows);
|
||||
|
||||
if(! $hidden_upload )
|
||||
{
|
||||
return $total;
|
||||
}
|
||||
|
||||
// tell client-side that this directory is writeable - allows upload + button
|
||||
$response = Api\Json\Response::get();
|
||||
$response->call('app.filemanager.set_readonly', $query['path'], false);
|
||||
|
||||
// Hide the hidden upload directory, mark everything else as readonly
|
||||
foreach($rows as $key => &$row)
|
||||
{
|
||||
if($this->is_hidden_upload_dir($row['path']))
|
||||
{
|
||||
unset($rows[$key]);
|
||||
$total--;
|
||||
continue;
|
||||
}
|
||||
$row['class'] .= 'noEdit noDelete ';
|
||||
}
|
||||
return $total;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,8 +15,9 @@ namespace EGroupware\Api\Vfs;
|
||||
|
||||
use EGroupware\Api;
|
||||
use EGroupware\Api\Vfs;
|
||||
use EGroupware\Collabora\Wopi;
|
||||
use filemanager_ui;
|
||||
use EGroupware\Filemanager\Sharing\AnonymousList;
|
||||
use EGroupware\Filemanager\Sharing\Ui;
|
||||
use EGroupware\Filemanager\Sharing\Ui as ShareUi;
|
||||
|
||||
/**
|
||||
* VFS sharing
|
||||
@ -119,7 +120,7 @@ class Sharing extends \EGroupware\Api\Sharing
|
||||
// ToDo: handle there's already something there with that name (incl. maybe the same share!)
|
||||
|
||||
Vfs::$is_root = true;
|
||||
if (!Vfs::mount(Vfs\Sharing\StreamWrapper::share2url($share), $share['share_root'], false, false, $clear_fstab))
|
||||
if (!Vfs::mount(Vfs\Sharing\StreamWrapper::share2url($share), $share['share_root'], false, false, false))
|
||||
{
|
||||
sleep(1);
|
||||
return static::share_fail(
|
||||
@ -129,8 +130,7 @@ class Sharing extends \EGroupware\Api\Sharing
|
||||
}
|
||||
Vfs::$is_root = false;
|
||||
|
||||
Api\Framework::message(lang('Share has been mounted into you shares directory').': '.$share['share_root'], 'success');
|
||||
// ToDo: ask user if he want's the share permanently mounted
|
||||
// get_ui() will ask user if he wants the share permanently mounted
|
||||
return;
|
||||
}
|
||||
|
||||
@ -233,6 +233,38 @@ class Sharing extends \EGroupware\Api\Sharing
|
||||
*/
|
||||
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 *
|
||||
if($GLOBALS['egw_info']['user']['account_lid'] !== 'anonymous' && $GLOBALS['egw_info']['user']['account_id'] !== $this->share['owner'])
|
||||
{
|
||||
// Check to see if this is already permanent mounted share
|
||||
$mount_target = Vfs\Sharing\StreamWrapper::share2url($this->share);
|
||||
if(($mounted = array_search($mount_target,$GLOBALS['egw_info']['user']['preferences']['common']['vfs_fstab'])))
|
||||
{
|
||||
Api\Json\Response::get()->apply('window.opener.egw.open_link',[
|
||||
Api\Framework::link('/index.php',[
|
||||
'menuaction' => 'filemanager.filemanager_ui.index',
|
||||
'path' => $mounted
|
||||
]),'filemanager',false,'filemanager'
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// New share, ask about it
|
||||
Api\Json\Response::get()->apply('window.opener.egw.open_link',[
|
||||
Api\Framework::link('/index.php',[
|
||||
'menuaction' => 'filemanager.EGroupware\\Filemanager\\Sharing\\Ui.share_received',
|
||||
'token' => $this->share['share_token']
|
||||
]),'filemanager','600x150','filemanager'
|
||||
]);
|
||||
}
|
||||
|
||||
Api\Json\Response::get()->apply('window.close');
|
||||
// Still need to load the list after though, since loading it processes what we just added
|
||||
$ui = new \filemanager_ui();
|
||||
return $ui->index();
|
||||
}
|
||||
|
||||
// run full eTemplate2 UI for directories
|
||||
$_GET['path'] = $this->share['share_root'];
|
||||
$GLOBALS['egw_info']['user']['preferences']['filemanager']['nm_view'] = 'tile';
|
||||
@ -240,7 +272,7 @@ class Sharing extends \EGroupware\Api\Sharing
|
||||
$GLOBALS['egw_info']['flags']['js_link_registry'] = true;
|
||||
$GLOBALS['egw_info']['flags']['currentapp'] = 'filemanager';
|
||||
Api\Framework::includeCSS('filemanager', 'sharing');
|
||||
$ui = new SharingUi();
|
||||
$ui = new AnonymousList();
|
||||
$ui->index();
|
||||
}
|
||||
|
||||
@ -546,134 +578,4 @@ class Sharing extends \EGroupware\Api\Sharing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (file_exists(__DIR__.'/../../../filemanager/inc/class.filemanager_ui.inc.php'))
|
||||
{
|
||||
require_once __DIR__.'/../../../filemanager/inc/class.filemanager_ui.inc.php';
|
||||
|
||||
class SharingUi extends filemanager_ui
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Reimplemented to load filemanager translations
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
Api\Translation::add_app('filemanager');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active view - override so it points to this class
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function get_view()
|
||||
{
|
||||
return array(new SharingUi(), 'listview');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filemanager listview
|
||||
*
|
||||
* @param array $content
|
||||
* @param string $msg
|
||||
*/
|
||||
function listview(array $content=null,$msg=null)
|
||||
{
|
||||
$this->etemplate = $this->etemplate ? $this->etemplate : new Api\Etemplate(static::LIST_TEMPLATE);
|
||||
|
||||
// Override and take over get_rows so we can customize
|
||||
$content['nm']['get_rows'] = '.' . get_class($this) . '.get_rows';
|
||||
|
||||
return parent::listview($content, $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configured start directory for the current user
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static function get_home_dir()
|
||||
{
|
||||
return $GLOBALS['egw']->sharing->get_root();
|
||||
}
|
||||
|
||||
/**
|
||||
* Context menu
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_actions()
|
||||
{
|
||||
$actions = parent::get_actions();
|
||||
$group = 1;
|
||||
// do not add edit setting action when we are in sharing
|
||||
unset($actions['edit']);
|
||||
if (Vfs::is_writable($GLOBALS['egw']->sharing->get_root()))
|
||||
{
|
||||
return $actions;
|
||||
}
|
||||
$actions+= array(
|
||||
'egw_copy' => array(
|
||||
'enabled' => false,
|
||||
'group' => $group + 0.5,
|
||||
'hideOnDisabled' => true
|
||||
),
|
||||
'egw_copy_add' => array(
|
||||
'enabled' => false,
|
||||
'group' => $group + 0.5,
|
||||
'hideOnDisabled' => true
|
||||
),
|
||||
'paste' => array(
|
||||
'enabled' => false,
|
||||
'group' => $group + 0.5,
|
||||
'hideOnDisabled' => true
|
||||
),
|
||||
);
|
||||
return $actions;
|
||||
}
|
||||
|
||||
protected function get_vfs_options($query)
|
||||
{
|
||||
$options = parent::get_vfs_options($query);
|
||||
|
||||
// Hide symlinks
|
||||
// TODO: This hides everything, see Vfs::_check_add() line 648
|
||||
//$options['type'] = '!l';
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to fetch the rows for the nextmatch widget
|
||||
*
|
||||
* @param array $query
|
||||
* @param array &$rows
|
||||
* @return int
|
||||
*/
|
||||
function get_rows(&$query, &$rows)
|
||||
{
|
||||
// Check for navigating outside share, redirect back to share
|
||||
if (!empty($query['path']) && (!Vfs::stat($query['path'],false) || !Vfs::is_dir($query['path']) || !Vfs::check_access($query['path'],Vfs::READABLE)))
|
||||
{
|
||||
// only redirect, if it would be to some other location, gives redirect-loop otherwise
|
||||
if ($query['path'] != ($path = static::get_home_dir()))
|
||||
{
|
||||
// we will leave here, since we are not allowed, go back to root
|
||||
// TODO: Give message about it, redirect to home dir
|
||||
}
|
||||
$rows = array();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get file list from parent
|
||||
$total = parent::get_rows($query, $rows);
|
||||
|
||||
return $total;
|
||||
}
|
||||
}
|
||||
}
|
@ -842,7 +842,17 @@ class filemanager_ui
|
||||
// feeding the links to dirs to Vfs::find() deletes the content of the dirs, not just the link!
|
||||
foreach($selected as $key => $path)
|
||||
{
|
||||
if (!Vfs::is_dir($path) || Vfs::is_link($path))
|
||||
if (Vfs::is_dir($path) && $GLOBALS['egw_info']['user']['preferences']['common']['vfs_fstab'][$path])
|
||||
{
|
||||
// Trying to delete a share. Unmount.
|
||||
$root = Vfs::$is_root;
|
||||
Vfs::$is_root = true;
|
||||
Vfs::umount($path);
|
||||
Vfs::$is_root = $root;
|
||||
++$dirs;
|
||||
unset($selected[$key]);
|
||||
}
|
||||
else if (!Vfs::is_dir($path) || Vfs::is_link($path))
|
||||
{
|
||||
if (Vfs::unlink($path))
|
||||
{
|
||||
@ -1705,4 +1715,24 @@ class filemanager_ui
|
||||
}
|
||||
return $mode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* User just got a new share. Ask the questions, let them customize
|
||||
*
|
||||
* @param array $content
|
||||
*/
|
||||
public function share_received($content = array())
|
||||
{
|
||||
// Deal with returning data & changes
|
||||
|
||||
// Read info for display
|
||||
$content['mount_location'] = $content['share_path'];
|
||||
$sel_options = array();
|
||||
$readonlys = array();
|
||||
$preserve = $content;
|
||||
$template = new Api\Etemplate("api.file_share_received");
|
||||
|
||||
$template->exec(__CLASS__ . '::' . __METHOD__, $content, $sel_options, $readonlys, $preserve, 2);
|
||||
}
|
||||
}
|
||||
|
144
filemanager/src/Sharing/AnonymousList.php
Normal file
144
filemanager/src/Sharing/AnonymousList.php
Normal file
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
* EGroupware - Filemanager - UI for sharing with anonymous user
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @package filemanager
|
||||
* @author Nathan Gray
|
||||
* @copyright (c) 2020 Nathan Gray
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
*/
|
||||
namespace EGroupware\Filemanager\Sharing;
|
||||
|
||||
use \filemanager_ui;
|
||||
use EGroupware\Api;
|
||||
use EGroupware\Api\Vfs;
|
||||
|
||||
/**
|
||||
* This is the file list for an anonymous user.
|
||||
* Logged in users may also end up here, but they will normally just use filemanager_ui
|
||||
*/
|
||||
class AnonymousList extends filemanager_ui
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Reimplemented to load filemanager translations
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
Api\Translation::add_app('filemanager');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active view - override so it points to this class
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function get_view()
|
||||
{
|
||||
return array(new AnonymousList(), 'listview');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filemanager listview
|
||||
*
|
||||
* @param array $content
|
||||
* @param string $msg
|
||||
*/
|
||||
function listview(array $content = null, $msg = null)
|
||||
{
|
||||
$this->etemplate = $this->etemplate ? $this->etemplate : new Api\Etemplate(static::LIST_TEMPLATE);
|
||||
|
||||
// Override and take over get_rows so we can customize
|
||||
$content['nm']['get_rows'] = '.' . get_class($this) . '.get_rows';
|
||||
|
||||
return parent::listview($content, $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configured start directory for the current user
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static function get_home_dir()
|
||||
{
|
||||
return $GLOBALS['egw']->sharing->get_root();
|
||||
}
|
||||
|
||||
/**
|
||||
* Context menu
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_actions()
|
||||
{
|
||||
$actions = parent::get_actions();
|
||||
$group = 1;
|
||||
// do not add edit setting action when we are in sharing
|
||||
unset($actions['edit']);
|
||||
if (Vfs::is_writable($GLOBALS['egw']->sharing->get_root()))
|
||||
{
|
||||
return $actions;
|
||||
}
|
||||
$actions += array(
|
||||
'egw_copy' => array(
|
||||
'enabled' => false,
|
||||
'group' => $group + 0.5,
|
||||
'hideOnDisabled' => true
|
||||
),
|
||||
'egw_copy_add' => array(
|
||||
'enabled' => false,
|
||||
'group' => $group + 0.5,
|
||||
'hideOnDisabled' => true
|
||||
),
|
||||
'paste' => array(
|
||||
'enabled' => false,
|
||||
'group' => $group + 0.5,
|
||||
'hideOnDisabled' => true
|
||||
),
|
||||
);
|
||||
return $actions;
|
||||
}
|
||||
|
||||
protected function get_vfs_options($query)
|
||||
{
|
||||
$options = parent::get_vfs_options($query);
|
||||
|
||||
// Hide symlinks
|
||||
// TODO: This hides everything, see Vfs::_check_add() line 648
|
||||
//$options['type'] = '!l';
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to fetch the rows for the nextmatch widget
|
||||
*
|
||||
* @param array $query
|
||||
* @param array &$rows
|
||||
* @return int
|
||||
*/
|
||||
function get_rows(&$query, &$rows)
|
||||
{
|
||||
// Check for navigating outside share, redirect back to share
|
||||
if (!empty($query['path']) && (!Vfs::stat($query['path'], false) || !Vfs::is_dir($query['path']) || !Vfs::check_access($query['path'], Vfs::READABLE)))
|
||||
{
|
||||
// only redirect, if it would be to some other location, gives redirect-loop otherwise
|
||||
if ($query['path'] != ($path = static::get_home_dir()))
|
||||
{
|
||||
// we will leave here, since we are not allowed, go back to root
|
||||
// TODO: Give message about it, redirect to home dir
|
||||
}
|
||||
$rows = array();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get file list from parent
|
||||
$total = parent::get_rows($query, $rows);
|
||||
|
||||
return $total;
|
||||
}
|
||||
}
|
139
filemanager/src/Sharing/HiddenUpload.php
Normal file
139
filemanager/src/Sharing/HiddenUpload.php
Normal file
@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace EGroupware\Filemanager\Sharing;
|
||||
|
||||
|
||||
use EGroupware\Api\Vfs;
|
||||
use EGroupware\Api\Vfs\Sharing;
|
||||
use EGroupware\Api\Vfs\UploadSharingUi;
|
||||
|
||||
class HiddenUpload extends AnonymousList
|
||||
{
|
||||
|
||||
/**
|
||||
* Get active view - override so it points to this class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_view()
|
||||
{
|
||||
return array(new HiddenUpload(), 'listview');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filemanager listview
|
||||
*
|
||||
* Override to customize for sharing with a hidden upload directory.
|
||||
* Everything not in the upload directory is readonly, but we make it look like you can upload.
|
||||
* The upload directory is not shown.
|
||||
*
|
||||
* @param array $content
|
||||
* @param string $msg
|
||||
*/
|
||||
function listview(array $content=null,$msg=null)
|
||||
{
|
||||
$this->etemplate = $this->etemplate ? $this->etemplate : new Api\Etemplate(static::LIST_TEMPLATE);
|
||||
|
||||
if (isset($GLOBALS['egw']->sharing) && $GLOBALS['egw']->sharing->has_hidden_upload())
|
||||
{
|
||||
// Tell client side that the path is actually writable
|
||||
$content['initial_path_readonly'] = false;
|
||||
|
||||
// No new anything
|
||||
$this->etemplate->disableElement('nm[new]');
|
||||
$this->etemplate->setElementAttribute('nm[button][createdir]', 'readonly', true);
|
||||
|
||||
// Take over upload, change target and conflict strategy
|
||||
$path = Vfs::concat(self::get_home_dir(), Sharing::HIDDEN_UPLOAD_DIR);
|
||||
$target = str_replace('\\', '\\\\', __CLASS__);
|
||||
$this->etemplate->setElementAttribute('nm[upload]', 'onFinishOne', "app.filemanager.upload(ev, 1, '$path', 'rename', '{$target}::ajax_action')");
|
||||
}
|
||||
|
||||
return parent::listview($content, $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deal with an uploaded file.
|
||||
* Overridden from the parent to change the message and message type
|
||||
*
|
||||
* @param string $action Should be 'upload'
|
||||
* @param $selected Array of file information
|
||||
* @param string $dir Target directory
|
||||
* @param $props
|
||||
* @param string[] $arr Result
|
||||
*
|
||||
* @throws Api\Exception\AssertionFailed
|
||||
*/
|
||||
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';
|
||||
}
|
||||
|
||||
protected function is_hidden_upload_dir($directory)
|
||||
{
|
||||
if (!isset($GLOBALS['egw']->sharing)) return false;
|
||||
// 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];
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to fetch the rows for the nextmatch widget
|
||||
*
|
||||
* @param array $query
|
||||
* @param array &$rows
|
||||
* @return int
|
||||
*
|
||||
* @throws Api\Json\Exception
|
||||
*/
|
||||
function get_rows(&$query, &$rows)
|
||||
{
|
||||
$hidden_upload = (isset($GLOBALS['egw']->sharing) && $GLOBALS['egw']->sharing->has_hidden_upload());
|
||||
|
||||
// Not allowed in hidden upload dir
|
||||
$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()))
|
||||
{
|
||||
// we will leave here, since we are not allowed, go back to root
|
||||
// TODO: Give message about it, redirect to home dir
|
||||
}
|
||||
$rows = array();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get file list from parent
|
||||
$total = parent::get_rows($query, $rows);
|
||||
|
||||
if(! $hidden_upload )
|
||||
{
|
||||
return $total;
|
||||
}
|
||||
|
||||
// tell client-side that this directory is writeable - allows upload + button
|
||||
$response = Api\Json\Response::get();
|
||||
$response->call('app.filemanager.set_readonly', $query['path'], false);
|
||||
|
||||
// Hide the hidden upload directory, mark everything else as readonly
|
||||
foreach($rows as $key => &$row)
|
||||
{
|
||||
if($this->is_hidden_upload_dir($row['path']))
|
||||
{
|
||||
unset($rows[$key]);
|
||||
$total--;
|
||||
continue;
|
||||
}
|
||||
$row['class'] .= 'noEdit noDelete ';
|
||||
}
|
||||
return $total;
|
||||
}
|
||||
}
|
105
filemanager/src/Sharing/Ui.php
Normal file
105
filemanager/src/Sharing/Ui.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/**
|
||||
* EGroupware - Filemanager - UI for sharing with regular users
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @package filemanager
|
||||
* @author Nathan Gray
|
||||
* @copyright (c) 2020 Nathan Gray
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
*/
|
||||
|
||||
namespace EGroupware\Filemanager\Sharing;
|
||||
|
||||
use EGroupware\Api;
|
||||
use EGroupware\Api\Vfs\Sharing;
|
||||
use EGroupware\Api\Etemplate;
|
||||
use EGroupware\Api\Framework;
|
||||
use EGroupware\Api\Link;
|
||||
use EGroupware\Api\Vfs;
|
||||
|
||||
/**
|
||||
* User interface for dealing with filemanager shares
|
||||
*/
|
||||
class Ui
|
||||
{
|
||||
|
||||
// These functions are allowed to be called from client
|
||||
public $public_functions = Array(
|
||||
'share_received' => true
|
||||
);
|
||||
|
||||
/**
|
||||
* The user has been given a new share. Ask what they want to do with it.
|
||||
*
|
||||
* This allows changing the name / mountpoint, and if they want to only
|
||||
* mount it temporarily.
|
||||
*
|
||||
* @param array $content
|
||||
*/
|
||||
public function share_received($content = array())
|
||||
{
|
||||
// Deal with response
|
||||
$this->handle_share_received($content);
|
||||
|
||||
// Set up for display
|
||||
$template = new Api\Etemplate('filemanager.file_share_received');
|
||||
|
||||
$token = $content['token'] ?: $_GET['token'];
|
||||
|
||||
$share = Sharing::so()->read(['share_token' => $token]);
|
||||
|
||||
// This should already have been done, but we want the correct share root
|
||||
Sharing::setup_share(true,$share);
|
||||
|
||||
$content = $share;
|
||||
$content['share_passwd'] = !!$content['share_passwd'];
|
||||
unset($content['share_id']);
|
||||
$content['mount_location'] = Vfs::basename($content['share_root']);
|
||||
$content['permanent'] = true;
|
||||
|
||||
$sel_options = array();
|
||||
$readonlys = array();
|
||||
$preserve = $content;
|
||||
$preserve['url'] = Vfs\Sharing\StreamWrapper::share2url($share);
|
||||
|
||||
$template->exec('filemanager.'.__CLASS__.'.'.__FUNCTION__, $content, $sel_options, $readonlys, $preserve);
|
||||
}
|
||||
|
||||
/**
|
||||
* User submitted the share_received dialog, update the share appropriately
|
||||
*
|
||||
* @param array $content
|
||||
*/
|
||||
protected function handle_share_received($content = array())
|
||||
{
|
||||
if(!$content) return;
|
||||
|
||||
// Set persistent
|
||||
$persistent_mount = $content['permanent'] ? $GLOBALS['egw_info']['user']['account_id'] : false;
|
||||
|
||||
$new_mountpoint = Vfs::dirname($content['share_root']) . '/' . $content['mount_location'];
|
||||
Vfs::$is_root = true;
|
||||
Vfs::umount($content['share_root']);
|
||||
if(Vfs::mount($content['url'], $new_mountpoint, false, $persistent_mount))
|
||||
{
|
||||
$content['share_root'] = $new_mountpoint;
|
||||
}
|
||||
Vfs::$is_root = false;
|
||||
|
||||
// also save for current session
|
||||
$GLOBALS['egw_info']['user']['preferences']['common']['vfs_fstab'][$new_mountpoint] =
|
||||
$_SESSION[Api\Session::EGW_INFO_CACHE]['user']['preferences']['common']['vfs_fstab'][$new_mountpoint] = $content['url'];
|
||||
|
||||
$GLOBALS['egw_info']['server']['vfs_fstab'] = Vfs::mount();
|
||||
|
||||
// Go to new share
|
||||
Api\Json\Response::get()->apply('window.opener.egw.open_link',[
|
||||
Api\Framework::link('/index.php',[
|
||||
'menuaction' => "filemanager.filemanager_ui.index",
|
||||
'path' => $content['share_root']
|
||||
]), 'filemanager',false,'filemanager'
|
||||
]);
|
||||
Api\Framework::window_close();
|
||||
}
|
||||
}
|
32
filemanager/templates/default/file_share_received.xet
Normal file
32
filemanager/templates/default/file_share_received.xet
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="filemanager.file_share_received" template="" lang="" group="0" version="20.1">
|
||||
<grid width="100%">
|
||||
<columns>
|
||||
<column width="20%"/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<label value="Location"/>
|
||||
<description id="share_root" />
|
||||
</row>
|
||||
<row>
|
||||
<label value="Name"/>
|
||||
<textbox id="mount_location"/>
|
||||
</row>
|
||||
<row>
|
||||
<label value="Mount permanently" for="permanent"/>
|
||||
<checkbox id="permanent"/>
|
||||
</row>
|
||||
<row class="dialogFooterToolbar">
|
||||
<hbox>
|
||||
<button label="Ok" id="ok" image="ok" background_image="1" align="center"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
</overlay>
|
Loading…
Reference in New Issue
Block a user