Page MenuHomePhorge

No OneTemporary

Size
39 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/api/document.php b/lib/api/document.php
index 16078e2..8886a38 100644
--- a/lib/api/document.php
+++ b/lib/api/document.php
@@ -1,188 +1,211 @@
<?php
/**
+--------------------------------------------------------------------------+
| This file is part of the Kolab File API |
| |
| Copyright (C) 2012-2015, 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_document extends file_api_common
{
/**
* Request handler
*/
public function handle()
{
$method = $_SERVER['REQUEST_METHOD'];
$this->args = $_GET;
if ($method == 'POST' && !empty($_SERVER['HTTP_X_HTTP_METHOD'])) {
$method = $_SERVER['HTTP_X_HTTP_METHOD'];
}
// Sessions and invitations management
if (strpos($this->args['method'], 'document_') === 0) {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$post = file_get_contents('php://input');
$this->args += (array) json_decode($post, true);
unset($post);
}
if (empty($this->args['id'])) {
throw new Exception("Missing document ID.", file_api_core::ERROR_CODE);
}
switch ($this->args['method']) {
case 'document_delete':
return $this->document_delete($this->args['id']);
case 'document_invite':
return $this->document_invite($this->args['id']);
// case 'document_request':
// case 'document_decline':
// case 'document_accept':
-// case 'document_remove':
+ case 'document_remove':
+ return $this->document_remove($this->args['id']);
}
}
// Document content actions for Manticore
else if ($method == 'PUT' || $method == 'GET') {
if (empty($this->args['id'])) {
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);
}
throw new Exception("Unknown method", file_api_core::ERROR_INVALID);
}
/**
* Get file path from manticore session identifier
*/
protected function get_file_path($id)
{
$manticore = new file_manticore($this->api);
return $manticore->session_file($id);
}
/**
* Close (delete) manticore session
*/
protected function document_delete($id)
{
$manticore = new file_manticore($this->api);
if (!$manticore->session_delete($id)) {
throw new Exception("Failed deleting the document session.", file_api_core::ERROR_CODE);
}
}
/**
- * Invite/add a session participant
+ * Invite/add a session participant(s)
*/
protected function document_invite($id)
{
$manticore = new file_manticore($this->api);
$users = $this->args['users'];
if (empty($users)) {
throw new Exception("Invalid arguments.", file_api_core::ERROR_CODE);
}
foreach ((array) $users as $user) {
if (!empty($user['user'])) {
$manticore->invitation_create($id, $user['user'], file_manticore::STATUS_INVITED);
$result[] = array(
'session_id' => $id,
'user' => $user['user'],
// 'name' => $user['name'],
'status' => file_manticore::STATUS_INVITED,
);
}
}
return array(
'list' => $result,
);
}
+ /**
+ * Remove a session participant(s)
+ */
+ protected function document_remove($id)
+ {
+ $manticore = new file_manticore($this->api);
+ $users = $this->args['users'];
+
+ if (empty($users)) {
+ throw new Exception("Invalid arguments.", file_api_core::ERROR_CODE);
+ }
+
+ foreach ((array) $users as $user) {
+ $manticore->invitation_delete($id, $user);
+ $result[] = $user;
+ }
+
+ return array(
+ 'list' => $result,
+ );
+ }
+
/**
* Update document file content
*/
protected function document_put($file)
{
list($driver, $path) = $this->api->get_driver($file);
$length = rcube_utils::request_header('Content-Length');
$tmp_dir = unslashify($this->api->config->get('temp_dir'));
$tmp_path = tempnam($tmp_dir, 'chwalaUpload');
// Create stream to copy input into a temp file
$input = fopen('php://input', 'r');
$tmp_file = fopen($tmp_path, 'w');
if (!$input || !$tmp_file) {
throw new Exception("Failed opening input or temp file stream.", file_api_core::ERROR_CODE);
}
// Create temp file from the input
$copied = stream_copy_to_stream($input, $tmp_file);
fclose($input);
fclose($tmp_file);
if ($copied < $length) {
throw new Exception("Failed writing to temp file.", file_api_core::ERROR_CODE);
}
$file = array(
'path' => $tmp_path,
'type' => rcube_mime::file_content_type($tmp_path, $file),
);
$driver->file_update($path, $file);
// remove the temp file
unlink($tmp_path);
}
/**
* Return document file content
*/
protected function document_get($file)
{
list($driver, $path) = $this->api->get_driver($file);
try {
$params = array('force-type' => 'application/vnd.oasis.opendocument.text');
$driver->file_get($path, $params);
}
catch (Exception $e) {
header("HTTP/1.0 " . file_api_core::ERROR_CODE . " " . $e->getMessage());
}
exit;
}
}
diff --git a/lib/file_manticore.php b/lib/file_manticore.php
index 966512d..7f10db3 100644
--- a/lib/file_manticore.php
+++ b/lib/file_manticore.php
@@ -1,559 +1,567 @@
<?php
/**
+--------------------------------------------------------------------------+
| This file is part of the Kolab File API |
| |
| Copyright (C) 2012-2015, 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> |
+--------------------------------------------------------------------------+
*/
/**
* Document editing sessions handling
*/
class file_manticore
{
protected $api;
protected $rc;
protected $request;
protected $sessions_table = 'chwala_sessions';
protected $invitations_table = 'chwala_invitations';
const STATUS_INVITED = 'invited';
const STATUS_REQUESTED = 'requested';
const STATUS_ACCEPTED = 'accepted';
const STATUS_DECLINED = 'declined';
/**
* Class constructor
*
* @param file_api Chwala API app instance
*/
public function __construct($api)
{
$this->rc = rcube::get_instance();
$this->api = $api;
$db = $this->rc->get_dbh();
$this->sessions_table = $db->table_name($this->sessions_table);
$this->invitations_table = $db->table_name($this->invitations_table);
}
/**
* Return viewer URI for specified file/session. This creates
* a new collaborative editing session when needed.
*
* @param string $file File path
* @param string &$session_id Optional session ID to join to
*
* @return string Manticore URI
* @throws Exception
*/
public function session_start($file, &$session_id = null)
{
list($driver, $path) = $this->api->get_driver($file);
$backend = $this->api->get_backend();
$uri = $driver->path2uri($path);
if ($session_id) {
$session = $this->session_info($session_id);
if (empty($session)) {
throw new Exception("Document session not found.", file_api_core::ERROR_CODE);
}
// check session ownership
if ($session['owner'] != $_SESSION['user']) {
// check if the user was invited
$invitations = $this->invitations_list($session_id);
$states = array(self::STATUS_DECLINED, self::STATUS_REQUESTED);
if (empty($invitations) || in_array($invitations[0]['status'], $states)) {
throw new Exception("No permission to join the editing session.", file_api_core::ERROR_CODE);
}
// automatically accept the invitation, if not done yet
if ($invitations[0]['status'] == self::STATUS_INVITED) {
$this->invitation_update($session_id, $_SESSION['user'], self::STATUS_ACCEPTED);
}
}
+ // authenticate to Manticore, we need auth token for frame_uri
+ $req = $this->get_request();
+
// @TODO: make sure the session exists in Manticore?
}
else {
// @TODO: to prevent from creating a new sessions for the same file+user
// (e.g. when user uses F5 to refresh the page), we should check
// if such a session exist
$session_id = rcube_utils::bin2ascii(md5(time() . $uri, true));
$data = array();
$owner = $_SESSION['user'];
// we'll store user credentials if the file comes from
// an external source that requires authentication
if ($backend != $driver) {
$auth = $driver->auth_info();
$auth['password'] = $this->rc->encrypt($auth['password']);
$data['auth_info'] = $auth;
}
$res = $this->session_create($session_id, $uri, $owner, $data);
if (!$res) {
throw new Exception("Failed creating document editing session", file_api_core::ERROR_CODE);
}
}
return $this->frame_uri($session_id);
}
/**
* Get file path (not URI) from session.
*
* @param string $id Session ID
*
* @return string File path
* @throws Exception
*/
public function session_file($id)
{
$session = $this->session_info($id);
if (empty($session)) {
throw new Exception("Document session not found.", file_api_core::ERROR_CODE);
}
$path = $this->uri2path($session['uri']);
if (empty($path)) {
throw new Exception("Document session not found.", file_api_core::ERROR_CODE);
}
// @TODO: check permissions to the session
return $path;
}
/**
* Get editing session info
*
* @param string $id Session identifier
* @param bool $with_invitations Return invitations list
*/
public function session_info($id, $with_invitations = false)
{
$db = $this->rc->get_dbh();
$result = $db->query("SELECT * FROM `{$this->sessions_table}`"
. " WHERE `id` = ?", $id);
if ($row = $db->fetch_assoc($result)) {
$session = $this->session_info_parse($row);
if ($with_invitations && $session['is_owner']) {
$session['invitations'] = $this->invitations_find(array('session_id' => $id));
}
return $session;
}
}
/**
* Find editing sessions for specified path
*/
public function session_find($path, $invitations = true)
{
// create an URI for specified path
list($driver, $path) = $this->api->get_driver($path);
$uri = trim($driver->path2uri($path), '/') . '/';
// get existing sessions
$sessions = array();
$filter = array('file', 'owner', 'is_owner');
$db = $this->rc->get_dbh();
$result = $db->query("SELECT * FROM `{$this->sessions_table}`"
. " WHERE `uri` LIKE '" . $db->escape($uri) . "%'");
while ($row = $db->fetch_assoc($result)) {
if ($path = $this->uri2path($row['uri'])) {
$sessions[$row['id']] = $this->session_info_parse($row, $path, $filter);
}
}
// set 'is_invited' flag
if ($invitations && !empty($sessions)) {
$invitations = $this->invitations_list();
$states = array(self::STATUS_INVITED, self::STATUS_ACCEPTED);
foreach ($invitations as $invitation) {
if (!empty($sessions[$invitation['session_id']]) && in_array($invitation['status'], $states)) {
$sessions[$invitation['session_id']]['is_invited'] = true;
}
}
}
return $sessions;
}
/**
* Delete editing session (only owner can do that)
*
* @param string $id Session identifier
* @param bool $local Remove session only from local database
*/
public function session_delete($id, $local = false)
{
$db = $this->rc->get_dbh();
$result = $db->query("DELETE FROM `{$this->sessions_table}`"
. " WHERE `id` = ? AND `owner` = ?",
$id, $_SESSION['user']);
$success = $db->affected_rows($result) > 0;
// Send document delete to Manticore
if ($success && !$local) {
$req = $this->get_request();
$res = $req->document_delete($id);
}
return $success;
}
/**
* Create editing session
*/
protected function session_create($id, $uri, $owner, $data)
{
// Do this before starting the session in Manticore,
// it will immediately call api/document to get the file body
$db = $this->rc->get_dbh();
$result = $db->query("INSERT INTO `{$this->sessions_table}`"
. " (`id`, `uri`, `owner`, `data`) VALUES (?, ?, ?, ?)",
$id, $uri, $owner, json_encode($data));
$success = $db->affected_rows($result) > 0;
// create the session in Manticore
if ($success) {
$req = $this->get_request();
$res = $req->document_create(array(
'id' => $id,
'title' => '', // @TODO: maybe set to a file path without extension?
'access' => array(
array(
'identity' => $owner,
'permission' => file_manticore_api::ACCESS_WRITE,
),
),
));
if (!$res) {
$this->session_delete($id, true);
return false;
}
}
return $success;
}
/**
* Find invitations for current user
*
*
*
* @return array Invitations list
*/
public function invitations_list($session_id = null)
{
$invitations = array();
$db = $this->rc->get_dbh();
$result = $db->query("SELECT * FROM `{$this->invitations_table}`"
. " WHERE `user`= ?"
. ($session_id ? " AND `session_id` = " . $db->quote($session_id) : "")
. " ORDER BY `changed`", $_SESSION['user']);
while ($row = $db->fetch_assoc($result)) {
$invitations[] = $row;
}
return $invitations;
}
/**
* Find invitations for specified session_id
*/
public function invitations_find($filter)
{
$invitations = array();
$db = $this->rc->get_dbh();
foreach ($filter as $column => $value) {
$filter[$column] = "`$column` = " . $db->quote($value);
}
$where = implode(' AND ', $filter);
$result = $db->query("SELECT * FROM `{$this->invitations_table}`"
. " WHERE $where ORDER BY `changed`");
while ($row = $db->fetch_assoc($result)) {
$invitations[] = $row;
}
return $invitations;
}
/**
* Create an invitation
*
* @param string $session_id Document session identifier
* @param string $user User identifier
* @param string $status Invitation status (invited, requested)
*
* @throws Exception
*/
public function invitation_create($session_id, $user, $status = 'invited')
{
if ($status != self::STATUS_INVITED && $status != self::STATUS_REQUESTED) {
throw new Exception("Invalid invitation status.", file_api_core::ERROR_CODE);
}
// get session information
$session = $this->session_info($session_id);
if (empty($session)) {
throw new Exception("Document session not found.", file_api_core::ERROR_CODE);
}
// check session ownership, only owner can create 'new' invitations
if ($status == self::STATUS_INVITED && $session['owner'] != $_SESSION['user']) {
throw new Exception("No permission to create an invitation.", file_api_core::ERROR_CODE);
}
if ($session['owner'] == $user) {
throw new Exception("Not possible to create an invitation for the session creator.", file_api_core::ERROR_CODE);
}
// Update Manticore 'access' array
if ($status == self::STATUS_INVITED) {
$req = $this->get_request();
$res = $req->editor_add($session_id, $user, file_manticore_api::ACCESS_WRITE);
if (!$res) {
throw new Exception("Failed to create an invitation.", file_api_core::ERROR_CODE);
}
}
// insert invitation
$db = $this->rc->get_dbh();
$result = $db->query("INSERT INTO `{$this->invitations_table}`"
. " (`session_id`, `user`, `status`, `changed`)"
. " VALUES (?, ?, ?, " . $db->now() . ")",
$session_id, $user, $status);
if (!$db->affected_rows($result)) {
throw new Exception("Failed to create an invitation.", file_api_core::ERROR_CODE);
}
}
/**
* Delete an invitation (only session owner can do that)
*
* @param string $session_id Session identifier
* @param string $user User identifier
*
* @throws Exception
*/
public function invitation_delete($session_id, $user)
{
$db = $this->rc->get_dbh();
$result = $db->query("DELETE FROM `{$this->invitations_table}`"
. " WHERE `session_id` = ? AND `user` = ?"
. " AND EXISTS (SELECT 1 FROM `{$this->sessions_table}` WHERE `id` = ? AND `owner` = ?)",
$session_id, $user, $session_id, $_SESSION['user']);
if (!$db->affected_rows($result)) {
throw new Exception("Failed to delete an invitation.", file_api_core::ERROR_CODE);
}
// Update Manticore 'access' array
- // @todo
+ $req = $this->get_request();
+ $res = $req->editor_delete($session_id, $user);
+
+ if (!$res) {
+ throw new Exception("Failed to remove an invitation.", file_api_core::ERROR_CODE);
+ }
}
/**
* Update an invitation status
*
* @param string $session_id Session identifier
* @param string $user User identifier
* @param string $status Invitation status (accepted, declined)
*
* @throws Exception
*/
public function invitation_update($session_id, $user, $status)
{
if ($status != self::STATUS_ACCEPTED && $status != self::STATUS_DECLINED) {
throw new Exception("Invalid invitation status.", file_api_core::ERROR_CODE);
}
// get session information
$session = $this->session_info($session_id);
if (empty($session)) {
throw new Exception("Document session not found.", file_api_core::ERROR_CODE);
}
// check session ownership
if ($user != $_SESSION['user'] && $session['owner'] != $_SESSION['user']) {
throw new Exception("No permission to update an invitation.", file_api_core::ERROR_CODE);
}
$db = $this->rc->get_dbh();
$result = $db->query("UPDATE `{$this->invitations_table}`"
. " SET `status` = ?, `changed` = " . $db->now()
. " WHERE `session_id` = ? AND `user` = ?",
$status, $session_id, $user);
if (!$db->affected_rows($result)) {
throw new Exception("Failed to update an invitation status.", file_api_core::ERROR_CODE);
}
// Update Manticore 'access' array if an owner accepted an invitation request
if ($status == self::STATUS_ACCEPTED && $_SESSION['user'] == $session['owner']) {
// @todo
}
}
/**
* Parse session info data
*/
protected function session_info_parse($record, $path = null, $filter = array())
{
/*
if (is_string($data) && !empty($data)) {
$data = json_decode($data, true);
}
*/
$session = array();
$fields = array('id', 'uri', 'owner');
foreach ($fields as $field) {
if (isset($record[$field])) {
$session[$field] = $record[$field];
}
}
if ($path) {
$session['file'] = $path;
}
// @TODO: is_invited?, last_modified?
if ($session['owner'] == $_SESSION['user']) {
$session['is_owner'] = true;
}
if (!empty($filter)) {
$session = array_intersect_key($session, array_flip($filter));
}
return $session;
}
/**
* Generate URI of Manticore editing session
*/
protected function frame_uri($id)
{
$base_url = rtrim($this->rc->config->get('fileapi_manticore'), ' /');
return $base_url . '/document/' . $id . '/' . $_SESSION['manticore_token'];
}
/**
* Get file path from the URI
*/
protected function uri2path($uri)
{
$backend = $this->api->get_backend();
try {
return $backend->uri2path($uri);
}
catch (Exception $e) {
// do nothing
}
foreach ($this->api->get_drivers(true) as $driver) {
try {
$path = $driver->uri2path($uri);
$title = $driver->title();
if ($title) {
$path = $title . file_storage::SEPARATOR . $path;
}
return $path;
}
catch (Exception $e) {
// do nothing
}
}
}
/**
* Return Manticore user/session info
*/
public function user_info()
{
$req = $this->get_request();
$res = $req->get('api/users/me');
return $res->get();
}
/**
* Initialize Manticore API request handler
*/
protected function get_request()
{
if (!$this->request) {
$uri = rcube_utils::resolve_url($this->rc->config->get('fileapi_manticore'));
$this->request = new file_manticore_api($uri);
// Use stored session token, check if it's still valid
if ($_SESSION['manticore_token']) {
-
$is_valid = $this->request->set_session_token($_SESSION['manticore_token'], true);
+
if ($is_valid) {
return $this->request;
}
}
$backend = $this->api->get_backend();
$auth = $backend->auth_info();
$_SESSION['manticore_token'] = $this->request->login($auth['username'], $auth['password']);
if (empty($_SESSION['manticore_token'])) {
throw new Exception("Unable to login to Manticore server.", file_api_core::ERROR_CODE);
}
}
return $this->request;
}
}
diff --git a/lib/file_manticore_api.php b/lib/file_manticore_api.php
index 7d0d951..4329dbe 100644
--- a/lib/file_manticore_api.php
+++ b/lib/file_manticore_api.php
@@ -1,405 +1,440 @@
<?php
/**
+--------------------------------------------------------------------------+
| This file is part of the Kolab File API |
| |
| Copyright (C) 2011-2015, 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> |
+--------------------------------------------------------------------------+
*/
/**
* Helper class to connect to the Manticore API
*/
class file_manticore_api
{
/**
* @var HTTP_Request2
*/
private $request;
/**
* @var string
*/
private $base_url;
/**
* @var bool
*/
private $debug = false;
const ERROR_INTERNAL = 100;
const ERROR_CONNECTION = 500;
const ACCEPT_HEADER = "application/json,text/javascript,*/*";
const ACCESS_WRITE = 'write';
const ACCESS_READ = 'read';
const ACCESS_DENY = 'deny';
/**
* Class constructor.
*
* @param string $base_url Base URL of the Kolab API
*/
public function __construct($base_url)
{
require_once 'HTTP/Request2.php';
$config = rcube::get_instance()->config;
$this->debug = rcube_utils::get_boolean($config->get('fileapi_manticore_debug'));
$this->base_url = rtrim($base_url, '/') . '/';
$this->request = new HTTP_Request2();
self::configure($this->request);
}
/**
* Configure HTTP_Request2 object
*
* @param HTTP_Request2 $request Request object
*/
public static function configure($request)
{
// Configure connection options
$config = rcube::get_instance()->config;
$http_config = (array) $config->get('http_request', $config->get('kolab_http_request'));
// Deprecated config, all options are separated variables
if (empty($http_config)) {
$options = array(
'ssl_verify_peer',
'ssl_verify_host',
'ssl_cafile',
'ssl_capath',
'ssl_local_cert',
'ssl_passphrase',
'follow_redirects',
);
foreach ($options as $optname) {
if (($optvalue = $config->get($optname)) !== null
|| ($optvalue = $config->get('kolab_' . $optname)) !== null
) {
$http_config[$optname] = $optvalue;
}
}
}
if (!empty($http_config)) {
try {
$request->setConfig($http_config);
}
catch (Exception $e) {
rcube::log_error("HTTP: " . $e->getMessage());
}
}
// proxy User-Agent
$request->setHeader('user-agent', $_SERVER['HTTP_USER_AGENT']);
// some HTTP server configurations require this header
$request->setHeader('accept', self::ACCEPT_HEADER);
$request->setHeader('Content-Type', 'application/json; charset=UTF-8');
}
/**
* Return API's base URL
*
* @return string Base URL
*/
public function base_url()
{
return $this->base_url;
}
/**
* Return HTTP_Request2 object
*
* @return HTTP_Request2 Request object
*/
public function request()
{
return $this->request;
}
/**
* Logs specified user into the API
*
* @param string $username User name
* @param string $password User password
*
* @return string Session token (on success)
*/
public function login($username, $password)
{
$query = array(
'email' => $username,
'password' => $password,
);
// remove current token if any
$this->request->setHeader('Authorization');
// authenticate the user
$response = $this->post('auth/local', $query);
if ($token = $response->get('token')) {
$this->set_session_token($token);
}
return $token;
}
/**
* Sets request session token.
*
* @param string $token Session token.
* @param bool $validate Enables token validatity check
*
* @return bool Token validity status
*/
public function set_session_token($token, $validate = false)
{
$this->request->setHeader('Authorization', "Bearer $token");
if ($validate) {
$result = $this->get('api/user/me');
return $result->get_error_code() == 200;
}
return true;
}
/**
* Delete document editing session
*
* @param array $id Session identifier
*
* @return bool True on success, False on failure
*/
public function document_delete($id)
{
$res = $this->delete('api/documents/' . $id);
return $res->get_error_code() == 204;
}
/**
* Create document editing session
*
* @param array $params Session parameters
*
* @return bool True on success, False on failure
*/
public function document_create($params)
{
$res = $this->post('api/documents', $params);
// @FIXME: 422?
return $res->get_error_code() == 201 || $res->get_error_code() == 422;
}
/**
* Add document editor (update 'access' array)
*
* @param array $session_id Session identifier
* @param array $identity User identifier
*
* @return bool True on success, False on failure
*/
public function editor_add($session_id, $identity, $permission)
{
$res = $this->get("api/documents/$session_id/access");
if ($res->get_error_code() != 200) {
return false;
}
$access = $res->get();
// sanity check, this should never be empty
if (empty($access)) {
return false;
}
- // @todo add editor to the 'access' array
+ // add editor to the 'access' array
foreach ($access as $entry) {
if ($entry['identity'] == $identity) {
return true;
}
}
$access[] = array('identity' => $identity, 'permission' => $permission);
$res = $this->put("api/documents/$session_id/access", $access);
return $res->get_error_code() == 200;
}
+ /**
+ * Remove document editor (update 'access' array)
+ *
+ * @param array $session_id Session identifier
+ * @param array $identity User identifier
+ *
+ * @return bool True on success, False on failure
+ */
+ public function editor_delete($session_id, $identity)
+ {
+ $res = $this->get("api/documents/$session_id/access");
+
+ if ($res->get_error_code() != 200) {
+ return false;
+ }
+
+ $access = $res->get();
+ $found = true;
+
+ // remove editor from the 'access' array
+ foreach ((array) $access as $idx => $entry) {
+ if ($entry['identity'] == $identity) {
+ unset($access[$idx]);
+ }
+ }
+
+ if (!$found) {
+ return false;
+ }
+
+ $res = $this->put("api/documents/$session_id/access", $access);
+
+ return $res->get_error_code() == 200;
+ }
+
/**
* API's GET request.
*
* @param string $action Action name
* @param array $get Request arguments
*
* @return file_ui_api_result Response
*/
public function get($action, $get = array())
{
$url = $this->build_url($action, $get);
if ($this->debug) {
rcube::write_log('manticore', "GET: $url " . json_encode($get));
}
$this->request->setMethod(HTTP_Request2::METHOD_GET);
$this->request->setBody('');
return $this->get_response($url);
}
/**
* API's POST request.
*
* @param string $action Action name
* @param array $post POST arguments
*
* @return kolab_client_api_result Response
*/
public function post($action, $post = array())
{
$url = $this->build_url($action);
if ($this->debug) {
rcube::write_log('manticore', "POST: $url " . json_encode($post));
}
$this->request->setMethod(HTTP_Request2::METHOD_POST);
$this->request->setBody(json_encode($post));
return $this->get_response($url);
}
/**
* API's PUT request.
*
* @param string $action Action name
* @param array $post POST arguments
*
* @return kolab_client_api_result Response
*/
public function put($action, $post = array())
{
$url = $this->build_url($action);
if ($this->debug) {
rcube::write_log('manticore', "PUT: $url " . json_encode($post));
}
$this->request->setMethod(HTTP_Request2::METHOD_PUT);
$this->request->setBody(json_encode($post));
return $this->get_response($url);
}
/**
* API's DELETE request.
*
* @param string $action Action name
* @param array $get Request arguments
*
* @return file_ui_api_result Response
*/
public function delete($action, $get = array())
{
$url = $this->build_url($action, $get);
if ($this->debug) {
rcube::write_log('manticore', "DELETE: $url " . json_encode($get));
}
$this->request->setMethod(HTTP_Request2::METHOD_DELETE);
$this->request->setBody('');
return $this->get_response($url);
}
/**
* @param string $action Action GET parameter
* @param array $args GET parameters (hash array: name => value)
*
* @return Net_URL2 URL object
*/
private function build_url($action, $args = array())
{
$url = new Net_URL2($this->base_url . $action);
$url->setQueryVariables((array) $args);
return $url;
}
/**
* HTTP Response handler.
*
* @param Net_URL2 $url URL object
*
* @return kolab_client_api_result Response object
*/
private function get_response($url)
{
try {
$this->request->setUrl($url);
$response = $this->request->send();
}
catch (Exception $e) {
return new file_ui_api_result(null,
self::ERROR_CONNECTION, $e->getMessage());
}
try {
$body = $response->getBody();
}
catch (Exception $e) {
return new file_ui_api_result(null,
self::ERROR_INTERNAL, $e->getMessage());
}
$code = $response->getStatus();
if ($this->debug) {
rcube::write_log('manticore', "Response [$code]: $body");
}
if ($code < 300) {
$result = $body ? json_decode($body, true) : array();
}
else {
if ($code != 401) {
rcube::raise_error("Error $code on $url", true, false);
}
$error = $body;
}
return new file_ui_api_result($result, $code, $error);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Feb 5, 8:22 PM (4 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
427966
Default Alt Text
(39 KB)

Event Timeline