From abf7dc44a2f5a9d3099a6306e4caf2437e104ab9 Mon Sep 17 00:00:00 2001 From: jerome mouneyrac Date: Fri, 18 Dec 2009 03:19:22 +0000 Subject: [PATCH] webservice MDL-20803 auto-doc: added protocol checking, removed IP checking, removed all $USER reference, remove DEBUG call. TODO: split the code between login and documentation display, add switch to disable documentation, remove all html from the renderer using output function (create empty tag, create box, ... + css), fix xhtml strict --- lang/en_utf8/webservice.php | 7 ++- webservice/lib.php | 2 +- webservice/renderer.php | 111 +++++++++++++++++++----------------- webservice/wsdoc.php | 50 ++++++++-------- 4 files changed, 88 insertions(+), 82 deletions(-) diff --git a/lang/en_utf8/webservice.php b/lang/en_utf8/webservice.php index 317ffcebc2..dfc031cf14 100644 --- a/lang/en_utf8/webservice.php +++ b/lang/en_utf8/webservice.php @@ -16,7 +16,7 @@ $string['disabledwarning'] = 'All webs service protocols are disabled, the \Enab $string['editservice'] = 'Edit the service: $a->name (id: $a->id)'; $string['enabled'] = 'Enabled'; $string['error'] = 'Error: $a'; -$string['errorcodes'] = 'Error Codes'; +$string['errorcodes'] = 'Error message'; $string['execute'] = 'Execute'; $string['executewarnign'] = 'WARNING: if you press execute your database will be modified and changes can not be reverted automatically!'; $string['externalservices'] = 'External services'; @@ -25,9 +25,9 @@ $string['externalservicefunctions'] = 'External service functions'; $string['externalserviceusers'] = 'External service users'; $string['function'] = 'Function'; $string['functions'] = 'Functions'; +$string['generalstructure'] = 'General structure'; $string['iprestriction'] = 'IP restriction'; $string['manageprotocols'] = 'Manage protocols'; -$string['noerrorcode'] = 'No error code'; $string['norequiredcapability'] = 'No required capability'; $string['optional'] = 'Optional'; $string['phpparam'] = 'XML-RPC (PHP structure)'; @@ -43,6 +43,7 @@ $string['required'] = 'Required'; $string['requiredcapability'] = 'Required capability'; $string['response'] = 'Response'; $string['restcode'] = 'REST'; +$string['restexception'] = 'REST'; $string['restparam'] = 'REST (POST parameters)'; $string['restrictedusers'] = 'Authorised users only'; $string['selectedcapabilitydoesntexit'] = 'The currently set required capability ($a) doesn\'t exist anymore. Please change it and save the changes.'; @@ -61,4 +62,4 @@ $string['wsdocumentationintro'] = 'Following a listing of web service functions $string['wsdocumentationlogin'] = 'Enter your web service username and password.'; $string['wspassword'] = 'Web service password'; $string['wsusername'] = 'Web service username'; -$string['xmlrpcstructure'] = 'documentation'; + diff --git a/webservice/lib.php b/webservice/lib.php index 23fe69f62c..b0a61cad87 100644 --- a/webservice/lib.php +++ b/webservice/lib.php @@ -195,7 +195,7 @@ abstract class webservice_server implements webservice_server_interface { */ abstract class webservice_zend_server extends webservice_server { - /** @property string name of the zend server class */ + /** @property string name of the zend server class : Zend_XmlRpc_Server, Zend_Soap_Server, Zend_Soap_AutoDiscover, ...*/ protected $zend_class; /** @property object Zend server instance */ diff --git a/webservice/renderer.php b/webservice/renderer.php index 83dee9e85d..fa0f074057 100644 --- a/webservice/renderer.php +++ b/webservice/renderer.php @@ -28,7 +28,7 @@ */ class core_webservice_renderer extends plugin_renderer_base { - /** + /** * Create documentation for a description object * @param object $params a part of parameter/return description * @return string the html to display @@ -63,8 +63,6 @@ class core_webservice_renderer extends plugin_renderer_base { } return $type." ".$paramdesc; } - - } /** @@ -236,7 +234,7 @@ EOF; * @param string $username * @return string the html to diplay */ - public function documentation_html($functions, $username) { + public function documentation_html($functions, $username, $activatedprotocol) { $brakeline = <<"; + $documentationhtml .= "
"; $documentationhtml .= get_string('wsdocumentationintro', 'webservice', $username); $documentationhtml .= "


