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

This commit is contained in:
jerome mouneyrac
2009-12-18 03:19:22 +00:00
parent 12f549e2ff
commit abf7dc44a2
4 changed files with 88 additions and 82 deletions
+4 -3
View File
@@ -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';
+1 -1
View File
@@ -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 */
+60 -51
View File
@@ -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 = <<<EOF
@@ -245,7 +243,7 @@ EOF;
$documentationhtml = "";
$documentationhtml .= "<table style=\"margin-left:auto; margin-right:auto;\"><tr><td>";
$documentationhtml .= "<table style=\"margin-left:auto; margin-right:auto;\"><tr><td style=\"text-align=left\">";
$documentationhtml .= get_string('wsdocumentationintro', 'webservice', $username);
$documentationhtml .= "<br/><br/><br/>";
@@ -258,38 +256,36 @@ EOF;
$documentationhtml .= "</div>";
$documentationhtml .= "<br/><br/>";
$documentationhtml .= "<span style=\"color:#EA33A6\">Authentication</span><br/>";
$documentationhtml .= "<span style=\"font-size:80%\">";
$documentationhtml .= get_string('requireauthentication', 'webservice'/*,$description->type*/);
$documentationhtml .= "</span>";
$documentationhtml .= "<br/><br/>";
$documentationhtml .= "<span style=\"color:#EA33A6\">".get_string('arguments', 'webservice')."</span><br/>";
foreach ($description->parameters_desc->keys as $paramname => $paramdesc) {
$documentationhtml .= "<span style=\"font-size:80%\">";
$required = $paramdesc->required?get_string('required', 'webservice'):get_string('optional', 'webservice');
$documentationhtml .= "<b>".$paramname . "</b> (" .$required. ")<br/>";
$documentationhtml .= "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".$paramdesc->desc." <br/><br/>";
$documentationhtml .= "<pre>";
$documentationhtml .= "<div style=\"border:solid 1px #DEDEDE;background:#FFF1BC;color:#222222;padding:4px;\">";
$documentationhtml .= "<pre>";
$documentationhtml .= print_collapsible_region_start('', 'aera_'.$functionname."_".$paramname,'<b>'.get_string('xmlrpcstructure', 'webservice').'</b>',false,true,true);
//echo '<b>'.get_string('xmlrpcstructure', 'webservice').'</b><br/>';
//$documentationhtml .= print_collapsible_region_start('', 'aera_'.$functionname."_".$paramname,'<b>'.get_string('generalstructure', 'webservice').'</b>',false,true,true);
$documentationhtml .= '<b>'.get_string('generalstructure', 'webservice').'</b><br/>';
$documentationhtml .= $brakeline.$this->detailed_description_html($paramdesc);
$documentationhtml .= print_collapsible_region_end(true);
$documentationhtml .= "</pre>";
$documentationhtml .= "</div><br/>";
$documentationhtml .= "<pre>";
$documentationhtml .= "<div style=\"border:solid 1px #DEDEDE;background:#DFEEE7;color:#222222;padding:4px;\">";
$documentationhtml .= '<b>'.get_string('phpparam', 'webservice').'</b><br/>';
$documentationhtml .= $brakeline.'['.$paramname.'] =>'.htmlentities($this->xmlrpc_param_description_html($paramdesc)). $brakeline. $brakeline;
$documentationhtml .= "</div><br/>";
$documentationhtml .= "</pre>";
$documentationhtml .= "<pre>";
$documentationhtml .= "<div style=\"border:solid 1px #DEDEDE;background:#FEEBE5;color:#222222;padding:4px;\">";
$documentationhtml .= '<b>'.get_string('restparam', 'webservice').'</b><br/>';
$documentationhtml .= $brakeline.htmlentities($this->rest_param_description_html($paramdesc,$paramname)). $brakeline. $brakeline;
//$documentationhtml .= print_collapsible_region_end(true);
$documentationhtml .= "</div>";
$documentationhtml .= "</pre>";
$documentationhtml .= "</pre><br/>";
if (!empty($activatedprotocol['xmlrpc'])) {
$documentationhtml .= "<pre>";
$documentationhtml .= "<div style=\"border:solid 1px #DEDEDE;background:#DFEEE7;color:#222222;padding:4px;\">";
$documentationhtml .= '<b>'.get_string('phpparam', 'webservice').'</b><br/>';
$documentationhtml .= $brakeline.'['.$paramname.'] =>'.htmlentities($this->xmlrpc_param_description_html($paramdesc)). $brakeline. $brakeline;
$documentationhtml .= "</div><br/>";
$documentationhtml .= "</pre>";
}
if (!empty($activatedprotocol['rest'])) {
$documentationhtml .= "<pre>";
$documentationhtml .= "<div style=\"border:solid 1px #DEDEDE;background:#FEEBE5;color:#222222;padding:4px;\">";
$documentationhtml .= '<b>'.get_string('restparam', 'webservice').'</b><br/>';
$documentationhtml .= $brakeline.htmlentities($this->rest_param_description_html($paramdesc,$paramname)). $brakeline. $brakeline;
$documentationhtml .= "</div>";
$documentationhtml .= "</pre>";
}
$documentationhtml .= "</span>";
}
$documentationhtml .= "<br/><br/>";
@@ -301,44 +297,58 @@ EOF;
}
if (!empty($description->returns_desc)) {
$documentationhtml .= "<pre>";
$documentationhtml .= "<div style=\"border:solid 1px #DEDEDE;background:#FFF1BC;color:#222222;padding:4px;\">";
$documentationhtml .= "<pre>";
$documentationhtml .= print_collapsible_region_start('', 'aera_'.$functionname."_xmlrpc_return",'<b>'.get_string('xmlrpcstructure', 'webservice').'</b>',false,true,true);
//echo '<b>'.get_string('xmlrpcstructure', 'webservice').'</b><br/>';
//$documentationhtml .= print_collapsible_region_start('', 'aera_'.$functionname."_xmlrpc_return",'<b>'.get_string('generalstructure', 'webservice').'</b>',false,true,true);
$documentationhtml .= '<b>'.get_string('generalstructure', 'webservice').'</b><br/>';
$documentationhtml .= $brakeline.$this->detailed_description_html($description->returns_desc);
$documentationhtml .= print_collapsible_region_end(true);
$documentationhtml .= "</pre>";
$documentationhtml .= "</div><br/>";
$documentationhtml .= "<pre>";
$documentationhtml .= "<div style=\"border:solid 1px #DEDEDE;background:#DFEEE7;color:#222222;padding:4px;\">";
$documentationhtml .= '<b>'.get_string('phpresponse', 'webservice').'</b><br/>';
$documentationhtml .= htmlentities($this->xmlrpc_param_description_html($description->returns_desc)).$brakeline.$brakeline;
//$documentationhtml .= print_collapsible_region_end(true);
$documentationhtml .= "</div>";
$documentationhtml .= "</pre><br/>";
$documentationhtml .= $this->rest_response_html($functionname, $description->returns_desc);
if (!empty($activatedprotocol['xmlrpc'])) {
$documentationhtml .= "<pre>";
$documentationhtml .= "<div style=\"border:solid 1px #DEDEDE;background:#DFEEE7;color:#222222;padding:4px;\">";
$documentationhtml .= '<b>'.get_string('phpresponse', 'webservice').'</b><br/>';
$documentationhtml .= htmlentities($this->xmlrpc_param_description_html($description->returns_desc)).$brakeline.$brakeline;
$documentationhtml .= "</div>";
$documentationhtml .= "</pre><br/>";
}
if (!empty($activatedprotocol['rest'])) {
$documentationhtml .= $this->rest_response_html($functionname, $description->returns_desc);
}
}
$documentationhtml .= "</span>";
$documentationhtml .= "<br/><br/>";
if (!empty($activatedprotocol['rest'])) {
$documentationhtml .= "<span style=\"color:#EA33A6\">".get_string('errorcodes', 'webservice')."</span><br/>";
$documentationhtml .= "<span style=\"font-size:80%\">";
$documentationhtml .= "<pre>";
$documentationhtml .= "<div style=\"border:solid 1px #DEDEDE;background:#FEEBE5;color:#222222;padding:4px;\">";
$documentationhtml .= "<span style=\"color:#EA33A6\">".get_string('errorcodes', 'webservice')."</span><br/>";
$documentationhtml .= "<span style=\"font-size:80%\">";
$documentationhtml .= get_string('noerrorcode', 'webservice');
$documentationhtml .= "</span>";
$documentationhtml .= "<br/><br/>";
$documentationhtml .= "<span style=\"color:#EA33A6\">".get_string('apiexplorer', 'webservice')."</span><br/>";
$documentationhtml .= "<span style=\"font-size:80%\">";
$documentationhtml .= get_string('apiexplorernotavalaible', 'webservice');
$documentationhtml .= '<b>'.get_string('restexception', 'webservice').'</b><br/>';
$errormessage = get_string('invalidparameter', 'debug');
$restexceptiontext =<<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<EXCEPTION class="invalid_parameter_exception">
<MESSAGE>{$errormessage}</MESSAGE>
<DEBUGINFO></DEBUGINFO>
</EXCEPTION>
EOF;
$documentationhtml .= $brakeline.htmlentities($restexceptiontext);
$documentationhtml .= "</div>";
$documentationhtml .= "</pre><br/>";
$documentationhtml .= "</span>";
}
$documentationhtml .= "<br/><br/>";
$documentationhtml .= print_collapsible_region_end(true);
}
$documentationhtml .= "</td></tr></table>";
$documentationhtml .= "</td>";
$documentationhtml .= "</tr></table>";
return $documentationhtml;
}
@@ -383,7 +393,6 @@ EOF;
$htmlloginpage .= $OUTPUT->form($form, $contents);
$htmlloginpage .= "</td></tr></table>";
return $htmlloginpage;
+23 -27
View File
@@ -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 <type> $PAGE
* @global <type> $OUTPUT
* @global <type> $SITE
* @global <type> $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) {