Skip to content
Snippets Groups Projects
Commit dfbf5720 authored by Tom Needham's avatar Tom Needham
Browse files

Merge pull request #1584 from owncloud/ocs_multiple_methods

Allow registering of multiple methods on each api route. Add /cloud/capabilities route.
parents 6bdb84ab e58dbd46
Branches
No related tags found
No related merge requests found
<?php <?php
OC::$CLASSPATH['OCA\Files\Capabilities'] = 'apps/files/lib/capabilities.php';
$l = OC_L10N::get('files'); $l = OC_L10N::get('files');
OCP\App::registerAdmin('files', 'admin'); OCP\App::registerAdmin('files', 'admin');
......
...@@ -9,3 +9,6 @@ ...@@ -9,3 +9,6 @@
$this->create('download', 'download{file}') $this->create('download', 'download{file}')
->requirements(array('file' => '.*')) ->requirements(array('file' => '.*'))
->actionInclude('files/download.php'); ->actionInclude('files/download.php');
// Register with the capabilities API
OC_API::register('get', '/cloud/capabilities', array('OCA\Files\Capabilities', 'getCapabilities'), 'files', OC_API::USER_AUTH);
\ No newline at end of file
<?php
/**
* Copyright (c) 2013 Tom Needham <tom@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files;
class Capabilities {
public static function getCapabilities() {
return new \OC_OCS_Result(array(
'capabilities' => array(
'files' => array(
'bigfilechunking' => true,
'undelete' => true,
),
),
));
}
}
\ No newline at end of file
...@@ -7,6 +7,7 @@ OC::$CLASSPATH['OCA\Encryption\Keymanager'] = 'files_encryption/lib/keymanager.p ...@@ -7,6 +7,7 @@ OC::$CLASSPATH['OCA\Encryption\Keymanager'] = 'files_encryption/lib/keymanager.p
OC::$CLASSPATH['OCA\Encryption\Stream'] = 'files_encryption/lib/stream.php'; OC::$CLASSPATH['OCA\Encryption\Stream'] = 'files_encryption/lib/stream.php';
OC::$CLASSPATH['OCA\Encryption\Proxy'] = 'files_encryption/lib/proxy.php'; OC::$CLASSPATH['OCA\Encryption\Proxy'] = 'files_encryption/lib/proxy.php';
OC::$CLASSPATH['OCA\Encryption\Session'] = 'files_encryption/lib/session.php'; OC::$CLASSPATH['OCA\Encryption\Session'] = 'files_encryption/lib/session.php';
OC::$CLASSPATH['OCA\Encryption\Capabilities'] = 'files_encryption/lib/capabilities.php';
OC_FileProxy::register( new OCA\Encryption\Proxy() ); OC_FileProxy::register( new OCA\Encryption\Proxy() );
......
<?php
/**
* Copyright (c) 2013, Tom Needham <tom@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or later.
* See the COPYING-README file.
*/
// Register with the capabilities API
OC_API::register('get', '/cloud/capabilities', array('OCA\Encryption\Capabilities', 'getCapabilities'), 'files_encryption', OC_API::USER_AUTH);
\ No newline at end of file
<?php
/**
* Copyright (c) 2013 Tom Needham <tom@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Encryption;
class Capabilities {
public static function getCapabilities() {
return new \OC_OCS_Result(array(
'capabilities' => array(
'files' => array(
'encryption' => true,
),
),
));
}
}
\ No newline at end of file
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
//require_once 'files_versions/versions.php'; //require_once 'files_versions/versions.php';
OC::$CLASSPATH['OCA\Files_Versions\Storage'] = 'files_versions/lib/versions.php'; OC::$CLASSPATH['OCA\Files_Versions\Storage'] = 'files_versions/lib/versions.php';
OC::$CLASSPATH['OCA\Files_Versions\Hooks'] = 'files_versions/lib/hooks.php'; OC::$CLASSPATH['OCA\Files_Versions\Hooks'] = 'files_versions/lib/hooks.php';
OC::$CLASSPATH['OCA\Files_Versions\Capabilities'] = 'files_versions/lib/capabilities.php';
OCP\Util::addscript('files_versions', 'versions'); OCP\Util::addscript('files_versions', 'versions');
......
<?php
/**
* Copyright (c) 2013, Tom Needham <tom@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or later.
* See the COPYING-README file.
*/
// Register with the capabilities API
OC_API::register('get', '/cloud/capabilities', array('OCA\Files_Versions\Capabilities', 'getCapabilities'), 'files_versions', OC_API::USER_AUTH);
\ No newline at end of file
<?php
/**
* Copyright (c) 2013 Tom Needham <tom@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Files_Versions;
class Capabilities {
public static function getCapabilities() {
return new \OC_OCS_Result(array(
'capabilities' => array(
'files' => array(
'versioning' => true,
),
),
));
}
}
\ No newline at end of file
...@@ -34,14 +34,13 @@ class OC_API { ...@@ -34,14 +34,13 @@ class OC_API {
const SUBADMIN_AUTH = 2; const SUBADMIN_AUTH = 2;
const ADMIN_AUTH = 3; const ADMIN_AUTH = 3;
private static $server;
/** /**
* initialises the OAuth store and server * API Response Codes
*/ */
private static function init() { const RESPOND_UNAUTHORISED = 997;
self::$server = new OC_OAuth_Server(new OC_OAuth_Store()); const RESPOND_SERVER_ERROR = 996;
} const RESPOND_NOT_FOUND = 998;
const RESPOND_UNKNOWN_ERROR = 999;
/** /**
* api actions * api actions
...@@ -71,7 +70,7 @@ class OC_API { ...@@ -71,7 +70,7 @@ class OC_API {
->action('OC_API', 'call'); ->action('OC_API', 'call');
self::$actions[$name] = array(); self::$actions[$name] = array();
} }
self::$actions[$name] = array('app' => $app, 'action' => $action, 'authlevel' => $authLevel); self::$actions[$name][] = array('app' => $app, 'action' => $action, 'authlevel' => $authLevel);
} }
/** /**
...@@ -86,29 +85,97 @@ class OC_API { ...@@ -86,29 +85,97 @@ class OC_API {
parse_str(file_get_contents("php://input"), $parameters['_delete']); parse_str(file_get_contents("php://input"), $parameters['_delete']);
} }
$name = $parameters['_route']; $name = $parameters['_route'];
// Foreach registered action
$responses = array();
foreach(self::$actions[$name] as $action) {
// Check authentication and availability // Check authentication and availability
if(self::isAuthorised(self::$actions[$name])) { if(!self::isAuthorised(self::$actions[$name])) {
if(is_callable(self::$actions[$name]['action'])) { $responses[] = array(
$response = call_user_func(self::$actions[$name]['action'], $parameters); 'app' => $action['app'],
if(!($response instanceof OC_OCS_Result)) { 'response' => new OC_OCS_Result(null, OC_API::RESPOND_UNAUTHORISED, 'Unauthorised'),
$response = new OC_OCS_Result(null, 996, 'Internal Server Error'); );
continue;
} }
} else { if(!is_callable($action['action'])) {
$response = new OC_OCS_Result(null, 998, 'Api method not found'); $responses[] = array(
'app' => $action['app'],
'response' => new OC_OCS_Result(null, OC_API::RESPOND_NOT_FOUND, 'Api method not found'),
);
continue;
} }
} else { // Run the action
header('WWW-Authenticate: Basic realm="Authorization Required"'); $responses[] = array(
header('HTTP/1.0 401 Unauthorized'); 'app' => $action['app'],
$response = new OC_OCS_Result(null, 997, 'Unauthorised'); 'response' => call_user_func($action['action'], $parameters),
);
} }
// Send the response $response = self::mergeResponses($responses);
$formats = array('json', 'xml'); $formats = array('json', 'xml');
$format = !empty($_GET['format']) && in_array($_GET['format'], $formats) ? $_GET['format'] : 'xml'; $format = !empty($_GET['format']) && in_array($_GET['format'], $formats) ? $_GET['format'] : 'xml';
self::respond($response, $format); self::respond($response);
// logout the user to be stateless
OC_User::logout(); OC_User::logout();
} }
/**
* merge the returned result objects into one response
* @param array $responses
*/
private static function mergeResponses($responses) {
$response = array();
// Sort into shipped and thirdparty
$shipped = array(
'succeeded' => array(),
'failed' => array(),
);
$thirdparty = array(
'succeeded' => array(),
'failed' => array(),
);
foreach($responses as $response) {
if(OC_App::isShipped($response['app']) || ($response['app'] === 'core')) {
if($response['response']->succeeded()) {
$shipped['succeeded'][$response['app']] = $response['response'];
} else {
$shipped['failed'][$response['app']] = $response['response'];
}
} else {
if($response['response']->succeeded()) {
$thirdparty['succeeded'][$response['app']] = $response['response'];
} else {
$thirdparty['failed'][$response['app']] = $response['response'];
}
}
}
// Remove any error responses if there is one shipped response that succeeded
if(!empty($shipped['succeeded'])) {
$responses = array_merge($shipped['succeeded'], $thirdparty['succeeded']);
} else if(!empty($shipped['failed'])) {
// Which shipped response do we use if they all failed?
// They may have failed for different reasons (different status codes)
// Which reponse code should we return?
// Maybe any that are not OC_API::RESPOND_SERVER_ERROR
$response = $shipped['failed'][0];
return $response;
} else {
// Return the third party failure result
$response = $thirdparty['failed'][0];
return $response;
}
// Merge the successful responses
$meta = array();
$data = array();
foreach($responses as $app => $response) {
if(OC_App::isShipped($app)) {
$data = array_merge_recursive($response->getData(), $data);
} else {
$data = array_merge_recursive($data, $response->getData());
}
}
$result = new OC_OCS_Result($data, 100);
return $result;
}
/** /**
* authenticate the api call * authenticate the api call
* @param array $action the action details as supplied to OC_API::register() * @param array $action the action details as supplied to OC_API::register()
...@@ -132,7 +199,8 @@ class OC_API { ...@@ -132,7 +199,8 @@ class OC_API {
return false; return false;
} else { } else {
$subAdmin = OC_SubAdmin::isSubAdmin($user); $subAdmin = OC_SubAdmin::isSubAdmin($user);
if($subAdmin) { $admin = OC_User::isAdminUser($user);
if($subAdmin || $admin) {
return true; return true;
} else { } else {
return false; return false;
...@@ -167,11 +235,21 @@ class OC_API { ...@@ -167,11 +235,21 @@ class OC_API {
/** /**
* respond to a call * respond to a call
* @param int|array $result the result from the api method * @param OC_OCS_Result $result
* @param string $format the format xml|json * @param string $format the format xml|json
*/ */
private static function respond($result, $format='xml') { private static function respond($result, $format='xml') {
$response = array('ocs' => $result->getResult()); // Send 401 headers if unauthorised
if($result->getStatusCode() === self::RESPOND_UNAUTHORISED) {
header('WWW-Authenticate: Basic realm="Authorisation Required"');
header('HTTP/1.0 401 Unauthorized');
}
$response = array(
'ocs' => array(
'meta' => $result->getMeta(),
'data' => $result->getData(),
),
);
if ($format == 'json') { if ($format == 'json') {
OC_JSON::encodedPrint($response); OC_JSON::encodedPrint($response);
} else if ($format == 'xml') { } else if ($format == 'xml') {
......
...@@ -24,49 +24,23 @@ ...@@ -24,49 +24,23 @@
class OC_OCS_Cloud { class OC_OCS_Cloud {
public static function getSystemWebApps() { public static function getCapabilities($parameters) {
OC_Util::checkLoggedIn(); $result = array();
$apps = OC_App::getEnabledApps(); list($major, $minor, $micro) = OC_Util::getVersion();
$values = array(); $result['version'] = array(
foreach($apps as $app) { 'major' => $major,
$info = OC_App::getAppInfo($app); 'minor' => $minor,
if(isset($info['standalone'])) { 'micro' => $micro,
$newValue = array('name'=>$info['name'], 'url'=>OC_Helper::linkToAbsolute($app, ''), 'icon'=>''); 'string' => OC_Util::getVersionString(),
$values[] = $newValue; 'edition' => OC_Util::getEditionString(),
} );
}
return new OC_OCS_Result($values);
}
public static function getUserQuota($parameters) {
$user = OC_User::getUser();
if(OC_User::isAdminUser($user) or ($user==$parameters['user'])) {
if(OC_User::userExists($parameters['user'])) {
// calculate the disc space
$userDir = '/'.$parameters['user'].'/files';
\OC\Files\Filesystem::init($parameters['user'], $userDir);
$rootInfo = \OC\Files\Filesystem::getFileInfo('');
$sharedInfo = \OC\Files\Filesystem::getFileInfo('/Shared');
$used = $rootInfo['size'] - $sharedInfo['size'];
$free = \OC\Files\Filesystem::free_space();
$total = $free + $used;
if($total===0) $total = 1; // prevent division by zero
$relative = round(($used/$total)*10000)/100;
$xml = array();
$xml['quota'] = $total;
$xml['free'] = $free;
$xml['used'] = $used;
$xml['relative'] = $relative;
return new OC_OCS_Result($xml); $result['capabilities'] = array(
} else { 'core' => array(
return new OC_OCS_Result(null, 300); 'pollinterval' => OC_Config::getValue('pollinterval', 60),
} ),
} else { );
return new OC_OCS_Result(null, 300); return new OC_OCS_Result($result);
}
} }
public static function getUserPublickey($parameters) { public static function getUserPublickey($parameters) {
......
...@@ -51,24 +51,46 @@ class OC_OCS_Result{ ...@@ -51,24 +51,46 @@ class OC_OCS_Result{
} }
/** /**
* returns the data associated with the api result * get the status code
* @return int
*/
public function getStatusCode() {
return $this->statusCode;
}
/**
* get the meta data for the result
* @return array * @return array
*/ */
public function getResult() { public function getMeta() {
$return = array(); $meta = array();
$return['meta'] = array(); $meta['status'] = ($this->statusCode === 100) ? 'ok' : 'failure';
$return['meta']['status'] = ($this->statusCode === 100) ? 'ok' : 'failure'; $meta['statuscode'] = $this->statusCode;
$return['meta']['statuscode'] = $this->statusCode; $meta['message'] = $this->message;
$return['meta']['message'] = $this->message;
if(isset($this->items)) { if(isset($this->items)) {
$return['meta']['totalitems'] = $this->items; $meta['totalitems'] = $this->items;
} }
if(isset($this->perPage)) { if(isset($this->perPage)) {
$return['meta']['itemsperpage'] = $this->perPage; $meta['itemsperpage'] = $this->perPage;
} }
$return['data'] = $this->data; return $meta;
// Return the result data.
return $return; }
/**
* get the result data
* @return array|string|int
*/
public function getData() {
return $this->data;
}
/**
* return bool if the method succedded
* @return bool
*/
public function succeeded() {
return (substr($this->statusCode, 0, 1) === '1');
} }
......
...@@ -17,4 +17,5 @@ OC_API::register('get', '/privatedata/getattribute/{app}', array('OC_OCS_Private ...@@ -17,4 +17,5 @@ OC_API::register('get', '/privatedata/getattribute/{app}', array('OC_OCS_Private
OC_API::register('get', '/privatedata/getattribute/{app}/{key}', array('OC_OCS_Privatedata', 'get'), 'ocs', OC_API::USER_AUTH); OC_API::register('get', '/privatedata/getattribute/{app}/{key}', array('OC_OCS_Privatedata', 'get'), 'ocs', OC_API::USER_AUTH);
OC_API::register('post', '/privatedata/setattribute/{app}/{key}', array('OC_OCS_Privatedata', 'set'), 'ocs', OC_API::USER_AUTH); OC_API::register('post', '/privatedata/setattribute/{app}/{key}', array('OC_OCS_Privatedata', 'set'), 'ocs', OC_API::USER_AUTH);
OC_API::register('post', '/privatedata/deleteattribute/{app}/{key}', array('OC_OCS_Privatedata', 'delete'), 'ocs', OC_API::USER_AUTH); OC_API::register('post', '/privatedata/deleteattribute/{app}/{key}', array('OC_OCS_Privatedata', 'delete'), 'ocs', OC_API::USER_AUTH);
// cloud
OC_API::register('get', '/cloud/capabilities', array('OC_OCS_Cloud', 'getCapabilities'), 'core', OC_API::USER_AUTH);
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment