diff options
Diffstat (limited to 'vendors/dokuwiki/lib/exe/xmlrpc.php')
-rw-r--r-- | vendors/dokuwiki/lib/exe/xmlrpc.php | 921 |
1 files changed, 921 insertions, 0 deletions
diff --git a/vendors/dokuwiki/lib/exe/xmlrpc.php b/vendors/dokuwiki/lib/exe/xmlrpc.php new file mode 100644 index 000000000..d3913482f --- /dev/null +++ b/vendors/dokuwiki/lib/exe/xmlrpc.php @@ -0,0 +1,921 @@ +<?php +if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); + +// fix when '<?xml' isn't on the very first line +if(isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA); + +/** + * Increased whenever the API is changed + */ +define('DOKU_XMLRPC_API_VERSION',2); + +require_once(DOKU_INC.'inc/init.php'); +require_once(DOKU_INC.'inc/common.php'); +require_once(DOKU_INC.'inc/auth.php'); +session_write_close(); //close session + +if(!$conf['xmlrpc']) die('XML-RPC server not enabled.'); + +require_once(DOKU_INC.'inc/IXR_Library.php'); + + +/** + * Contains needed wrapper functions and registers all available + * XMLRPC functions. + */ +class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { + var $methods = array(); + var $public_methods = array(); + + /** + * Checks if the current user is allowed to execute non anonymous methods + */ + function checkAuth(){ + global $conf; + global $USERINFO; + + if(!$conf['useacl']) return true; //no ACL - then no checks + + $allowed = explode(',',$conf['xmlrpcuser']); + $allowed = array_map('trim', $allowed); + $allowed = array_unique($allowed); + $allowed = array_filter($allowed); + + if(!count($allowed)) return true; //no restrictions + + $user = $_SERVER['REMOTE_USER']; + $groups = (array) $USERINFO['grps']; + + if(in_array($user,$allowed)) return true; //user explicitly mentioned + + //check group memberships + foreach($groups as $group){ + if(in_array('@'.$group,$allowed)) return true; + } + + //still here? no access! + return false; + } + + /** + * Adds a callback, extends parent method + * + * add another parameter to define if anonymous access to + * this method should be granted. + */ + function addCallback($method, $callback, $args, $help, $public=false){ + if($public) $this->public_methods[] = $method; + return parent::addCallback($method, $callback, $args, $help); + } + + /** + * Execute a call, extends parent method + * + * Checks for authentication first + */ + function call($methodname, $args){ + if(!in_array($methodname,$this->public_methods) && !$this->checkAuth()){ + return new IXR_Error(-32603, 'server error. not authorized to call method "'.$methodname.'".'); + } + return parent::call($methodname, $args); + } + + /** + * Constructor. Register methods and run Server + */ + function dokuwiki_xmlrpc_server(){ + $this->IXR_IntrospectionServer(); + + /* DokuWiki's own methods */ + $this->addCallback( + 'dokuwiki.getXMLRPCAPIVersion', + 'this:getAPIVersion', + array('integer'), + 'Returns the XMLRPC API version.', + true + ); + + $this->addCallback( + 'dokuwiki.getVersion', + 'getVersion', + array('string'), + 'Returns the running DokuWiki version.', + true + ); + + $this->addCallback( + 'dokuwiki.login', + 'this:login', + array('integer','string','string'), + 'Tries to login with the given credentials and sets auth cookies.', + true + ); + + $this->addCallback( + 'dokuwiki.getPagelist', + 'this:readNamespace', + array('struct','string','struct'), + 'List all pages within the given namespace.' + ); + + $this->addCallback( + 'dokuwiki.getTime', + 'time', + array('int'), + 'Return the current time at the wiki server.' + ); + + $this->addCallback( + 'dokuwiki.setLocks', + 'this:setLocks', + array('struct','struct'), + 'Lock or unlock pages.' + ); + + /* Wiki API v2 http://www.jspwiki.org/wiki/WikiRPCInterface2 */ + $this->addCallback( + 'wiki.getRPCVersionSupported', + 'this:wiki_RPCVersion', + array('int'), + 'Returns 2 with the supported RPC API version.', + true + ); + $this->addCallback( + 'wiki.getPage', + 'this:rawPage', + array('string','string'), + 'Get the raw Wiki text of page, latest version.' + ); + $this->addCallback( + 'wiki.getPageVersion', + 'this:rawPage', + array('string','string','int'), + 'Get the raw Wiki text of page.' + ); + $this->addCallback( + 'wiki.getPageHTML', + 'this:htmlPage', + array('string','string'), + 'Return page in rendered HTML, latest version.' + ); + $this->addCallback( + 'wiki.getPageHTMLVersion', + 'this:htmlPage', + array('string','string','int'), + 'Return page in rendered HTML.' + ); + $this->addCallback( + 'wiki.getAllPages', + 'this:listPages', + array('struct'), + 'Returns a list of all pages. The result is an array of utf8 pagenames.' + ); + $this->addCallback( + 'wiki.getAttachments', + 'this:listAttachments', + array('struct', 'string', 'struct'), + 'Returns a list of all media files.' + ); + $this->addCallback( + 'wiki.getBackLinks', + 'this:listBackLinks', + array('struct','string'), + 'Returns the pages that link to this page.' + ); + $this->addCallback( + 'wiki.getPageInfo', + 'this:pageInfo', + array('struct','string'), + 'Returns a struct with infos about the page.' + ); + $this->addCallback( + 'wiki.getPageInfoVersion', + 'this:pageInfo', + array('struct','string','int'), + 'Returns a struct with infos about the page.' + ); + $this->addCallback( + 'wiki.getPageVersions', + 'this:pageVersions', + array('struct','string','int'), + 'Returns the available revisions of the page.' + ); + $this->addCallback( + 'wiki.putPage', + 'this:putPage', + array('int', 'string', 'string', 'struct'), + 'Saves a wiki page.' + ); + $this->addCallback( + 'wiki.listLinks', + 'this:listLinks', + array('struct','string'), + 'Lists all links contained in a wiki page.' + ); + $this->addCallback( + 'wiki.getRecentChanges', + 'this:getRecentChanges', + array('struct','int'), + 'Returns a struct about all recent changes since given timestamp.' + ); + $this->addCallback( + 'wiki.getRecentMediaChanges', + 'this:getRecentMediaChanges', + array('struct','int'), + 'Returns a struct about all recent media changes since given timestamp.' + ); + $this->addCallback( + 'wiki.aclCheck', + 'this:aclCheck', + array('int', 'string'), + 'Returns the permissions of a given wiki page.' + ); + $this->addCallback( + 'wiki.putAttachment', + 'this:putAttachment', + array('struct', 'string', 'base64', 'struct'), + 'Upload a file to the wiki.' + ); + $this->addCallback( + 'wiki.deleteAttachment', + 'this:deleteAttachment', + array('int', 'string'), + 'Delete a file from the wiki.' + ); + $this->addCallback( + 'wiki.getAttachment', + 'this:getAttachment', + array('base64', 'string'), + 'Download a file from the wiki.' + ); + $this->addCallback( + 'wiki.getAttachmentInfo', + 'this:getAttachmentInfo', + array('struct', 'string'), + 'Returns a struct with infos about the attachment.' + ); + + /** + * Trigger XMLRPC_CALLBACK_REGISTER, action plugins can use this event + * to extend the XMLRPC interface and register their own callbacks. + * + * Event data: + * The XMLRPC server object: + * + * $event->data->addCallback() - register a callback, the second + * paramter has to be of the form "plugin:<pluginname>:<plugin + * method>" + * + * $event->data->callbacks - an array which holds all awaylable + * callbacks + */ + trigger_event('XMLRPC_CALLBACK_REGISTER', $this); + + $this->serve(); + } + + /** + * Return a raw wiki page + */ + function rawPage($id,$rev=''){ + if(auth_quickaclcheck($id) < AUTH_READ){ + return new IXR_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; + } + } + + /** + * Return a media file encoded in base64 + * + * @author Gina Haeussge <osd@foosel.net> + */ + function getAttachment($id){ + $id = cleanID($id); + if (auth_quickaclcheck(getNS($id).':*') < AUTH_READ) + return new IXR_Error(1, 'You are not allowed to read this file'); + + $file = mediaFN($id); + if (!@ file_exists($file)) + return new IXR_Error(1, 'The requested file does not exist'); + + $data = io_readFile($file, false); + $base64 = base64_encode($data); + return $base64; + } + + /** + * Return info about a media file + * + * @author Gina Haeussge <osd@foosel.net> + */ + 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 IXR_Date(filemtime($file)); + $info['size'] = filesize($file); + } + + return $info; + } + + /** + * Return a wiki page rendered to html + */ + function htmlPage($id,$rev=''){ + if(auth_quickaclcheck($id) < AUTH_READ){ + return new IXR_Error(1, 'You are not allowed to read this page'); + } + return p_wiki_xhtml($id,$rev,false); + } + + /** + * List all pages - we use the indexer list here + */ + 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 IXR_Date(@filemtime(wikiFN($pages[$idx]))); + $list[] = $page; + } + } + } + + return $list; + } + + /** + * List all pages in the given namespace (and below) + */ + 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; + } + + /** + * List all media files. + * + * Available options are 'recursive' for also including the subnamespaces + * in the listing, and 'pattern' for filtering the returned files against + * a regular expression matching their name. + * + * @author Gina Haeussge <osd@foosel.net> + */ + 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 IXR_Date($data[$i]['mtime']); + } + return $data; + } else { + return new IXR_Error(1, 'You are not allowed to list media files.'); + } + } + + /** + * Return a list of backlinks + */ + function listBackLinks($id){ + require_once(DOKU_INC.'inc/fulltext.php'); + return ft_backlinks($id); + } + + /** + * Return some basic data about a page + */ + function pageInfo($id,$rev=''){ + if(auth_quickaclcheck($id) < AUTH_READ){ + return new IXR_Error(1, 'You are not allowed to read this page'); + } + $file = wikiFN($id,$rev); + $time = @filemtime($file); + if(!$time){ + return new IXR_Error(10, 'The requested page does not exist'); + } + + $info = getRevisionInfo($id, $time, 1024); + + $data = array( + 'name' => $id, + 'lastModified' => new IXR_Date($time), + 'author' => (($info['user']) ? $info['user'] : $info['ip']), + 'version' => $time + ); + + return ($data); + } + + /** + * Save a wiki page + * + * @author Michael Klier <chi@chimeric.de> + */ + 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 IXR_Error(1, 'Empty page ID'); + + if(!page_exists($id) && trim($TEXT) == '' ) { + return new IXR_ERROR(1, 'Refusing to write an empty new wiki page'); + } + + if(auth_quickaclcheck($id) < AUTH_EDIT) + return new IXR_Error(1, 'You are not allowed to edit this page'); + + // Check, if page is locked + if(checklock($id)) + return new IXR_Error(1, 'The page is currently locked'); + + // SPAM check + if(checkwordblock()) + return new IXR_Error(1, 'Positive wordblock check'); + + // autoset summary on new pages + if(!page_exists($id) && empty($sum)) { + $sum = $lang['created']; + } + + // autoset summary on deleted pages + 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($conf['dperm']) chmod($lock, $conf['dperm']); + + require_once(DOKU_INC.'inc/indexer.php'); + + // do the work + idx_addPage($id); + + // we're finished - save and free lock + io_saveFile(metaFN($id,'.indexed'),INDEXER_VERSION); + @rmdir($lock); + } + + return 0; + } + + /** + * Uploads a file to the wiki. + * + * Michael Klier <chi@chimeric.de> + */ + function putAttachment($id, $file, $params) { + global $conf; + global $lang; + + $auth = auth_quickaclcheck(getNS($id).':*'); + if($auth >= AUTH_UPLOAD) { + if(!isset($id)) { + return new IXR_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 IXR_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 IXR_ERROR(1, sprintf($lang['uploadexist'].'2', ".$iext")); + } elseif($ok == -2) { + return new IXR_ERROR(1, $lang['uploadspam']); + } elseif($ok == -3) { + return new IXR_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 IXR_ERROR(1, $lang['uploadwrong']); + } + } else { + return new IXR_ERROR(1, "You don't have permissions to upload files."); + } + } + + /** + * Deletes a file from the wiki. + * + * @author Gina Haeussge <osd@foosel.net> + */ + function deleteAttachment($id){ + $auth = auth_quickaclcheck(getNS($id).':*'); + if($auth < AUTH_DELETE) return new IXR_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 IXR_ERROR(1, 'Could not delete file'); + } else { + return new IXR_ERROR(1, 'File is still referenced'); + } + } + + /** + * Moves the temporary file to its final destination. + * + * Michael Klier <chi@chimeric.de> + */ + 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 IXR_ERROR(1, 'Upload failed.'); + } + } else { + return new IXR_ERROR(1, 'Upload failed.'); + } + } + + /** + * Returns the permissions of a given wiki page + */ + function aclCheck($id) { + return auth_quickaclcheck($id); + } + + /** + * Lists all links contained in a wiki page + * + * @author Michael Klier <chi@chimeric.de> + */ + function listLinks($id) { + if(auth_quickaclcheck($id) < AUTH_READ){ + return new IXR_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); + } + + /** + * Returns a list of recent changes since give timestamp + * + * @author Michael Hamann <michael@content-space.de> + * @author Michael Klier <chi@chimeric.de> + */ + function getRecentChanges($timestamp) { + if(strlen($timestamp) != 10) + return new IXR_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 IXR_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 IXR_Error(30, 'There are no changes in the specified timeframe'); + } + } + + /** + * Returns a list of recent media changes since give timestamp + * + * @author Michael Hamann <michael@content-space.de> + * @author Michael Klier <chi@chimeric.de> + */ + function getRecentMediaChanges($timestamp) { + if(strlen($timestamp) != 10) + return new IXR_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 IXR_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 IXR_Error(30, 'There are no changes in the specified timeframe'); + } + } + + /** + * Returns a list of available revisions of a given wiki page + * + * @author Michael Klier <chi@chimeric.de> + */ + function pageVersions($id, $first) { + global $conf; + + $versions = array(); + + if(empty($id)) + return new IXR_Error(1, 'Empty page ID'); + + require_once(DOKU_INC.'inc/changelog.php'); + + $revisions = getRevisions($id, $first, $conf['recent']+1); + + if(count($revisions)==0 && $first!=0) { + $first=0; + $revisions = getRevisions($id, $first, $conf['recent']+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)>$conf['recent']) { + $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 IXR_Date($info['date']); + $data['version'] = $info['date']; + array_push($versions, $data); + } + } + } + return $versions; + } else { + return array(); + } + } + + /** + * The version of Wiki RPC API supported + */ + function wiki_RPCVersion(){ + return 2; + } + + + /** + * Locks or unlocks a given batch of pages + * + * Give an associative array with two keys: lock and unlock. Both should contain a + * list of pages to lock or unlock + * + * Returns an associative array with the keys locked, lockfail, unlocked and + * unlockfail, each containing lists of pages. + */ + function setLocks($set){ + $locked = array(); + $lockfail = array(); + $unlocked = array(); + $unlockfail = array(); + + foreach((array) $set['lock'] as $id){ + if(checklock($id)){ + $lockfail[] = $id; + }else{ + lock($id); + $locked[] = $id; + } + } + + foreach((array) $set['unlock'] as $id){ + if(unlock($id)){ + $unlocked[] = $id; + }else{ + $unlockfail[] = $id; + } + } + + return array( + 'locked' => $locked, + 'lockfail' => $lockfail, + 'unlocked' => $unlocked, + 'unlockfail' => $unlockfail, + ); + } + + function getAPIVersion(){ + return DOKU_XMLRPC_API_VERSION; + } + + 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_xmlrpc_server(); + +// vim:ts=4:sw=4:et:enc=utf-8: |