first step for new file-sharing feature

This commit is contained in:
Ralf Becker 2014-11-13 17:31:36 +00:00
parent 450225f145
commit 223455b7aa
6 changed files with 190 additions and 2 deletions

View File

@ -0,0 +1,113 @@
<?php
/**
* EGroupware API: VFS sharing
*
* @link http://www.egroupware.org
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @author Ralf Becker <rb@stylite.de>
* @copyright (c) 2014 by Ralf Becker <rb@stylite.de>
* @version $Id$
*/
/**
* VFS sharing
*
* Token generation uses openssl_random_pseudo_bytes, if available, otherwise
* mt_rand based auth::randomstring is used.
*/
class egw_sharing
{
/**
* Length of base64 encoded token (real length is only 3/4 of it)
*/
const TOKEN_LENGTH = 64;
/**
* Name of table used for storing tokens
*/
const TABLE = 'egw_sharing';
/**
* Reference to global db object
*
* @var egw_db
*/
protected $db;
/**
* Constructor
*/
public function __construct()
{
$this->db = $GLOBALS['egw']->db;
}
/**
* Server a request on a share specified in REQUEST_URI
*/
public function ServeRequest()
{
// WebDAV has no concept of a query string and clients (including cadaver)
// seem to pass '?' unencoded, so we need to extract the path info out
// of the request URI ourselves
// if request URI contains a full url, remove schema and domain
$matches = null;
if (preg_match('|^https?://[^/]+(/.*)$|', $path_info=$_SERVER['REQUEST_URI'], $matches))
{
$path_info = $matches[1];
}
$path_info = substr($path_info, strlen($_SERVER['SCRIPT_NAME']));
list(, $token/*, $path*/) = explode('/', $path_info, 3);
if (empty($token) || !($share = $this->db->select(self::TABLE, '*', array(
'share_token' => $token,
'(share_expires IS NULL OR share_expires > '.$this->db->quote(time(), 'date').')',
), __LINE__, __FILE__)->fetch()))
{
sleep(1);
$status = '404 Not Found';
header("HTTP/1.1 $status");
header("X-WebDAV-Status: $status", true);
echo "Requested resource '".htmlspecialchars($path_info)."' does NOT exist!\n";
common::egw_exit();
}
$share['resolve_url'] = egw_vfs::resolve_url($share['share_path']);
//_debug_array($share);
// arrange vfs to only contain shared url
egw_vfs::$is_root = true;
if (!egw_vfs::mount($share['resolve_url'], '/', false, false, true))
{
sleep(1);
$status = '404 Not Found';
header("HTTP/1.1 $status");
header("X-WebDAV-Status: $status", true);
echo "Requested resource '".htmlspecialchars($path_info)."' does NOT exist!\n";
common::egw_exit();
}
egw_vfs::$is_root = false;
egw_vfs::$user = $GLOBALS['egw_info']['user']['account_id'] = $share['share_owner'];
egw_vfs::clearstatcache();
// ToDo: password and write protection
//$GLOBALS['egw']->session->commit_session();
$webdav_server = new vfs_webdav_server();
$webdav_server->ServeRequest('/'.$token);
}
/**
* Generate a new token
*
* @return string
*/
public static function token()
{
// generate random token (using oppenssl if available otherwise mt_rand based auth::randomstring)
$token = function_exists('openssl_random_pseudo_bytes') ?
base64_encode(openssl_random_pseudo_bytes(3*self::TOKEN_LENGTH/4)) :
auth::randomstring(self::TOKEN_LENGTH);
return $token;
}
}

View File

