Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F174593
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
18 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/file_ui.php b/lib/file_ui.php
index e8f5032..f440f8f 100644
--- a/lib/file_ui.php
+++ b/lib/file_ui.php
@@ -1,573 +1,580 @@
<?php
/*
+--------------------------------------------------------------------------+
| This file is part of the Kolab File API |
| |
| Copyright (C) 2011-2012, Kolab Systems AG |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU Affero General Public License as published |
| by the Free Software Foundation, either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/> |
+--------------------------------------------------------------------------+
| Author: Aleksander Machniak <machniak@kolabsys.com> |
| Author: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> |
+--------------------------------------------------------------------------+
*/
class file_ui extends file_locale
{
/**
* @var kolab_client_output
*/
protected $output;
/**
* @var kolab_client_api
*/
public $api;
/**
* @var Conf
*/
protected $config;
protected $ajax_only = false;
protected $page_title = 'Kolab File API';
protected $menu = array();
protected $cache = array();
protected $devel_mode = false;
protected $object_types = array();
const API_VERSION = 2;
/**
* Class constructor.
*
* @param file_ui_output $output Optional output object
*/
public function __construct($output = null)
{
$rcube = rcube::get_instance();
- $rcube->add_shutdown_function(array($this, 'shutdown'));
+ register_shutdown_function(array($this, 'shutdown'));
$this->config_init();
$this->devel_mode = $this->config->get('devel_mode', false);
$this->output_init($output);
$this->api_init();
ini_set('session.use_cookies', 'On');
session_start();
// Initialize locales
$this->locale_init();
$this->auth();
}
/**
* Configuration initialization.
*/
private function config_init()
{
$this->config = rcube::get_instance()->config;
}
/**
* Output initialization.
*/
private function output_init($output = null)
{
if ($output) {
$this->output = $output;
return;
}
$skin = $this->config->get('file_api_skin', 'default');
$this->output = new file_ui_output($skin);
// Assign self to template variable
$this->output->assign('engine', $this);
}
/**
* API initialization
*/
private function api_init()
{
$url = $this->config->get('file_api_url', '');
if (!$url) {
$schema = rcube_utils::https_check() ? 'https' : 'http';
$port = $schema == 'http' ? 80 : 443;
$url = $schema . '://' . $_SERVER['SERVER_NAME'];
$url .= $_SERVER['SERVER_PORT'] != $port ? ':' . $_SERVER['SERVER_PORT'] : '';
$url .= preg_replace('/\/?\?.*$/', '', $_SERVER['REQUEST_URI']);
$url .= '/api/';
}
$this->api = new file_ui_api($url);
}
/**
* Initializes User Interface
*/
protected function ui_init()
{
// assign token
$this->output->set_env('token', $_SESSION['user']['token']);
// assign capabilities
$this->output->set_env('capabilities', $_SESSION['caps']);
// add watermark content
$this->output->set_env('watermark', $this->output->get_template('watermark'));
// $this->watermark('taskcontent');
// assign default set of translations
$this->output->add_translation('loading', 'servererror');
// $this->output->assign('tasks', $this->menu);
// $this->output->assign('main_menu', $this->menu());
$this->output->assign('user', $_SESSION['user']);
if ($_SESSION['caps']['MAX_UPLOAD']) {
$this->output->assign('max_upload', $this->show_bytes($_SESSION['caps']['MAX_UPLOAD']));
}
}
/**
* User authentication (and authorization).
*/
private function auth()
{
if (isset($_POST['login'])) {
$login = $this->get_input('login', 'POST');
if ($login['username']) {
$result = $this->api->login($login['username'], $login['password'],
array('version' => self::API_VERSION));
if ($token = $result->get('token')) {
$user = array(
'token' => $token,
'username' => $login['username'],
);
$this->api->set_session_token($user['token']);
/*
// Find user settings
// Don't call API user.info for non-existing users (#1025)
if (preg_match('/^cn=([a-z ]+)/i', $login['username'], $m)) {
$user['fullname'] = ucwords($m[1]);
}
else {
$res = $this->api->get('user.info', array('user' => $user['id']));
$res = $res->get();
if (is_array($res) && !empty($res)) {
$user['language'] = $res['preferredlanguage'];
$user['fullname'] = $res['cn'];
}
}
*/
// Save capabilities
$_SESSION['caps'] = $result->get('capabilities');
// Save user data
$_SESSION['user'] = $user;
if (($language = $this->get_language()) && $language != 'en_US') {
$_SESSION['user']['language'] = $language;
// $session_config['language'] = $language;
}
/*
// Configure API session
if (!empty($session_config)) {
$this->api->post('system.configure', null, $session_config);
}
*/
header('Location: ?');
die;
}
else {
$code = $result->get_error_code();
$str = $result->get_error_str();
$label = 'loginerror';
if ($code == file_ui_api::ERROR_INTERNAL
|| $code == file_ui_api::ERROR_CONNECTION
) {
$label = 'internalerror';
$this->raise_error(500, 'Login failed. ' . $str);
}
$this->output->command('display_message', $label, 'error');
}
}
}
else if (!empty($_SESSION['user']) && !empty($_SESSION['user']['token'])) {
// Validate session
$timeout = $this->config->get('session_timeout', 3600);
if ($timeout && $_SESSION['time'] && $_SESSION['time'] < time() - $timeout) {
$this->action_logout(true);
}
// update session time
$_SESSION['time'] = time();
// Set API session key
$this->api->set_session_token($_SESSION['user']['token']);
}
}
/**
* Main execution.
*/
public function run()
{
// Session check
if (empty($_SESSION['user']) || empty($_SESSION['user']['token'])) {
$this->action_logout();
}
// Run security checks
$this->input_checks();
$this->action = $this->get_input('action', 'GET');
if ($this->action) {
$method = 'action_' . $this->action;
if (method_exists($this, $method)) {
$this->$method();
}
}
else if (method_exists($this, 'action_default')) {
$this->action_default();
}
}
/**
* Security checks and input validation.
*/
public function input_checks()
{
$ajax = $this->output->is_ajax();
// Check AJAX-only tasks
if ($this->ajax_only && !$ajax) {
$this->raise_error(500, 'Invalid request type!', null, true);
}
// CSRF prevention
$token = $ajax ? rcube_utils::request_header('X-Session-Token') : $this->get_input('token');
$task = $this->get_task();
if ($task != 'main' && $token != $_SESSION['user']['token']) {
$this->raise_error(403, 'Invalid request data!', null, true);
}
}
/**
* Logout action.
*/
private function action_logout($sess_expired = false, $stop_sess = true)
{
if (!empty($_SESSION['user']) && !empty($_SESSION['user']['token']) && $stop_sess) {
$this->api->logout();
}
$_SESSION = array();
if ($this->output->is_ajax()) {
if ($sess_expired) {
$args = array('error' => 'session.expired');
}
$this->output->command('main_logout', $args);
if ($sess_expired) {
$this->output->send();
exit;
}
}
else {
$this->output->add_translation('loginerror', 'internalerror', 'session.expired');
}
if ($sess_expired) {
$error = 'session.expired';
}
else {
$error = $this->get_input('error', 'GET');
}
if ($error) {
$this->output->command('display_message', $error, 'error', 60000);
}
$this->output->send('login');
exit;
}
/**
* Error action (with error logging).
*
* @param int $code Error code
* @param string $msg Error message
* @param array $args Optional arguments (type, file, line)
* @param bool $output Enable to send output and finish
*/
public function raise_error($code, $msg, $args = array(), $output = false)
{
$log_line = sprintf("%s Error: %s (%s)",
isset($args['type']) ? $args['type'] : 'PHP',
$msg . (isset($args['file']) ? sprintf(' in %s on line %d', $args['file'], $args['line']) : ''),
$_SERVER['REQUEST_METHOD']);
rcube::write_log('errors', $log_line);
if (!$output) {
return;
}
if ($this->output->is_ajax()) {
header("HTTP/1.0 $code $msg");
die;
}
$this->output->assign('error_code', $code);
$this->output->assign('error_message', $msg);
$this->output->send('error');
exit;
}
/**
* Script shutdown handler
*/
public function shutdown()
{
// write performance stats to logs/console
- if ($this->devel_mode) {
- if (function_exists('memory_get_peak_usage'))
- $mem = memory_get_peak_usage();
- else if (function_exists('memory_get_usage'))
- $mem = memory_get_usage();
-
- $log = 'ui:' . $this->get_task() . ($this->action ? '/' . $this->action : '');
- $log .= ($mem ? sprintf(' [%.1f MB]', $mem/1024/1024) : '');
+ if ($this->config->get('devel_mode') || $this->config->get('performance_stats')) {
+ // we have to disable per_user_logging to make sure stats end up in the main console log
+ $this->config->set('per_user_logging', false);
+
+ // make sure logged numbers use unified format
+ setlocale(LC_NUMERIC, 'en_US.utf8', 'en_US.UTF-8', 'en_US', 'C');
+
+ if (function_exists('memory_get_usage')) {
+ $mem = round(memory_get_usage() / 1024 /1024, 1);
+ }
+ if (function_exists('memory_get_peak_usage')) {
+ $mem .= '/'. round(memory_get_peak_usage() / 1024 / 1024, 1);
+ }
+
+ $log = 'ui:' . $this->get_task() . ($this->action ? '/' . $this->action : '') . " [$mem]";
if (defined('FILE_API_START')) {
rcube::print_timer(FILE_API_START, $log);
}
else {
rcube::console($log);
}
}
}
/**
* Output sending.
*/
public function send()
{
$task = $this->get_task();
if ($this->page_title) {
$this->output->assign('pagetitle', $this->page_title);
}
$this->output->set_env('task', $task);
$this->output->send($this->task_template ? $this->task_template : $task);
exit;
}
/**
* Returns name of the current task.
*
* @return string Task name
*/
public function get_task()
{
$class_name = get_class($this);
if (preg_match('/^file_ui_client_([a-z]+)$/', $class_name, $m)) {
return $m[1];
}
}
/**
* Returns input parameter value.
*
* @param string $name Parameter name
* @param string $type Parameter type (GET|POST|NULL)
* @param bool $allow_html Disables stripping of insecure content (HTML tags)
*
* @see rcube_utils::get_input_value
* @return mixed Input value.
*/
public static function get_input($name, $type = null, $allow_html = false)
{
if ($type == 'GET') {
$type = rcube_utils::INPUT_GET;
}
else if ($type == 'POST') {
$type = rcube_utils::INPUT_POST;
}
else {
$type = rcube_utils::INPUT_GPC;
}
$result = rcube_utils::get_input_value($name, $type, $allow_html);
return $result;
}
/**
* Returns task menu output.
*
* @return string HTML output
*/
protected function menu()
{
}
/**
* Adds watermark page definition into main page.
*/
protected function watermark($name)
{
$this->output->command('set_watermark', $name);
}
/**
* API GET request wrapper
*/
protected function api_get($action, $get = array())
{
return $this->api_call('get', $action, $get);
}
/**
* API POST request wrapper
*/
protected function api_post($action, $get = array(), $post = array())
{
return $this->api_call('post', $action, $get, $post);
}
/**
* API request wrapper with error handling
*/
protected function api_call($type, $action, $get = array(), $post = array())
{
if ($type == 'post') {
$result = $this->api->post($action, $get, $post);
}
else {
$result = $this->api->get($action, $get);
}
// error handling
if ($code = $result->get_error_code()) {
// Invalid session, do logout
if ($code == 403) {
$this->action_logout(true, false);
}
// Log communication errors, other should be logged on API side
if ($code < 400) {
$this->raise_error($code, 'API Error: ' . $result->get_error_str());
}
}
return $result;
}
/**
* Returns execution time in seconds
*
* @param string Execution time
*/
public function gentime()
{
return sprintf('%.4f', microtime(true) - FILE_API_START);
}
/**
* Returns HTML output of login form
*
* @param string HTML output
*/
public function login_form()
{
$post = $this->get_input('login', 'POST');
$user_input = new html_inputfield(array(
'type' => 'text',
'id' => 'login_name',
'name' => 'login[username]',
'autofocus' => true,
));
$pass_input = new html_inputfield(array(
'type' => 'password',
'id' => 'login_pass',
'name' => 'login[password]',
));
$button = new html_inputfield(array(
'type' => 'submit',
'id' => 'login_submit',
'value' => $this->translate('login.login'),
));
$username = html::label(array('for' => 'login_name'), $this->translate('login.username'))
. $user_input->show($post['username']);
$password = html::label(array('for' => 'login_pass'), $this->translate('login.password'))
. $pass_input->show('');
$form = html::tag('form', array(
'id' => 'login_form',
'name' => 'login',
'method' => 'post',
'action' => '?'),
html::span(null, $username) . html::span(null, $password) . $button->show());
return $form;
}
/**
* Create a human readable string for a number of bytes
*
* @param int Number of bytes
*
* @return string Byte string
*/
protected function show_bytes($bytes)
{
if ($bytes >= 1073741824) {
$gb = $bytes/1073741824;
$str = sprintf($gb>=10 ? "%d " : "%.1f ", $gb) . $this->translate('size.GB');
}
else if ($bytes >= 1048576) {
$mb = $bytes/1048576;
$str = sprintf($mb>=10 ? "%d " : "%.1f ", $mb) . $this->translate('size.MB');
}
else if ($bytes >= 1024) {
$str = sprintf("%d ", round($bytes/1024)) . $this->translate('size.KB');
}
else {
$str = sprintf("%d ", $bytes) . $this->translate('size.B');
}
return $str;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Jan 18, 12:51 PM (1 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
119951
Default Alt Text
(18 KB)
Attached To
Mode
R26 chwala
Attached
Detach File
Event Timeline
Log In to Comment