mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 14:27:22 +01:00
336 lines
12 KiB
PHP
336 lines
12 KiB
PHP
<?php
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// This file is part of Moodle - http://moodle.org/ //
|
|
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
|
// //
|
|
// Moodle is free software: you can redistribute it and/or modify //
|
|
// it under the terms of the GNU General Public License as published by //
|
|
// the Free Software Foundation, either version 3 of the License, or //
|
|
// (at your option) any later version. //
|
|
// //
|
|
// Moodle is distributed in the hope that it will be useful, //
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
|
// GNU General Public License for more details. //
|
|
// //
|
|
// You should have received a copy of the GNU General Public License //
|
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// disable moodle specific debug messages and any errors in output
|
|
define('NO_MOODLE_COOKIES', true);
|
|
|
|
require_once('../config.php');
|
|
require_once('lib.php');
|
|
|
|
|
|
/**
|
|
* This class generate the web service documentation specific to one
|
|
* web service user
|
|
* @package webservice
|
|
* @copyright 2009 Moodle Pty Ltd (http://moodle.com)
|
|
* @author Jerome Mouneyrac
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
class webservice_documentation_generator {
|
|
|
|
/** @property array all external function description*/
|
|
protected $functions;
|
|
|
|
/** @property string $username name of local user */
|
|
protected $username = null;
|
|
|
|
/** @property string $password password of the local user */
|
|
protected $password = null;
|
|
|
|
/** @property string $token token of the local user */
|
|
protected $token = null;
|
|
|
|
/** @property object $webserviceuser authenticated web service user */
|
|
protected $webserviceuser = null;
|
|
|
|
/**
|
|
* Contructor
|
|
*/
|
|
public function __construct() {
|
|
$this->functionsdescriptions = array();
|
|
$this->functions = array();
|
|
}
|
|
|
|
/**
|
|
* Run the documentation generation
|
|
* @return void
|
|
*/
|
|
public function run() {
|
|
|
|
// init all properties from the request data
|
|
$this->get_authentication_parameters();
|
|
|
|
// this sets up $this->webserviceuser
|
|
try {
|
|
$this->authenticate_user();
|
|
} catch(moodle_exception $e) {
|
|
$errormessage = $e->debuginfo;
|
|
$displayloginpage = true;
|
|
}
|
|
|
|
if (!empty($displayloginpage)){
|
|
$this->display_login_page_html($errormessage);
|
|
} else {
|
|
// make a descriptions list of all function that user is allowed to excecute
|
|
$this->generate_documentation();
|
|
|
|
//finally display the documentation
|
|
$this->display_documentation_html();
|
|
}
|
|
|
|
die;
|
|
}
|
|
|
|
|
|
///////////////////////////
|
|
/////// CLASS METHODS /////
|
|
///////////////////////////
|
|
|
|
/**
|
|
* This method parses the $_REQUEST superglobal and looks for
|
|
* the following information:
|
|
* user authentication - username+password
|
|
* @return void
|
|
*/
|
|
protected function get_authentication_parameters() {
|
|
if (isset($_REQUEST['wsusername'])) {
|
|
$this->username = $_REQUEST['wsusername'];
|
|
}
|
|
if (isset($_REQUEST['wspassword'])) {
|
|
$this->password = $_REQUEST['wspassword'];
|
|
}
|
|
if (isset($_REQUEST['token'])) {
|
|
$this->token = $_REQUEST['token'];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate the documentation specific to the auhenticated webservice user
|
|
* @return void
|
|
*/
|
|
protected function generate_documentation() {
|
|
global $DB;
|
|
|
|
/// first of all get a complete list of services user is allowed to access
|
|
$params = array();
|
|
$wscond1 = '';
|
|
$wscond2 = '';
|
|
|
|
// make sure the function is listed in at least one service user is allowed to use
|
|
// allow access only if:
|
|
// 1/ entry in the external_services_users table if required
|
|
// 2/ validuntil not reached
|
|
// 3/ has capability if specified in service desc
|
|
// 4/ iprestriction
|
|
|
|
$sql = "SELECT s.*, NULL AS iprestriction
|
|
FROM {external_services} s
|
|
JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND s.restrictedusers = 0)
|
|
WHERE s.enabled = 1 $wscond1
|
|
|
|
UNION
|
|
|
|
SELECT s.*, su.iprestriction
|
|
FROM {external_services} s
|
|
JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND s.restrictedusers = 1)
|
|
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'=>$this->webserviceuser->id, 'now'=>time()));
|
|
|
|
$serviceids = array();
|
|
$rs = $DB->get_recordset_sql($sql, $params);
|
|
|
|
// make sure user may access at least one service
|
|
$allowed = false;
|
|
foreach ($rs as $service) {
|
|
if (isset($serviceids[$service->id])) {
|
|
continue;
|
|
}
|
|
if ($service->requiredcapability and !has_capability($service->requiredcapability, $this->restricted_context)) {
|
|
continue; // cap required, sorry
|
|
}
|
|
$serviceids[$service->id] = $service->id;
|
|
}
|
|
$rs->close();
|
|
|
|
// now get the list of all functions
|
|
if ($serviceids) {
|
|
list($serviceids, $params) = $DB->get_in_or_equal($serviceids);
|
|
$sql = "SELECT f.*
|
|
FROM {external_functions} f
|
|
WHERE f.name IN (SELECT sf.functionname
|
|
FROM {external_services_functions} sf
|
|
WHERE sf.externalserviceid $serviceids)";
|
|
$functions = $DB->get_records_sql($sql, $params);
|
|
} else {
|
|
$functions = array();
|
|
}
|
|
|
|
foreach ($functions as $function) {
|
|
$this->functions[$function->name] = external_function_info($function);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Authenticate user using username+password
|
|
* This function sets up $this->webserviceuser.
|
|
* called into the Moodle header
|
|
* @return void
|
|
*/
|
|
protected function authenticate_user() {
|
|
global $CFG, $DB;
|
|
|
|
if (!NO_MOODLE_COOKIES) {
|
|
throw new coding_exception('Cookies must be disabled!');
|
|
}
|
|
|
|
if (!$this->token) {
|
|
if (!is_enabled_auth('webservice')) {
|
|
throw new webservice_access_exception(get_string('wsauthnotenabled', 'webservice'));
|
|
}
|
|
|
|
if (!$auth = get_auth_plugin('webservice')) {
|
|
throw new webservice_access_exception(get_string('wsauthmissing', 'webservice'));
|
|
}
|
|
|
|
if (!$this->username) {
|
|
throw new webservice_access_exception(get_string('missingusername', 'webservice'));
|
|
}
|
|
|
|
if (!$this->password) {
|
|
throw new webservice_access_exception(get_string('missingpassword', 'webservice'));
|
|
}
|
|
|
|
if (!$auth->user_login_webservice($this->username, $this->password)) {
|
|
throw new webservice_access_exception(get_string('wrongusernamepassword', 'webservice'));
|
|
}
|
|
|
|
$this->webserviceuser = $DB->get_record('user', array('username'=>$this->username, 'mnethostid'=>$CFG->mnet_localhost_id, 'deleted'=>0), '*', MUST_EXIST);
|
|
} else {
|
|
|
|
if (!$token = $DB->get_record('external_tokens', array('token'=>$this->token, 'tokentype'=>EXTERNAL_TOKEN_PERMANENT))) {
|
|
// log failed login attempts
|
|
throw new webservice_access_exception(get_string('invalidtoken', 'webservice'));
|
|
}
|
|
|
|
if ($token->validuntil and $token->validuntil < time()) {
|
|
throw new webservice_access_exception(get_string('invalidtimedtoken', 'webservice'));
|
|
}
|
|
|
|
if ($token->iprestriction and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
|
|
throw new webservice_access_exception(get_string('invalidiptoken', 'webservice'));
|
|
}
|
|
|
|
$this->webserviceuser = $DB->get_record('user', array('id'=>$token->userid, 'deleted'=>0), '*', MUST_EXIST);
|
|
|
|
// log token access
|
|
$DB->set_field('external_tokens', 'lastaccess', time(), array('id'=>$token->id));
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////
|
|
///// DISPLAY METHODS /////
|
|
////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Generate and display the documentation
|
|
*/
|
|
protected function display_documentation_html() {
|
|
global $PAGE, $OUTPUT, $SITE, $CFG;
|
|
|
|
$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');
|
|
$PAGE->set_pagetype('webservice-doc-generator');
|
|
|
|
echo $OUTPUT->header();
|
|
|
|
$activatedprotocol = array();
|
|
$activatedprotocol['rest'] = webservice_protocol_is_enabled('rest');
|
|
$activatedprotocol['xmlrpc'] = webservice_protocol_is_enabled('xmlrpc');
|
|
$renderer = $PAGE->get_renderer('core', 'webservice');
|
|
/// Check if we are in printable mode
|
|
$printableformat = false;
|
|
if (isset($_REQUEST['print'])) {
|
|
$printableformat = $_REQUEST['print'];
|
|
}
|
|
|
|
$authparams = array();
|
|
if (empty($this->token)) {
|
|
$authparams['wsusername'] = $this->username;
|
|
$authparams['wspassword'] = $this->password;
|
|
} else {
|
|
$authparams['wsusername'] = $this->webserviceuser->username;
|
|
$authparams['token'] = $this->token;
|
|
}
|
|
|
|
echo $renderer->documentation_html($this->functions, $printableformat, $activatedprotocol, $authparams);
|
|
|
|
/// trigger browser print operation
|
|
if (!empty($printableformat)) {
|
|
$PAGE->requires->js_function_call('window.print', array());
|
|
}
|
|
|
|
echo $OUTPUT->footer();
|
|
|
|
}
|
|
|
|
/**
|
|
* Display login page to the web service documentation
|
|
* @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) {
|
|
global $PAGE, $OUTPUT, $SITE, $CFG;
|
|
|
|
$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');
|
|
$PAGE->set_pagetype('webservice-doc-generator-login');
|
|
|
|
echo $OUTPUT->header();
|
|
|
|
$renderer = $PAGE->get_renderer('core', 'webservice');
|
|
echo $renderer->login_page_html($errormessage);
|
|
|
|
echo $OUTPUT->footer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
///////////////////////////
|
|
/////// RUN THE SCRIPT ////
|
|
///////////////////////////
|
|
|
|
if (empty($CFG->enablewsdocumentation)) {
|
|
echo get_string('wsdocumentationdisable', 'webservice');
|
|
die;
|
|
}
|
|
|
|
//run the documentation generator
|
|
$generator = new webservice_documentation_generator();
|
|
$generator->run();
|
|
die;
|