From d2b6031c34c83e2f28315cff8f649000ce5a4175 Mon Sep 17 00:00:00 2001 From: Fox Date: Fri, 27 Mar 2015 22:45:52 +0530 Subject: [PATCH 1/5] Initial commit --- IJR_Base64.php | 17 + IJR_CallbackDefines.php | 224 ++++++ IJR_Date.php | 49 ++ IJR_Error.php | 22 + IJR_IntrospectionServer.php | 146 ++++ IJR_Message.php | 155 ++++ IJR_Server.php | 235 +++++++ README | 0 _test/jsonrpc_test.php | 46 ++ conf/.svn/entries | 96 +++ conf/.svn/prop-base/default.php.svn-base | 5 + conf/.svn/prop-base/metadata.php.svn-base | 5 + conf/.svn/text-base/default.php.svn-base | 4 + conf/.svn/text-base/metadata.php.svn-base | 4 + conf/default.php | 6 + conf/metadata.php | 6 + jsonrpc.php | 702 +++++++++++++++++++ lang/.svn/entries | 31 + lang/en/.svn/entries | 96 +++ lang/en/.svn/prop-base/lang.php.svn-base | 5 + lang/en/.svn/prop-base/settings.php.svn-base | 5 + lang/en/.svn/text-base/lang.php.svn-base | 3 + lang/en/.svn/text-base/settings.php.svn-base | 3 + lang/en/lang.php | 3 + lang/en/settings.php | 6 + manager.dat | 2 + plugin.info.txt | 7 + 27 files changed, 1883 insertions(+) create mode 100755 IJR_Base64.php create mode 100755 IJR_CallbackDefines.php create mode 100755 IJR_Date.php create mode 100755 IJR_Error.php create mode 100755 IJR_IntrospectionServer.php create mode 100755 IJR_Message.php create mode 100755 IJR_Server.php create mode 100755 README create mode 100755 _test/jsonrpc_test.php create mode 100755 conf/.svn/entries create mode 100755 conf/.svn/prop-base/default.php.svn-base create mode 100755 conf/.svn/prop-base/metadata.php.svn-base create mode 100755 conf/.svn/text-base/default.php.svn-base create mode 100755 conf/.svn/text-base/metadata.php.svn-base create mode 100755 conf/default.php create mode 100755 conf/metadata.php create mode 100755 jsonrpc.php create mode 100755 lang/.svn/entries create mode 100755 lang/en/.svn/entries create mode 100755 lang/en/.svn/prop-base/lang.php.svn-base create mode 100755 lang/en/.svn/prop-base/settings.php.svn-base create mode 100755 lang/en/.svn/text-base/lang.php.svn-base create mode 100755 lang/en/.svn/text-base/settings.php.svn-base create mode 100755 lang/en/lang.php create mode 100755 lang/en/settings.php create mode 100755 manager.dat create mode 100755 plugin.info.txt diff --git a/IJR_Base64.php b/IJR_Base64.php new file mode 100755 index 0000000..62feab8 --- /dev/null +++ b/IJR_Base64.php @@ -0,0 +1,17 @@ + + * @author Magnus Wolf + */ +class IJR_Base64 { + var $data; + function IJR_Base64($data) { + $this->data = $data; + } + function getXml() { + return ''.base64_encode($this->data).''; + } +} +?> diff --git a/IJR_CallbackDefines.php b/IJR_CallbackDefines.php new file mode 100755 index 0000000..05e168d --- /dev/null +++ b/IJR_CallbackDefines.php @@ -0,0 +1,224 @@ +obj['method'] = 'dokuwiki.getVersion'; + $this->obj['callback'] = 'getVersion'; + $this->obj['args'] = array('string'); + $this->obj['help'] = 'Returns the running DokuWiki version.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'dokuwiki.login'; + $this->obj['callback'] = 'this:login'; + $this->obj['args'] = array('integer','string','string'); + $this->obj['help'] = 'Tries to login with the given credentials and sets auth cookies.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'dokuwiki.getPagelist'; + $this->obj['callback'] = 'this:readNamespace'; + $this->obj['args'] = array('string','struct'); + $this->obj['help'] = 'List all pages within the given namespace.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'dokuwiki.getTime'; + $this->obj['callback'] = 'time'; + $this->obj['args'] = array('int'); + $this->obj['help'] = 'Return the current time at the wiki server.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'dokuwiki.getTitle'; + $this->obj['callback'] = 'this:getTitle'; + $this->obj['args'] = array('string'); + $this->obj['help'] = 'Get wiki title.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'dokuwiki.appendPage'; + $this->obj['callback'] = 'this:appendPage'; + $this->obj['args'] = array('string', 'string', 'struct'); + $this->obj['help'] = 'Appends text to a Wiki Page.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'dokuwiki.setLocks'; + $this->obj['callback'] = 'this:setLocks'; + $this->obj['args'] = array('struct'); + $this->obj['help'] = 'Lock or unlock pages.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getPage'; + $this->obj['callback'] = 'this:rawPage'; + $this->obj['args'] = array('string','string'); + $this->obj['help'] = 'Get the raw Wiki text of page, latest version.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getPageVersion'; + $this->obj['callback'] = 'this:rawPage'; + $this->obj['args'] = array('string', 'string'); + $this->obj['help'] = 'Get the raw Wiki text of page.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getPageHTML'; + $this->obj['callback'] = 'this:htmlPage'; + $this->obj['args'] = array('string','string'); + $this->obj['help'] = 'Return page in rendered HTML, latest version.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getPageHTMLVersion'; + $this->obj['callback'] = 'this:htmlPage'; + $this->obj['args'] = array('string','string'); + $this->obj['help'] = 'Return page in rendered HTML.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getAllPages'; + $this->obj['callback'] = 'this:listPages'; + $this->obj['args'] = array('struct'); + $this->obj['help'] = 'Returns a list of all pages. The result is an array of utf8 pagenames.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getAttachments'; + $this->obj['callback'] = 'this:listAttachments'; + $this->obj['args'] = array('string', 'struct'); + $this->obj['help'] = 'Returns a list of all media files.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getBackLinks'; + $this->obj['callback'] = 'this:listBackLinks'; + $this->obj['args'] = array('struct','string'); + $this->obj['help'] = 'Returns the pages that link to this page.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getPageInfo'; + $this->obj['callback'] = 'this:pageInfo'; + $this->obj['args'] = array('struct','string'); + $this->obj['help'] = 'Returns a struct with infos about the page.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getPageInfoVersion'; + $this->obj['callback'] = 'this:pageInfo'; + $this->obj['args'] = array('string','string'); + $this->obj['help'] = 'Returns a struct with infos about the page.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getPageVersions'; + $this->obj['callback'] = 'this:pageVersions'; + $this->obj['args'] = array('string','string','string'); + $this->obj['help'] = 'Returns the available revisions of the page.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.putPage'; + $this->obj['callback'] = 'this:putPage'; + $this->obj['args'] = array('string', 'string', 'struct'); + $this->obj['help'] = 'Saves a wiki page.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.search'; + $this->obj['callback'] = 'this:search'; + $this->obj['args'] = array('string'); + $this->obj['help'] = 'Serches for a string in wiki pages.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.listLinks'; + $this->obj['callback'] = 'this:listLinks'; + $this->obj['args'] = array('struct','string'); + $this->obj['help'] = 'Lists all links contained in a wiki page.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getRecentChanges'; + $this->obj['callback'] = 'this:getRecentChanges'; + $this->obj['args'] = array('string'); + $this->obj['help'] = 'Returns a struct about all recent changes since given timestamp.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getRecentMediaChanges'; + $this->obj['callback'] = 'this:getRecentMediaChanges'; + $this->obj['args'] = array('struct'); + $this->obj['help'] = 'Returns a struct about all recent media changes since given timestamp.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.aclCheck'; + $this->obj['callback'] = 'this:aclCheck'; + $this->obj['args'] = array('int', 'string'); + $this->obj['help'] = 'Returns the permissions of a given wiki page.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.putAttachment'; + $this->obj['callback'] = 'this:putAttachment'; + $this->obj['args'] = array('string', 'base64', 'struct'); + $this->obj['help'] = 'Upload a file to the wiki.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.deleteAttachment'; + $this->obj['callback'] = 'this:deleteAttachment'; + $this->obj['args'] = array('int', 'string'); + $this->obj['help'] = 'Delete a file from the wiki.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getAttachment'; + $this->obj['callback'] = 'this:getAttachment'; + $this->obj['args'] = array('base64', 'string'); + $this->obj['help'] = 'Download a file from the wiki.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getAttachmentInfo'; + $this->obj['callback'] = 'this:getAttachmentInfo'; + $this->obj['args'] = array('struct', 'string'); + $this->obj['help'] = 'Returns a struct with infos about the attachment.'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'wiki.getPageHTMLPart'; + $this->obj['callback'] = 'this:htmlPagePart'; + $this->obj['args'] = array('string','string','string','int','int'); + $this->obj['help'] = 'Return parts of a page in rendered HTML, latest version.'; + $this->methods[] = $this->obj; + } + + private function defineSystemMethods() + { + $this->obj['method'] = 'system.methodSignature'; + $this->obj['callback'] = 'this:methodSignature'; + $this->obj['args'] = array('array', 'string'); + $this->obj['help'] = 'Returns an array describing the return type and required parameters of a method'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'system.getCapabilities'; + $this->obj['callback'] = 'this:getCapabilities'; + $this->obj['args'] = array('struct'); + $this->obj['help'] = 'Returns a struct describing the XML-RPC specifications supported by this server'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'system.listMethods'; + $this->obj['callback'] = 'this:listMethods'; + $this->obj['args'] = array('array'); + $this->obj['help'] = 'Returns an array of available methods on this server'; + $this->methods[] = $this->obj; + + $this->obj['method'] = 'system.methodHelp'; + $this->obj['callback'] = 'this:methodHelp'; + $this->obj['args'] = array('string', 'string'); + $this->obj['help'] = 'Returns a documentation string for the specified method'; + $this->methods[] = $this->obj; + } + + public function getWikiMethods() + { + $this->defineWikiMethods(); + return $this->methods; + } + + public function getSystemMethods() + { + $this->defineSystemMethods(); + return $this->methods; + } +} +?> diff --git a/IJR_Date.php b/IJR_Date.php new file mode 100755 index 0000000..e4da4af --- /dev/null +++ b/IJR_Date.php @@ -0,0 +1,49 @@ + + * @author Magnus Wolf + */ +class IJR_Date { + var $year; + var $month; + var $day; + var $hour; + var $minute; + var $second; + function IJR_Date($time) { + // $time can be a PHP timestamp or an ISO one + if (is_numeric($time)) { + $this->parseTimestamp($time); + } else { + $this->parseIso($time); + } + } + function parseTimestamp($timestamp) { + $this->year = gmdate('Y', $timestamp); + $this->month = gmdate('m', $timestamp); + $this->day = gmdate('d', $timestamp); + $this->hour = gmdate('H', $timestamp); + $this->minute = gmdate('i', $timestamp); + $this->second = gmdate('s', $timestamp); + } + function parseIso($iso) { + $this->year = substr($iso, 0, 4); + $this->month = substr($iso, 5, 2); + $this->day = substr($iso, 8, 2); + $this->hour = substr($iso, 11, 2); + $this->minute = substr($iso, 14, 2); + $this->second = substr($iso, 17, 2); + } + function getIso() { + return $this->year.'-'.$this->month.'-'.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second; + } + function getXml() { + return ''.$this->getIso().''; + } + function getTimestamp() { + return gmmktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); + } +} +?> diff --git a/IJR_Error.php b/IJR_Error.php new file mode 100755 index 0000000..d0becfe --- /dev/null +++ b/IJR_Error.php @@ -0,0 +1,22 @@ + + * @author Magnus Wolf + */ +class IJR_Error { + var $code; + var $message; + function IJR_Error($code, $message) { + $this->code = $code; + $this->message = $message; + } + + function getJson(){ + $result['code'] = $this->code; + $result['message'] = $this->message; + return $result; + } +} +?> diff --git a/IJR_IntrospectionServer.php b/IJR_IntrospectionServer.php new file mode 100755 index 0000000..7ef087e --- /dev/null +++ b/IJR_IntrospectionServer.php @@ -0,0 +1,146 @@ + + * @author Magnus Wolf + */ +require_once('./IJR_Server.php'); +require_once('./IJR_CallbackDefines.php'); + +class IJR_IntrospectionServer extends IJR_Server { + private $signatures; + private $help; + private $callbackMethods; + + protected function IJR_IntrospectionServer() { + $this->setCallbacks(); + $this->setCapabilities(); + $this->capabilities['introspection'] = array( + 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html', + 'specVersion' => 1 + ); + $callbackDef = new IJR_CallbackDefines(); + $this->callbackMethods = $callbackDef->getSystemMethods(); + + foreach($this->callbackMethods as $key) + { + $this->addCallback($key['method'], $key['callback'], $key['args'], $key['help']); + } + } + + protected function addCallback($method, $callback, $args, $help) { + $this->callbacks[$method] = $callback; + $this->signatures[$method] = $args; + $this->help[$method] = $help; + } + + protected function call($methodname, $args) { + if ($args && !is_array($args)) + { + $args = array($args); + } + if (!$this->hasMethod($methodname)) + { + return new IJR_Error(-32601, 'server error. requested method "'.$methodname.'" not specified.'); + } + + $method = $this->callbacks[$methodname]; + $signature = $this->signatures[$methodname]; + $returnType = array_shift($signature); + + if (count($args) < count($signature)) + { + return new IJR_Error(-32602, 'server error. missing method parameters'); + } + // Check the argument types + $ok = true; + $argsbackup = $args; + + for ($i = 0, $j = count($args); $i < $j; $i++) { + + $arg = array_shift($args); + $type = array_shift($signature); + + switch ($type) { + case 'int': + case 'i4': + if (is_array($arg) || !is_int($arg)) { + $ok = false; + } + break; + case 'base64': + case 'string': + if (!is_string($arg)) { + $ok = false; + } + break; + case 'boolean': + if ($arg !== false && $arg !== true) { + $ok = false; + } + break; + case 'float': + case 'double': + if (!is_float($arg)) { + $ok = false; + } + break; + case 'date': + case 'dateTime.iso8601': + if (!is_a($arg, 'IJR_Date')) { + $ok = false; + } + break; + } + if (!$ok) { + return new IJR_Error(-32602, 'server error. invalid method parameters'); + } + } + return parent::call($methodname, $argsbackup); + } + + private function methodSignature($method) { + if (!$this->hasMethod($method)) { + return new IJR_Error(-32601, 'server error. requested method "'.$method.'" not specified.'); + } + // We should be returning an array of types + $types = $this->signatures[$method]; + $return = array(); + foreach ($types as $type) { + switch ($type) { + case 'string': + $return[] = 'string'; + break; + case 'int': + case 'i4': + $return[] = 42; + break; + case 'double': + $return[] = 3.1415; + break; + case 'dateTime.iso8601': + $return[] = new IJR_Date(time()); + break; + case 'boolean': + $return[] = true; + break; + case 'base64': + $return[] = new IJR_Base64('base64'); + break; + case 'array': + $return[] = array('array'); + break; + case 'struct': + $return[] = array('struct' => 'struct'); + break; + } + } + return $return; + } + + function methodHelp($method) { + return $this->help[$method]; + } +} +?> diff --git a/IJR_Message.php b/IJR_Message.php new file mode 100755 index 0000000..809563d --- /dev/null +++ b/IJR_Message.php @@ -0,0 +1,155 @@ + + * @author Magnus Wolf + */ + +require_once('./IJR_Error.php'); + +class IJR_Message { + var $message; + var $messageType; // methodCall / methodResponse / fault + var $faultCode; + var $faultString; + var $methodName; + var $params; + // Current variable stacks + var $_arraystructs = array(); // The stack used to keep track of the current array/struct + var $_arraystructstypes = array(); // Stack keeping track of if things are structs or array + var $_currentStructName = array(); // A stack as well + var $_param; + var $_value; + var $_currentTag; + var $_currentTagContents; + // The XML parser + var $_parser; + function IJR_Message ($message) { + $this->message = $message; + } + function parse() { + $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message); + $this->message = str_replace('<', '<', $this->message); + $this->message = str_replace('>', '>', $this->message); + $this->message = str_replace('&', '&', $this->message); + $this->message = str_replace(''', ''', $this->message); + $this->message = str_replace('"', '"', $this->message); + if (trim($this->message) == '') { + return false; + } + $this->_parser = xml_parser_create(); + xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); + xml_set_object($this->_parser, $this); + xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); + xml_set_character_data_handler($this->_parser, 'cdata'); + if (!xml_parse($this->_parser, $this->message)) { + return false; + } + xml_parser_free($this->_parser); + if ($this->messageType == 'fault') { + $this->faultCode = $this->params[0]['faultCode']; + $this->faultString = $this->params[0]['faultString']; + } + return true; + } + function tag_open($parser, $tag, $attr) { + $this->currentTag = $tag; + $this->_currentTagContents = ''; + switch($tag) { + case 'methodCall': + case 'methodResponse': + case 'fault': + $this->messageType = $tag; + break; + case 'data': // data is to all intents and puposes more interesting than array + $this->_arraystructstypes[] = 'array'; + $this->_arraystructs[] = array(); + break; + case 'struct': + $this->_arraystructstypes[] = 'struct'; + $this->_arraystructs[] = array(); + break; + } + } + function cdata($parser, $cdata) { + $this->_currentTagContents .= $cdata; + } + function tag_close($parser, $tag) { + $valueFlag = false; + switch($tag) { + case 'int': + case 'i4': + $value = (int)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'double': + $value = (double)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'string': + $value = (string)$this->_currentTagContents; + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'dateTime.iso8601': + $value = new IJR_Date(trim($this->_currentTagContents)); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'value': + if (trim($this->_currentTagContents) != '') { + $value = (string)$this->_currentTagContents; + $this->_currentTagContents = ''; + $valueFlag = true; + } + break; + case 'boolean': + $value = (boolean)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'base64': + $value = base64_decode($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'data': + case 'struct': + $value = array_pop($this->_arraystructs); + array_pop($this->_arraystructstypes); + $valueFlag = true; + break; + case 'member': + array_pop($this->_currentStructName); + break; + case 'name': + $this->_currentStructName[] = trim($this->_currentTagContents); + $this->_currentTagContents = ''; + break; + case 'methodName': + $this->methodName = trim($this->_currentTagContents); + $this->_currentTagContents = ''; + break; + } + if ($valueFlag) { + if (count($this->_arraystructs) > 0) { + if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') { + $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value; + } else { + $this->_arraystructs[count($this->_arraystructs)-1][] = $value; + } + } else { + $this->params[] = $value; + } + } + } +} \ No newline at end of file diff --git a/IJR_Server.php b/IJR_Server.php new file mode 100755 index 0000000..bcb4385 --- /dev/null +++ b/IJR_Server.php @@ -0,0 +1,235 @@ + + * @author Magnus Wolf + */ +class IJR_Server { + + var $data; + var $callbacks = array(); + var $message; + var $capabilities; + var $method; + var $id; + + + function IJR_Server($callbacks = false, $data = false) + { + $this->setCapabilities(); + if ($callbacks) { + $this->callbacks = $callbacks; + } + $this->setCallbacks(); + $this->serve($data); + } + + + private function verifyData($data) + { + if($data == NULL){ + $this->error(-32700, 'decode error. no correct json string'); + } + + if(!$data['method']){ + $this->error(-32600, 'server error. invalid json-rpc. not conforming to spec. Request must be a method'); + } + + if(!$data['jsonrpc'] || $data['jsonrpc']!='2.0'){ + $this->error(-32600, 'server error. invalid json-rpc. wrong jsonrpc-spec 2.0 is available'); + } + } + + function serve($data = false) + { + if (!$data) { + global $HTTP_RAW_POST_DATA; + if (!$HTTP_RAW_POST_DATA) { + die('JSON-RPC server accepts POST requests only.'); + } + $data = $HTTP_RAW_POST_DATA; + } + + $data = json_decode($data, true); + $this->verifyData($data); + $this->id = $data['id']; + $parameter = array(); + + foreach($data['params'] as $param){ + foreach($param as $key => $value){ + $parameter[] = $value; + } + } + + $res = $this->call($data['method']['methodName'], $parameter); + if (is_a($res, 'IJR_Error')) { + $this->error($res); + } + + // Send it + $result['jsonrpc']='2.0'; + $result['result']=$res; + $result['error']=''; + $result['id']=$this->id; + $result = json_encode($result); + $this->output($result); + } + + + private function callClassMethod($method, $args) + { + $method = substr($method, 5); + if (!method_exists($this, $method)) { + return new IJR_Error(-32601, 'server error. requested class method "'.$method.'" does not exist.'); + } + return call_user_func_array(array(&$this,$method),$args); + } + + + private function callPlugin($pluginname, $callback, $method, $args) + { + require_once(DOKU_INC.'inc/pluginutils.php'); + list($pluginname, $callback) = explode(':', substr($method, 7), 2); + if(!plugin_isdisabled($pluginname)) + { + $plugin = plugin_load('action', $pluginname); + return call_user_func_array(array($plugin, $callback), $args); + } + else + { + return new IJR_Error(-99999, 'server error'); + } + } + + + private function callFunction($method, $args) + { + if (!function_exists($method)) + { + return new IJR_Error(-32601, 'server error. requested function "'.$method.'" does not exist.'); + } + return call_user_func_array($method,$args); + } + + + protected function call($methodname, $args) + { + if (!$this->hasMethod($methodname)) + { + return new IJR_Error(-32601, 'server error. requested method '.$methodname.' does not exist.'); + } + $method = $this->callbacks[$methodname]; + // Perform the callback and send the response +# Adjusted for DokuWiki to use call_user_func_array + // args need to be an array + $args = (array) $args; + if (substr($method, 0, 5) == 'this:') + { + $result = $this->callClassMethod($method, $args); + } + elseif (substr($method, 0, 7) == 'plugin:') + { + return $this->callPlugin($pluginname, $callback, $method, $args); + } + else + { + $result = $this->callFunction($method, $args); + } + return $result; + } + + + function error($error, $message = false) + { + if ($message && !is_object($error)) { + $error = new IJR_Error($error, $message); + } + $result['jsonrpc']='2.0'; + $result['result']=''; + $result['error']=$error->getJson(); + $result['id']=$this->id; + $result = json_encode($result); + $this->output($result); + } + + + function output($json) + { + $length = strlen($json); + header('Connection: close'); + header('Content-Length: '.$length); + header('Content-Type: application/json'); + header('Date: '.date('r')); + echo $json; + exit; + } + + + function hasMethod($method) { + return in_array($method, array_keys($this->callbacks)); + } + + + function setCapabilities() { + // Initialises capabilities array + $this->capabilities = array( + 'xmlrpc' => array( + 'specUrl' => 'http://www.xmlrpc.com/spec', + 'specVersion' => 1 + ), + 'faults_interop' => array( + 'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php', + 'specVersion' => 20010516 + ), + 'system.multicall' => array( + 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208', + 'specVersion' => 1 + ), + ); + } + + + function getCapabilities() { + return $this->capabilities; + } + + + function setCallbacks() { + $this->callbacks['system.getCapabilities'] = 'this:getCapabilities'; + $this->callbacks['system.listMethods'] = 'this:listMethods'; + $this->callbacks['system.multicall'] = 'this:multiCall'; + } + + + function listMethods() { + // Returns a list of methods - uses array_reverse to ensure user defined + // methods are listed before server defined methods + return array_reverse(array_keys($this->callbacks)); + } + + + function multiCall($methodcalls) { + // See http://www.xmlrpc.com/discuss/msgReader$1208 + $return = array(); + foreach ($methodcalls as $call) { + $method = $call['methodName']; + $params = $call['params']; + if ($method == 'system.multicall') { + $result = new IJR_Error(-32600, 'Recursive calls to system.multicall are forbidden'); + } else { + $result = $this->call($method, $params); + } + if (is_a($result, 'IJR_Error')) { + $return[] = array( + 'faultCode' => $result->code, + 'faultString' => $result->message + ); + } else { + $return[] = array($result); + } + } + return $return; + } +} +?> diff --git a/README b/README new file mode 100755 index 0000000..e69de29 diff --git a/_test/jsonrpc_test.php b/_test/jsonrpc_test.php new file mode 100755 index 0000000..0ec4eef --- /dev/null +++ b/_test/jsonrpc_test.php @@ -0,0 +1,46 @@ +assertTrue(checkAuth(), "Failure checkAuth, allow_all"); + } + + function testAuthCheckAllowUser() + { + $conf['plugin']['jsonrpc']['allow_all'] = 0; + $conf['plugin']['jsonrpc']['allowed'] = 'testuser'; + $_SERVER['REMOTE_USER'] = 'testuser'; + + $this->assertTrue(checkAuth(), "Failer checkAuth, allow testuser"); + } + + function testAuthCheckNotAllowed() + { + $conf['plugin']['jsonrpc']['allow_all'] = 0; + $conf['plugin']['jsonrpc']['allowed'] = ''; + + $_SERVER['REMOTE_USER'] = 'testuser'; + + $this->assertFalse(checkAuth(), "Failer checkAuth, notallow testuser"); + } + +} + +?> diff --git a/conf/.svn/entries b/conf/.svn/entries new file mode 100755 index 0000000..30af131 --- /dev/null +++ b/conf/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +4886 +svn://devel02.acodeas.de/aic/trunk/wiki/lib/plugins/s5/conf +svn://devel02.acodeas.de + + + +2008-12-19T12:02:34.800762Z +399 +twoell + + + + + + + + + + + + + + +f9853db8-6a22-4a6e-a02a-45224da4fc10 + +metadata.php +file + + + + +2010-12-06T08:16:51.370722Z +0daf6952d3570ab5d7485a80b7783c26 +2008-12-19T12:02:34.800762Z +399 +twoell +has-props + + + + + + + + + + + + + + + + + + + + +88 + +default.php +file + + + + +2010-12-06T08:16:51.370722Z +80aebfc73e69ee04d43db76c84dc3397 +2008-12-19T12:02:34.800762Z +399 +twoell +has-props + + + + + + + + + + + + + + + + + + + + +43 + diff --git a/conf/.svn/prop-base/default.php.svn-base b/conf/.svn/prop-base/default.php.svn-base new file mode 100755 index 0000000..a669705 --- /dev/null +++ b/conf/.svn/prop-base/default.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 0 + +END diff --git a/conf/.svn/prop-base/metadata.php.svn-base b/conf/.svn/prop-base/metadata.php.svn-base new file mode 100755 index 0000000..a669705 --- /dev/null +++ b/conf/.svn/prop-base/metadata.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 0 + +END diff --git a/conf/.svn/text-base/default.php.svn-base b/conf/.svn/text-base/default.php.svn-base new file mode 100755 index 0000000..cd1f40c --- /dev/null +++ b/conf/.svn/text-base/default.php.svn-base @@ -0,0 +1,4 @@ + DOKU_INC.'lib/plugins/s5/ui/'); + diff --git a/conf/default.php b/conf/default.php new file mode 100755 index 0000000..b073bbc --- /dev/null +++ b/conf/default.php @@ -0,0 +1,6 @@ + + * @author Gina Haeussge + * @author Michael Klier + * @author Michael Hamann + * @author Magnus Wolf + */ + +if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../../'); + +// fix when 'config = $conf['plugin']['jsonrpc']; + + if($this->config['allow_all'] == 1) + { + return true; + } + + $user = $_SERVER['REMOTE_USER']; + $allowed_users = explode(';',$this->config['allowed']); + $allowed_users = array_map('trim', $allowed_users); + $allowed_users = array_unique($allowed_users); + + if(in_array($user,$allowed_users)) + { + return true; + } + return false; + } + + function addCallback($method, $callback, $args, $help, $public=false){ + if($public) $this->public_methods[] = $method; + return parent::addCallback($method, $callback, $args, $help); + } + + + function call($methodname, $args){ + if(!in_array($methodname,$this->public_methods) && !$this->checkAuth()){ + return new IJR_Error(-32603, 'server error. not authorized to call method "'.$methodname.'".'); + } + return parent::call($methodname, $args); + } + + + function dokuwiki_jsonrpc_server(){ + $callbackDef = new IJR_CallbackDefines(); + $this->callbackMethods = $callbackDef->getWikiMethods(); + + $this->IJR_IntrospectionServer(); + + foreach($this->callbackMethods as $key) + { + $this->addCallback($key['method'], $key['callback'], $key['args'], $key['help'], $key['public']); + } + trigger_event('JSONRPC_CALLBACK_REGISTER', $this); + + $this->serve(); + } + + public function rawPage($id,$rev=''){ + if(auth_quickaclcheck($id) < AUTH_READ){ + return new IJR_Error(1, 'You are not allowed to read this page'); + } + $text = rawWiki($id,$rev); + if(!$text) { + $data = array($id); + return trigger_event('HTML_PAGE_FROMTEMPLATE',$data,'pageTemplate',true); + } else { + return $text; + } + } + + public function getTitle() + { + global $conf; + return $conf['title']; + } + + public function appendPage($page, $text, $opt) + { + $page_cont = $this->rawPage($page); + $page_cont = $page_cont."\n".$text; + return saveWikiText($page, $tmp, $opt); + } + + public function getAttachment($id){ + $id = cleanID($id); + if (auth_quickaclcheck(getNS($id).':*') < AUTH_READ) + return new IJR_Error(1, 'You are not allowed to read this file'); + + $file = mediaFN($id); + if (!@ file_exists($file)) + return new IJR_Error(1, 'The requested file does not exist'); + + $data = io_readFile($file, false); + $base64 = base64_encode($data); + return $base64; + } + + public function getAttachmentInfo($id){ + $id = cleanID($id); + $info = array( + 'lastModified' => 0, + 'size' => 0, + ); + + $file = mediaFN($id); + if ((auth_quickaclcheck(getNS($id).':*') >= AUTH_READ) && file_exists($file)){ + $info['lastModified'] = new IJR_Date(filemtime($file)); + $info['size'] = filesize($file); + } + + return $info; + } + + public function htmlPage($id,$rev=''){ + if(auth_quickaclcheck($id) < AUTH_READ){ + return new IJR_Error(1, 'You are not allowed to read this page'); + } + return p_wiki_xhtml($id,$rev,false); + } + + public function htmlPagePart($id,$rev='',$maxHeader=3,$maxItems=3){ + if(auth_quickaclcheck($id) < AUTH_READ){ + return new IJR_Error(1, 'You are not allowed to read this page'); + } + $title = ''; + $cfg = array('maxHeader'=>$maxHeader,'maxItems'=>$maxItems); + return p_wiki_xhtml_summary_ext($id,$title,$rev,true,$cfg); + } + + public function listPages(){ + global $conf; + + $list = array(); + $pages = file($conf['indexdir'] . '/page.idx'); + $pages = array_filter($pages, 'isVisiblePage'); + + foreach(array_keys($pages) as $idx) { + if(page_exists($pages[$idx])) { + $perm = auth_quickaclcheck($pages[$idx]); + if($perm >= AUTH_READ) { + $page = array(); + $page['id'] = trim($pages[$idx]); + $page['perms'] = $perm; + $page['size'] = @filesize(wikiFN($pages[$idx])); + $page['lastModified'] = new IJR_Date(@filemtime(wikiFN($pages[$idx]))); + $list[] = $page; + } + } + } + + return $list; + } + + public function readNamespace($ns,$opts){ + global $conf; + + if(!is_array($opts)) $opts=array(); + + $ns = cleanID($ns); + $dir = utf8_encodeFN(str_replace(':', '/', $ns)); + $data = array(); + require_once(DOKU_INC.'inc/search.php'); + $opts['skipacl'] = 0; // no ACL skipping for XMLRPC + search($data, $conf['datadir'], 'search_allpages', $opts, $dir); + return $data; + } + + public function listAttachments($ns, $options = array()) { + global $conf; + global $lang; + + $ns = cleanID($ns); + if (!is_array($options)) $options = array(); + $options['skipacl'] = 0; // no ACL skipping for XMLRPC + + if(auth_quickaclcheck($ns.':*') >= AUTH_READ) { + $dir = utf8_encodeFN(str_replace(':', '/', $ns)); + + $data = array(); + require_once(DOKU_INC.'inc/search.php'); + search($data, $conf['mediadir'], 'search_media', $options, $dir); + $len = count($data); + + if(!$len) return array(); + + for($i=0; $i<$len; $i++) { + unset($data[$i]['meta']); + $data[$i]['lastModified'] = new IJR_Date($data[$i]['mtime']); + } + + return $data; + } else { + return new IJR_Error(1, 'You are not allowed to list media files.'); + } + } + + public function search($searchString) + { + require_once(DOKU_INC.'inc/html.php'); + require_once(DOKU_INC.'inc/search.php'); + require_once(DOKU_INC.'inc/fulltext.php'); + require_once(DOKU_INC.'inc/pageutils.php'); + + $data = array(); + $result = array(); + + $searchStr = cleanID($searchString); + $data = ft_pageLookup($searchStr); + foreach($data as $id) + { + $ns = getNS($id); + if($ns){ + $name = shorten(noNS($id), ' ('.$ns.')',30); + }else{ + $name = $id; + } + $result[] = $id; + } + + $data = ft_pageSearch($searchString, $regex); + if(count($data)) + { + foreach($data as $id => $cnt) + { + $result[] = $id; + } + } + return $result; + } + + public function listBackLinks($id){ + require_once(DOKU_INC.'inc/fulltext.php'); + return ft_backlinks($id); + } + + public function pageInfo($id,$rev=''){ + if(auth_quickaclcheck($id) < AUTH_READ){ + return new IJR_Error(1, 'You are not allowed to read this page'); + } + $file = wikiFN($id,$rev); + $time = @filemtime($file); + if(!$time){ + return new IJR_Error(10, 'The requested page does not exist'); + } + + $info = getRevisionInfo($id, $time, 1024); + + $data = array( + 'name' => $id, + 'lastModified' => new IJR_Date($time), + 'author' => (($info['user']) ? $info['user'] : $info['ip']), + 'version' => $time + ); + + return ($data); + } + + public function putPage($id, $text, $params) { + global $TEXT; + global $lang; + global $conf; + + $id = cleanID($id); + $TEXT = cleanText($text); + $sum = $params['sum']; + $minor = $params['minor']; + + if(empty($id)) + return new IJR_Error(1, 'Empty page ID'); + + if(!page_exists($id) && trim($TEXT) == '' ) { + return new IJR_ERROR(1, 'Refusing to write an empty new wiki page'); + } + + if(auth_quickaclcheck($id) < AUTH_EDIT) + return new IJR_Error(1, 'You are not allowed to edit this page'); + + if(checklock($id)) + return new IJR_Error(1, 'The page is currently locked'); + + if(checkwordblock()) + return new IJR_Error(1, 'Positive wordblock check'); + + if(!page_exists($id) && empty($sum)) { + $sum = $lang['created']; + } + + if(page_exists($id) && empty($TEXT) && empty($sum)) { + $sum = $lang['deleted']; + } + + lock($id); + + saveWikiText($id,$TEXT,$sum,$minor); + + unlock($id); + + // run the indexer if page wasn't indexed yet + if(!@file_exists(metaFN($id, '.indexed'))) { + // try to aquire a lock + $lock = $conf['lockdir'].'/_indexer.lock'; + while(!@mkdir($lock,$conf['dmode'])){ + usleep(50); + if(time()-@filemtime($lock) > 60*5){ + // looks like a stale lock - remove it + @rmdir($lock); + }else{ + return false; + } + } + if(isset($conf['dperm']) && $conf['dperm']) chmod($lock, $conf['dperm']); + + require_once(DOKU_INC.'inc/indexer.php'); + + if(!defined('INDEXER_VERSION')){ + define('INDEXER_VERSION', 2); + } + // do the work + idx_addPage($id); + + io_saveFile(metaFN($id,'.indexed'),INDEXER_VERSION); + @rmdir($lock); + } + + return 0; + } + + public function putAttachment($id, $file, $params) { + global $conf; + global $lang; + + $auth = auth_quickaclcheck(getNS($id).':*'); + if($auth >= AUTH_UPLOAD) { + if(!isset($id)) { + return new IJR_ERROR(1, 'Filename not given.'); + } + + $ftmp = $conf['tmpdir'] . '/' . $id; + + // save temporary file + @unlink($ftmp); + $buff = base64_decode($file); + io_saveFile($ftmp, $buff); + + // get filename + list($iext, $imime,$dl) = mimetype($id); + $id = cleanID($id); + $fn = mediaFN($id); + + // get filetype regexp + $types = array_keys(getMimeTypes()); + $types = array_map(create_function('$q','return preg_quote($q,"/");'),$types); + $regex = join('|',$types); + + // because a temp file was created already + if(preg_match('/\.('.$regex.')$/i',$fn)) { + //check for overwrite + $overwrite = @file_exists($fn); + if($overwrite && (!$params['ow'] || $auth < AUTH_DELETE)) { + return new IJR_ERROR(1, $lang['uploadexist'].'1'); + } + // check for valid content + @require_once(DOKU_INC.'inc/media.php'); + $ok = media_contentcheck($ftmp, $imime); + if($ok == -1) { + return new IJR_ERROR(1, sprintf($lang['uploadexist'].'2', ".$iext")); + } elseif($ok == -2) { + return new IJR_ERROR(1, $lang['uploadspam']); + } elseif($ok == -3) { + return new IJR_ERROR(1, $lang['uploadxss']); + } + + // prepare event data + $data[0] = $ftmp; + $data[1] = $fn; + $data[2] = $id; + $data[3] = $imime; + $data[4] = $overwrite; + + // trigger event + require_once(DOKU_INC.'inc/events.php'); + return trigger_event('MEDIA_UPLOAD_FINISH', $data, array($this, '_media_upload_action'), true); + + } else { + return new IJR_ERROR(1, $lang['uploadwrong']); + } + } else { + return new IJR_ERROR(1, "You don't have permissions to upload files."); + } + } + + public function deleteAttachment($id){ + $auth = auth_quickaclcheck(getNS($id).':*'); + if($auth < AUTH_DELETE) return new IJR_ERROR(1, "You don't have permissions to delete files."); + global $conf; + global $lang; + + // check for references if needed + $mediareferences = array(); + if($conf['refcheck']){ + require_once(DOKU_INC.'inc/fulltext.php'); + $mediareferences = ft_mediause($id,$conf['refshow']); + } + + if(!count($mediareferences)){ + $file = mediaFN($id); + if(@unlink($file)){ + require_once(DOKU_INC.'inc/changelog.php'); + addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE); + io_sweepNS($id,'mediadir'); + return 0; + } + //something went wrong + return new IJR_ERROR(1, 'Could not delete file'); + } else { + return new IJR_ERROR(1, 'File is still referenced'); + } + } + + public function _media_upload_action($data) { + global $conf; + + if(is_array($data) && count($data)===5) { + io_createNamespace($data[2], 'media'); + if(rename($data[0], $data[1])) { + chmod($data[1], $conf['fmode']); + media_notify($data[2], $data[1], $data[3]); + // add a log entry to the media changelog + require_once(DOKU_INC.'inc/changelog.php'); + if ($data[4]) { + addMediaLogEntry(time(), $data[2], DOKU_CHANGE_TYPE_EDIT); + } else { + addMediaLogEntry(time(), $data[2], DOKU_CHANGE_TYPE_CREATE); + } + return $data[2]; + } else { + return new IJR_ERROR(1, 'Upload failed.'); + } + } else { + return new IJR_ERROR(1, 'Upload failed.'); + } + } + + public function aclCheck($id) { + return auth_quickaclcheck($id); + } + + public function listLinks($id) { + if(auth_quickaclcheck($id) < AUTH_READ){ + return new IJR_Error(1, 'You are not allowed to read this page'); + } + $links = array(); + + // resolve page instructions + $ins = p_cached_instructions(wikiFN(cleanID($id))); + + // instantiate new Renderer - needed for interwiki links + include(DOKU_INC.'inc/parser/xhtml.php'); + $Renderer = new Doku_Renderer_xhtml(); + $Renderer->interwiki = getInterwiki(); + + // parse parse instructions + foreach($ins as $in) { + $link = array(); + switch($in[0]) { + case 'internallink': + $link['type'] = 'local'; + $link['page'] = $in[1][0]; + $link['href'] = wl($in[1][0]); + array_push($links,$link); + break; + case 'externallink': + $link['type'] = 'extern'; + $link['page'] = $in[1][0]; + $link['href'] = $in[1][0]; + array_push($links,$link); + break; + case 'interwikilink': + $url = $Renderer->_resolveInterWiki($in[1][2],$in[1][3]); + $link['type'] = 'extern'; + $link['page'] = $url; + $link['href'] = $url; + array_push($links,$link); + break; + } + } + + return ($links); + } + + public function getRecentChanges($timestamp) { + if(strlen($timestamp) != 10) + return new IJR_Error(20, 'The provided value is not a valid timestamp'); + + require_once(DOKU_INC.'inc/changelog.php'); + require_once(DOKU_INC.'inc/pageutils.php'); + + $recents = getRecentsSince($timestamp); + + $changes = array(); + + foreach ($recents as $recent) { + $change = array(); + $change['name'] = $recent['id']; + $change['lastModified'] = new IJR_Date($recent['date']); + $change['author'] = $recent['user']; + $change['version'] = $recent['date']; + $change['perms'] = $recent['perms']; + $change['size'] = @filesize(wikiFN($recent['id'])); + array_push($changes, $change); + } + + if (!empty($changes)) { + return $changes; + } else { + // in case we still have nothing at this point + return new IJR_Error(30, 'There are no changes in the specified timeframe'); + } + } + + public function getRecentMediaChanges($timestamp) { + if(strlen($timestamp) != 10) + return new IJR_Error(20, 'The provided value is not a valid timestamp'); + + require_once(DOKU_INC.'inc/changelog.php'); + require_once(DOKU_INC.'inc/pageutils.php'); + + $recents = getRecentsSince($timestamp, null, '', RECENTS_MEDIA_CHANGES); + + $changes = array(); + + foreach ($recents as $recent) { + $change = array(); + $change['name'] = $recent['id']; + $change['lastModified'] = new IJR_Date($recent['date']); + $change['author'] = $recent['user']; + $change['version'] = $recent['date']; + $change['perms'] = $recent['perms']; + $change['size'] = @filesize(mediaFN($recent['id'])); + array_push($changes, $change); + } + + if (!empty($changes)) { + return $changes; + } else { + // in case we still have nothing at this point + return new IJR_Error(30, 'There are no changes in the specified timeframe'); + } + } + + public function pageVersions($id, $first,$num=null) { + global $conf; + + $versions = array(); + + if(empty($id)) + return new IJR_Error(1, 'Empty page ID'); + + require_once(DOKU_INC.'inc/changelog.php'); + + if(is_null($num)){ + $num = $conf['recent']; + } + + $revisions = getRevisions($id, $first, $num+1); + + if(count($revisions)==0 && $first!=0) { + $first=0; + $revisions = getRevisions($id, $first, $num+1); + } + + if(count($revisions)>0 && $first==0) { + array_unshift($revisions, ''); // include current revision + array_pop($revisions); // remove extra log entry + } + + $hasNext = false; + if(count($revisions)>$num) { + $hasNext = true; + array_pop($revisions); // remove extra log entry + } + + if(!empty($revisions)) { + foreach($revisions as $rev) { + $file = wikiFN($id,$rev); + $time = @filemtime($file); + // we check if the page actually exists, if this is not the + // case this can lead to less pages being returned than + // specified via $conf['recent'] + if($time){ + $info = getRevisionInfo($id, $time, 1024); + if(!empty($info)) { + $data['user'] = $info['user']; + $data['ip'] = $info['ip']; + $data['type'] = $info['type']; + $data['sum'] = $info['sum']; + $data['modified'] = new IJR_Date($info['date']); + $data['version'] = $info['date']; + array_push($versions, $data); + } + } + } + return $versions; + } else { + return array(); + } + } + + public function setLocks($set){ + $locked = array(); + $lockfail = array(); + $unlocked = array(); + $unlockfail = array(); + + foreach($set['lock'] as $id){ + if(checklock($id)){ + $lockfail[] = $id; + }else{ + lock($id); + $locked[] = $id; + } + } + + foreach($set['unlock'] as $id){ + if(unlock($id)){ + $unlocked[] = $id; + }else{ + $unlockfail[] = $id; + } + } + + return array( + 'locked' => $locked, + 'lockfail' => $lockfail, + 'unlocked' => $unlocked, + 'unlockfail' => $unlockfail, + ); + } + + public function login($user,$pass){ + global $conf; + global $auth; + if(!$conf['useacl']) + { + return 0; + } + if(!$auth) + { + return 0; + } + if($auth->canDo('external')) + { + return $auth->trustExternal($user,$pass,false); + } + else + { + return auth_login($user,$pass,false,true); + } + } +} + +$server = new dokuwiki_jsonrpc_server(); \ No newline at end of file diff --git a/lang/.svn/entries b/lang/.svn/entries new file mode 100755 index 0000000..35ccd50 --- /dev/null +++ b/lang/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +4886 +svn://devel02.acodeas.de/aic/trunk/wiki/lib/plugins/s5/lang +svn://devel02.acodeas.de + + + +2008-12-19T12:02:34.800762Z +399 +twoell + + + + + + + + + + + + + + +f9853db8-6a22-4a6e-a02a-45224da4fc10 + +en +dir + diff --git a/lang/en/.svn/entries b/lang/en/.svn/entries new file mode 100755 index 0000000..c6f99d1 --- /dev/null +++ b/lang/en/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +4886 +svn://devel02.acodeas.de/aic/trunk/wiki/lib/plugins/s5/lang/en +svn://devel02.acodeas.de + + + +2008-12-19T12:02:34.800762Z +399 +twoell + + + + + + + + + + + + + + +f9853db8-6a22-4a6e-a02a-45224da4fc10 + +settings.php +file + + + + +2010-12-06T08:16:51.350717Z +9c283c7672356c1e8cc6fea2b229839a +2008-12-19T12:02:34.800762Z +399 +twoell +has-props + + + + + + + + + + + + + + + + + + + + +66 + +lang.php +file + + + + +2010-12-06T08:16:51.354716Z +d33b3685284e030bd3b4b7a5b0d5a52e +2008-12-19T12:02:34.800762Z +399 +twoell +has-props + + + + + + + + + + + + + + + + + + + + +50 + diff --git a/lang/en/.svn/prop-base/lang.php.svn-base b/lang/en/.svn/prop-base/lang.php.svn-base new file mode 100755 index 0000000..a669705 --- /dev/null +++ b/lang/en/.svn/prop-base/lang.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 0 + +END diff --git a/lang/en/.svn/prop-base/settings.php.svn-base b/lang/en/.svn/prop-base/settings.php.svn-base new file mode 100755 index 0000000..a669705 --- /dev/null +++ b/lang/en/.svn/prop-base/settings.php.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 0 + +END diff --git a/lang/en/.svn/text-base/lang.php.svn-base b/lang/en/.svn/text-base/lang.php.svn-base new file mode 100755 index 0000000..d38a363 --- /dev/null +++ b/lang/en/.svn/text-base/lang.php.svn-base @@ -0,0 +1,3 @@ + Date: Sat, 28 Mar 2015 02:16:15 +0530 Subject: [PATCH 2/5] Added the ability to create new users via JSON RPC --- IJR_CallbackDefines.php | 7 +++++++ jsonrpc.php | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/IJR_CallbackDefines.php b/IJR_CallbackDefines.php index 05e168d..f411eec 100755 --- a/IJR_CallbackDefines.php +++ b/IJR_CallbackDefines.php @@ -25,6 +25,13 @@ private function defineWikiMethods() $this->obj['help'] = 'Tries to login with the given credentials and sets auth cookies.'; $this->methods[] = $this->obj; + /* Function to create user */ + $this->obj['method'] = 'dokuwiki.createUser'; + $this->obj['callback'] = 'this:createUser'; + $this->obj['args'] = array('string','string','string','string'); + $this->obj['help'] = 'Creates an user, based on the Username and password provided'; + $this->methods[] = $this->obj; + $this->obj['method'] = 'dokuwiki.getPagelist'; $this->obj['callback'] = 'this:readNamespace'; $this->obj['args'] = array('string','struct'); diff --git a/jsonrpc.php b/jsonrpc.php index ee83012..3bcc4d0 100755 --- a/jsonrpc.php +++ b/jsonrpc.php @@ -697,6 +697,43 @@ public function login($user,$pass){ return auth_login($user,$pass,false,true); } } + + /** + * Copied from the register() function auth.php + */ + public function createUser($login, $pass, $fullname, $email) { + global $lang; + global $conf; + /* @var DokuWiki_Auth_Plugin $auth */ + global $auth; + + // gather input + $login = trim($auth->cleanUser($login)); + $fullname = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $fullname)); + $email = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $email)); + $pass = $pass; + + if(empty($login) || empty($fullname) || empty($email)) { + return new IJR_Error(-32602, 'Empty login / fullname / email'); + } + + //check mail + if(!mail_isvalid($email)) { + return new IJR_Error(-32602, 'Invalid E-mail'); + } + + //okay try to create the user + if(!$auth->triggerUserMod('create', array($login, $pass, $fullname, $email))) { + return new IJR_Error(-32099, 'Error creating user'); + } + + // send notification about the new user + $subscription = new Subscription(); + $subscription->send_register($login, $fullname, $email); + + // are we done? + return 1; + } } $server = new dokuwiki_jsonrpc_server(); \ No newline at end of file From 5d9132588a4548921e5f476d318d99919fd30d58 Mon Sep 17 00:00:00 2001 From: Santhosh Raju Date: Mon, 30 Mar 2015 15:33:30 +0530 Subject: [PATCH 3/5] Made "dokuwiki.login" passthrough function to enable login without checking for prior authentication --- jsonrpc.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/jsonrpc.php b/jsonrpc.php index 3bcc4d0..981a6d9 100755 --- a/jsonrpc.php +++ b/jsonrpc.php @@ -73,9 +73,11 @@ function addCallback($method, $callback, $args, $help, $public=false){ function call($methodname, $args){ - if(!in_array($methodname,$this->public_methods) && !$this->checkAuth()){ - return new IJR_Error(-32603, 'server error. not authorized to call method "'.$methodname.'".'); - } + if($methodname != "dokuwiki.login") { + if(!in_array($methodname,$this->public_methods) && !$this->checkAuth()){ + return new IJR_Error(-32603, 'server error. not authorized to call method "'.$methodname.'".'); + } + } return parent::call($methodname, $args); } From 105035d5421472ba451be7be909d51075327c9b3 Mon Sep 17 00:00:00 2001 From: Santhosh Raju Date: Sun, 3 May 2015 19:39:37 +0530 Subject: [PATCH 4/5] Updated the file file permissions from 755 to 644 --- IJR_Base64.php | 0 IJR_CallbackDefines.php | 0 IJR_Date.php | 0 IJR_Error.php | 0 IJR_IntrospectionServer.php | 0 IJR_Message.php | 0 IJR_Server.php | 0 README | 0 jsonrpc.php | 0 manager.dat | 0 plugin.info.txt | 0 11 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 IJR_Base64.php mode change 100755 => 100644 IJR_CallbackDefines.php mode change 100755 => 100644 IJR_Date.php mode change 100755 => 100644 IJR_Error.php mode change 100755 => 100644 IJR_IntrospectionServer.php mode change 100755 => 100644 IJR_Message.php mode change 100755 => 100644 IJR_Server.php mode change 100755 => 100644 README mode change 100755 => 100644 jsonrpc.php mode change 100755 => 100644 manager.dat mode change 100755 => 100644 plugin.info.txt diff --git a/IJR_Base64.php b/IJR_Base64.php old mode 100755 new mode 100644 diff --git a/IJR_CallbackDefines.php b/IJR_CallbackDefines.php old mode 100755 new mode 100644 diff --git a/IJR_Date.php b/IJR_Date.php old mode 100755 new mode 100644 diff --git a/IJR_Error.php b/IJR_Error.php old mode 100755 new mode 100644 diff --git a/IJR_IntrospectionServer.php b/IJR_IntrospectionServer.php old mode 100755 new mode 100644 diff --git a/IJR_Message.php b/IJR_Message.php old mode 100755 new mode 100644 diff --git a/IJR_Server.php b/IJR_Server.php old mode 100755 new mode 100644 diff --git a/README b/README old mode 100755 new mode 100644 diff --git a/jsonrpc.php b/jsonrpc.php old mode 100755 new mode 100644 diff --git a/manager.dat b/manager.dat old mode 100755 new mode 100644 diff --git a/plugin.info.txt b/plugin.info.txt old mode 100755 new mode 100644 From db6553495997604301ddf50207312851aa852a28 Mon Sep 17 00:00:00 2001 From: Santhosh Raju Date: Sun, 3 May 2015 19:48:09 +0530 Subject: [PATCH 5/5] Updated the permissions of the folders to 755 and files to 644 --- _test/jsonrpc_test.php | 0 conf/.svn/entries | 0 conf/.svn/prop-base/default.php.svn-base | 0 conf/.svn/prop-base/metadata.php.svn-base | 0 conf/.svn/text-base/default.php.svn-base | 0 conf/.svn/text-base/metadata.php.svn-base | 0 conf/default.php | 0 conf/metadata.php | 0 lang/.svn/entries | 0 lang/en/.svn/entries | 0 lang/en/.svn/prop-base/lang.php.svn-base | 0 lang/en/.svn/prop-base/settings.php.svn-base | 0 lang/en/.svn/text-base/lang.php.svn-base | 0 lang/en/.svn/text-base/settings.php.svn-base | 0 lang/en/lang.php | 0 lang/en/settings.php | 0 16 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 _test/jsonrpc_test.php mode change 100755 => 100644 conf/.svn/entries mode change 100755 => 100644 conf/.svn/prop-base/default.php.svn-base mode change 100755 => 100644 conf/.svn/prop-base/metadata.php.svn-base mode change 100755 => 100644 conf/.svn/text-base/default.php.svn-base mode change 100755 => 100644 conf/.svn/text-base/metadata.php.svn-base mode change 100755 => 100644 conf/default.php mode change 100755 => 100644 conf/metadata.php mode change 100755 => 100644 lang/.svn/entries mode change 100755 => 100644 lang/en/.svn/entries mode change 100755 => 100644 lang/en/.svn/prop-base/lang.php.svn-base mode change 100755 => 100644 lang/en/.svn/prop-base/settings.php.svn-base mode change 100755 => 100644 lang/en/.svn/text-base/lang.php.svn-base mode change 100755 => 100644 lang/en/.svn/text-base/settings.php.svn-base mode change 100755 => 100644 lang/en/lang.php mode change 100755 => 100644 lang/en/settings.php diff --git a/_test/jsonrpc_test.php b/_test/jsonrpc_test.php old mode 100755 new mode 100644 diff --git a/conf/.svn/entries b/conf/.svn/entries old mode 100755 new mode 100644 diff --git a/conf/.svn/prop-base/default.php.svn-base b/conf/.svn/prop-base/default.php.svn-base old mode 100755 new mode 100644 diff --git a/conf/.svn/prop-base/metadata.php.svn-base b/conf/.svn/prop-base/metadata.php.svn-base old mode 100755 new mode 100644 diff --git a/conf/.svn/text-base/default.php.svn-base b/conf/.svn/text-base/default.php.svn-base old mode 100755 new mode 100644 diff --git a/conf/.svn/text-base/metadata.php.svn-base b/conf/.svn/text-base/metadata.php.svn-base old mode 100755 new mode 100644 diff --git a/conf/default.php b/conf/default.php old mode 100755 new mode 100644 diff --git a/conf/metadata.php b/conf/metadata.php old mode 100755 new mode 100644 diff --git a/lang/.svn/entries b/lang/.svn/entries old mode 100755 new mode 100644 diff --git a/lang/en/.svn/entries b/lang/en/.svn/entries old mode 100755 new mode 100644 diff --git a/lang/en/.svn/prop-base/lang.php.svn-base b/lang/en/.svn/prop-base/lang.php.svn-base old mode 100755 new mode 100644 diff --git a/lang/en/.svn/prop-base/settings.php.svn-base b/lang/en/.svn/prop-base/settings.php.svn-base old mode 100755 new mode 100644 diff --git a/lang/en/.svn/text-base/lang.php.svn-base b/lang/en/.svn/text-base/lang.php.svn-base old mode 100755 new mode 100644 diff --git a/lang/en/.svn/text-base/settings.php.svn-base b/lang/en/.svn/text-base/settings.php.svn-base old mode 100755 new mode 100644 diff --git a/lang/en/lang.php b/lang/en/lang.php old mode 100755 new mode 100644 diff --git a/lang/en/settings.php b/lang/en/settings.php old mode 100755 new mode 100644