From 7adbbfe05cfbbfad08e2ece6e8b7150bbe2514ca Mon Sep 17 00:00:00 2001 From: Frank Karlitschek Date: Wed, 14 Apr 2010 16:58:52 +0200 Subject: [PATCH] add Open Collaboration API support. You can now connect your ownCloud with the KDE Social Desktop and push notifications to your Social News Plasmoid. This requires KDE trunk or KDE SV 4.5 --- img/owncloud-icon.png | Bin 0 -> 2098 bytes inc/lib_base.php | 4 +- inc/lib_config.php | 2 - inc/lib_ocs.php | 432 ++++++++++++++++++++++++++++++++++++++++++ index.php | 4 +- ocs/providers.php | 45 +++++ ocs/v1.php | 27 +++ 7 files changed, 507 insertions(+), 7 deletions(-) create mode 100644 img/owncloud-icon.png create mode 100755 inc/lib_ocs.php create mode 100755 ocs/providers.php create mode 100644 ocs/v1.php diff --git a/img/owncloud-icon.png b/img/owncloud-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..af123f0cd529a925773d7e630c23d53ae1aa6f22 GIT binary patch literal 2098 zcmV-22+jA2P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igP< z3_1p{{>Cx@00**3L_t(&-tAa>a8+j!|Lu3qeI+*!0+na6fnpNCLWoXFFrrip$N*De zC}T&)s%=M{QAel$)K+KgV0Emoe?-xt*0gpUXdT*GgF?%rP!N%nM>2($NaRhRdEDH` zIp6O3$GtbXgquVhsCDN4W_Hdw`|a*I`|Y=nIY0pg6i`3`1r$&~0XGYDqYb{IrH573oI{5LLTetpSII`v730ht^O?S3+{FFt%0RXC+egP2xq=K%q{9{#6&T`XuIf)BvWu`K`u3OC@IhZ?GH-SEDN$gZ}Il~$zQ zA#-5<^vTcdXg&3FEBZA6I>=`3GehA-g6{NrRg>EO=ZoT@CHbQMTE0*gQ+tXudyr#yW{b5 z&4*5$*nZ?>0|0DoIZp3ML=+kqQ5c6_bII%@!cGyLE202F0RmJBfMX1`8AHv6s9n=V zY?6p96wx^fH7o){#8!0*d%COn(24If&Yt%8dy*rs9X&b4F{ZpHo@xNFK%uFi>ugN< z{OA6iam@Nr(eTf@V~LMiMk5H7>Bwt`LuPAPad@BOnD~XR*r}Z32LKcbIBObbPiwmA z5$Q{KYpuw)a(U$?#gCm!^$HQ`sN&G9p1Aj!i|@wX%F`(7EoAk@?igG{zZhE@z3qH= z>`hfI%L=4C{T+a&n;MZV`;RrVXk$(SrxV^We+W6|uSMa|&Ubs`&x`6EgLgX5JsG02 zQ^r-)zH|OctEyH2Pz6j;FtBQIUDc+WlI$=2t@UBwN~5ZZs*vSInx3TR*Lara5@8GhE#u2eH{MnA!OQ=(BQNehR_|N8QWRy; zNN96cU*Z)4UGq@{VDgyq51s1lI{u$F#6b=z0cK2D(c~+=i4K-)Gs|`8g_ZMWt+*~n z+Rj`IAAaZTUKXj%41C7|u4(do{z1N7HHP+uTxUbVvm1x`SQ?2J4!TeHmZ!4ls(ev5 zhGGk*-!}RKV@7$yR;{1>aR=4cR7MV+IDJ7xqLfZN5aEI_BAL#8%?229wt1FUCY9p`kq zTc`N%0!g2_ zG-D^990cN}EPn(5o_Y1aguISe<~mI)X=bp~j8VTgk$QIKF-Q5O((^Q*{|TL+KI=CpYhIS(fztGaI+Q(fizvgY{QA zBBDLQ0u?0{&AkTLvT12Q+f*73&5eeFpYQHXJk*!)Hl;lO?v!u88x97Z&d6$xZY~YW z6IKKqX9F{@$oYnAbvctX>De0AN;sBC?%DkMKc@CO;uv~WRKe-vl}jqB>UsWx-gxp6 z1=>7oS4)QPTN@!@oT?tToR%M~pU-B_l@;1sS{ym;Tdo#W9ZJ^<2VKWBcf}HSri*~M z)-rngQtSF1nL7TKEeb`tQuSAhY{ei2;0v3S?|+U5_)q|y-La<1aif4`M@x*UM z#Z#yi6&M04N+aLycjW#>_4?yY+suPY8rBwvgZB_oj73})H7sgW)OC${>9Y;9k48d) z`$ROzqQs&GfPTHyj$SIsWqHoeQnyX_iGIq2SpEmo)r|i1?ZgsY*n2!+-J>P(T3%6i`3` c1>9i#8x#Wql+w*6W&i*H07*qoM6N<$g8K#XNB{r; literal 0 HcmV?d00001 diff --git a/inc/lib_base.php b/inc/lib_base.php index c38ef4b1fc..8c0c1ca606 100755 --- a/inc/lib_base.php +++ b/inc/lib_base.php @@ -47,7 +47,6 @@ $CONFIG_HTTPFORCESSL=false; $CONFIG_DATEFORMAT='j M Y G:i'; $CONFIG_DBNAME='owncloud'; $CONFIG_DBTYPE='sqlite'; - // include the generated configfile @include_once('config.php'); @@ -64,6 +63,7 @@ if(isset($CONFIG_HTTPFORCESSL) and $CONFIG_HTTPFORCESSL){ require_once('lib_files.php'); require_once('lib_log.php'); require_once('lib_config.php'); +require_once('lib_ocs.php'); // load plugins $CONFIG_LOADPLUGINS='music'; @@ -257,7 +257,7 @@ class OC_DB { if($CONFIG_DBTYPE=='sqlite'){ $DBConnection = @new SQLiteDatabase($DOCUMENTROOT.'/'.$CONFIG_DBNAME); }elseif($CONFIG_DBTYPE=='mysql'){ - $DBConnection = @new mysqli($CONFIG_DBHOST, $CONFIG_DBUSER, $CONFIG_DBPASSWORD,$CONFIG_DBNAME); + $DBConnection =@new mysqli($CONFIG_DBHOST, $CONFIG_DBUSER, $CONFIG_DBPASSWORD,$CONFIG_DBNAME); } if (!$DBConnection) { @ob_end_clean(); diff --git a/inc/lib_config.php b/inc/lib_config.php index d2853e7173..e3bce232f5 100755 --- a/inc/lib_config.php +++ b/inc/lib_config.php @@ -210,5 +210,3 @@ GRANT ALL PRIVILEGES ON `{$_POST['dbname']}` . * TO '{$_POST['dbuser']}';"; } } ?> - - diff --git a/inc/lib_ocs.php b/inc/lib_ocs.php new file mode 100755 index 0000000000..97c412c419 --- /dev/null +++ b/inc/lib_ocs.php @@ -0,0 +1,432 @@ +. +* +*/ + + + +/** + * 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 + */ + public static function readdata($key,$type='raw',$getpriority=false,$default='') { + 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 + $url=$_SERVER['PHP_SELF']; + 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 + // personcheck - POST - PERSON/CHECK + }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 + }elseif(($method=='get') and (strtolower($ex[$paracount-3])=='v1.php')and (strtolower($ex[$paracount-2])=='activity')){ + $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 + }elseif(($method=='post') and (strtolower($ex[$paracount-3])=='v1.php')and (strtolower($ex[$paracount-2])=='activity')){ + $format=OC_OCS::readdata('format','text'); + $message=OC_OCS::readdata('message','text'); + OC_OCS::activityput($format,$message); + + + }else{ + $format=OC_OCS::readdata('format','text'); + $txt='please check the syntax. api specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services'."\n"; + $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 + */ + private static function getdebugoutput() { + $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 + * 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) { + global $CONFIG_ADMINLOGIN; + global $CONFIG_ADMINPASSWORD; + + //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(($authuser<>$CONFIG_ADMINLOGIN) or ($authpw<>$CONFIG_ADMINPASSWORD)) { + 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 + */ + private static function generatexml($format,$status,$statuscode,$message,$data=array(),$tag='',$tagattribute='',$dimension=-1,$itemscount='',$itemsperpage='') { + 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); + } + } + + public static function toxml($writer,$data,$node) { + 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 + */ + private static function apiconfig($format) { + $user=OC_OCS::checkpassword(false); + $url=substr($_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'],0,-11).''; + + $xml['version']='1.5'; + $xml['website']='ownCloud'; + $xml['host']=$_SERVER['HTTP_HOST']; + $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) { + global $CONFIG_ADMINLOGIN; + global $CONFIG_ADMINPASSWORD; + + if($login<>''){ + if(($login==$CONFIG_ADMINLOGIN) and ($passwd==$CONFIG_ADMINPASSWORD)) { + $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(); + + $result = OC_DB::query('select count(id) as co from log'); + $entry=OC_DB::fetch_assoc($result); + $totalcount=$entry['co']; + OC_DB::free_result($result); + + $result = OC_DB::query('select id,timestamp,user,type,message from log order by timestamp desc limit '.($page*$pagesize).','.$pagesize); + $itemscount=OC_DB::numrows($result); + + $url='http://'.substr($_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'],0,-11).''; + $xml=array(); + for ($i=0; $i < $itemscount;$i++) { + $log=OC_DB::fetch_assoc($result); + $xml[$i]['id']=$log['id']; + $xml[$i]['personid']=$log['user']; + $xml[$i]['firstname']=$log['user']; + $xml[$i]['lastname']=''; + $xml[$i]['profilepage']=$url; + + $pic=$url.'/img/owncloud-icon.png'; + $xml[$i]['avatarpic']=$pic; + + $xml[$i]['timestamp']=date('c',$log['timestamp']); + $xml[$i]['type']=1; + $xml[$i]['message']=OC_LOG::$TYPE[$log['type']].' '.strip_tags($log['message']); + $xml[$i]['link']=$url; + } + + $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,'')); + } + + + +} + + +?> diff --git a/index.php b/index.php index e755ab8623..6b0bcf63a4 100755 --- a/index.php +++ b/index.php @@ -28,9 +28,7 @@ if(isset($_GET['dir'])) $dir=$_GET['dir']; else $dir=''; if(isset($_GET['file'])) { OC_FILES::get($dir,$_GET['file']); -OC_FILES::get($dir,$_GET['file']); -OC_FILES::get($dir,$_GET['file']); -echo('heya'); + }else{ OC_UTIL::addscript('js/ajax.js'); diff --git a/ocs/providers.php b/ocs/providers.php new file mode 100755 index 0000000000..93ab38f838 --- /dev/null +++ b/ocs/providers.php @@ -0,0 +1,45 @@ +. +* +*/ + +require_once('../inc/lib_base.php'); + +$url='http://'.substr($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'],0,-17).'ocs/v1.php/'; + +echo(' + + + ownCloud + '.$url.' + ownCloud + + + + + + + + +'); + + +?> diff --git a/ocs/v1.php b/ocs/v1.php new file mode 100644 index 0000000000..14d56bbec6 --- /dev/null +++ b/ocs/v1.php @@ -0,0 +1,27 @@ +. +* +*/ + +require_once('../inc/lib_base.php'); +OC_OCS::handle(); + +?>