"; @@ -258,38 +256,36 @@ EOF; $documentationhtml .= ""; $documentationhtml .= "

"; - $documentationhtml .= "Authentication
"; - $documentationhtml .= ""; - $documentationhtml .= get_string('requireauthentication', 'webservice'/*,$description->type*/); - $documentationhtml .= ""; - $documentationhtml .= "

"; - $documentationhtml .= "".get_string('arguments', 'webservice')."
"; foreach ($description->parameters_desc->keys as $paramname => $paramdesc) { $documentationhtml .= ""; $required = $paramdesc->required?get_string('required', 'webservice'):get_string('optional', 'webservice'); $documentationhtml .= "".$paramname . " (" .$required. ")
"; $documentationhtml .= "        ".$paramdesc->desc."

"; - $documentationhtml .= "
"; $documentationhtml .= "
";
-                $documentationhtml .= print_collapsible_region_start('', 'aera_'.$functionname."_".$paramname,''.get_string('xmlrpcstructure', 'webservice').'',false,true,true);
-                //echo ''.get_string('xmlrpcstructure', 'webservice').'
'; + $documentationhtml .= "
"; + //$documentationhtml .= print_collapsible_region_start('', 'aera_'.$functionname."_".$paramname,''.get_string('generalstructure', 'webservice').'',false,true,true); + $documentationhtml .= ''.get_string('generalstructure', 'webservice').'
'; $documentationhtml .= $brakeline.$this->detailed_description_html($paramdesc); - $documentationhtml .= print_collapsible_region_end(true); - $documentationhtml .= "
"; - $documentationhtml .= "

"; - $documentationhtml .= "
";
-                $documentationhtml .= "
"; - $documentationhtml .= ''.get_string('phpparam', 'webservice').'
'; - $documentationhtml .= $brakeline.'['.$paramname.'] =>'.htmlentities($this->xmlrpc_param_description_html($paramdesc)). $brakeline. $brakeline; - $documentationhtml .= "

"; - $documentationhtml .= "
"; - $documentationhtml .= "
";
-                $documentationhtml .= "
"; - $documentationhtml .= ''.get_string('restparam', 'webservice').'
'; - $documentationhtml .= $brakeline.htmlentities($this->rest_param_description_html($paramdesc,$paramname)). $brakeline. $brakeline; + //$documentationhtml .= print_collapsible_region_end(true); $documentationhtml .= "
"; - $documentationhtml .= "
"; + $documentationhtml .= "
"; + if (!empty($activatedprotocol['xmlrpc'])) { + $documentationhtml .= "
";
+                    $documentationhtml .= "
"; + $documentationhtml .= ''.get_string('phpparam', 'webservice').'
'; + $documentationhtml .= $brakeline.'['.$paramname.'] =>'.htmlentities($this->xmlrpc_param_description_html($paramdesc)). $brakeline. $brakeline; + $documentationhtml .= "

"; + $documentationhtml .= "
"; + } + if (!empty($activatedprotocol['rest'])) { + $documentationhtml .= "
";
+                    $documentationhtml .= "
"; + $documentationhtml .= ''.get_string('restparam', 'webservice').'
'; + $documentationhtml .= $brakeline.htmlentities($this->rest_param_description_html($paramdesc,$paramname)). $brakeline. $brakeline; + $documentationhtml .= "
"; + $documentationhtml .= "
"; + } $documentationhtml .= "
"; } $documentationhtml .= "

