From 8434549acead79e6ffed289cc8c90a9815ed8279 Mon Sep 17 00:00:00 2001 From: nathan Date: Fri, 18 Nov 2022 12:42:53 -0700 Subject: [PATCH] Add quota for home directories Set default quota amount in Admin -> Applications -> Filemanager -> Quota --- admin/setup/setup.inc.php | 2 +- admin/templates/default/account.xet | 14 ++-- api/src/Vfs/StreamWrapper.php | 10 ++- api/src/WebDAV/Server/Filesystem.php | 55 +++++++++----- .../inc/class.filemanager_admin.inc.php | 71 ++++++++++++++++--- .../inc/class.filemanager_hooks.inc.php | 8 +-- filemanager/templates/default/quota.xet | 29 ++++++++ 7 files changed, 149 insertions(+), 40 deletions(-) create mode 100644 filemanager/templates/default/quota.xet diff --git a/admin/setup/setup.inc.php b/admin/setup/setup.inc.php index 8cd47ebcf6..07df54b7f9 100644 --- a/admin/setup/setup.inc.php +++ b/admin/setup/setup.inc.php @@ -36,7 +36,7 @@ $setup_info['admin']['hooks']['config'] = 'admin_hooks::config'; $setup_info['admin']['hooks']['edit_group'] = \EGroupware\Admin\Groups::class.'::edit_group'; // add account tab to addressbook.edit -$setup_info['admin']['hooks']['addressbook_edit'] = 'admin.admin_account.addressbook_edit'; +$setup_info['admin']['hooks']['addressbook_edit'][] = 'admin.admin_account.addressbook_edit'; // Dependencies for this app to work $setup_info['admin']['depends'][] = array( diff --git a/admin/templates/default/account.xet b/admin/templates/default/account.xet index ba2996f6f5..e224144053 100644 --- a/admin/templates/default/account.xet +++ b/admin/templates/default/account.xet @@ -52,13 +52,13 @@ - - - - - - - + + + + + + + diff --git a/api/src/Vfs/StreamWrapper.php b/api/src/Vfs/StreamWrapper.php index 1dee58c7e5..1e3b2c3d8c 100644 --- a/api/src/Vfs/StreamWrapper.php +++ b/api/src/Vfs/StreamWrapper.php @@ -275,7 +275,15 @@ class StreamWrapper extends Base implements StreamWrapperIface */ function stream_write ( $data ) { - return fwrite($this->opened_stream,$data); + Api\Hooks::process( + array( + 'location' => 'vfs_pre-write', + 'path' => $this->opened_stream_path, + 'length' => strlen($data) + ) + ); + + return fwrite($this->opened_stream, $data); } /** diff --git a/api/src/WebDAV/Server/Filesystem.php b/api/src/WebDAV/Server/Filesystem.php index 4c9ce9fd39..4cfd7f8594 100644 --- a/api/src/WebDAV/Server/Filesystem.php +++ b/api/src/WebDAV/Server/Filesystem.php @@ -504,30 +504,51 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server */ function PUT(&$options) { - $fspath = $this->base . $options["path"]; + $fspath = $this->base . $options["path"]; - $dir = dirname($fspath); - if (!file_exists($dir) || !is_dir($dir)) { - return "409 Conflict"; // TODO right status code for both? - } + $dir = dirname($fspath); + if(!file_exists($dir) || !is_dir($dir)) + { + return "409 Conflict"; // TODO right status code for both? + } - $options["new"] = ! file_exists($fspath); + $options["new"] = !file_exists($fspath); - if ($options["new"] && !$this->_is_writable($dir)) { - return "403 Forbidden"; - } - if (!$options["new"] && !$this->_is_writable($fspath)) { - return "403 Forbidden"; - } - if (!$options["new"] && is_dir($fspath)) { - return "403 Forbidden"; - } + if($options["new"] && !$this->_is_writable($dir)) + { + return "403 Forbidden"; + } + if(!$options["new"] && !$this->_is_writable($fspath)) + { + return "403 Forbidden"; + } + if(!$options["new"] && is_dir($fspath)) + { + return "403 Forbidden"; + } + + // Check quota + try + { + \EGroupware\Api\Hooks::process( + array( + 'location' => 'vfs_pre-write', + 'path' => $options['path'], + 'length' => $options['content_length'] + ) + ); + } + catch (Exception $e) + { + // $e->getMessage() has information about limits + return "413 Payload Too Large"; + } // for range requests we need to open with "c" as "w" truncates the file! $fp = fopen($fspath, empty($options['ranges']) ? "w" : "c"); - return $fp; - } + return $fp; + } /** diff --git a/filemanager/inc/class.filemanager_admin.inc.php b/filemanager/inc/class.filemanager_admin.inc.php index b2eb271835..49101d1975 100644 --- a/filemanager/inc/class.filemanager_admin.inc.php +++ b/filemanager/inc/class.filemanager_admin.inc.php @@ -28,8 +28,8 @@ class filemanager_admin extends filemanager_ui */ public $public_functions = array( 'index' => true, - 'fsck' => true, - 'quotaRecalc' => true, + 'fsck' => true, + 'quota' => true, ); /** @@ -359,18 +359,69 @@ class filemanager_admin extends filemanager_ui } $check_only = !isset($_POST['fix']); - if (!($msgs = Vfs\Sqlfs\Utils::fsck($check_only))) + if(!($msgs = Vfs\Sqlfs\Utils::fsck($check_only))) { $msgs = lang('Filesystem check reported no problems.'); } - $content = '

