. * */ class OC_API { /** * API authentication levels */ const GUEST_AUTH = 0; const USER_AUTH = 1; const SUBADMIN_AUTH = 2; const ADMIN_AUTH = 3; private static $server; /** * initialises the OAuth store and server */ private static function init() { self::$server = new OC_OAuth_Server(new OC_OAuth_Store()); } /** * api actions */ protected static $actions = array(); /** * 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 */ public static function register($method, $url, $action, $app, $authlevel = OC_API::USER_AUTH, $defaults = array(), $requirements = array()){ $name = strtolower($method).$url; $name = str_replace(array('/', '{', '}'), '_', $name); if(!isset(self::$actions[$name])){ OC::getRouter()->useCollection('ocs'); OC::getRouter()->create($name, $url) ->method($method) ->action('OC_API', 'call'); self::$actions[$name] = array(); } self::$actions[$name] = array('app' => $app, 'action' => $action, 'authlevel' => $authlevel); } /** * handles an api call * @param array $parameters */ public static function call($parameters){ // Prepare the request variables if($_SERVER['REQUEST_METHOD'] == 'PUT'){ parse_str(file_get_contents("php://input"), $_PUT); } else if($_SERVER['REQUEST_METHOD'] == 'DELETE'){ parse_str(file_get_contents("php://input"), $_DELETE); } $name = $parameters['_route']; // Loop through registered actions if(is_callable(self::$actions[$name]['action'])){ $response = call_user_func(self::$actions[$name]['action'], $parameters); } else { $response = new OC_OCS_Result(null, 998, 'Internal server error.'); } // Send the response $formats = array('json', 'xml'); $format = !empty($_GET['format']) && in_array($_GET['format'], $formats) ? $_GET['format'] : 'xml'; self::respond($response, $format); // logout the user to be stateless OC_User::logout(); } /** * authenticate the api call * @param array $action the action details as supplied to OC_API::register() * @return bool */ private static function isAuthorised($action){ $level = $action['authlevel']; switch($level){ case OC_API::GUEST_AUTH: // Anyone can access return true; break; case OC_API::USER_AUTH: // User required return self::loginUser(); break; case OC_API::SUBADMIN_AUTH: // Check for subadmin $user = self::loginUser(); if(!$user){ return false; } else { $subadmin = OC_SubAdmin::isSubAdmin($user); $admin = OC_Group::inGroup($user, 'admin'); if($subadmin || $admin){ return true; } else { return false; } } break; case OC_API::ADMIN_AUTH: // Check for admin $user = self::loginUser(); if(!$user){ return false; } else { return OC_Group::inGroup($user, 'admin'); } break; default: // oops looks like invalid level supplied return false; break; } } /** * http basic auth * @return string|false (username, or false on failure) */ private static function loginUser(){ $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; } /** * 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'){ $response = array('ocs' => $result->getResult()); if ($format == 'json') { 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); } else { var_dump($format, $response); } } private static function toXML($array, $writer){ foreach($array as $k => $v) { if (is_numeric($k)) { $k = 'element'; } if (is_array($v)) { $writer->startElement($k); self::toXML($v, $writer); $writer->endElement(); } else { $writer->writeElement($k, $v); } } } }