forked from extern/egroupware
first step for new file-sharing feature
This commit is contained in:
parent
450225f145
commit
223455b7aa
113
phpgwapi/inc/class.egw_sharing.inc.php
Normal file
113
phpgwapi/inc/class.egw_sharing.inc.php
Normal 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;
|
||||
}
|
||||
}
|
@ -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.');
|
||||
|
@ -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';
|
||||
|
||||
|
@ -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')
|
||||
)
|
||||
);
|
||||
|
@ -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
25
share.php
Normal 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();
|
Loading…
Reference in New Issue
Block a user