'.implode("

\n

", (array)$msgs)."

\n"; + $content = '

' . implode("

\n

", (array)$msgs) . "

\n"; - $content .= Api\Html::form('

'.($check_only&&is_array($msgs) ? - Api\Html::submit_button('fix', lang('Fix reported problems')) : ''). - Api\Html::submit_button('cancel', lang('Cancel')).'

', - '','/index.php',array('menuaction'=>'filemanager.filemanager_admin.fsck')); + $content .= Api\Html::form('

' . ($check_only && is_array($msgs) ? + Api\Html::submit_button('fix', lang('Fix reported problems')) : '') . + Api\Html::submit_button('cancel', lang('Cancel')) . '

', + '', '/index.php', array('menuaction' => 'filemanager.filemanager_admin.fsck') + ); - $GLOBALS['egw']->framework->render($content, lang('Admin').' - '.lang('Check virtual filesystem'), true); + $GLOBALS['egw']->framework->render($content, lang('Admin') . ' - ' . lang('Check virtual filesystem'), true); + } + + /** + * Admin tasks related to quota + * + * Manually trigger a directory size recalculation + * + * @param array $content + * @return void + * @throws Api\Exception\AssertionFailed + */ + public function quota(array $content = null) + { + if(is_array($content)) + { + $button = key($content['button']); + switch($button) + { + case 'recalculate': + Framework::message($this->quotaRecalc()); + break; + case 'save': + case 'apply': + + + if($button == 'apply') + { + break; + } + // fall-through for save + case 'cancel': + + // Reload tracker app + if(Api\Json\Response::isJSONResponse()) + { + Api\Json\Response::get()->apply('app.admin.load'); + } + Framework::redirect_link('/index.php', array( + 'menuaction' => 'admin.admin_ui.index', + 'ajax' => 'true' + ), 'admin'); + break; + } + } + + $content = []; + $readonlys['quota'] = !($GLOBALS['egw_info']['apps']['stylite']); + $tpl = new Etemplate('filemanager.quota'); + $GLOBALS['egw_info']['flags']['app_header'] = lang('Quota'); + $tpl->exec('filemanager.filemanager_admin.quota', $content, $sel_options, $readonlys); } /** @@ -380,6 +431,6 @@ class filemanager_admin extends filemanager_ui { list($dirs, $iterations, $time) = Vfs\Sqlfs\Utils::quotaRecalc(); - echo lang("Recalculated %1 directories in %2 iterations and %3 seconds", $dirs, $iterations, number_format($time, 1))."\n"; + return lang("Recalculated %1 directories in %2 iterations and %3 seconds", $dirs, $iterations, number_format($time, 1)) . "\n"; } } \ No newline at end of file diff --git a/filemanager/inc/class.filemanager_hooks.inc.php b/filemanager/inc/class.filemanager_hooks.inc.php index 3a21b0cf18..af49637741 100644 --- a/filemanager/inc/class.filemanager_hooks.inc.php +++ b/filemanager/inc/class.filemanager_hooks.inc.php @@ -94,11 +94,11 @@ class filemanager_hooks { if (is_array($location)) $location = $location['location']; - $file = Array( + $file = array( //'Site Configuration' => Egw::link('/index.php','menuaction=admin.admin_config.index&appname='.self::$appname.'&ajax=true'), - 'Custom fields' => Egw::link('/index.php','menuaction=admin.admin_customfields.index&appname='.self::$appname.'&ajax=true'), - 'Check virtual filesystem' => Egw::link('/index.php','menuaction=filemanager.filemanager_admin.fsck'), - 'Recalculate quota' => Egw::link('/index.php','menuaction=filemanager.filemanager_admin.quotaRecalc'), + 'Custom fields' => Egw::link('/index.php', 'menuaction=admin.admin_customfields.index&appname=' . self::$appname . '&ajax=true'), + 'Check virtual filesystem' => Egw::link('/index.php', 'menuaction=filemanager.filemanager_admin.fsck'), + 'Quota' => Egw::link('/index.php', 'menuaction=filemanager.filemanager_admin.quota&ajax=true'), 'VFS mounts and versioning' => Egw::link('/index.php', 'menuaction=filemanager.filemanager_admin.index&ajax=true'), ); if ($location == 'admin') diff --git a/filemanager/templates/default/quota.xet b/filemanager/templates/default/quota.xet new file mode 100644 index 0000000000..393fa0c6bc --- /dev/null +++ b/filemanager/templates/default/quota.xet @@ -0,0 +1,29 @@ + + + + + + \ No newline at end of file