2010-04-14 14:58:52 +00:00
< ? php
/**
* ownCloud
*
2010-05-16 21:13:42 +00:00
* @ author Frank Karlitschek
2012-05-26 17:14:24 +00:00
* @ copyright 2012 Frank Karlitschek frank @ owncloud . org
2010-05-16 21:13:42 +00:00
*
2010-04-14 14:58:52 +00:00
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
2010-05-16 21:13:42 +00:00
* License as published by the Free Software Foundation ; either
2010-04-14 14:58:52 +00:00
* version 3 of the License , or any later version .
2010-05-16 21:13:42 +00:00
*
2010-04-14 14:58:52 +00:00
* 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 .
2010-05-16 21:13:42 +00:00
*
2011-02-09 14:50:27 +00:00
* You should have received a copy of the GNU Affero General Public
2010-04-14 14:58:52 +00:00
* License along with this library . If not , see < http :// www . gnu . org / licenses />.
2010-05-16 21:13:42 +00:00
*
2010-04-14 14:58:52 +00:00
*/
/**
* Class to handle open collaboration services API requests
*
*/
class OC_OCS {
/**
* reads input date from get / post / cookies and converts the date to a special data - type
*
* @ param variable $key
* @ param variable - type $type
* @ param priority $getpriority
* @ param default $default
* @ return data
*/
2010-07-10 17:59:18 +00:00
public static function readData ( $key , $type = 'raw' , $getpriority = false , $default = '' ) {
2010-04-14 14:58:52 +00:00
if ( $getpriority ) {
if ( isset ( $_GET [ $key ])) {
$data = $_GET [ $key ];
} elseif ( isset ( $_POST [ $key ])) {
$data = $_POST [ $key ];
} else {
if ( $default == '' ) {
if (( $type == 'int' ) or ( $type == 'float' )) $data = 0 ; else $data = '' ;
} else {
$data = $default ;
}
}
} else {
if ( isset ( $_POST [ $key ])) {
$data = $_POST [ $key ];
} elseif ( isset ( $_GET [ $key ])) {
$data = $_GET [ $key ];
} elseif ( isset ( $_COOKIE [ $key ])) {
$data = $_COOKIE [ $key ];
} else {
if ( $default == '' ) {
if (( $type == 'int' ) or ( $type == 'float' )) $data = 0 ; else $data = '' ;
} else {
$data = $default ;
}
}
}
if ( $type == 'raw' ) return ( $data );
elseif ( $type == 'text' ) return ( addslashes ( strip_tags ( $data )));
elseif ( $type == 'int' ) { $data = ( int ) $data ; return ( $data ); }
elseif ( $type == 'float' ) { $data = ( float ) $data ; return ( $data ); }
elseif ( $type == 'array' ) { $data = $data ; return ( $data ); }
}
/**
main function to handle the REST request
**/
public static function handle () {
// overwrite the 404 error page returncode
header ( " HTTP/1.0 200 OK " );
if ( $_SERVER [ 'REQUEST_METHOD' ] == 'GET' ) {
$method = 'get' ;
} elseif ( $_SERVER [ 'REQUEST_METHOD' ] == 'PUT' ) {
$method = 'put' ;
parse_str ( file_get_contents ( " php://input " ), $put_vars );
} elseif ( $_SERVER [ 'REQUEST_METHOD' ] == 'POST' ) {
$method = 'post' ;
} else {
echo ( 'internal server error: method not supported' );
exit ();
}
// preprocess url
2010-05-16 21:13:42 +00:00
$url = $_SERVER [ 'REQUEST_URI' ];
2010-04-14 14:58:52 +00:00
if ( substr ( $url ,( strlen ( $url ) - 1 )) <> '/' ) $url .= '/' ;
$ex = explode ( '/' , $url );
$paracount = count ( $ex );
// eventhandler
// CONFIG
// apiconfig - GET - CONFIG
if (( $method == 'get' ) and ( strtolower ( $ex [ $paracount - 3 ]) == 'v1.php' ) and ( strtolower ( $ex [ $paracount - 2 ]) == 'config' )){
$format = OC_OCS :: readdata ( 'format' , 'text' );
OC_OCS :: apiconfig ( $format );
// PERSON
2010-05-16 21:13:42 +00:00
// personcheck - POST - PERSON/CHECK
2010-04-14 14:58:52 +00:00
} elseif (( $method == 'post' ) and ( strtolower ( $ex [ $paracount - 4 ]) == 'v1.php' ) and ( strtolower ( $ex [ $paracount - 3 ]) == 'person' ) and ( strtolower ( $ex [ $paracount - 2 ]) == 'check' )){
$format = OC_OCS :: readdata ( 'format' , 'text' );
$login = OC_OCS :: readdata ( 'login' , 'text' );
$passwd = OC_OCS :: readdata ( 'password' , 'text' );
OC_OCS :: personcheck ( $format , $login , $passwd );
// ACTIVITY
// activityget - GET ACTIVITY page,pagesize als urlparameter
2010-05-16 21:13:42 +00:00
} elseif (( $method == 'get' ) and ( strtolower ( $ex [ $paracount - 3 ]) == 'v1.php' ) and ( strtolower ( $ex [ $paracount - 2 ]) == 'activity' )){
2010-04-14 14:58:52 +00:00
$format = OC_OCS :: readdata ( 'format' , 'text' );
$page = OC_OCS :: readdata ( 'page' , 'int' );
$pagesize = OC_OCS :: readdata ( 'pagesize' , 'int' );
if ( $pagesize < 1 or $pagesize > 100 ) $pagesize = 10 ;
OC_OCS :: activityget ( $format , $page , $pagesize );
// activityput - POST ACTIVITY
2010-05-16 21:13:42 +00:00
} elseif (( $method == 'post' ) and ( strtolower ( $ex [ $paracount - 3 ]) == 'v1.php' ) and ( strtolower ( $ex [ $paracount - 2 ]) == 'activity' )){
2010-04-14 14:58:52 +00:00
$format = OC_OCS :: readdata ( 'format' , 'text' );
$message = OC_OCS :: readdata ( 'message' , 'text' );
OC_OCS :: activityput ( $format , $message );
2010-07-16 09:36:03 +00:00
// PRIVATEDATA
// get - GET DATA
2010-07-25 00:38:35 +00:00
} elseif (( $method == 'get' ) and ( strtolower ( $ex [ $paracount - 4 ]) == 'v1.php' ) and ( strtolower ( $ex [ $paracount - 2 ]) == 'getattribute' )){
2010-07-25 10:55:52 +00:00
$format = OC_OCS :: readdata ( 'format' , 'text' );
2011-01-23 02:23:03 +00:00
OC_OCS :: privateDataGet ( $format );
2010-07-25 00:38:35 +00:00
} elseif (( $method == 'get' ) and ( strtolower ( $ex [ $paracount - 5 ]) == 'v1.php' ) and ( strtolower ( $ex [ $paracount - 3 ]) == 'getattribute' )){
2010-07-25 10:55:52 +00:00
$format = OC_OCS :: readdata ( 'format' , 'text' );
2011-01-23 02:23:03 +00:00
$app = $ex [ $paracount - 2 ];
OC_OCS :: privateDataGet ( $format , $app );
} elseif (( $method == 'get' ) and ( strtolower ( $ex [ $paracount - 6 ]) == 'v1.php' ) and ( strtolower ( $ex [ $paracount - 4 ]) == 'getattribute' )){
$format = OC_OCS :: readdata ( 'format' , 'text' );
2010-07-25 00:38:35 +00:00
$key = $ex [ $paracount - 2 ];
2011-01-23 02:23:03 +00:00
$app = $ex [ $paracount - 3 ];
OC_OCS :: privateDataGet ( $format , $app , $key );
2010-07-16 09:36:03 +00:00
// set - POST DATA
2010-08-02 18:39:14 +00:00
} elseif (( $method == 'post' ) and ( strtolower ( $ex [ $paracount - 6 ]) == 'v1.php' ) and ( strtolower ( $ex [ $paracount - 4 ]) == 'setattribute' )){
2010-07-25 10:55:52 +00:00
$format = OC_OCS :: readdata ( 'format' , 'text' );
2010-07-25 00:38:35 +00:00
$key = $ex [ $paracount - 2 ];
2010-08-02 18:39:14 +00:00
$app = $ex [ $paracount - 3 ];
2010-07-24 23:48:36 +00:00
$value = OC_OCS :: readdata ( 'value' , 'text' );
2010-08-02 18:39:14 +00:00
OC_OCS :: privatedataset ( $format , $app , $key , $value );
2011-02-06 00:22:48 +00:00
// delete - POST DATA
} elseif (( $method == 'post' ) and ( strtolower ( $ex [ $paracount - 6 ]) == 'v1.php' ) and ( strtolower ( $ex [ $paracount - 4 ]) == 'deleteattribute' )){
$format = OC_OCS :: readdata ( 'format' , 'text' );
$key = $ex [ $paracount - 2 ];
$app = $ex [ $paracount - 3 ];
OC_OCS :: privatedatadelete ( $format , $app , $key );
2010-04-14 14:58:52 +00:00
} else {
$format = OC_OCS :: readdata ( 'format' , 'text' );
2010-07-16 09:36:03 +00:00
$txt = 'Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:' . " \n " ;
2010-04-14 14:58:52 +00:00
$txt .= OC_OCS :: getdebugoutput ();
echo ( OC_OCS :: generatexml ( $format , 'failed' , 999 , $txt ));
}
exit ();
}
/**
* generated some debug information to make it easier to find faild API calls
* @ return debug data string
*/
2010-07-10 17:59:18 +00:00
private static function getDebugOutput () {
2010-04-14 14:58:52 +00:00
$txt = '' ;
$txt .= " debug output: \n " ;
if ( isset ( $_SERVER [ 'REQUEST_METHOD' ])) $txt .= 'http request method: ' . $_SERVER [ 'REQUEST_METHOD' ] . " \n " ;
if ( isset ( $_SERVER [ 'REQUEST_URI' ])) $txt .= 'http request uri: ' . $_SERVER [ 'REQUEST_URI' ] . " \n " ;
if ( isset ( $_GET )) foreach ( $_GET as $key => $value ) $txt .= 'get parameter: ' . $key . '->' . $value . " \n " ;
if ( isset ( $_POST )) foreach ( $_POST as $key => $value ) $txt .= 'post parameter: ' . $key . '->' . $value . " \n " ;
return ( $txt );
}
/**
* checks if the user is authenticated
* checks the IP whitlist , apikeys and login / password combination
2010-05-16 21:13:42 +00:00
* if $forceuser is true and the authentication failed it returns an 401 http response .
2010-04-14 14:58:52 +00:00
* if $forceuser is false and authentification fails it returns an empty username string
* @ param bool $forceuser
* @ return username string
*/
2010-07-10 17:59:18 +00:00
private static function checkPassword ( $forceuser = true ) {
2010-04-14 14:58:52 +00:00
//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 {
2011-07-29 19:36:03 +00:00
if ( ! OC_User :: login ( $authuser , $authpw )){
2010-04-14 14:58:52 +00:00
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 .
* @ param string $format
* @ param string $status
* @ param string $statuscode
* @ param string $message
* @ param array $data
* @ param string $tag
* @ param string $tagattribute
* @ param int $dimension
* @ param int $itemscount
* @ param int $itemsperpage
* @ return string xml / json
*/
2010-07-10 17:59:18 +00:00
private static function generateXml ( $format , $status , $statuscode , $message , $data = array (), $tag = '' , $tagattribute = '' , $dimension =- 1 , $itemscount = '' , $itemsperpage = '' ) {
2010-04-14 14:58:52 +00:00
if ( $format == 'json' ) {
$json = array ();
$json [ 'status' ] = $status ;
$json [ 'statuscode' ] = $statuscode ;
$json [ 'message' ] = $message ;
$json [ 'totalitems' ] = $itemscount ;
$json [ 'itemsperpage' ] = $itemsperpage ;
$json [ 'data' ] = $data ;
return ( json_encode ( $json ));
} else {
$txt = '' ;
$writer = xmlwriter_open_memory ();
xmlwriter_set_indent ( $writer , 2 );
xmlwriter_start_document ( $writer );
xmlwriter_start_element ( $writer , 'ocs' );
xmlwriter_start_element ( $writer , 'meta' );
xmlwriter_write_element ( $writer , 'status' , $status );
xmlwriter_write_element ( $writer , 'statuscode' , $statuscode );
xmlwriter_write_element ( $writer , 'message' , $message );
if ( $itemscount <> '' ) xmlwriter_write_element ( $writer , 'totalitems' , $itemscount );
if ( ! empty ( $itemsperpage )) xmlwriter_write_element ( $writer , 'itemsperpage' , $itemsperpage );
xmlwriter_end_element ( $writer );
if ( $dimension == '0' ) {
// 0 dimensions
xmlwriter_write_element ( $writer , 'data' , $data );
} elseif ( $dimension == '1' ) {
xmlwriter_start_element ( $writer , 'data' );
foreach ( $data as $key => $entry ) {
xmlwriter_write_element ( $writer , $key , $entry );
}
xmlwriter_end_element ( $writer );
} elseif ( $dimension == '2' ) {
xmlwriter_start_element ( $writer , 'data' );
foreach ( $data as $entry ) {
xmlwriter_start_element ( $writer , $tag );
if ( ! empty ( $tagattribute )) {
xmlwriter_write_attribute ( $writer , 'details' , $tagattribute );
}
foreach ( $entry as $key => $value ) {
if ( is_array ( $value )){
foreach ( $value as $k => $v ) {
xmlwriter_write_element ( $writer , $k , $v );
}
} else {
xmlwriter_write_element ( $writer , $key , $value );
}
}
xmlwriter_end_element ( $writer );
}
xmlwriter_end_element ( $writer );
} elseif ( $dimension == '3' ) {
xmlwriter_start_element ( $writer , 'data' );
foreach ( $data as $entrykey => $entry ) {
xmlwriter_start_element ( $writer , $tag );
if ( ! empty ( $tagattribute )) {
xmlwriter_write_attribute ( $writer , 'details' , $tagattribute );
}
foreach ( $entry as $key => $value ) {
if ( is_array ( $value )){
xmlwriter_start_element ( $writer , $entrykey );
foreach ( $value as $k => $v ) {
xmlwriter_write_element ( $writer , $k , $v );
}
xmlwriter_end_element ( $writer );
} else {
xmlwriter_write_element ( $writer , $key , $value );
}
}
xmlwriter_end_element ( $writer );
}
xmlwriter_end_element ( $writer );
} elseif ( $dimension == 'dynamic' ) {
xmlwriter_start_element ( $writer , 'data' );
OC_OCS :: toxml ( $writer , $data , 'comment' );
xmlwriter_end_element ( $writer );
}
xmlwriter_end_element ( $writer );
xmlwriter_end_document ( $writer );
$txt .= xmlwriter_output_memory ( $writer );
unset ( $writer );
return ( $txt );
}
}
2010-07-10 17:59:18 +00:00
public static function toXml ( $writer , $data , $node ) {
2010-04-14 14:58:52 +00:00
foreach ( $data as $key => $value ) {
if ( is_numeric ( $key )) {
$key = $node ;
}
if ( is_array ( $value )){
xmlwriter_start_element ( $writer , $key );
OC_OCS :: toxml ( $writer , $value , $node );
xmlwriter_end_element ( $writer );
} else {
xmlwriter_write_element ( $writer , $key , $value );
}
}
}
/**
* return the config data of this server
* @ param string $format
* @ return string xml / json
*/
2010-07-10 17:59:18 +00:00
private static function apiConfig ( $format ) {
2010-04-14 14:58:52 +00:00
$user = OC_OCS :: checkpassword ( false );
2012-05-31 18:26:09 +00:00
$url = substr ( OCP\Util :: getServerHost () . $_SERVER [ 'SCRIPT_NAME' ], 0 , - 11 ) . '' ;
2010-04-14 14:58:52 +00:00
$xml [ 'version' ] = '1.5' ;
$xml [ 'website' ] = 'ownCloud' ;
2012-05-31 18:26:09 +00:00
$xml [ 'host' ] = OCP\Util :: getServerHost ();
2010-04-14 14:58:52 +00:00
$xml [ 'contact' ] = '' ;
$xml [ 'ssl' ] = 'false' ;
echo ( OC_OCS :: generatexml ( $format , 'ok' , 100 , '' , $xml , 'config' , '' , 1 ));
}
2010-05-16 21:13:42 +00:00
/**
2010-04-14 14:58:52 +00:00
* check if the provided login / apikey / password is valid
* @ param string $format
* @ param string $login
* @ param string $passwd
* @ return string xml / json
*/
2010-07-10 17:59:18 +00:00
private static function personCheck ( $format , $login , $passwd ) {
2010-04-14 14:58:52 +00:00
if ( $login <> '' ){
2011-07-29 19:36:03 +00:00
if ( OC_User :: login ( $login , $passwd )){
2010-04-14 14:58:52 +00:00
$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 #############################################
2010-05-16 21:13:42 +00:00
/**
2010-04-14 14:58:52 +00:00
* get my activities
* @ param string $format
* @ param string $page
* @ param string $pagesize
* @ return string xml / json
*/
2010-07-10 17:59:18 +00:00
private static function activityGet ( $format , $page , $pagesize ) {
2010-04-14 14:58:52 +00:00
$user = OC_OCS :: checkpassword ();
2011-04-16 11:55:33 +00:00
2011-08-10 10:36:32 +00:00
//TODO
2010-04-14 14:58:52 +00:00
$txt = OC_OCS :: generatexml ( $format , 'ok' , 100 , '' , $xml , 'activity' , 'full' , 2 , $totalcount , $pagesize );
echo ( $txt );
}
2010-05-16 21:13:42 +00:00
/**
2010-04-14 14:58:52 +00:00
* submit a activity
* @ param string $format
* @ param string $message
* @ return string xml / json
*/
2010-07-10 17:59:18 +00:00
private static function activityPut ( $format , $message ) {
2010-04-14 14:58:52 +00:00
// not implemented in ownCloud
$user = OC_OCS :: checkpassword ();
echo ( OC_OCS :: generatexml ( $format , 'ok' , 100 , '' ));
}
2010-07-16 09:36:03 +00:00
// PRIVATEDATA API #############################################
2010-04-14 14:58:52 +00:00
2010-07-16 09:36:03 +00:00
/**
2011-02-06 00:22:48 +00:00
* get private data and create the xml for ocs
* @ param string $format
* @ param string $app
2010-07-16 09:36:03 +00:00
* @ param string $key
* @ return string xml / json
*/
2011-01-23 02:23:03 +00:00
private static function privateDataGet ( $format , $app = " " , $key = " " ) {
2010-07-16 09:36:03 +00:00
$user = OC_OCS :: checkpassword ();
2011-02-06 00:22:48 +00:00
$result = OC_OCS :: getData ( $user , $app , $key );
2010-07-16 09:36:03 +00:00
$xml = array ();
foreach ( $result as $i => $log ) {
$xml [ $i ][ 'key' ] = $log [ 'key' ];
2011-02-06 00:22:48 +00:00
$xml [ $i ][ 'app' ] = $log [ 'app' ];
2010-07-16 09:36:03 +00:00
$xml [ $i ][ 'value' ] = $log [ 'value' ];
}
2011-02-06 00:22:48 +00:00
$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
2010-07-16 09:36:03 +00:00
echo ( $txt );
}
/**
2011-02-06 00:22:48 +00:00
* set private data referenced by $key to $value and generate the xml for ocs
* @ param string $format
* @ param string $app
2010-07-16 09:36:03 +00:00
* @ param string $key
* @ param string $value
* @ return string xml / json
*/
2011-01-23 02:23:03 +00:00
private static function privateDataSet ( $format , $app , $key , $value ) {
2011-02-06 00:22:48 +00:00
$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
* @ param string $app
* @ param string $key
2011-03-16 17:18:45 +00:00
* @ param bool $like use LIKE instead of = when comparing keys
2011-02-06 00:22:48 +00:00
* @ return array
*/
2011-07-28 18:23:58 +00:00
public static function getData ( $user , $app = " " , $key = " " ) {
2011-02-06 00:22:48 +00:00
if ( $app ){
2011-07-28 18:23:58 +00:00
$apps = array ( $app );
} else {
2011-07-29 19:36:03 +00:00
$apps = OC_Preferences :: getApps ( $user );
2011-07-28 18:23:58 +00:00
}
if ( $key ){
$keys = array ( $key );
2011-02-06 00:22:48 +00:00
} else {
2011-07-28 18:23:58 +00:00
foreach ( $apps as $app ){
2011-07-29 19:36:03 +00:00
$keys = OC_Preferences :: getKeys ( $user , $app );
2011-07-28 18:23:58 +00:00
}
}
$result = array ();
foreach ( $apps as $app ){
foreach ( $keys as $key ){
2011-07-29 19:36:03 +00:00
$value = OC_Preferences :: getValue ( $user , $app , $key );
2011-07-28 18:23:58 +00:00
$result [] = array ( 'app' => $app , 'key' => $key , 'value' => $value );
2011-02-06 00:22:48 +00:00
}
}
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 ) {
2011-07-29 19:36:03 +00:00
return OC_Preferences :: setValue ( $user , $app , $key , $value );
2011-01-23 02:23:03 +00:00
}
2010-04-14 14:58:52 +00:00
2011-02-06 00:22:48 +00:00
/**
* 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 ) {
2011-07-29 19:36:03 +00:00
return OC_Preferences :: deleteKey ( $user , $app , $key );
2011-03-16 17:18:45 +00:00
}
2011-02-06 00:22:48 +00:00
}