Development:Web services
Note: This article is a work in progress. Please use the page comments or an appropriate moodle.org forum for any recommendations/suggestions for improvement.
Introduction
This page described the Web Services module implemented for Moodle 2.0
The tracker issue is here: MDL-12886
This module is been implemented by the DFWS Team and Moodle.
Implementation
Web Services module has been conceived in a purpose to be ported on different Moodle version, and also on different project. It has also for purpose to support multiple web service protocols (REST, SOAP, AMF, ...). Adding a new protocol support should be relatively easy.
How it works
- The client sends a username and password to the web service protocol server script.
- The protocol server returns a session token for that user account (how this is sent depends on the protocol).
- The client calls a particular web service function (module name, function name, and function parameters), including the session token.
- The protocol server uses the token to check that the session is still active.
- The protocol server call the matching external function, located in a external.php file inside the relevant module.
- The external function checks that the current user has_capability to do this operation.
- The external function calls the matching Moodle core function (in lib.php usually).
- The core function can return a result to the external function.
- The external function will return a result to the protocol server.
- The protocol server returns the result to the client.
Code example
Following some bits of code in order to explain the concept
REST_server.php
///REST params conversion
$functionname = 'delete_user' //retrieve function name from the REST parameters
$modulename = 'user' //retrieve module name from the REST parameters
$classname = $modulename.'_external';
/// Authentication process
$token = ... //retrieve token from the REST parameters
if (empty($token)) {
if ($functionname != 'generate_token') {
throw new moodle_exception('mustidentifyfirst');
} else {
///authentication + token generation
$username = ... //retrieve username from the REST parameters
$password = ... //retrieve password from the REST parameters
if ($token = generate_token($username,$password)) {
return $token;
} else {
throw new moodle_exception('wrongusernamepassword');
}
}
} else {
///the client is already identified
$user = verify_token($token);
if (empty($user)) {
throw new moodle_exception('wrongidentification');
}
else {
///Load the user in order to get its context
$USER = $user;
}
}
/// load the external class
require_once($CFG->dirroot.$apipath.'external.php');
$wsapi = new $classname();
$description = $wsapi->get_function_webservice_description($functionname); //retrieve the web service description for this function
/// retrieve all rest params in an array
$params = retrieve_rest_params ($description); //retrieve the REST params
/// call the web service function
$result = call_user_func_array ( $classname.'::'.$functionname, array($params));
/// Return the result to the client
echo convert_into_rest_format(result);
external.php
final class user_external extends moodle_external {
/**
* Constructor - We set the description of this API in order to be access by Web service
*/
function __construct () {
$this->descriptions = array();
///The desciption of the web service
///
///'params', 'optionalparams' and 'return' are used to described the web services to the end user
///(can build WSDL file from these information)
$this->descriptions['delete_user'] = array( 'params' => array('username'=> PARAM_ALPHANUM),
'optionalparams' => array( ),
'return' => array('result' => PARAM_BOOL));
/**
* Delete a user
* @global object $DB
* @param array $params
* ->username string
* @return boolean true if success
*/
static function delete_user($params) {
global $DB,$USER;
$user = $DB->get_record('user', array('username'=>$params['username']));
if (has_capability('moodle/user:delete', get_context_instance(CONTEXT_SYSTEM))) {
return delete_user($user); //this core function is in moodlelib.php
}
else {
throw new moodle_exception('couldnotdeleteuser');
}
}
}
?>
List of functions
All callable functions are declared into each external.php. A "description" array contains all function names, parameter names and types, and return type.
Authentication
Clients needing to use a web service will need a Moodle user account with the 'moodle/site:usewebservices' capability enabled. After the first login with username and password the session is retained with a token that gets passed with every web service request (until the session expires).
The Moodle administrator can control access to the site using the 'Security -> Web services' page, which contains settings for:
- enabling/disabling particular protocols (SOAP, REST, AMF, XMLRPC, ...)
- configure protocol-specific settings (though we can't think of any such settings)
- configure system-wide default settings (stored in config table):
- IP whitelist
- Anything else?
- configure per-user settings (stored in user_preferences):
- IP whitelist
- Anything else?
Each protocol will call a webservice authentication function before allowing access, which will:
- Check that particular protocol is enabled for the system
- Authenticate the user using username/password and normal auth plugins (internal, LDAP etc)
- Check that the user has 'moodle/site:usewebservices' at SYSTEM level.
- Check the per-user restrictions, if there are any, else check the system settings
- Create a session and return a token for the web service protocol to use.
This is probably enough (an auth/webservice is not necessary).