diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 109f86b2e8..0104d0d017 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -6,4 +6,4 @@ OC::$CLASSPATH['OC_Filestorage_Shared'] = "apps/files_sharing/lib/sharedstorage. OCP\Util::connectHook('OC_Filesystem', 'setup', 'OC_Filestorage_Shared', 'setup'); OCP\Share::registerBackend('file', 'OC_Share_Backend_File'); OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file'); -OCP\Util::addScript('files_sharing', 'share'); +OCP\Util::addScript('files_sharing', 'share'); \ No newline at end of file diff --git a/lib/api.php b/lib/api.php new file mode 100644 index 0000000000..cb67e0c2a8 --- /dev/null +++ b/lib/api.php @@ -0,0 +1,200 @@ +. +* +*/ + +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"), $parameters['_put']); + } else if($_SERVER['REQUEST_METHOD'] == 'DELETE'){ + parse_str(file_get_contents("php://input"), $parameters['_delete']); + } + $name = $parameters['_route']; + // Check authentication and availability + if(self::isAuthorised(self::$actions[$name])) { + if(is_callable(self::$actions[$name]['action'])) { + $response = call_user_func(self::$actions[$name]['action'], $parameters); + } else { + $response = new OC_OCS_Result(null, 998, 'Api method not found'); + } + } else { + $response = new OC_OCS_Result(null, 997, 'Unauthorised'); + } + // 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); + } + } + + 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); + } + } + } + +} diff --git a/lib/app.php b/lib/app.php old mode 100755 new mode 100644 index be6d5ab3dd..30f7630036 --- a/lib/app.php +++ b/lib/app.php @@ -137,6 +137,20 @@ class OC_App{ OC_Appconfig::setValue($app, 'types', $appTypes); } + + /** + * check if app is shipped + * @param string $appid the id of the app to check + * @return bool + */ + public static function isShipped($appid){ + $info = self::getAppInfo($appid); + if(isset($info['shipped']) && $info['shipped']=='true'){ + return true; + } else { + return false; + } + } /** * get all enabled apps diff --git a/lib/ocs.php b/lib/ocs.php index 1a0abf0e36..879aaa7668 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -73,14 +73,7 @@ class OC_OCS { } } - /** - main function to handle the REST request - **/ - public static function handle() { - // overwrite the 404 error page returncode - header("HTTP/1.0 200 OK"); - - + public static function notFound() { if($_SERVER['REQUEST_METHOD'] == 'GET') { $method='get'; }elseif($_SERVER['REQUEST_METHOD'] == 'PUT') { @@ -94,169 +87,10 @@ class OC_OCS { } $format = self::readData($method, 'format', 'text', ''); + $txt='Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n"; + $txt.=OC_OCS::getDebugOutput(); + echo(OC_OCS::generateXml($format,'failed',999,$txt)); - $router = new OC_Router(); - $router->useCollection('root'); - // CONFIG - $router->create('config', '/config.{format}') - ->defaults(array('format' => $format)) - ->action('OC_OCS', 'apiConfig') - ->requirements(array('format'=>'xml|json')); - - // PERSON - $router->create('person_check', '/person/check.{format}') - ->post() - ->defaults(array('format' => $format)) - ->action(function ($parameters) { - $format = $parameters['format']; - $login = OC_OCS::readData('post', 'login', 'text'); - $passwd = OC_OCS::readData('post', 'password', 'text'); - OC_OCS::personCheck($format, $login, $passwd); - }) - ->requirements(array('format'=>'xml|json')); - - // ACTIVITY - // activityget - GET ACTIVITY page,pagesize als urlparameter - $router->create('activity_get', '/activity.{format}') - ->defaults(array('format' => $format)) - ->action(function ($parameters) { - $format = $parameters['format']; - $page = OC_OCS::readData('get', 'page', 'int', 0); - $pagesize = OC_OCS::readData('get', 'pagesize', 'int', 10); - if($pagesize<1 or $pagesize>100) $pagesize=10; - OC_OCS::activityGet($format, $page, $pagesize); - }) - ->requirements(array('format'=>'xml|json')); - // activityput - POST ACTIVITY - $router->create('activity_put', '/activity.{format}') - ->post() - ->defaults(array('format' => $format)) - ->action(function ($parameters) { - $format = $parameters['format']; - $message = OC_OCS::readData('post', 'message', 'text'); - OC_OCS::activityPut($format, $message); - }) - ->requirements(array('format'=>'xml|json')); - - // PRIVATEDATA - // get - GET DATA - $router->create('privatedata_get', - '/privatedata/getattribute/{app}/{key}.{format}') - ->defaults(array('app' => '', 'key' => '', 'format' => $format)) - ->action(function ($parameters) { - $format = $parameters['format']; - $app = addslashes(strip_tags($parameters['app'])); - $key = addslashes(strip_tags($parameters['key'])); - OC_OCS::privateDataGet($format, $app, $key); - }) - ->requirements(array('format'=>'xml|json')); - // set - POST DATA - $router->create('privatedata_set', - '/privatedata/setattribute/{app}/{key}.{format}') - ->post() - ->defaults(array('format' => $format)) - ->action(function ($parameters) { - $format = $parameters['format']; - $app = addslashes(strip_tags($parameters['app'])); - $key = addslashes(strip_tags($parameters['key'])); - $value=OC_OCS::readData('post', 'value', 'text'); - OC_OCS::privateDataSet($format, $app, $key, $value); - }) - ->requirements(array('format'=>'xml|json')); - // delete - POST DATA - $router->create('privatedata_delete', - '/privatedata/deleteattribute/{app}/{key}.{format}') - ->post() - ->defaults(array('format' => $format)) - ->action(function ($parameters) { - $format = $parameters['format']; - $app = addslashes(strip_tags($parameters['app'])); - $key = addslashes(strip_tags($parameters['key'])); - OC_OCS::privateDataDelete($format, $app, $key); - }) - ->requirements(array('format'=>'xml|json')); - - // CLOUD - // systemWebApps - $router->create('system_webapps', - '/cloud/system/webapps.{format}') - ->defaults(array('format' => $format)) - ->action(function ($parameters) { - $format = $parameters['format']; - OC_OCS::systemwebapps($format); - }) - ->requirements(array('format'=>'xml|json')); - - // quotaget - $router->create('quota_get', - '/cloud/user/{user}.{format}') - ->defaults(array('format' => $format)) - ->action(function ($parameters) { - $format = $parameters['format']; - $user = $parameters['user']; - OC_OCS::quotaGet($format, $user); - }) - ->requirements(array('format'=>'xml|json')); - // quotaset - $router->create('quota_set', - '/cloud/user/{user}.{format}') - ->post() - ->defaults(array('format' => $format)) - ->action(function ($parameters) { - $format = $parameters['format']; - $user = $parameters['user']; - $quota = self::readData('post', 'quota', 'int'); - OC_OCS::quotaSet($format, $user, $quota); - }) - ->requirements(array('format'=>'xml|json')); - - // keygetpublic - $router->create('keygetpublic', - '/cloud/user/{user}/publickey.{format}') - ->defaults(array('format' => $format)) - ->action(function ($parameters) { - $format = $parameters['format']; - $user = $parameters['user']; - OC_OCS::publicKeyGet($format, $user); - }) - ->requirements(array('format'=>'xml|json')); - - // keygetprivate - $router->create('keygetpublic', - '/cloud/user/{user}/privatekey.{format}') - ->defaults(array('format' => $format)) - ->action(function ($parameters) { - $format = $parameters['format']; - $user = $parameters['user']; - OC_OCS::privateKeyGet($format, $user); - }) - ->requirements(array('format'=>'xml|json')); - - -// add more calls here -// please document all the call in the draft spec -// http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-1.7#CLOUD - -// TODO: -// users -// groups -// bookmarks -// sharing -// versioning -// news (rss) - try { - $router->match($_SERVER['PATH_INFO']); - } catch (ResourceNotFoundException $e) { - $txt='Invalid query, please check the syntax. ' - .'API specifications are here: ' - .'http://www.freedesktop.org/wiki/Specifications/open-collaboration-services.' - .'DEBUG OUTPUT:'."\n"; - $txt.=OC_OCS::getdebugoutput(); - echo(OC_OCS::generatexml($format, 'failed', 999, $txt)); - } catch (MethodNotAllowedException $e) { - OC_Response::setStatus(405); - } - exit(); } /** @@ -273,44 +107,6 @@ class OC_OCS { return($txt); } - /** - * checks if the user is authenticated - * checks the IP whitlist, apikeys and login/password combination - * if $forceuser is true and the authentication failed it returns an 401 http response. - * if $forceuser is false and authentification fails it returns an empty username string - * @param bool $forceuser - * @return username string - */ - private static function checkPassword($forceuser=true) { - //valid user account ? - if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser=''; - if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw=''; - - if(empty($authuser)) { - if($forceuser) { - header('WWW-Authenticate: Basic realm="your valid user account or api key"'); - header('HTTP/1.0 401 Unauthorized'); - exit; - }else{ - $identifieduser=''; - } - }else{ - if(!OC_User::login($authuser, $authpw)) { - if($forceuser) { - header('WWW-Authenticate: Basic realm="your valid user account or api key"'); - header('HTTP/1.0 401 Unauthorized'); - exit; - }else{ - $identifieduser=''; - } - }else{ - $identifieduser=$authuser; - } - } - - return($identifieduser); - } - /** * generates the xml or json response for the API call from an multidimenional data array. @@ -431,130 +227,6 @@ class OC_OCS { } } - /** - * return the config data of this server - * @param string $format - * @return string xml/json - */ - public static function apiConfig($parameters) { - $format = $parameters['format']; - $user=OC_OCS::checkpassword(false); - $url=substr(OCP\Util::getServerHost().$_SERVER['SCRIPT_NAME'], 0, -11).''; - - $xml['version']='1.7'; - $xml['website']='ownCloud'; - $xml['host']=OCP\Util::getServerHost(); - $xml['contact']=''; - $xml['ssl']='false'; - echo(OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'config', '', 1)); - } - - /** - * check if the provided login/apikey/password is valid - * @param string $format - * @param string $login - * @param string $passwd - * @return string xml/json - */ - private static function personCheck($format, $login, $passwd) { - if($login<>'') { - if(OC_User::login($login, $passwd)) { - $xml['person']['personid']=$login; - echo(OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'person', 'check', 2)); - }else{ - echo(OC_OCS::generatexml($format, 'failed', 102, 'login not valid')); - } - }else{ - echo(OC_OCS::generatexml($format, 'failed', 101, 'please specify all mandatory fields')); - } - } - - // ACTIVITY API ############################################# - - /** - * get my activities - * @param string $format - * @param string $page - * @param string $pagesize - * @return string xml/json - */ - private static function activityGet($format, $page, $pagesize) { - $user=OC_OCS::checkpassword(); - - //TODO - - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'activity', 'full', 2, $totalcount, $pagesize); - echo($txt); - } - - /** - * submit a activity - * @param string $format - * @param string $message - * @return string xml/json - */ - private static function activityPut($format, $message) { - // not implemented in ownCloud - $user=OC_OCS::checkpassword(); - echo(OC_OCS::generatexml($format, 'ok', 100, '')); - } - - // PRIVATEDATA API ############################################# - - /** - * get private data and create the xml for ocs - * @param string $format - * @param string $app - * @param string $key - * @return string xml/json - */ - private static function privateDataGet($format, $app="", $key="") { - $user=OC_OCS::checkpassword(); - $result=OC_OCS::getData($user, $app, $key); - $xml=array(); - foreach($result as $i=>$log) { - $xml[$i]['key']=$log['key']; - $xml[$i]['app']=$log['app']; - $xml[$i]['value']=$log['value']; - } - - - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'privatedata', 'full', 2, count($xml), 0);//TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it - echo($txt); - } - - /** - * set private data referenced by $key to $value and generate the xml for ocs - * @param string $format - * @param string $app - * @param string $key - * @param string $value - * @return string xml/json - */ - private static function privateDataSet($format, $app, $key, $value) { - $user=OC_OCS::checkpassword(); - if(OC_OCS::setData($user, $app, $key, $value)) { - echo(OC_OCS::generatexml($format, 'ok', 100, '')); - } - } - - /** - * delete private data referenced by $key and generate the xml for ocs - * @param string $format - * @param string $app - * @param string $key - * @return string xml/json - */ - private static function privateDataDelete($format, $app, $key) { - if($key=="" or $app=="") { - return; //key and app are NOT optional here - } - $user=OC_OCS::checkpassword(); - if(OC_OCS::deleteData($user, $app, $key)) { - echo(OC_OCS::generatexml($format, 'ok', 100, '')); - } - } - /** * get private data * @param string $user @@ -586,156 +258,4 @@ class OC_OCS { return $result; } - /** - * set private data referenced by $key to $value - * @param string $user - * @param string $app - * @param string $key - * @param string $value - * @return bool - */ - public static function setData($user, $app, $key, $value) { - return OC_Preferences::setValue($user, $app, $key, $value); - } - - /** - * delete private data referenced by $key - * @param string $user - * @param string $app - * @param string $key - * @return string xml/json - */ - public static function deleteData($user, $app, $key) { - return OC_Preferences::deleteKey($user, $app, $key); - } - - - // CLOUD API ############################################# - - /** - * get a list of installed web apps - * @param string $format - * @return string xml/json - */ - private static function systemWebApps($format) { - $login=OC_OCS::checkpassword(); - $apps=OC_App::getEnabledApps(); - $values=array(); - foreach($apps as $app) { - $info=OC_App::getAppInfo($app); - if(isset($info['standalone'])) { - $newvalue=array('name'=>$info['name'], 'url'=>OC_Helper::linkToAbsolute($app, ''), 'icon'=>''); - $values[]=$newvalue; - } - - } - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $values, 'cloud', '', 2, 0, 0); - echo($txt); - - } - - - /** - * get the quota of a user - * @param string $format - * @param string $user - * @return string xml/json - */ - private static function quotaGet($format, $user) { - $login=OC_OCS::checkpassword(); - if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { - - if(OC_User::userExists($user)) { - // calculate the disc space - $user_dir = '/'.$user.'/files'; - OC_Filesystem::init($user_dir); - $rootInfo=OC_FileCache::get(''); - $sharedInfo=OC_FileCache::get('/Shared'); - $used=$rootInfo['size']-$sharedInfo['size']; - $free=OC_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; - - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); - echo($txt); - }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); - } - }else{ - echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); - } - } - - /** - * set the quota of a user - * @param string $format - * @param string $user - * @param string $quota - * @return string xml/json - */ - private static function quotaSet($format, $user, $quota) { - $login=OC_OCS::checkpassword(); - if(OC_Group::inGroup($login, 'admin')) { - - // todo - // not yet implemented - // add logic here - error_log('OCS call: user:'.$user.' quota:'.$quota); - - $xml=array(); - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); - echo($txt); - }else{ - echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); - } - } - - /** - * get the public key of a user - * @param string $format - * @param string $user - * @return string xml/json - */ - private static function publicKeyGet($format, $user) { - $login=OC_OCS::checkpassword(); - - if(OC_User::userExists($user)) { - // calculate the disc space - $txt='this is the public key of '.$user; - echo($txt); - }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); - } - } - - /** - * get the private key of a user - * @param string $format - * @param string $user - * @return string xml/json - */ - private static function privateKeyGet($format, $user) { - $login=OC_OCS::checkpassword(); - if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { - - if(OC_User::userExists($user)) { - // calculate the disc space - $txt='this is the private key of '.$user; - echo($txt); - }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); - } - }else{ - echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); - } - } - - } diff --git a/lib/ocs/activity.php b/lib/ocs/activity.php new file mode 100644 index 0000000000..c30e21018d --- /dev/null +++ b/lib/ocs/activity.php @@ -0,0 +1,28 @@ +. +* +*/ + +class OC_OCS_Activity { + + public static function activityGet($parameters){ + // TODO + } +} diff --git a/lib/ocs/cloud.php b/lib/ocs/cloud.php new file mode 100644 index 0000000000..21095ec91e --- /dev/null +++ b/lib/ocs/cloud.php @@ -0,0 +1,98 @@ +. +* +*/ + +class OC_OCS_Cloud { + + public static function getSystemWebApps($parameters) { + OC_Util::checkLoggedIn(); + $apps = OC_App::getEnabledApps(); + $values = array(); + foreach($apps as $app) { + $info = OC_App::getAppInfo($app); + if(isset($info['standalone'])) { + $newValue = array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>''); + $values[] = $newValue; + } + } + return new OC_OCS_Result($values); + } + + public static function getUserQuota($parameters) { + $user = OC_User::getUser(); + if(OC_Group::inGroup($user, 'admin') or ($user==$parameters['user'])) { + + if(OC_User::userExists($parameters['user'])) { + // calculate the disc space + $userDir = '/'.$parameters['user'].'/files'; + OC_Filesystem::init($useDir); + $rootInfo = OC_FileCache::get(''); + $sharedInfo = OC_FileCache::get('/Shared'); + $used = $rootInfo['size'] - $sharedInfo['size']; + $free = OC_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); + } else { + return new OC_OCS_Result(null, 300); + } + } else { + return new OC_OCS_Result(null, 300); + } + } + + public static function getUserPublickey($parameters) { + + if(OC_User::userExists($parameters['user'])) { + // calculate the disc space + // TODO + return new OC_OCS_Result(array()); + } else { + return new OC_OCS_Result(null, 300); + } + } + + public static function getUserPrivatekey($parameters) { + $user = OC_User::getUser(); + if(OC_Group::inGroup($user, 'admin') or ($user==$parameters['user'])) { + + if(OC_User::userExists($user)) { + // calculate the disc space + $txt = 'this is the private key of '.$parameters['user']; + echo($txt); + } else { + return new OC_OCS_Result(null, 300, 'User does not exist'); + } + } else { + return new OC_OCS_Result('null', 300, 'You don´t have permission to access this ressource.'); + } + } +} diff --git a/lib/ocs/config.php b/lib/ocs/config.php new file mode 100644 index 0000000000..03c54aa231 --- /dev/null +++ b/lib/ocs/config.php @@ -0,0 +1,36 @@ +. +* +*/ + +class OC_OCS_Config { + + public static function apiConfig($parameters) { + $xml['version'] = '1.7'; + $xml['website'] = 'ownCloud'; + $xml['host'] = OCP\Util::getServerHost(); + $xml['contact'] = ''; + $xml['ssl'] = 'false'; + return new OC_OCS_Result($xml); + } + +} diff --git a/lib/ocs/person.php b/lib/ocs/person.php new file mode 100644 index 0000000000..169cc8211d --- /dev/null +++ b/lib/ocs/person.php @@ -0,0 +1,42 @@ +. +* +*/ + +class OC_OCS_Person { + + public static function check($parameters) { + $login = isset($_POST['login']) ? $_POST['login'] : false; + $password = isset($_POST['password']) ? $_POST['password'] : false; + if($login && $password) { + if(OC_User::checkPassword($login, $password)) { + $xml['person']['personid'] = $login; + return new OC_OCS_Result($xml); + } else { + return new OC_OCS_Result(null, 102); + } + } else { + return new OC_OCS_Result(null, 101); + } + } + +} diff --git a/lib/ocs/privatedata.php b/lib/ocs/privatedata.php new file mode 100644 index 0000000000..e01ed5e8b0 --- /dev/null +++ b/lib/ocs/privatedata.php @@ -0,0 +1,66 @@ +. +* +*/ + +class OC_OCS_Privatedata { + + public static function get($parameters) { + OC_Util::checkLoggedIn(); + $user = OC_User::getUser(); + $app = addslashes(strip_tags($parameters['app'])); + $key = addslashes(strip_tags($parameters['key'])); + $result = OC_OCS::getData($user,$app,$key); + $xml = array(); + foreach($result as $i=>$log) { + $xml[$i]['key']=$log['key']; + $xml[$i]['app']=$log['app']; + $xml[$i]['value']=$log['value']; + } + return new OC_OCS_Result($xml); + //TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it + } + + public static function set($parameters) { + OC_Util::checkLoggedIn(); + $user = OC_User::getUser(); + $app = addslashes(strip_tags($parameters['app'])); + $key = addslashes(strip_tags($parameters['key'])); + $value = OC_OCS::readData('post', 'value', 'text'); + if(OC_Preferences::setValue($user, $app, $key, $value)){ + return new OC_OCS_Result(null, 100); + } + } + + public static function delete($parameters) { + OC_Util::checkLoggedIn(); + $user = OC_User::getUser(); + $app = addslashes(strip_tags($parameters['app'])); + $key = addslashes(strip_tags($parameters['key'])); + if($key==="" or $app==="") { + return new OC_OCS_Result(null, 101); //key and app are NOT optional here + } + if(OC_Preferences::deleteKey($user, $app, $key)) { + return new OC_OCS_Result(null, 100); + } + } +} diff --git a/lib/ocs/result.php b/lib/ocs/result.php new file mode 100644 index 0000000000..b08d911f78 --- /dev/null +++ b/lib/ocs/result.php @@ -0,0 +1,75 @@ +. +* +*/ + +class OC_OCS_Result{ + + private $data, $message, $statusCode, $items, $perPage; + + /** + * create the OCS_Result object + * @param $data mixed the data to return + */ + public function __construct($data=null, $code=100, $message=null) { + $this->data = $data; + $this->statusCode = $code; + $this->message = $message; + } + + /** + * optionally set the total number of items available + * @param $items int + */ + public function setTotalItems(int $items) { + $this->items = $items; + } + + /** + * optionally set the the number of items per page + * @param $items int + */ + public function setItemsPerPage(int $items) { + $this->perPage = $items; + } + + /** + * returns the data associated with the api result + * @return array + */ + public function getResult() { + $return = array(); + $return['meta'] = array(); + $return['meta']['status'] = ($this->statusCode === 100) ? 'ok' : 'failure'; + $return['meta']['statuscode'] = $this->statusCode; + $return['meta']['message'] = $this->message; + if(isset($this->items)) { + $return['meta']['totalitems'] = $this->items; + } + if(isset($this->perPage)) { + $return['meta']['itemsperpage'] = $this->perPage; + } + $return['data'] = $this->data; + // Return the result data. + return $return; + } + + +} \ No newline at end of file diff --git a/lib/public/api.php b/lib/public/api.php new file mode 100644 index 0000000000..a85daa1935 --- /dev/null +++ b/lib/public/api.php @@ -0,0 +1,44 @@ +. +* +*/ + +namespace OCP; + +/** + * This class provides functions to manage apps in ownCloud + */ +class API { + + /** + * 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 (See OC_API constants) + * @param array $defaults + * @param array $requirements + */ + public static function register($method, $url, $action, $app, $authLevel = OC_API::USER_AUTH, $defaults = array(), $requirements = array()){ + \OC_API::register($method, $url, $action, $app, $authLevel, $defaults, $requirements); + } + +} diff --git a/lib/router.php b/lib/router.php index 8cb8fd4f33..27e14c38ab 100644 --- a/lib/router.php +++ b/lib/router.php @@ -58,6 +58,23 @@ class OC_Router { * loads the api routes */ public function loadRoutes() { + + // TODO cache + $this->root = $this->getCollection('root'); + foreach(OC_APP::getEnabledApps() as $app){ + $file = OC_App::getAppPath($app).'/appinfo/routes.php'; + if(file_exists($file)){ + $this->useCollection($app); + require_once($file); + $collection = $this->getCollection($app); + $this->root->addCollection($collection, '/apps/'.$app); + } + } + // include ocs routes + require_once(OC::$SERVERROOT.'/ocs/routes.php'); + $collection = $this->getCollection('ocs'); + $this->root->addCollection($collection, '/ocs'); + foreach($this->getRoutingFiles() as $app => $file) { $this->useCollection($app); require_once $file; @@ -67,6 +84,7 @@ class OC_Router { $this->useCollection('root'); require_once 'settings/routes.php'; require_once 'core/routes.php'; + } protected function getCollection($name) { diff --git a/ocs/routes.php b/ocs/routes.php new file mode 100644 index 0000000000..d77b96fc14 --- /dev/null +++ b/ocs/routes.php @@ -0,0 +1,20 @@ + + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +// Config +OC_API::register('get', '/config', array('OC_OCS_Config', 'apiConfig'), 'ocs', OC_API::GUEST_AUTH); +// Person +OC_API::register('post', '/person/check', array('OC_OCS_Person', 'check'), 'ocs', OC_API::GUEST_AUTH); +// Activity +OC_API::register('get', '/activity', array('OC_OCS_Activity', 'activityGet'), 'ocs', OC_API::USER_AUTH); +// Privatedata +OC_API::register('get', '/privatedata/getattribute', array('OC_OCS_Privatedata', 'get'), 'ocs', OC_API::USER_AUTH, array('app' => '', 'key' => '')); +OC_API::register('get', '/privatedata/getattribute/{app}', array('OC_OCS_Privatedata', 'get'), 'ocs', OC_API::USER_AUTH, array('key' => '')); +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/deleteattribute/{app}/{key}', array('OC_OCS_Privatedata', 'delete'), 'ocs', OC_API::USER_AUTH); +?> diff --git a/ocs/v1.php b/ocs/v1.php index 1652b0bedb..af83a56ff1 100644 --- a/ocs/v1.php +++ b/ocs/v1.php @@ -21,6 +21,15 @@ * */ -require_once '../lib/base.php'; -@ob_clean(); -OC_OCS::handle(); +require_once('../lib/base.php'); +use Symfony\Component\Routing\Exception\ResourceNotFoundException; +use Symfony\Component\Routing\Exception\MethodNotAllowedException; + +try { + OC::getRouter()->match('/ocs'.$_SERVER['PATH_INFO']); +} catch (ResourceNotFoundException $e) { + OC_OCS::notFound(); +} catch (MethodNotAllowedException $e) { + OC_Response::setStatus(405); +} + diff --git a/settings/css/oauth.css b/settings/css/oauth.css new file mode 100644 index 0000000000..ccdb98cfa3 --- /dev/null +++ b/settings/css/oauth.css @@ -0,0 +1,4 @@ +.guest-container{ width:35%; margin: 2em auto 0 auto; } +#oauth-request a.button{ float: right; } +#oauth-request ul li{ list-style: disc; } +#oauth-request ul { margin-left: 2em; margin-top: 1em; } diff --git a/settings/oauth.php b/settings/oauth.php new file mode 100644 index 0000000000..8dba9b33a5 --- /dev/null +++ b/settings/oauth.php @@ -0,0 +1,98 @@ + + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +require_once('../lib/base.php'); +// Logic +$operation = isset($_GET['operation']) ? $_GET['operation'] : ''; +$server = OC_OAuth_server::init(); + +switch($operation){ + + case 'register': + + // Here external apps can register with an ownCloud + if(empty($_GET['name']) || empty($_GET['url'])){ + // Invalid request + echo 401; + } else { + $callbacksuccess = empty($_GET['callback_success']) ? null : $_GET['callback_success']; + $callbackfail = empty($_GET['callback_fail']) ? null : $_GET['callback_fail']; + $consumer = OC_OAuth_Server::register_consumer($_GET['name'], $_GET['url'], $callbacksuccess, $callbackfail); + + echo 'Registered consumer successfully!