"; @@ -301,44 +297,58 @@ EOF; } if (!empty($description->returns_desc)) { - $documentationhtml .= "
"; $documentationhtml .= "
";
-                $documentationhtml .= print_collapsible_region_start('', 'aera_'.$functionname."_xmlrpc_return",''.get_string('xmlrpcstructure', 'webservice').'',false,true,true);
-                //echo ''.get_string('xmlrpcstructure', 'webservice').'
'; + $documentationhtml .= "
"; + //$documentationhtml .= print_collapsible_region_start('', 'aera_'.$functionname."_xmlrpc_return",''.get_string('generalstructure', 'webservice').'',false,true,true); + $documentationhtml .= ''.get_string('generalstructure', 'webservice').'
'; $documentationhtml .= $brakeline.$this->detailed_description_html($description->returns_desc); - $documentationhtml .= print_collapsible_region_end(true); - $documentationhtml .= "
"; - $documentationhtml .= "

"; - $documentationhtml .= "
";
-                $documentationhtml .= "
"; - $documentationhtml .= ''.get_string('phpresponse', 'webservice').'
'; - $documentationhtml .= htmlentities($this->xmlrpc_param_description_html($description->returns_desc)).$brakeline.$brakeline; + //$documentationhtml .= print_collapsible_region_end(true); $documentationhtml .= "
"; $documentationhtml .= "

"; - $documentationhtml .= $this->rest_response_html($functionname, $description->returns_desc); + if (!empty($activatedprotocol['xmlrpc'])) { + $documentationhtml .= "
";
+                    $documentationhtml .= "
"; + $documentationhtml .= ''.get_string('phpresponse', 'webservice').'
'; + $documentationhtml .= htmlentities($this->xmlrpc_param_description_html($description->returns_desc)).$brakeline.$brakeline; + $documentationhtml .= "
"; + $documentationhtml .= "

"; + } + if (!empty($activatedprotocol['rest'])) { + $documentationhtml .= $this->rest_response_html($functionname, $description->returns_desc); + } } $documentationhtml .= ""; $documentationhtml .= "

"; + if (!empty($activatedprotocol['rest'])) { + $documentationhtml .= "".get_string('errorcodes', 'webservice')."
"; + $documentationhtml .= ""; + $documentationhtml .= "
";
+                $documentationhtml .= "
"; - $documentationhtml .= "".get_string('errorcodes', 'webservice')."
"; - $documentationhtml .= ""; - $documentationhtml .= get_string('noerrorcode', 'webservice'); - $documentationhtml .= ""; - $documentationhtml .= "

"; - - - $documentationhtml .= "".get_string('apiexplorer', 'webservice')."
"; - $documentationhtml .= ""; - $documentationhtml .= get_string('apiexplorernotavalaible', 'webservice'); + $documentationhtml .= ''.get_string('restexception', 'webservice').'
'; + $errormessage = get_string('invalidparameter', 'debug'); + $restexceptiontext =<< + + {$errormessage} + + +EOF; + $documentationhtml .= $brakeline.htmlentities($restexceptiontext); + $documentationhtml .= "
"; + $documentationhtml .= "

"; $documentationhtml .= "
"; + } $documentationhtml .= "

