Page MenuHomePhorge

No OneTemporary

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

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)

Event Timeline