Key: ' . $consumer->key . '
Secret: ' . $consumer->secret; + } + break; + + case 'request_token': + + try { + $request = OAuthRequest::from_request(); + $token = $server->get_request_token($request); + echo $token; + } catch (OAuthException $exception) { + OC_Log::write('OC_OAuth_Server', $exception->getMessage(), OC_LOG::ERROR); + echo $exception->getMessage(); + } + + break; + case 'authorise'; + + OC_API::checkLoggedIn(); + // Example + $consumer = array( + 'name' => 'Firefox Bookmark Sync', + 'scopes' => array('ookmarks'), + ); + + // Check that the scopes are real and installed + $apps = OC_App::getEnabledApps(); + $notfound = array(); + foreach($consumer['scopes'] as $requiredapp){ + // App scopes are in this format: app_$appname + $requiredapp = end(explode('_', $requiredapp)); + if(!in_array($requiredapp, $apps)){ + $notfound[] = $requiredapp; + } + } + if(!empty($notfound)){ + // We need more apps :( Show error + if(count($notfound)==1){ + $message = 'requires that you have an extra app installed on your ownCloud. Please contact your ownCloud administrator and ask them to install the app below.'; + } else { + $message = 'requires that you have some extra apps installed on your ownCloud. Please contract your ownCloud administrator and ask them to install the apps below.'; + } + $t = new OC_Template('settings', 'oauth-required-apps', 'guest'); + OC_Util::addStyle('settings', 'oauth'); + $t->assign('requiredapps', $notfound); + $t->assign('consumer', $consumer); + $t->assign('message', $message); + $t->printPage(); + } else { + $t = new OC_Template('settings', 'oauth', 'guest'); + OC_Util::addStyle('settings', 'oauth'); + $t->assign('consumer', $consumer); + $t->printPage(); + } + break; + + case 'access_token'; + try { + $request = OAuthRequest::from_request(); + $token = $server->fetch_access_token($request); + echo $token; + } catch (OAuthException $exception) { + OC_Log::write('OC_OAuth_Server', $exception->getMessage(), OC_LOG::ERROR); + echo $exception->getMessage(); + } + + break; + default: + // Something went wrong, we need an operation! + OC_Response::setStatus(400); + break; + +} diff --git a/settings/templates/oauth-required-apps.php b/settings/templates/oauth-required-apps.php new file mode 100644 index 0000000000..d4fce54c59 --- /dev/null +++ b/settings/templates/oauth-required-apps.php @@ -0,0 +1,19 @@ + + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ +?> +
+

'.$_['message']; ?>

+ + Back to ownCloud +
diff --git a/settings/templates/oauth.php b/settings/templates/oauth.php new file mode 100644 index 0000000000..053a8aee6d --- /dev/null +++ b/settings/templates/oauth.php @@ -0,0 +1,20 @@ + + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ +?> +
+

is requesting your permission to read, write, modify and delete data from the following apps:

+ + Allow + Disallow +