2012-07-28 21:40:11 +00:00
|
|
|
<?php
|
|
|
|
/**
|
2012-07-28 21:50:40 +00:00
|
|
|
* ownCloud
|
|
|
|
*
|
|
|
|
* @author Tom Needham
|
|
|
|
* @author Michael Gapczynski
|
|
|
|
* @author Bart Visscher
|
|
|
|
* @copyright 2012 Tom Needham tom@owncloud.com
|
|
|
|
* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
|
|
|
|
* @copyright 2012 Bart Visscher bartv@thisnet.nl
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 3 of the License, or any later version.
|
|
|
|
*
|
|
|
|
* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
2012-08-03 11:47:05 +00:00
|
|
|
|
2012-07-28 21:50:40 +00:00
|
|
|
class OC_API {
|
2012-08-03 00:02:31 +00:00
|
|
|
|
2012-09-13 09:41:20 +00:00
|
|
|
/**
|
|
|
|
* API authentication levels
|
|
|
|
*/
|
|
|
|
const GUEST_AUTH = 0;
|
|
|
|
const USER_AUTH = 1;
|
|
|
|
const SUBADMIN_AUTH = 2;
|
|
|
|
const ADMIN_AUTH = 3;
|
|
|
|
|
2012-08-03 00:02:31 +00:00
|
|
|
private static $server;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* initialises the OAuth store and server
|
|
|
|
*/
|
|
|
|
private static function init() {
|
2012-08-03 11:47:05 +00:00
|
|
|
self::$server = new OC_OAuth_Server(new OC_OAuth_Store());
|
2012-08-03 00:02:31 +00:00
|
|
|
}
|
2013-01-14 19:30:39 +00:00
|
|
|
|
2012-07-28 21:50:40 +00:00
|
|
|
/**
|
2012-12-31 15:47:15 +00:00
|
|
|
* api actions
|
|
|
|
*/
|
2012-07-30 10:56:21 +00:00
|
|
|
protected static $actions = array();
|
2013-01-14 19:30:39 +00:00
|
|
|
|
2012-07-28 21:50:40 +00:00
|
|
|
/**
|
2012-12-31 15:47:15 +00:00
|
|
|
* registers an api call
|
|
|
|
* @param string $method the http method
|
|
|
|
* @param string $url the url to match
|
|
|
|
* @param callable $action the function to run
|
|
|
|
* @param string $app the id of the app registering the call
|
|
|
|
* @param int $authLevel the level of authentication required for the call
|
|
|
|
* @param array $defaults
|
|
|
|
* @param array $requirements
|
|
|
|
*/
|
2013-01-14 19:30:39 +00:00
|
|
|
public static function register($method, $url, $action, $app,
|
2012-12-31 15:47:15 +00:00
|
|
|
$authLevel = OC_API::USER_AUTH,
|
2012-07-31 21:26:15 +00:00
|
|
|
$defaults = array(),
|
2012-12-31 15:47:15 +00:00
|
|
|
$requirements = array()) {
|
2012-07-28 21:50:40 +00:00
|
|
|
$name = strtolower($method).$url;
|
2012-07-30 18:52:47 +00:00
|
|
|
$name = str_replace(array('/', '{', '}'), '_', $name);
|
2012-12-31 15:47:15 +00:00
|
|
|
if(!isset(self::$actions[$name])) {
|
2012-08-02 19:51:31 +00:00
|
|
|
OC::getRouter()->useCollection('ocs');
|
2012-12-11 22:36:46 +00:00
|
|
|
OC::getRouter()->create($name, $url)
|
2012-07-31 20:34:35 +00:00
|
|
|
->method($method)
|
2012-07-28 21:50:40 +00:00
|
|
|
->action('OC_API', 'call');
|
|
|
|
self::$actions[$name] = array();
|
|
|
|
}
|
2012-12-31 15:47:15 +00:00
|
|
|
self::$actions[$name] = array('app' => $app, 'action' => $action, 'authlevel' => $authLevel);
|
2012-07-28 21:50:40 +00:00
|
|
|
}
|
2013-01-14 19:30:39 +00:00
|
|
|
|
2012-07-28 21:50:40 +00:00
|
|
|
/**
|
2012-12-31 15:47:15 +00:00
|
|
|
* handles an api call
|
|
|
|
* @param array $parameters
|
|
|
|
*/
|
|
|
|
public static function call($parameters) {
|
2012-09-17 12:08:17 +00:00
|
|
|
// Prepare the request variables
|
2012-12-31 15:47:15 +00:00
|
|
|
if($_SERVER['REQUEST_METHOD'] == 'PUT') {
|
2012-12-15 12:37:44 +00:00
|
|
|
parse_str(file_get_contents("php://input"), $parameters['_put']);
|
2012-09-17 12:08:17 +00:00
|
|
|
} else if($_SERVER['REQUEST_METHOD'] == 'DELETE'){
|
2012-12-15 12:37:44 +00:00
|
|
|
parse_str(file_get_contents("php://input"), $parameters['_delete']);
|
2012-09-17 12:08:17 +00:00
|
|
|
}
|
2012-07-30 19:03:41 +00:00
|
|
|
$name = $parameters['_route'];
|
2012-12-12 21:04:23 +00:00
|
|
|
// Check authentication and availability
|
2012-12-31 15:47:15 +00:00
|
|
|
if(self::isAuthorised(self::$actions[$name])) {
|
|
|
|
if(is_callable(self::$actions[$name]['action'])) {
|
2012-12-12 21:04:23 +00:00
|
|
|
$response = call_user_func(self::$actions[$name]['action'], $parameters);
|
2013-01-23 23:39:29 +00:00
|
|
|
if(!($response instanceof OC_OCS_Result)) {
|
2013-01-16 21:46:00 +00:00
|
|
|
$response = new OC_OCS_Result(null, 996, 'Internal Server Error');
|
|
|
|
}
|
2012-12-12 21:04:23 +00:00
|
|
|
} else {
|
2012-12-15 12:37:44 +00:00
|
|
|
$response = new OC_OCS_Result(null, 998, 'Api method not found');
|
2013-01-14 19:30:39 +00:00
|
|
|
}
|
2012-12-12 16:50:25 +00:00
|
|
|
} else {
|
2013-01-17 16:30:14 +00:00
|
|
|
header('WWW-Authenticate: Basic realm="Authorization Required"');
|
2013-01-16 20:29:29 +00:00
|
|
|
header('HTTP/1.0 401 Unauthorized');
|
2012-12-12 21:04:23 +00:00
|
|
|
$response = new OC_OCS_Result(null, 997, 'Unauthorised');
|
|
|
|
}
|
2012-07-28 21:50:40 +00:00
|
|
|
// Send the response
|
2012-12-11 22:36:46 +00:00
|
|
|
$formats = array('json', 'xml');
|
|
|
|
$format = !empty($_GET['format']) && in_array($_GET['format'], $formats) ? $_GET['format'] : 'xml';
|
|
|
|
self::respond($response, $format);
|
2012-09-13 15:18:38 +00:00
|
|
|
// logout the user to be stateless
|
2012-08-01 13:39:05 +00:00
|
|
|
OC_User::logout();
|
2012-07-28 21:50:40 +00:00
|
|
|
}
|
2013-01-14 19:30:39 +00:00
|
|
|
|
2012-09-13 09:41:20 +00:00
|
|
|
/**
|
|
|
|
* authenticate the api call
|
|
|
|
* @param array $action the action details as supplied to OC_API::register()
|
|
|
|
* @return bool
|
|
|
|
*/
|
2012-12-31 15:47:15 +00:00
|
|
|
private static function isAuthorised($action) {
|
2012-09-13 09:41:20 +00:00
|
|
|
$level = $action['authlevel'];
|
2012-12-31 15:47:15 +00:00
|
|
|
switch($level) {
|
2012-09-13 09:41:20 +00:00
|
|
|
case OC_API::GUEST_AUTH:
|
|
|
|
// Anyone can access
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case OC_API::USER_AUTH:
|
|
|
|
// User required
|
2012-09-13 15:18:38 +00:00
|
|
|
return self::loginUser();
|
2012-09-13 09:41:20 +00:00
|
|
|
break;
|
|
|
|
case OC_API::SUBADMIN_AUTH:
|
|
|
|
// Check for subadmin
|
2012-09-13 15:18:38 +00:00
|
|
|
$user = self::loginUser();
|
2012-12-31 15:47:15 +00:00
|
|
|
if(!$user) {
|
2012-09-13 15:18:38 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
2012-12-31 15:47:15 +00:00
|
|
|
$subAdmin = OC_SubAdmin::isSubAdmin($user);
|
2013-01-14 18:45:17 +00:00
|
|
|
if($subAdmin) {
|
2012-09-14 13:41:06 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2012-09-13 15:18:38 +00:00
|
|
|
}
|
2012-09-13 09:41:20 +00:00
|
|
|
break;
|
|
|
|
case OC_API::ADMIN_AUTH:
|
|
|
|
// Check for admin
|
2012-09-13 15:18:38 +00:00
|
|
|
$user = self::loginUser();
|
2012-12-31 15:47:15 +00:00
|
|
|
if(!$user) {
|
2012-09-13 15:18:38 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
2013-01-14 18:45:17 +00:00
|
|
|
return OC_User::isAdminUser($user);
|
2012-09-13 15:18:38 +00:00
|
|
|
}
|
2012-09-13 09:41:20 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// oops looks like invalid level supplied
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
2013-01-14 19:30:39 +00:00
|
|
|
}
|
|
|
|
|
2012-09-13 09:41:20 +00:00
|
|
|
/**
|
2012-09-13 15:18:38 +00:00
|
|
|
* http basic auth
|
|
|
|
* @return string|false (username, or false on failure)
|
2012-09-13 09:41:20 +00:00
|
|
|
*/
|
2013-01-14 19:30:39 +00:00
|
|
|
private static function loginUser(){
|
2012-12-31 15:47:15 +00:00
|
|
|
$authUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
|
|
|
|
$authPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
|
|
|
|
return OC_User::login($authUser, $authPw) ? $authUser : false;
|
2012-09-13 09:41:20 +00:00
|
|
|
}
|
2013-01-14 19:30:39 +00:00
|
|
|
|
2012-07-28 21:50:40 +00:00
|
|
|
/**
|
2012-12-31 15:47:15 +00:00
|
|
|
* respond to a call
|
|
|
|
* @param int|array $result the result from the api method
|
|
|
|
* @param string $format the format xml|json
|
|
|
|
*/
|
|
|
|
private static function respond($result, $format='xml') {
|
2012-12-12 16:50:25 +00:00
|
|
|
$response = array('ocs' => $result->getResult());
|
2012-07-30 19:03:41 +00:00
|
|
|
if ($format == 'json') {
|
2012-08-01 17:48:51 +00:00
|
|
|
OC_JSON::encodedPrint($response);
|
|
|
|
} else if ($format == 'xml') {
|
|
|
|
header('Content-type: text/xml; charset=UTF-8');
|
|
|
|
$writer = new XMLWriter();
|
|
|
|
$writer->openMemory();
|
|
|
|
$writer->setIndent( true );
|
|
|
|
$writer->startDocument();
|
|
|
|
self::toXML($response, $writer);
|
|
|
|
$writer->endDocument();
|
|
|
|
echo $writer->outputMemory(true);
|
2012-07-30 19:03:41 +00:00
|
|
|
}
|
2012-07-28 21:50:40 +00:00
|
|
|
}
|
2012-08-01 17:48:51 +00:00
|
|
|
|
2012-12-31 15:47:15 +00:00
|
|
|
private static function toXML($array, $writer) {
|
2012-08-01 17:48:51 +00:00
|
|
|
foreach($array as $k => $v) {
|
2013-01-24 10:49:48 +00:00
|
|
|
if ($k[0] === '@') {
|
2013-01-24 10:39:33 +00:00
|
|
|
$writer->writeAttribute(substr($k, 1), $v);
|
|
|
|
continue;
|
|
|
|
} else if (is_numeric($k)) {
|
2012-08-02 15:48:09 +00:00
|
|
|
$k = 'element';
|
|
|
|
}
|
2013-01-24 10:39:33 +00:00
|
|
|
if(is_array($v)) {
|
2012-08-01 17:48:51 +00:00
|
|
|
$writer->startElement($k);
|
|
|
|
self::toXML($v, $writer);
|
|
|
|
$writer->endElement();
|
|
|
|
} else {
|
|
|
|
$writer->writeElement($k, $v);
|
|
|
|
}
|
|
|
|
}
|
2012-09-14 13:41:06 +00:00
|
|
|
}
|
2013-01-14 19:30:39 +00:00
|
|
|
|
2012-07-30 19:03:41 +00:00
|
|
|
}
|