@ -304,9 +304,10 @@ class egw_vfs extends vfs_stream_wrapper
* @param boolean $check_url=null check if url is an existing directory, before mounting it
* default null only checks if url does not contain a $ as used in $user or $pass
* @param boolean $persitent_mount=true create a persitent mount, or only a temprary for current request
* @param boolean $clear_fstab =false true clear current fstab, false (default) only add given mount
* @return array|boolean array with fstab, if called without parameter or true on successful mount
*/
static function mount($url=null,$path=null,$check_url=null,$persitent_mount=true)
static function mount($url=null,$path=null,$check_url=null,$persitent_mount=true,$clear_fstab=false)
{
if (is_null($check_url)) $check_url = strpos($url,'$') === false;
@ -329,6 +330,10 @@ class egw_vfs extends vfs_stream_wrapper
if (self::LOG_LEVEL > 0) error_log(__METHOD__.'('.array2string($url).','.array2string($path).') permission denied, you are NOT root!');
return false; // only root can mount
}
if ($clear_fstab)
{
self::$fstab = array();
}
if (isset(self::$fstab[$path]) && self::$fstab[$path] === $url)
{
if (self::LOG_LEVEL > 0) error_log(__METHOD__.'('.array2string($url).','.array2string($path).') already mounted.');

View File

@ -12,7 +12,7 @@
/* Basic information about this app */
$setup_info['phpgwapi']['name'] = 'phpgwapi';
$setup_info['phpgwapi']['title'] = 'EGroupware API';
$setup_info['phpgwapi']['version'] = '14.1';
$setup_info['phpgwapi']['version'] = '14.1.900';
$setup_info['phpgwapi']['versions']['current_header'] = '1.29';
$setup_info['phpgwapi']['enable'] = 3;
$setup_info['phpgwapi']['app_order'] = 1;
@ -49,6 +49,7 @@ $setup_info['phpgwapi']['tables'][] = 'egw_cat2entry';
$setup_info['phpgwapi']['tables'][] = 'egw_locks';
$setup_info['phpgwapi']['tables'][] = 'egw_sqlfs_props';
$setup_info['phpgwapi']['tables'][] = 'egw_customfields';
$setup_info['phpgwapi']['tables'][] = 'egw_sharing';
// hooks used by vfs_home_hooks to manage user- and group-directories for the new stream based VFS
$setup_info['phpgwapi']['hooks']['addaccount'] = 'phpgwapi.vfs_home_hooks.addAccount';
@ -78,3 +79,4 @@ $setup_info['groupdav']['author'] = $setup_info['groupdav']['maintainer'] = arra
$setup_info['groupdav']['license'] = 'GPL';
$setup_info['groupdav']['hooks']['preferences'] = 'groupdav_hooks::menus';
$setup_info['groupdav']['hooks']['settings'] = 'groupdav_hooks::settings';

View File

@ -450,5 +450,23 @@ $phpgw_baseline = array(
'fk' => array(),
'ix' => array(array('cf_app','cf_order')),
'uc' => array(array('cf_app','cf_name'))
),
'egw_sharing' => array(
'fd' => array(
'share_id' => array('type' => 'auto','nullable' => False,'comment' => 'auto-id'),
'share_token' => array('type' => 'varchar','precision' => '64','nullable' => False,'comment' => 'secure token'),
'share_path' => array('type' => 'varchar','precision' => '255','nullable' => False,'comment' => 'path to share'),
'share_owner' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'owner of share'),
'share_expires' => array('type' => 'date','comment' => 'expire date of share'),
'share_writable' => array('type' => 'int','precision' => '1','nullable' => False,'default' => '0','comment' => '0=readable, 1=writable'),
'share_with' => array('type' => 'varchar','precision' => '4096','comment' => 'email addresses, comma seperated'),
'share_passwd' => array('type' => 'varchar','precision' => '128','comment' => 'optional password-hash'),
'share_created' => array('type' => 'timestamp','nullable' => False,'comment' => 'creation date'),
'share_last_accessed' => array('type' => 'timestamp','comment' => 'last access of share')
),
'pk' => array('share_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('share_token')
)
);

View File

@ -21,3 +21,28 @@ include('tables_update_1_2.inc.php');
include('tables_update_1_4.inc.php');
include('tables_update_1_6.inc.php');
include('tables_update_1_8.inc.php');
function phpgwapi_upgrade14_1()
{
$GLOBALS['egw_setup']->oProc->CreateTable('egw_sharing',array(
'fd' => array(
'share_id' => array('type' => 'auto','nullable' => False,'comment' => 'auto-id'),
'share_token' => array('type' => 'varchar','precision' => '64','nullable' => False,'comment' => 'secure token'),
'share_path' => array('type' => 'varchar','precision' => '255','nullable' => False,'comment' => 'path to share'),
'share_owner' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'owner of share'),
'share_expires' => array('type' => 'date','comment' => 'expire date of share'),
'share_writable' => array('type' => 'int','precision' => '1','nullable' => False,'default' => '0','comment' => '0=readable, 1=writable'),
'share_with' => array('type' => 'varchar','precision' => '4096','comment' => 'email addresses, comma seperated'),
'share_passwd' => array('type' => 'varchar','precision' => '128','comment' => 'optional password-hash'),
'share_created' => array('type' => 'timestamp','nullable' => False,'comment' => 'creation date'),
'share_last_accessed' => array('type' => 'timestamp','comment' => 'last access of share')
),
'pk' => array('share_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('share_token')
));
return $GLOBALS['setup_info']['phpgwapi']['currentver'] = '14.1.900';
}

25
share.php Normal file
View File

@ -0,0 +1,25 @@
<?php
/**
* EGroupware API: VFS sharing
*
* @link http://www.egroupware.org
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @author Ralf Becker <rb@stylite.de>
* @copyright (c) 2014 by Ralf Becker <rb@stylite.de>
* @version $Id$
*/
$GLOBALS['egw_info'] = array(
'flags' => array(
'disable_Template_class' => True,
'noheader' => True,
'currentapp' => 'login',
'no_exception_handler' => 'basic_auth', // we use a basic auth exception handler (sends exception message as basic auth realm)
)
);
include('./header.inc.php');
$sharing = new egw_sharing();
$sharing->ServeRequest();