Projects
Kolab:Winterfell
chwala
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 25
View file
chwala.spec
Changed
@@ -37,7 +37,7 @@ %global _ap_sysconfdir %{_sysconfdir}/%{httpd_name} Name: chwala -Version: 0.5.2 +Version: 0.5.3 Release: 1%{?dist} Summary: Glorified WebDAV, done right @@ -158,6 +158,9 @@ %attr(0750,%{httpd_user},%{httpd_group}) %{_localstatedir}/log/%{name} %changelog +* Fri Aug 10 2018 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 0.5.3-1 +- Release 0.5.3 + * Wed Dec 20 2017 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 0.5.2-1 - Release 0.5.2
View file
chwala-0.5.3.tar.gz/autogen.sh
Added
@@ -0,0 +1,51 @@ +#!/bin/bash + +package="chwala" + +if [ $# -ne 1 ]; then + echo "Usage: $0 <version>" + exit 1 +fi + +version=$1 + +if [ ! -z "$(git tag -l | grep -E '${package}-${version}$')" ]; then + echo "Version ${version} already exists" + exit 1 +fi + +if [ -f "./composer.phar" ]; then + git clean -d -f -x + rm -rf vendor/ +fi + +curl -sS https://getcomposer.org/installer | php + +if [ $? -ne 0 ]; then + echo "Getting composer failed... Bye!" + exit 1 +fi + +cp composer.json composer-dev.json +cp composer.json-dist composer.json + +./composer.phar install --no-dev + +if [ $? -ne 0 ]; then + echo "Running ./composer.phar install failed... Bye!" + exit 1 +fi + +if [ -d "../${package}-${version}/" ]; then + rm -rf ../${package}-${version}/ +fi + +mkdir -p ../${package}-${version}/ +cp -a * ../${package}-${version}/. +find ../${package}-${version}/ -type d -name ".git" -exec rm -rf {} \; 2>/dev/null +find ../${package}-${version}/ -mindepth 1 -maxdepth 1 -type f -name "composer.phar" -delete 2>/dev/null + +pwd=$(pwd) +pushd .. +tar czvf ${pwd}/${package}-${version}.tar.gz ${package}-${version}/ +popd
View file
chwala-0.5.2.tar.gz/config/config.inc.php.dist -> chwala-0.5.3.tar.gz/config/config.inc.php.dist
Changed
@@ -60,10 +60,6 @@ // Note: this URL should be accessible from Chwala host and Roundcube host as well. $config['fileapi_wopi_office'] = null; -// Kolab WOPI service URL. Enables use of collaborative editor supporting WOPI. -// Note: this URL should be accessible from Chwala host and Office host as well. -$config['fileapi_wopi_service'] = null; - // Name of the user interface skin. $config['file_api_skin'] = 'default'; @@ -85,7 +81,7 @@ // ------------------------------------------------ // Enables SeaFile Web API conversation log -$config['fileapi_seafile_debug'] = true; +$config['fileapi_seafile_debug'] = false; // Enables caching of some SeaFile information e.g. folders list // Note: 'db', 'apc' and 'memcache' are supported
View file
chwala-0.5.2.tar.gz/doc/chwala.conf -> chwala-0.5.3.tar.gz/doc/chwala.conf
Changed
@@ -3,7 +3,14 @@ Alias /chwala /usr/share/chwala/public_html <Directory "/usr/share/chwala/public_html/"> - AllowOverride All + AllowOverride None + + php_flag session.auto_start Off + php_flag display_errors Off + php_flag log_errors On + php_flag suhosin.session.encrypt Off + php_value error_log /var/log/chwala/errors + <IfModule mod_authz_core.c> # Apache 2.4 Require all granted @@ -23,6 +30,6 @@ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^api/document/(.*)$ api/index.php?method=document&id=$1 [L,QSA] + RewriteRule ^api/wopi/(.*)$ api/index.php?wopi=1&method=$1 [L,QSA] </IfModule> </Directory> -
View file
chwala-0.5.2.tar.gz/lib/api/document.php -> chwala-0.5.3.tar.gz/lib/api/document.php
Changed
@@ -75,9 +75,7 @@ throw new Exception("Missing document ID.", file_api_core::ERROR_CODE); } - $file = $this->get_file_path($this->args['id']); - - return $this->{'document_' . strtolower($method)}($file); + return $this->{'document_' . strtolower($method)}($this->args['id']); } throw new Exception("Unknown method", file_api_core::ERROR_INVALID); @@ -238,11 +236,10 @@ /** * Return document informations */ - protected function document_info($id) + protected function document_info($id, $extended = true) { $document = file_document::get_handler($this->api, $id); $file = $document->session_file($id); - $session = $document->session_info($id); $rcube = rcube::get_instance(); try { @@ -260,17 +257,21 @@ ); } - $result['owner'] = $session['owner']; - $result['owner_name'] = $session['owner_name']; - $result['user'] = $rcube->user->get_username(); - $result['readonly'] = !empty($session['readonly']); - $result['origin'] = $session['origin']; + if ($extended) { + $session = $document->session_info($id); - if ($result['owner'] == $result['user']) { - $result['user_name'] = $result['owner_name']; - } - else { - $result['user_name'] = $this->api->resolve_user($result['user']) ?: ''; + $result['owner'] = $session['owner']; + $result['owner_name'] = $session['owner_name']; + $result['user'] = $rcube->user->get_username(); + $result['readonly'] = !empty($session['readonly']); + $result['origin'] = $session['origin']; + + if ($result['owner'] == $result['user']) { + $result['user_name'] = $result['owner_name']; + } + else { + $result['user_name'] = $this->api->resolve_user($result['user']) ?: ''; + } } return $result; @@ -279,8 +280,9 @@ /** * Update document file content */ - protected function document_put($file) + protected function document_put($id) { + $file = $this->get_file_path($id); list($driver, $path) = $this->api->get_driver($file); $length = rcube_utils::request_header('Content-Length'); @@ -324,8 +326,9 @@ /** * Return document file content */ - protected function document_get($file) + protected function document_get($id) { + $file = $this->get_file_path($id); list($driver, $path) = $this->api->get_driver($file); try { @@ -337,6 +340,6 @@ header("HTTP/1.0 " . file_api_core::ERROR_CODE . " " . $e->getMessage()); } - exit; + $this->api->output_send(); } }
View file
chwala-0.5.2.tar.gz/lib/drivers/kolab/kolab_file_storage.php -> chwala-0.5.3.tar.gz/lib/drivers/kolab/kolab_file_storage.php
Changed
@@ -1364,7 +1364,7 @@ $owner = $this->rc->get_user_name(); // find the owner and remove namespace prefix - foreach ($namespace as $type => $ns) { + foreach (array_filter($namespace) as $type => $ns) { foreach ($ns as $root) { if (is_array($root) && $root[0] && strpos($path, $root[0]) === 0) { $path = substr($path, strlen($root[0]));
View file
chwala-0.5.2.tar.gz/lib/drivers/seafile/seafile_api.php -> chwala-0.5.3.tar.gz/lib/drivers/seafile/seafile_api.php
Changed
@@ -157,10 +157,8 @@ // Note: It didn't work for me without the last backslash $url = rtrim($url, '/') . '/'; } - // If Seafile is behind a proxy and different port, it will return - // wrong URL for file uploads. We force the original URL prefix here - else if (stripos($url, $this->url_prefix) !== 0) { - $url = $this->url_prefix . preg_replace('|^(https?://[^/]+)|i', '', $url); + else { + $url = $this->mod_url($url); } if (!$this->request) { @@ -398,13 +396,14 @@ /** * List directory entries (files and directories) * - * @param string $repo_id Library identifier - * @param string $dir Directory name (with path) - * @param string $type Entry type ('dir' or 'file') + * @param string $repo_id Library identifier + * @param string $dir Directory name (with path) + * @param string $type Entry type ('dir' or 'file') (requires Seafile 4.4.1) + * @param bool $recursive Enable recursive call for 'dir' listing (requires Seafile 4.4.1) * * @return bool|array List of directories/files on success, False on failure */ - public function directory_entries($repo_id, $dir, $type = null) + public function directory_entries($repo_id, $dir, $type = null, $recursive = false) { // sanity checks if (!is_string($dir)) { @@ -440,6 +439,10 @@ $params['t'] = $type == 'dir' ? 'd' : 'f'; } + if ($recursive && $type == 'dir') { + $params['recursive'] = 1; + } + return $this->request('GET', "repos/$repo_id/dir", $params); } @@ -876,4 +879,18 @@ return $this->is_error() === false; } + + /** + * Parse and fix API request URLs + */ + public function mod_url($url) + { + // If Seafile is behind a proxy and different port, it will return + // wrong URL for file uploads/downloads. We force the original URL prefix here + if (stripos($url, $this->url_prefix) !== 0) { + $url = $this->url_prefix . preg_replace('|^(https?://[^/]+)|i', '', $url); + } + + return $url; + } }
View file
chwala-0.5.2.tar.gz/lib/drivers/seafile/seafile_file_storage.php -> chwala-0.5.3.tar.gz/lib/drivers/seafile/seafile_file_storage.php
Changed
@@ -862,11 +862,31 @@ $folders = array(); if ($this->config['cache']) { - $cache = $this->rc->get_cache('seafile_' . $this->title, + $repos = array(); + $repo_ids = array(); + $cache = $this->rc->get_cache('seafile_' . $this->title, $this->config['cache'], $this->config['cache_ttl'], true); if ($cache) { - $cached = $cache->get('folders'); + $repos = (array) $cache->get('repos'); + } + + // Mark unmodified repos + foreach ($libraries as $idx => $library) { + if ($mtime = $repos[$library['id']]) { + if ($mtime == $library['mtime']) { + $libraries[$idx]['use-cache'] = true; + } + else { + $cache_update = true; + } + } + else { + $cache_update = true; + } + + $repos[$library['id']] = $library['mtime']; + $repo_ids[] = $library['id']; } } @@ -884,8 +904,8 @@ 'permission' => $library['permission'], ); - if ($folder_tree = $this->folders_tree($library, '', $library, $cached)) { - $folders = array_merge($folders, $folder_tree); + foreach ($this->folders_tree($library) as $folder_name => $folder) { + $folders[$library['name'] . '/' . $folder_name] = $folder; } } @@ -893,8 +913,11 @@ throw new Exception("Storage error. Unable to get folders list.", file_storage::ERROR); } - if ($cache && $cached != $folders) { - $cache->set('folders', $folders); + if ($cache && $cache_update) { + // Cleanup repos data + $repos = array_intersect_key($repos, array_flip($repo_ids)); + + $cache->set('repos', $repos); } // remove read-only folders when requested @@ -1083,46 +1106,40 @@ } /** - * Recursively builds folders list + * Get folders tree in the Seafile library */ - protected function folders_tree($library, $path, $folder, $cached) + protected function folders_tree($library) { - $folders = array(); - $fname = strlen($path) ? $path . $folder['name'] : '/'; - $root = $library['name'] . ($fname != '/' ? $fname : ''); - - // nothing changed, use cached folders tree of this folder - if ($cached && is_array($cached[$root]) && $cached[$root]['mtime'] == $folder['mtime']) { - foreach ($cached as $folder_name => $f) { - if (strpos($folder_name, $root . '/') === 0) { - $folders[$folder_name] = array( - 'mtime' => $f['mtime'], - 'permission' => $f['permission'], - ); - } + if ($this->config['cache']) { + $cache = $this->rc->get_cache('seafile_' . $this->title, + $this->config['cache'], $this->config['cache_ttl'], true); + + if ($cache && $library['use-cache']) { + $folders = $cache->get('folders.' . $library['id']); } } - // get folder content (files and sub-folders) - // there's no API method to get only folders - else if ($content = $this->api->directory_entries($library['id'], $fname, 'dir')) { - if ($fname != '/') { - $fname .= '/'; - } - foreach ($content as $item) { - if ($item['type'] == 'dir' && strlen($item['name'])) { - $folders[$root . '/' . $item['name']] = array( - 'mtime' => $item['mtime'], - 'permission' => $item['permission'], - ); - - // get subfolders recursively - $folders_tree = $this->folders_tree($library, $fname, $item, $cached); - if (!empty($folders_tree)) { - $folders = array_merge($folders, $folders_tree); + if (!isset($folders) || !is_array($folders)) { + $folders = array(); + + // get folders in the repo (requires Seafile 4.4.1) + if ($content = $this->api->directory_entries($library['id'], '', 'dir', true)) { + foreach ($content as $item) { + if ($item['type'] == 'dir' && strlen($item['name'])) { + $parent = trim($item['parent_dir'], '/'); + $name = (strlen($parent) > 0 ? "$parent/" : '') . $item['name']; + + $folders[$name] = array( + 'mtime' => $item['mtime'], + 'permission' => $item['permission'], + ); } } } + + if ($cache && is_array($content)) { + $cache->set('folders.' . $library['id'], $folders); + } } return $folders; @@ -1261,7 +1278,7 @@ $observer->set_fp($fp); try { - $request->setUrl($location); + $request->setUrl($this->api->mod_url($location)); $request->attach($observer); $response = $request->send();
View file
chwala-0.5.2.tar.gz/lib/drivers/webdav/webdav_file_storage.php -> chwala-0.5.3.tar.gz/lib/drivers/webdav/webdav_file_storage.php
Changed
@@ -418,7 +418,11 @@ throw new Exception("Storage error. File not found.", file_storage::ERROR); } + // Sometimes Content-Length is an array here (T3757) $size = $response['headers']['content-length']; + if (is_array($size)) { + $size = $size[0]; + } // write to file pointer, send no headers if ($fp) {
View file
chwala-0.5.2.tar.gz/lib/file_api.php -> chwala-0.5.3.tar.gz/lib/file_api.php
Changed
@@ -30,6 +30,19 @@ public $output_type = file_api_core::OUTPUT_JSON; + /** + * Class factory. + */ + public static function factory() + { + $class = 'file_api' . (!empty($_GET['wopi']) ? '_wopi' : ''); + + return new $class; + } + + /** + * Class constructor. + */ public function __construct() { $rcube = rcube::get_instance(); @@ -47,7 +60,7 @@ $this->request = strtolower($_GET['method']); // Check the session, authenticate the user - if (!$this->session_validate($this->request == 'authenticate')) { + if (!$this->session_validate($this->request == 'authenticate', $_REQUEST['token'])) { $this->session->destroy(session_id()); $this->session->regenerate_id(false); @@ -72,7 +85,7 @@ } } else { - throw new Exception("Invalid session", 403); + throw new Exception("Invalid session", file_api_core::ERROR_UNAUTHORIZED); } } else { @@ -91,10 +104,10 @@ /** * Session validation check and session start */ - private function session_validate($new_session = false) + protected function session_validate($new_session = false, $token = null) { if (!$new_session) { - $sess_id = rcube_utils::request_header('X-Session-Token') ?: $_REQUEST['token']; + $sess_id = rcube_utils::request_header('X-Session-Token') ?: $token; } if (empty($sess_id)) { @@ -109,11 +122,12 @@ return false; } - // Document-only session - if (($doc_id = $_SESSION['document_session']) + // Single-document session? + if (!($this instanceof file_api_wopi) + && ($doc_id = $_SESSION['document_session']) && (strpos($this->request, 'document') !== 0 || $doc_id != $_GET['id']) ) { - throw new Exception("Access denied", 403); + throw new Exception("Access denied", file_api_core::ERROR_UNAUTHORIZED); } if ($_SESSION['env']) { @@ -126,7 +140,7 @@ /** * Initializes session */ - private function session_init() + protected function session_init() { $rcube = rcube::get_instance(); $sess_name = $this->config->get('session_name'); @@ -163,13 +177,27 @@ public function shutdown() { // write performance stats to logs/console - if ($this->config->get('devel_mode')) { - if (function_exists('memory_get_peak_usage')) + if ($this->config->get('devel_mode') || $this->config->get('performance_stats')) { + // 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_peak_usage')) { $mem = memory_get_peak_usage(); - else if (function_exists('memory_get_usage')) + } + else if (function_exists('memory_get_usage')) { $mem = memory_get_usage(); + } + + $request = ($this instanceof file_api_wopi ? 'wopi/' : '') + . $this->request + . (!empty($this->path) ? '/' . implode($this->path, '/') : ''); + + $log = trim(sprintf('%s: %s %s', + $this->method ?: $_SERVER['REQUEST_METHOD'], + $request, + $mem ? sprintf('[%.1f MB]', $mem/1024/1024) : '' + )); - $log = trim($this->request . ($mem ? sprintf(' [%.1f MB]', $mem/1024/1024) : '')); if (defined('FILE_API_START')) { rcube::print_timer(FILE_API_START, $log); } @@ -182,7 +210,7 @@ /** * Authentication request handler (HTTP Auth) */ - private function authenticate() + protected function authenticate() { if (isset($_POST['username'])) { $username = $_POST['username']; @@ -223,7 +251,7 @@ header('HTTP/1.1 401 Unauthorized'); exit; */ - throw new Exception("Invalid password or username", file_api_core::ERROR_CODE); + throw new Exception("Invalid password or username", file_api_core::ERROR_UNAUTHORIZED); } } @@ -233,7 +261,7 @@ /** * Storage/System method handler */ - private function request_handler($request) + protected function request_handler($request) { // handle "global" requests that don't require api driver switch ($request) { @@ -446,11 +474,14 @@ * * @param mixed $data Data */ - protected function output_send($data) + public function output_send($data = null) { // Send response - header("Content-Type: {$this->output_type}; charset=utf-8"); - echo json_encode($data); + if ($data !== null) { + header("Content-Type: {$this->output_type}; charset=utf-8"); + echo rcube_output::json_serialize($data); + } + exit; } @@ -459,8 +490,8 @@ */ protected function is_binary_request() { - return preg_match('/^(file_get|document)$/', $this->request) - && $_SERVER['REQUEST_METHOD'] == 'GET'; + return $_SERVER['REQUEST_METHOD'] == 'GET' && + ($this->request == 'file_get' || $this->request == 'document'); } /**
View file
chwala-0.5.2.tar.gz/lib/file_api_core.php -> chwala-0.5.3.tar.gz/lib/file_api_core.php
Changed
@@ -26,8 +26,12 @@ { const API_VERSION = 3; - const ERROR_CODE = 500; - const ERROR_INVALID = 501; + const ERROR_UNAUTHORIZED = 401; + const ERROR_NOT_FOUND = 404; + const ERROR_PRECONDITION_FAILED = 412; + const ERROR_CODE = 500; + const ERROR_INVALID = 501; + const ERROR_NOT_IMPLEMENTED = 501; const OUTPUT_JSON = 'application/json'; const OUTPUT_HTML = 'text/html';
View file
chwala-0.5.3.tar.gz/lib/file_api_wopi.php
Added
@@ -0,0 +1,122 @@ +<?php +/* + +--------------------------------------------------------------------------+ + | This file is part of the Kolab File API | + | | + | Copyright (C) 2012-2018, 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> | + +--------------------------------------------------------------------------+ +*/ + +class file_api_wopi extends file_api +{ + public $output_type = file_api_core::OUTPUT_JSON; + public $path = array(); + public $args = array(); + public $method = 'GET'; + + + /** + * Session validation check and session start + */ + protected function session_validate($new_session = false, $token = null) + { + if (empty($_GET['access_token'])) { + throw new Exception("Token missing", file_api_core::ERROR_UNAUTHORIZED); + } + + return parent::session_validate($new_session = false, $_GET['access_token']); + } + + /** + * Storage/System method handler + */ + protected function request_handler($request) + { + // header("X-WOPI-HostEndpoint: " . $endpoint_desc); + // header("X-WOPI-MachineName: " . $machine_name); + header("X-WOPI-ServerVersion: " . file_api_core::API_VERSION); + + $request = $_GET['method']; // file_api uses strtolower(), we don't want that + + // handle request + if ($request && preg_match('/^[a-z]+\/*[a-zA-Z0-9_\/-]*$/', $request)) { + $path = explode('/', $request); + $request = array_shift($path); + $method = $_SERVER['REQUEST_METHOD']; + + if ($_method = rcube_utils::request_header('X-WOPI-Override')) { + $method = $_method; + } + else if ($method == 'POST' && !empty($_SERVER['HTTP_X_HTTP_METHOD'])) { + $method = $_SERVER['HTTP_X_HTTP_METHOD']; + } + + $this->path = $path; + $this->args = $_GET; + $this->method = $method; + + include_once __DIR__ . "/wopi/$request.php"; + + $class_name = "file_wopi_$request"; + if (class_exists($class_name, false)) { + $handler = new $class_name($this); + return $handler->handle(); + } + } + + throw new Exception("Unknown method", file_api_core::ERROR_NOT_FOUND); + } + + /** + * Send success response + * + * @param mixed $data Data + */ + public function output_success($data) + { + $this->output_send($data); + } + + /** + * Send error response + * + * @param mixed $response Response data + * @param int $code Error code + */ + public function output_error($response, $code = null) + { + header(sprintf("HTTP/1.0 %d %s", $code ?: file_api_core::ERROR_CODE, $response)); + + $this->output_send(); + } + + /** + * Send response + * + * @param mixed $data Data + */ + public function output_send($data = null) + { + // Remove NULL data according to WOPI spec. + if (is_array($data)) { + $data = array_filter($data, function($v) { return $v !== null; }); + } + + parent::output_send($data); + } +}
View file
chwala-0.5.2.tar.gz/lib/file_document.php -> chwala-0.5.3.tar.gz/lib/file_document.php
Changed
@@ -864,7 +864,7 @@ return $url['scheme'] . '://' . $url['host'] . ($url['port'] ?: ''); } - return $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST']; + return (rcube_utils::https_check() ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST']; } /**
View file
chwala-0.5.2.tar.gz/lib/file_wopi.php -> chwala-0.5.3.tar.gz/lib/file_wopi.php
Changed
@@ -97,9 +97,8 @@ return; } - $office_url = rtrim($metadata['urlsrc'], ' /?'); // collabora - $service_url = rtrim($this->rc->config->get('fileapi_wopi_service'), ' /'); // kolab-wopi - $service_url .= '/wopi/files/' . $id; + $office_url = rtrim($metadata['urlsrc'], ' /?'); // collabora + $service_url = $this->api->api_url() . '/wopi/files/' . $id; // @TODO: Parsing and replacing placeholder values // https://wopi.readthedocs.io/en/latest/discovery.html#action-urls
View file
chwala-0.5.2.tar.gz/lib/viewers/media.php -> chwala-0.5.3.tar.gz/lib/viewers/media.php
Changed
@@ -87,19 +87,14 @@ .mejs-container { text-align: center; } </style> <script> - var content_frame = $('#media-player').parent(), - height = content_frame.height(), - width = content_frame.width(), + var height = '100%'; + width = '100%'; player = new MediaElementPlayer('#media-player', { videoHeight: height, audioHeight: height, videoWidth: width, audioWidth: width }); player.pause(); player.play(); - // add player resize handler - $(window).resize(function() { - player.setPlayerSize(content_frame.width(), content_frame.height()); - }); </script> EOT; }
View file
chwala-0.5.3.tar.gz/lib/wopi
Added
+(directory)
View file
chwala-0.5.3.tar.gz/lib/wopi/containers.php
Added
@@ -0,0 +1,34 @@ +<?php +/** + +--------------------------------------------------------------------------+ + | This file is part of the Kolab File API | + | | + | Copyright (C) 2012-2018, 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> | + +--------------------------------------------------------------------------+ +*/ + +class file_wopi_containers +{ + /** + * Request handler + */ + public function handle() + { + throw new Exception("Not implemented", file_api_core::ERROR_NOT_IMPLEMENTED); + } +}
View file
chwala-0.5.3.tar.gz/lib/wopi/ecosystem.php
Added
@@ -0,0 +1,34 @@ +<?php +/** + +--------------------------------------------------------------------------+ + | This file is part of the Kolab File API | + | | + | Copyright (C) 2012-2018, 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> | + +--------------------------------------------------------------------------+ +*/ + +class file_wopi_ecosystem +{ + /** + * Request handler + */ + public function handle() + { + throw new Exception("Not implemented", file_api_core::ERROR_NOT_IMPLEMENTED); + } +}
View file
chwala-0.5.3.tar.gz/lib/wopi/files.php
Added
@@ -0,0 +1,181 @@ +<?php +/** + +--------------------------------------------------------------------------+ + | This file is part of the Kolab File API | + | | + | Copyright (C) 2012-2018, 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> | + +--------------------------------------------------------------------------+ +*/ + +require_once __DIR__ . "/../api/common.php"; +require_once __DIR__ . "/../api/document.php"; + +class file_wopi_files extends file_api_document +{ + /** + * Request handler + */ + public function handle() + { + if (empty($this->api->path)) { + throw new Exception("File ID not specified", file_api_core::ERROR_NOT_FOUND); + } + + $file_id = $this->api->path[0]; + $command = $this->api->path[1]; + + if ($file_id != $_SESSION['document_session']) { + throw new Exception("File ID not specified", file_api_core::ERROR_UNAUTHORIZED); + } + + if ($this->api->method == 'GET') { + if (empty($command)) { + return $this->document_info($file_id); + } + + if ($command == 'contents') { + return $this->document_get($file_id); + } + } + else if ($this->api->method == 'PUT') { + if ($command == 'contents') { + return $this->document_put($file_id); + } + } +/* + else if (empty($command)) { + switch ($api->method) + // TODO case 'UNLOCK': + // TODO case 'LOCK': + // TODO case 'GET_LOCK': + // TODO case 'REFRESH_LOCK': + // TODO case 'PUT_RELATIVE': + // TODO case 'RENAME_FILE': + // TODO case 'DELETE': + // TODO case 'PUT_USER_INFO': + // TODO case 'GET_SHARE_URL': + } + } +*/ + throw new Exception("Unknown method", file_api_core::ERROR_NOT_IMPLEMENTED); + } + + /** + * Return document informations + * + * JSON Response (only required attributes listed): + * - BaseFileName: The string name of the file without a path. Used for + * display in user interface (UI), and determining the extension + * of the file. + * - OwnerId: A string that uniquely identifies the owner of the file. + * - Size: The size of the file in bytes, expressed as a long, + * a 64-bit signed integer. + * - UserId: A string value uniquely identifying the user currently + * accessing the file. + * - Version: The current version of the file based on the server’s file + * version schema, as a string. This value must change when the file changes. + */ + protected function document_info($id) + { + $info = parent::document_info($id); + + // Convert file metadata to Wopi format + // TODO: support more properties from + // https://wopirest.readthedocs.io/en/latest/files/CheckFileInfo.html + + $result = array( + 'BaseFileName' => $info['name'], + 'Size' => $info['size'], + 'Version' => $info['modified'], + 'OwnerId' => $info['owner'], + 'UserId' => $info['user'], + 'UserFriendlyName' => $info['user_name'], + 'UserCanWrite' => empty($info['readonly']), + 'PostMessageOrigin' => $info['origin'], + // Tell the client we do not support PutRelativeFile yet + 'UserCanNotWriteRelative' => true, + // Properties specific to Collabora Online + 'HideSaveOption' => true, + 'HideExportOption' => true, + 'HidePrintOption' => true, + 'EnableOwnerTermination' => true, + // TODO: 'UserExtraInfo' => ['avatar' => 'http://url/to/user/avatar', 'mail' => 'user@server.com'] + ); + + return $result; + } + + /** + * Update document file content + * + * Request Headers: + * - X-WOPI-Lock: A string provided by the WOPI client in a previous Lock request. + * Note that this header will not be included during document creation. + * Collabora-specific Request Headers: + * - X-LOOL-WOPI-IsModifiedByUser: true/false indicates whether the document + * was modified by the user when they saved it. + * - X-LOOL-WOPI-IsAutosave: true/false indicates whether the PutFile + * is a result of autosave or the user pressing the Save button. + * Response Headers: + * - X-WOPI-Lock: A string value identifying the current lock on the file. + * This header must always be included when responding to the request with 409. + * It should not be included when responding to the request with 200 OK. + * - X-WOPI-LockFailureReason: An optional string value indicating the cause + * of a lock failure. + * - X-WOPI-ItemVersion: An optional string value indicating the version of the file. + * Its value should be the same as Version value in CheckFileInfo. + * Status Codes: + * - 409 Conflict: Lock mismatch/locked by another interface + * - 413 Request Entity Too Large: File is too large; Host limit exceeded. + */ + protected function document_put($file_id) + { + // TODO: Locking + + parent::document_put($file_id); + } + + /** + * Return document file content + * + * Request Headers: + * - X-WOPI-MaxExpectedSize: An integer specifying the upper bound + * of the expected size of the file being requested. Optional. + * The host should use the maximum value of a 4-byte integer + * if this value is not set in the request. + * Response Headers: + * - X-WOPI-ItemVersion: An optional string value indicating the version of the file. + * Its value should be the same as Version value in CheckFileInfo. + * Status Codes: + * - 412 File is larger than X-WOPI-MaxExpectedSize + */ + protected function document_get($id) + { + $doc_info = parent::document_info($id, false); + $max_size = rcube_utils::request_header('X-WOPI-MaxExpectedSize') ?: 1024 * 1024 * 1024; + + // Check max file size + if ($doc_info['size'] > $max_size) { + throw new Exception("File exceeds max expected size", file_api_core::ERROR_PRECONDITION_FAILED); + } + + header("X-WOPI-ItemVersion: " . $doc_info['modified']); + + parent::document_get($id); + } +}
View file
chwala-0.5.2.tar.gz/public_html/.htaccess -> chwala-0.5.3.tar.gz/public_html/.htaccess
Changed
@@ -1,6 +1,5 @@ -php_flag session.auto_start Off -php_flag display_errors Off -php_flag log_errors On -php_value error_log ../logs/errors -php_value post_max_size 20M -php_value upload_max_filesize 20M \ No newline at end of file +php_flag session.auto_start Off +php_flag display_errors Off +php_flag log_errors On +php_flag suhosin.session.encrypt Off +php_value error_log ../logs/errors
View file
chwala-0.5.2.tar.gz/public_html/api/index.php -> chwala-0.5.3.tar.gz/public_html/api/index.php
Changed
@@ -4,7 +4,7 @@ +--------------------------------------------------------------------------+ | Kolab File API | | | - | Copyright (C) 2011-2012, Kolab Systems AG <contact@kolabsys.com> | + | Copyright (C) 2011-2018, Kolab Systems AG <contact@kolabsys.com> | | | | 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 | @@ -27,7 +27,7 @@ require_once '../../lib/init.php'; try { - $API = new file_api; + $API = file_api::factory(); $API->run(); } catch (Exception $e) { //rcube::console('API Error: ' . $e->getMessage());
View file
chwala-0.5.2.tar.gz/public_html/skins/default/images/mimetypes/style.css -> chwala-0.5.3.tar.gz/public_html/skins/default/images/mimetypes/style.css
Changed
@@ -1,715 +1,722 @@ -.filelist tbody td.filename.application_vnd_sun_xml_calc span { - background: url(application_vnd.sun.xml.calc.png) 0 0 no-repeat; -} -.filelist tbody td.filename.message_rfc822 span { - background: url(message_rfc822.png) 0 0 no-repeat; +.filelist tbody td.filename._css_sh span { + background: url(_css.sh) 0 0 no-repeat; } .filelist tbody td.filename.application_illustrator span { background: url(application_illustrator.png) 0 0 no-repeat; } -.filelist tbody td.filename.audio_ac3 span { - background: url(audio_ac3.png) 0 0 no-repeat; +.filelist tbody td.filename.application_octet_stream span { + background: url(application_octet_stream.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_x_gzdvi span { - background: url(application_x_gzdvi.png) 0 0 no-repeat; +.filelist tbody td.filename.application_pgp_encrypted span { + background: url(application_pgp_encrypted.png) 0 0 no-repeat; } -.filelist tbody td.filename.sound span { - background: url(sound.png) 0 0 no-repeat; +.filelist tbody td.filename.application_pgp_keys span, +.filelist tbody td.filename.application_pkcs7_mime span { + background: url(application_pgp_keys.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_x_executable span { - background: url(application_x_executable.png) 0 0 no-repeat; +.filelist tbody td.filename.application_pgp_signature span, +.filelist tbody td.filename.application_pkcs7_signature span { + background: url(application_pgp_signature.png) 0 0 no-repeat; } -.filelist tbody td.filename.wordprocessing span { - background: url(wordprocessing.png) 0 0 no-repeat; +.filelist tbody td.filename.application_relaxng span { + background: url(application_relaxng.png) 0 0 no-repeat; } -.filelist tbody td.filename.image_x_eps span { - background: url(image_x_eps.png) 0 0 no-repeat; +.filelist tbody td.filename.application_rss_xml span { + background: url(application_rss+xml.png) 0 0 no-repeat; } -.filelist tbody td.filename.news span { - background: url(news.png) 0 0 no-repeat; +.filelist tbody td.filename.application_rtf span { + background: url(application_rtf.png) 0 0 no-repeat; } -.filelist tbody td.filename.x_media_podcast span { - background: url(x_media_podcast.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_ms_excel span, +.filelist tbody td.filename.application_vnd_openxmlformats_officedocument_spreadsheetml_sheet span, +.filelist tbody td.filename.application_vnd_openxmlformats_officedocument_spreadsheetml_template span { + background: url(application_vnd.ms_excel.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_vnd_oasis_opendocument_spreadsheet span { - background: url(application_vnd.oasis.opendocument.spreadsheet.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_ms_powerpoint span, +.filelist tbody td.filename.application_vnd_openxmlformats_officedocument_presentationml_presentation span, +.filelist tbody td.filename.application_vnd_openxmlformats_officedocument_presentationml_template span, +.filelist tbody td.filename.application_vnd_openxmlformats_officedocument_presentationml_slideshow span { + background: url(application_vnd.ms_powerpoint.png) 0 0 no-repeat; } -.filelist tbody td.filename.text_x_dtd span { - background: url(text_x_dtd.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_ms_word span, +.filelist tbody td.filename.application_msword span, +.filelist tbody td.filename.application_vnd_openxmlformats_officedocument_wordprocessingml_document span, +.filelist tbody td.filename.application_vnd_openxmlformats_officedocument_wordprocessingml_template span { + background: url(application_vnd.ms_word.png) 0 0 no-repeat; } -.filelist tbody td.filename.txt span { - background: url(txt.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_oasis_opendocument_chart span { + background: url(application_vnd.oasis.opendocument.chart.png) 0 0 no-repeat; } -.filelist tbody td.filename.text_x_xslfo span { - background: url(text_x_xslfo.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_oasis_opendocument_database span { + background: url(application_vnd.oasis.opendocument.database.png) 0 0 no-repeat; } -.filelist tbody td.filename.html span { - background: url(html.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_oasis_opendocument_formula span { + background: url(application_vnd.oasis.opendocument.formula.png) 0 0 no-repeat; +} +.filelist tbody td.filename.application_vnd_oasis_opendocument_graphics span { + background: url(application_vnd.oasis.opendocument.graphics.png) 0 0 no-repeat; } .filelist tbody td.filename.application_vnd_oasis_opendocument_image span { background: url(application_vnd.oasis.opendocument.image.png) 0 0 no-repeat; } -.filelist tbody td.filename.x_office_document span { - background: url(x_office_document.png) 0 0 no-repeat; -} -.filelist tbody td.filename.application_x_compress span { - background: url(application_x_compress.png) 0 0 no-repeat; -} -.filelist tbody td.filename.man span { - background: url(man.png) 0 0 no-repeat; -} -.filelist tbody td.filename.audio span { - background: url(audio.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_oasis_opendocument_presentation span { + background: url(application_vnd.oasis.opendocument.presentation.png) 0 0 no-repeat; } -.filelist tbody td.filename.font_truetype span { - background: url(font_truetype.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_oasis_opendocument_presentation_template span { + background: url(application_vnd.oasis.opendocument.presentation_template.png) 0 0 no-repeat; } -.filelist tbody td.filename.source_py span { - background: url(source_py.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_oasis_opendocument_spreadsheet span { + background: url(application_vnd.oasis.opendocument.spreadsheet.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_x_mswinurl span { - background: url(application_x_mswinurl.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_oasis_opendocument_spreadsheet_template span { + background: url(application_vnd.oasis.opendocument.spreadsheet_template.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_octet_stream span { - background: url(application_octet_stream.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_oasis_opendocument_text span { + background: url(application_vnd.oasis.opendocument.text.png) 0 0 no-repeat; } -.filelist tbody td.filename.folder span { - background: url(folder.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_rn_realmedia span { + background: url(application_vnd.rn_realmedia.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_x_lzop span { - background: url(application_x_lzop.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_stardivision_calc span { + background: url(application_vnd.stardivision.calc.png) 0 0 no-repeat; } -.filelist tbody td.filename.text_x_pascal span { - background: url(text_x_pascal.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_sun_xml_calc span { + background: url(application_vnd.sun.xml.calc.png) 0 0 no-repeat; } -.filelist tbody td.filename.vcard span { - background: url(vcard.png) 0 0 no-repeat; +.filelist tbody td.filename.application_vnd_sun_xml_calc_template span { + background: url(application_vnd.sun.xml.calc.template.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_x_quattropro span { - background: url(application_x_quattropro.png) 0 0 no-repeat; +.filelist tbody td.filename.application_x_applix_spreadsheet span { + background: url(application_x_applix_spreadsheet.png) 0 0 no-repeat; } .filelist tbody td.filename.application_x_archive span, .filelist tbody td.filename.application_x_ar span, .filelist tbody td.filename.application_x_cpio span { background: url(application_x_archive.png) 0 0 no-repeat; } -.filelist tbody td.filename.audio_x_flac span { - background: url(audio_x_flac.png) 0 0 no-repeat; +.filelist tbody td.filename.application_x_awk span { + background: url(application_x_awk.png) 0 0 no-repeat; } -.filelist tbody td.filename.tex span { - background: url(tex.png) 0 0 no-repeat; +.filelist tbody td.filename.application_x_bittorrent span { + background: url(application_x_bittorrent.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_vnd_oasis_opendocument_chart span { - background: url(application_vnd.oasis.opendocument.chart.png) 0 0 no-repeat; +.filelist tbody td.filename.application_x_bzdvi span { + background: url(application_x_bzdvi.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_x_php span { - background: url(application_x_php.png) 0 0 no-repeat; +.filelist tbody td.filename.application_x_bzip span { + background: url(application_x_bzip.png) 0 0 no-repeat; } -.filelist tbody td.filename.text_x_chdr span { - background: url(text_x_chdr.png) 0 0 no-repeat; +.filelist tbody td.filename.application_x_cd_image span { + background: url(application_x_cd_image.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_x_kgetlist span { - background: url(application_x_kgetlist.png) 0 0 no-repeat; +.filelist tbody td.filename.application_x_cda span { + background: url(application_x_cda.png) 0 0 no-repeat; } -.filelist tbody td.filename.text_x_texinfo span { - background: url(text_x_texinfo.png) 0 0 no-repeat; +.filelist tbody td.filename.application_x_compress span { + background: url(application_x_compress.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_vnd_ms_excel span { - background: url(application_vnd.ms_excel.png) 0 0 no-repeat; +.filelist tbody td.filename.application_x_compressed_tar span { + background: url(application_x_compressed_tar.png) 0 0 no-repeat; } -.filelist tbody td.filename.application_vnd_oasis_opendocument_graphics span { - background: url(application_vnd.oasis.opendocument.graphics.png) 0 0 no-repeat; +.filelist tbody td.filename.application_x_cue span {
View file
chwala.dsc
Changed
@@ -2,7 +2,7 @@ Source: chwala Binary: chwala Architecture: all -Version: 0.5.2-0~kolab1 +Version: 0.5.3-0~kolab1 Maintainer: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Uploaders: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>, Paul Klos <kolab@klos2day.nl> Homepage: http://kolab.org/about/chwala/ @@ -11,5 +11,5 @@ Package-List: roundcubemail deb web extra Files: - 00000000000000000000000000000000 0 chwala-0.5.2.tar.gz + 00000000000000000000000000000000 0 chwala-0.5.3.tar.gz 00000000000000000000000000000000 0 debian.tar.gz
View file
debian.changelog
Changed
@@ -1,3 +1,9 @@ +chwala (0.5.3-0~kolab1) unsable; urgency=low + + * Release version 0.5.3 + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabys.com> Fri, 10 Aug 2018 12:12:12 +0100 + chwala (0.5.2-0~kolab1) unsable; urgency=low * Release version 0.5.2
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.