"; $documentationhtml .= print_collapsible_region_end(true); } - $documentationhtml .= "
"; + $documentationhtml .= ""; + + $documentationhtml .= ""; return $documentationhtml; } @@ -383,7 +393,6 @@ EOF; $htmlloginpage .= $OUTPUT->form($form, $contents); - $htmlloginpage .= ""; return $htmlloginpage; diff --git a/webservice/wsdoc.php b/webservice/wsdoc.php index b8e1c29656..33471e5b44 100644 --- a/webservice/wsdoc.php +++ b/webservice/wsdoc.php @@ -21,7 +21,6 @@ // disable moodle specific debug messages and any errors in output -define('NO_DEBUG_DISPLAY', true); define('NO_MOODLE_COOKIES', true); require_once('../config.php'); @@ -38,8 +37,7 @@ require_once('lib.php'); */ class webservice_documentation_generator { - /** @property array all external function description - * they */ + /** @property array all external function description*/ protected $functions; /** @property string $username name of local user */ @@ -48,6 +46,9 @@ class webservice_documentation_generator { /** @property string $password password of the local user */ protected $password = null; + /** @property object $webserviceuser authenticated web service user */ + protected $webserviceuser = null; + /** * Contructor */ @@ -66,7 +67,7 @@ class webservice_documentation_generator { // init all properties from the request data $this->get_authentication_parameters(); - // this sets up $USER + // this sets up $this->webserviceuser try { $this->authenticate_user(); } catch(moodle_exception $e) { @@ -112,7 +113,7 @@ class webservice_documentation_generator { * @return void */ protected function generate_documentation() { - global $USER, $DB; + global $DB; /// first of all get a complete list of services user is allowed to access $params = array(); @@ -139,13 +140,12 @@ class webservice_documentation_generator { JOIN {external_services_users} su ON (su.externalserviceid = s.id AND su.userid = :userid) WHERE s.enabled = 1 AND su.validuntil IS NULL OR su.validuntil < :now $wscond2"; - $params = array_merge($params, array('userid'=>$USER->id, 'now'=>time())); + $params = array_merge($params, array('userid'=>$this->webserviceuser->id, 'now'=>time())); $serviceids = array(); $rs = $DB->get_recordset_sql($sql, $params); // make sure user may access at least one service - $remoteaddr = getremoteaddr(); $allowed = false; foreach ($rs as $service) { if (isset($serviceids[$service->id])) { @@ -154,9 +154,6 @@ class webservice_documentation_generator { if ($service->requiredcapability and !has_capability($service->requiredcapability, $this->restricted_context)) { continue; // cap required, sorry } - if ($service->iprestriction and !address_in_subnet($remoteaddr, $service->iprestriction)) { - continue; // wrong request source ip, sorry - } $serviceids[$service->id] = $service->id; } $rs->close(); @@ -181,12 +178,12 @@ class webservice_documentation_generator { /** * Authenticate user using username+password - * This function sets up $USER global. + * This function sets up $this->webserviceuser. * called into the Moodle header * @return void */ protected function authenticate_user() { - global $CFG, $DB, $USER; + global $CFG, $DB; if (!NO_MOODLE_COOKIES) { throw new coding_exception('Cookies must be disabled!'); @@ -212,7 +209,7 @@ class webservice_documentation_generator { throw new webservice_access_exception('Wrong username or password'); } - $USER = $DB->get_record('user', array('username'=>$this->username, 'mnethostid'=>$CFG->mnet_localhost_id, 'deleted'=>0), '*', MUST_EXIST); + $this->webserviceuser = $DB->get_record('user', array('username'=>$this->username, 'mnethostid'=>$CFG->mnet_localhost_id, 'deleted'=>0), '*', MUST_EXIST); } @@ -225,33 +222,32 @@ class webservice_documentation_generator { * Generate and display the documentation */ protected function display_documentation_html() { - global $PAGE, $OUTPUT, $SITE, $USER; + global $PAGE, $OUTPUT, $SITE; $PAGE->set_url('/webservice/wsdoc'); $PAGE->set_docs_path(''); $PAGE->set_title($SITE->fullname." ".get_string('wsdocumentation', 'webservice')); $PAGE->set_heading($SITE->fullname." ".get_string('wsdocumentation', 'webservice')); $PAGE->set_pagelayout('popup'); - //unlog temporarly the user in order to not trigger environment.php called by Moodle header. - //environment.php checkes the sessionkey that we don't have here. - //emvrionment.php is just used to detect the flash player. We don't need - //to check the flash player version. - $userid = $USER->id; - $USER->id = null; + echo $OUTPUT->header(); - $USER->id = $userid; - $renderer = $PAGE->get_renderer('core', 'wsdoc'); - echo $renderer->documentation_html($this->functions, $this->username); + + $activatedprotocol = array(); + $activatedprotocol['rest'] = webservice_protocol_is_enabled('rest'); + $activatedprotocol['xmlrpc'] = webservice_protocol_is_enabled('xmlrpc'); + $renderer = $PAGE->get_renderer('core', 'webservice'); + echo $renderer->documentation_html($this->functions, $this->username, $activatedprotocol); + echo $OUTPUT->footer(); } /** * Display login page to the web service documentation - * @global $PAGE - * @global $OUTPUT - * @global $SITE - * @global $CFG + * @global object $PAGE + * @global object $OUTPUT + * @global object $SITE + * @global object $CFG * @param string $errormessage error message displayed if wrong login */ protected function display_login_page_html($errormessage) { -- 2.39.5