MDL-52210 webservices: Remove AMF webservice

This commit is contained in:
Cameron Ball 2016-01-05 10:36:26 +08:00
parent ef343c3299
commit 13ae7db2bb
19 changed files with 20 additions and 1217 deletions

View File

@ -95,10 +95,6 @@ if (!$function or !$protocol) {
$descparams = new stdClass();
$descparams->atag = $atag;
$descparams->mode = get_string('debugnormal', 'admin');
$amfclienturl = new moodle_url('/webservice/amf/testclient/index.php');
$amfclientatag =html_writer::tag('a', get_string('amftestclient', 'webservice'),
array('href' => $amfclienturl));
$descparams->amfatag = $amfclientatag;
echo get_string('testclientdescription', 'webservice', $descparams);
echo $OUTPUT->box_end();

View File

@ -35,7 +35,6 @@ $string['addrequiredcapability'] = 'Assign/unassign the required capability';
$string['addservice'] = 'Add a new service: {$a->name} (id: {$a->id})';
$string['addservicefunction'] = 'Add functions to the service "{$a}"';
$string['allusers'] = 'All users';
$string['amftestclient'] = 'AMF test client';
$string['apiexplorer'] = 'API explorer';
$string['apiexplorernotavalaible'] = 'API explorer not available yet.';
$string['arguments'] = 'Arguments';
@ -185,7 +184,7 @@ $string['step'] = 'Step';
$string['supplyinfo'] = 'More details';
$string['testauserwithtestclientdescription'] = 'Simulate external access to the service using the web service test client. Before doing so, log in as a user with the moodle/webservice:createtoken capability and obtain the security key (token) via the user\'s preferences page. You will use this token in the test client. In the test client, also choose an enabled protocol with the token authentication. <strong>WARNING: The functions that you test WILL BE EXECUTED for this user, so be careful what you choose to test!</strong>';
$string['testclient'] = 'Web service test client';
$string['testclientdescription'] = '* The web service test client <strong>executes</strong> the functions for <strong>REAL</strong>. Do not test functions that you don\'t know. <br/>* All existing web service functions are not yet implemented into the test client. <br/>* In order to check that a user cannot access some functions, you can test some functions that you didn\'t allow.<br/>* To see clearer error messages set the debugging to <strong>{$a->mode}</strong> into {$a->atag}<br/>* Access the {$a->amfatag}.';
$string['testclientdescription'] = '* The web service test client <strong>executes</strong> the functions for <strong>REAL</strong>. Do not test functions that you don\'t know. <br/>* All existing web service functions are not yet implemented into the test client. <br/>* In order to check that a user cannot access some functions, you can test some functions that you didn\'t allow.<br/>* To see clearer error messages set the debugging to <strong>{$a->mode}</strong> into {$a->atag}.';
$string['testwithtestclient'] = 'Test the service';
$string['testwithtestclientdescription'] = 'Simulate external access to the service using the web service test client. Use an enabled protocol with token authentication. <strong>WARNING: The functions that you test WILL BE EXECUTED, so be careful what you choose to test!</strong>';
$string['token'] = 'Token';

View File

@ -1665,6 +1665,7 @@ class core_plugin_manager {
'theme' => array('mymobile', 'afterburner', 'anomaly', 'arialist', 'binarius', 'boxxie', 'brick', 'formal_white',
'formfactor', 'fusion', 'leatherbound', 'magazine', 'nimble', 'nonzero', 'overlay', 'serenity', 'sky_high',
'splash', 'standard', 'standardold'),
'webservice' => array('amf'),
);
if (!isset($plugins[$type])) {
@ -1897,7 +1898,7 @@ class core_plugin_manager {
),
'webservice' => array(
'amf', 'rest', 'soap', 'xmlrpc'
'rest', 'soap', 'xmlrpc'
),
'workshopallocation' => array(

View File

@ -4606,6 +4606,17 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2015100800.01);
}
if ($oldversion < 2015123100.01) {
// Force uninstall of deleted tool.
if (!file_exists("$CFG->dirroot/webservice/amf")) {
// Remove capabilities.
capabilities_cleanup('webservice_amf');
// Remove all other associated config.
unset_all_config_for_plugin('webservice_amf');
}
upgrade_main_savepoint(true, 2015123100.01);
}
// Moodle v3.0.0 release upgrade line.
// Put any upgrade step following this.

View File

@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2015123100.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2015123100.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.

View File

@ -1,36 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// 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/>.
/**
* AMF server capabilities.
*
* @package webservice_amf
* @category access
* @copyright 2009 Petr Skodak
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$capabilities = array(
'webservice/amf:use' => array(
'captype' => 'read', // in fact this may be considered read and write at the same time
'contextlevel' => CONTEXT_COURSE, // the context level should be probably CONTEXT_MODULE
'archetypes' => array(
),
),
);

View File

@ -1,144 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// 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/>.
/**
* Introspection for amf
*
* Figures out where all the services are and
* returns a list of their available methods.
* Requires $CFG->amf_introspection = true for security.
*
* @package webservice_amf
* @copyright 2009 Penny Leach <penny@liip.ch>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Provides a function to get details of methods available on another class.
*
* @package webservice_amf
* @copyright HP
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class MethodDescriptor {
/** @var array The details of the methods*/
private $methods;
/** @var array Classes to introspect
* Note: setup() code has been written to introspect multiple classes.
* However the setup() only deal with $classnametointrospect.
*/
private $classes;
/** @var string Class to introspect */
static public $classnametointrospect;
/**
* constructor
*/
public function __construct() {
$this->setup();
}
/**
* Generate the class method descriptions.
* These description are assigned in the class properties
*
* @return void
*/
private function setup() {
global $CFG;
if (!empty($this->nothing)) {
return; // we've already tried, no classes.
}
if (!empty($this->classes)) { // we've already done it successfully.
return;
}
//TODO MDL-31148 most likely can be removed, but check if there is any interest, never know...
/*if (empty($CFG->amf_introspection)) {
throw new Exception(get_string('amfintrospectiondisabled', 'local'));
}*/
//TODO MDL-31148 just one class here, possibility for expansion in future
$classes = array(MethodDescriptor::$classnametointrospect);
$hugestructure = array();
foreach ($classes as $c) {
$r = new ReflectionClass($c);
if (!$methods = $r->getMethods()) {
continue;
}
$this->classes[] = $c;
$hugestructure[$c] = array('docs' => $r->getDocComment(), 'methods' => array());
foreach ($methods as $method) {
if (!$method->isPublic()) {
continue;
}
$params = array();
foreach ($method->getParameters() as $param) {
$params[] = array('name' => $param->getName(), 'required' => !$param->isOptional());
}
$hugestructure[$c]['methods'][$method->getName()] = array(
'docs' => $method->getDocComment(),
'params' => $params,
);
}
}
$this->methods = $hugestructure;
if (empty($this->classes)) {
$this->nothing = true;
}
}
/**
* Get the method descriptions
*
* @return array
*/
public function getMethods() {
$this->setup();
return $this->methods;
}
/**
* Get the class descriptions
*
* @return array
*/
public function getClasses() {
$this->setup();
return $this->classes;
}
/**
* As the class does not extend another class and as this function does nothing
* except return true,
* I guess this is just a function that was a copy/paste and it has been forgotten.
* TODO MDL-31148 this function is not called and most likely can be removed
*
* @return true
*/
public function isConnected() {
return true;
}
}

View File

@ -1,29 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// 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/>.
/**
* Strings for component 'webservice_amf', language 'en', branch 'MOODLE_20_STABLE'
*
* @package webservice_amf
* @category string
* @copyright 2010 Petr Skodak
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['amf:use'] = 'Use AMF protocol';
$string['pluginname'] = 'AMF protocol';

View File

@ -1,227 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// 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/>.
/**
* AMF web service implementation classes and methods.
*
* @package webservice_amf
* @copyright 2009 Petr Skodak
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once("$CFG->dirroot/webservice/lib.php");
require_once( "{$CFG->dirroot}/webservice/amf/introspector.php");
require_once 'Zend/Amf/Server.php';
/**
* Exception indicating an invalid return value from a function.
*
* Used when an externallib function does not return values of the expected structure.
*
* @package webservice_amf
* @copyright 2010 Jamie Pratt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class invalid_return_value_exception extends moodle_exception {
/**
* Constructor
*
* @param string $debuginfo some detailed information
*/
function __construct($debuginfo=null) {
parent::__construct('invalidreturnvalue', 'webservice_amf', '', $debuginfo, $debuginfo);
}
}
/**
* AMF service server implementation.
*
* @package webservice_amf
* @copyright 2009 Petr Skodak
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class webservice_amf_server extends webservice_zend_server {
/**
* Contructor
*
* @param integer $authmethod authentication method - one of WEBSERVICE_AUTHMETHOD_*
*/
public function __construct($authmethod) {
parent::__construct($authmethod, 'Moodle_Amf_Server');
$this->wsname = 'amf';
}
/**
* Load virtual class needed for Zend api
*/
protected function init_service_class(){
parent::init_service_class();
//allow access to data about methods available.
$this->zend_server->setClass( "MethodDescriptor" );
MethodDescriptor::$classnametointrospect = $this->service_class;
}
/**
* Get the generated web service function code.
*
* @param stdClass $function contains function name and class name
* @param array $params all the function parameters
* @return string the generate web service function code
*/
protected function service_class_method_body($function, $params){
//cast the param from object to array (validate_parameters except array only)
$castingcode = '';
if ($params){
$paramstocast = explode(',', $params);
foreach ($paramstocast as $paramtocast) {
$paramtocast = trim($paramtocast);
$castingcode .= $paramtocast .
'=webservice_zend_server::cast_objects_to_array('.$paramtocast.');';
}
}
$externallibcall = $function->classname.'::'.$function->methodname.'('.$params.')';
$descriptionmethod = $function->methodname.'_returns()';
$callforreturnvaluedesc = $function->classname.'::'.$descriptionmethod;
return $castingcode .
' return webservice_amf_server::validate_and_cast_values('.$callforreturnvaluedesc.', '.$externallibcall.');';
}
/**
* Validates submitted value, comparing it to a description. If anything is incorrect
* invalid_return_value_exception is thrown. Also casts the values to the type specified in
* the description.
*
* @param external_description $description description of parameters or null if no return value
* @param mixed $value the actual values
* @return mixed params with added defaults for optional items
* @throws invalid_return_value_exception
*/
public static function validate_and_cast_values($description, $value) {
if (is_null($description)){
return;
}
if ($description instanceof external_value) {
if (is_array($value) or is_object($value)) {
throw new invalid_return_value_exception('Scalar type expected, array or object received.');
}
if ($description->type == PARAM_BOOL) {
// special case for PARAM_BOOL - we want true/false instead of the usual 1/0 - we can not be too strict here ;-)
if (is_bool($value) or $value === 0 or $value === 1 or $value === '0' or $value === '1') {
return (bool)$value;
}
}
return validate_param($value, $description->type, $description->allownull, 'Invalid external api parameter');
} else if ($description instanceof external_single_structure) {
if (!is_array($value)) {
throw new invalid_return_value_exception('Only arrays accepted.');
}
$result = array();
foreach ($description->keys as $key=>$subdesc) {
if (!array_key_exists($key, $value)) {
if ($subdesc->required == VALUE_REQUIRED) {
throw new invalid_return_value_exception('Missing required key in single structure: '.$key);
}
if ($subdesc instanceof external_value) {
if ($subdesc->required == VALUE_DEFAULT) {
$result[$key] = self::validate_and_cast_values($subdesc, $subdesc->default);
}
}
} else {
$result[$key] = self::validate_and_cast_values($subdesc, $value[$key]);
}
unset($value[$key]);
}
return (object)$result;
} else if ($description instanceof external_multiple_structure) {
if (!is_array($value)) {
throw new invalid_return_value_exception('Only arrays accepted.');
}
$result = array();
foreach ($value as $param) {
$result[] = self::validate_and_cast_values($description->content, $param);
}
return $result;
} else {
throw new invalid_return_value_exception('Invalid external api description.');
}
}
/**
* Set up zend service class
*/
protected function init_zend_server() {
parent::init_zend_server();
$this->zend_server->setProduction(false); //set to false for development mode
//(complete error message displayed into your AMF client)
}
}
/**
* Zend Amf server with a different fault management
*
* @package webservice_amf
* @copyright 2010 Jamie Pratt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class Moodle_Amf_Server extends Zend_Amf_Server{
/**
* Raise a server fault
*
* @param string|Exception $fault
* @param int $code fault code
*/
public function fault($fault = null, $code = 404)
{
if (!$fault instanceof Exception) {
$fault = new Exception($fault);
}
$request = $this->getRequest();
// Get the object encoding of the request.
$objectEncoding = $request->getObjectEncoding();
// create a response object to place the output from the services.
$response = $this->getResponse();
// set response encoding
$response->setObjectEncoding($objectEncoding);
$responseBody = $request->getAmfBodies();
foreach($responseBody as $body){
$return = $this->_errorMessage($objectEncoding, $fault->getMessage(),
$fault->getMessage(), $fault->getTraceAsString(),$fault->getCode(), $fault->getLine());
$responseType = Zend_AMF_Constants::STATUS_METHOD;
$responseURI = $body->getResponseURI() . $responseType;
$newBody = new Zend_Amf_Value_MessageBody($responseURI, null, $return);
$response->addAmfBody($newBody);
}
$response->finalize();
echo $response;
}
}

View File

@ -1,54 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// 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/>.
/**
* AMF web service entry point. The authentication is done via tokens.
*
* @package webservice_amf
* @copyright 2009 Jerome Mouneyrac
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* NO_DEBUG_DISPLAY - disable moodle specific debug messages and any errors in output
*/
define('NO_DEBUG_DISPLAY', true);
define('WS_SERVER', true);
// Make sure OPcache does not strip comments, we need them for Zend!
if (ini_get('opcache.enable') and strtolower(ini_get('opcache.enable')) !== 'off') {
if (!ini_get('opcache.save_comments') or strtolower(ini_get('opcache.save_comments')) === 'off') {
ini_set('opcache.enable', 0);
} else {
ini_set('opcache.load_comments', 1);
}
}
require('../../config.php');
require_once("$CFG->dirroot/webservice/amf/locallib.php");
if (!webservice_protocol_is_enabled('amf')) {
debugging('The server died because the web services or the AMF protocol are not enable',
DEBUG_DEVELOPER);
die;
}
$server = new webservice_amf_server(WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN);
$server->run();
die;

View File

@ -1,58 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// 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/>.
/**
* AMF web service entry point. The authentication is done via username/password.
*
* @package webservice_amf
* @copyright 2009 Petr Skodak
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* NO_DEBUG_DISPLAY - disable moodle specific debug messages and any errors in output
*/
define('NO_DEBUG_DISPLAY', true);
define('WS_SERVER', true);
// Make sure OPcache does not strip comments, we need them for Zend!
if (ini_get('opcache.enable') and strtolower(ini_get('opcache.enable')) !== 'off') {
if (!ini_get('opcache.save_comments') or strtolower(ini_get('opcache.save_comments')) === 'off') {
ini_set('opcache.enable', 0);
} else {
ini_set('opcache.load_comments', 1);
}
}
require('../../config.php');
require_once("$CFG->dirroot/webservice/amf/locallib.php");
//disable all 'displayed error' mess in xml
ini_set('display_errors', '0');
ini_set('log_errors', '1');
$CFG->debugdisplay = false;
if (!webservice_protocol_is_enabled('amf')) {
die;
}
$server = new webservice_amf_server(WEBSERVICE_AUTHMETHOD_USERNAME);
$server->run();
die;

View File

@ -1,512 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundColor="white"
layout="vertical"
creationPolicy="all"
height="100%" width="100%"
applicationComplete="init()"
xmlns:cv="customValidators.*"
defaultButton="{call}">
<mx:Script>
<![CDATA[
import mx.rpc.remoting.Operation;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.messaging.Channel;
import mx.rpc.remoting.RemoteObject;
import mx.events.ValidationResultEvent;
import mx.validators.Validator;
/**
* Main class/dialog
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* @author Jordi Boggiano <j.boggiano@seld.be>
* @author Jamie Pratt <me@jamiep.org>
*/
import mx.controls.Label;
import mx.controls.Alert;
import mx.messaging.channels.AMFChannel;
import com.adobe.serialization.json.JSON;
// Import the debugger
// import nl.demonsters.debugger.MonsterDebugger;
protected var methods:Array;
protected var introspector:String;
public var rooturl:String;
[Bindable]
public var serviceurl:String;
public var channel:AMFChannel;
[Bindable]
public var argumentToolTip:String = "You can use JSON syntax for method arguments ie. an array is written like this [item1, item2, etc.] objects are written {\"propname\":value, \"propname2\":value2, etc}";
// Variable to hold the debugger
// private var debugger:MonsterDebugger;
/**
* restores the last settings if available
*/
public function init():void
{
// Init the debugger
// debugger = new MonsterDebugger(this);
// Send a simple trace
// MonsterDebugger.trace(this, "Hello World!");
var so:SharedObject = SharedObject.getLocal('AMFTester');
if (so.data.token) {
token.text = so.data.token;
}
if (so.data.username) {
username.text = so.data.username;
password.text = so.data.password;
}
if (so.data.mode == 'username'){
loginType.selectedIndex = 1;
}
this.rememberpassword.selected = so.data.rememberpassword;
this.remembertoken.selected = so.data.remembertoken;
this.rooturl = Application.application.parameters.rooturl;
this.urllabel1.text = 'Root URL :'+this.rooturl;
this.urllabel2.text = 'Root URL :'+this.rooturl;
}
public function doConnectToken():void
{
serviceurl = this.rooturl + '/webservice/amf/server.php?'+
'wstoken='+this.token.text;
this.doConnect();
// saving settings for next time
var so:SharedObject = SharedObject.getLocal('AMFTester');
if (this.rememberpassword.selected == true ){
so.setProperty('token', this.token.text);
} else {
so.setProperty('token', null);//delete shared obj prop
}
so.setProperty('remembertoken', this.remembertoken.selected);
so.setProperty('mode', 'token');
so.flush();
}
public function doConnectUsername():void
{
serviceurl = this.rooturl + '/webservice/amf/simpleserver.php?'+
'wsusername=' + this.username.text+
'&wspassword=' + this.password.text;
this.doConnect();
// saving settings for next time
var so:SharedObject = SharedObject.getLocal('AMFTester');
if (this.rememberpassword.selected == true ){
so.setProperty('username', this.username.text);
so.setProperty('password', this.password.text);
} else {
so.setProperty('username', null);//delete shared obj prop
so.setProperty('password', null);
}
so.setProperty('rememberpassword', this.rememberpassword.selected);
so.setProperty('mode', 'username');
so.flush();
}
/**
* initializes the connection
*/
private function doConnect():void
{
push("Connecting to "+serviceurl);
//api.source = 'MethodDescriptor';
api.setCredentials(this.username.text, this.password.text);
api.removeEventListener("result", outputResult);
api.addEventListener("result", handleConnection);
api.getOperation("MethodDescriptor.getMethods").send();
if (!api.hasEventListener("fault")) {
api.addEventListener("fault", faultHandler);
}
this.panelDebug.enabled = false;
}
/**
* initializes the debugger dialog with the method list and everything
*/
protected function handleConnection(event:ResultEvent):void
{
methods = [];
for (var cls:String in event.result) {
for (var meth:String in event.result[cls]['methods']) {
methods.push({label: cls+'.'+meth, docs: event.result[cls]['methods'][meth]['docs'], args: event.result[cls]['methods'][meth]['params']});
}
}
methods.sortOn('label', Array.CASEINSENSITIVE);
this.panelDebug.enabled = true;
this.maintabs.selectedIndex = 1;
func.dataProvider = methods;
api.removeEventListener("result", handleConnection);
api.addEventListener("result", outputResult);
reloadArgs();
}
/**
* outputs a response from the server
*/
protected function outputResult(event:ResultEvent):void
{
var keys:Array = new Array();
for (var key:String in event.result){
keys.push(key);
}
push("Result returned \n" + obj2string(event.result));
}
protected function obj2string(obj:Object, depth:Number=0):String{
var string:String = '';
if (obj==null){
return 'NULL';
}
switch (typeof(obj)){
case 'object':
if (obj is Array){
string += "Array\n";
} else {
string += "Object\n";
}
string += depth2string(depth+1)+"(\n";
for (var key:String in obj){
string += depth2string(depth+2)+'['+key+'] => '+obj2string(obj[key], depth+3);
}
string += depth2string(depth+1)+")\n";
break;
case 'string':
var formattedstring:String = obj.toString();
formattedstring = formattedstring.replace(/\r/g, "");
formattedstring = formattedstring.replace(/\n/g, "\n"+depth2string(depth+3));
string += '"'+formattedstring+'"'+"-("+typeof(obj)+")"+"\n";
break;
default :
string += obj.toString()+"-("+typeof(obj)+")"+"\n";
}
return string;
}
protected function depth2string(depth:Number):String{
var string:String = '';
var i:Number = 0;
while (i<depth){
string += ' ';
i++;
}
return string;
}
/**
* updates the display of arguments when the selected method changes
*
* it's hardly optimal to do it that way but it was faster to copy paste, I just hope nobody needs more than 7 args
*/
protected function reloadArgs():void
{
var i:int;
for (i = 1; i <= 7; i++) {
this['arg'+i].visible = false;
this['arg'+i].includeInLayout = false;
this['larg'+i].visible = false;
this['larg'+i].includeInLayout = false;
this['cbarg'+i].visible = false;
this['cbarg'+i].includeInLayout = false;
this['JSONV'+i].enabled = false;
}
i = 1;
for (var arg:String in func.selectedItem.args) {
(this['arg'+i] as TextInput).visible = true;
(this['arg'+i] as TextInput).includeInLayout = true;
if (func.selectedItem.args[arg]['required']){
(this['arg'+i] as TextInput).enabled = true;
this['cbarg'+i].selected = true;
}
(this['larg'+i] as Label).visible = true;
(this['larg'+i] as Label).includeInLayout = true;
this['cbarg'+i].visible = !func.selectedItem.args[arg]['required'];
this['cbarg'+i].includeInLayout = !func.selectedItem.args[arg]['required'];
this['JSONV'+i].enabled = this['cbarg'+i].selected;
this['JSONV'+i].required = true;
(this['larg'+i] as Label).text = func.selectedItem.args[arg]['name'] + (func.selectedItem.args[arg]['required'] ? "*":"");
i++;
}
while (i <= 7) {
this['cbarg'+i].selected = false;
i++;
}
if (func.selectedItem.docs == ""){
(this.methodDescription as TextArea).text = "";
(this.methodDescription as TextArea).visible = false;
(this.methodDescription as TextArea).includeInLayout = false;
} else {
(this.methodDescription as TextArea).text = func.selectedItem.docs.replace(/[\n\r\f]+/g, "\n");
(this.methodDescription as TextArea).visible = true;
(this.methodDescription as TextArea).includeInLayout = true;
}
}
public function toggleCheckBoxes(startAt:uint):void{
var i:uint= startAt;
if (this['cbarg'+i].selected){
i--;
while (i >= 1){
this['cbarg'+i].selected = true;
i--;
}
} else {
i++;
while (i <= 7){
this['cbarg'+i].selected = false;
i++;
}
}
}
/**
* calls a method on the server
*/
protected function execute():void
{
var input:TextInput;
var argumentArray:Array = [];
var argumentErrors:Array = Validator.validateAll(argumentValidators);
if (argumentErrors.length != 0){
// MonsterDebugger.trace(this, argumentErrors);
return;
}
for(var i:int = 1; i <= 7; i++)
{
input = this['arg' +i] as TextInput;
if(input && input.visible)
{
if (!this['cbarg' +i].selected){
break;
} else if (input.text.indexOf("\"") == 0 || input.text.indexOf("{") == 0 || input.text.indexOf("[") == 0)
try {
argumentArray.push(JSON.decode(input.text));
} catch (err:Error){
return;
}
else
argumentArray.push(input.text as String);
}
}
//no other way to pass arguments as array :
switch (argumentArray.length){
case 0:
api.getOperation(func.selectedLabel).send();
break;
case 1:
api.getOperation(func.selectedLabel).send(argumentArray[0]);
break;
case 2:
api.getOperation(func.selectedLabel).send(argumentArray[0], argumentArray[1]);
break;
case 3:
api.getOperation(func.selectedLabel).send(argumentArray[0], argumentArray[1], argumentArray[2]);
break;
case 4:
api.getOperation(func.selectedLabel).send(argumentArray[0], argumentArray[1], argumentArray[2], argumentArray[3]);
break;
case 5:
api.getOperation(func.selectedLabel).send(argumentArray[0], argumentArray[1], argumentArray[2], argumentArray[3], argumentArray[4]);
break;
case 6:
api.getOperation(func.selectedLabel).send(argumentArray[0], argumentArray[1], argumentArray[2], argumentArray[3], argumentArray[4], argumentArray[5]);
break;
case 7:
api.getOperation(func.selectedLabel).send(argumentArray[0], argumentArray[1], argumentArray[2], argumentArray[3], argumentArray[4], argumentArray[5], argumentArray[6]);
break;
}
// MonsterDebugger.trace(this, [func.selectedLabel, argumentArray[0], argumentArray[1], argumentArray[2], argumentArray[3], argumentArray[4], argumentArray[5], argumentArray[6]]);
push("Calling "+func.selectedLabel+" with arguments \n"+obj2string(argumentArray));
}
/**
* clears debug consoles
*/
protected function clear():void
{
output.text = output.text = "";
}
/**
* clears debug consoles
*/
protected function goBottom():void
{
output.verticalScrollPosition = output.maxVerticalScrollPosition;
}
/**
* refreshes the method list
*/
protected function refresh():void
{
api.removeEventListener("result", outputResult);
api.addEventListener("result", handleConnection);
api.exec(introspector);
}
/**
* returns timestamp string
*/
protected function time():String
{
var d:Date = new Date();
var ret:String = d.hours+":"+d.minutes+":"+d.seconds+"."+d.milliseconds;
return ret + "000000000000".substring(ret.length);
}
/**
* handler for specific net events
*/
public function faultHandler(event:FaultEvent):void
{
push("Error("+event.type+" - "+ event.fault.faultCode + "): "+event.fault.faultString+", "+event.fault.faultDetail);
}
/**
* pushes text into a console and scrolls it down automatically
*/
public function push(text:String):void
{
output.text += time() + ": "+ text + "\n";
output.verticalScrollPosition = output.maxVerticalScrollPosition;
}
]]>
</mx:Script>
<mx:RemoteObject id="api" destination="zend" endpoint="{serviceurl}" />
<mx:Array id="argumentValidators">
<cv:JSONValidator id="JSONV1" required="true" enabled="{cbarg1.selected}" source="{arg1}" property="text" />
<cv:JSONValidator id="JSONV2" required="true" enabled="{cbarg2.selected}" source="{arg2}" property="text" />
<cv:JSONValidator id="JSONV3" required="true" enabled="{cbarg3.selected}" source="{arg3}" property="text" />
<cv:JSONValidator id="JSONV4" required="true" enabled="{cbarg4.selected}" source="{arg4}" property="text" />
<cv:JSONValidator id="JSONV5" required="true" enabled="{cbarg5.selected}" source="{arg5}" property="text" />
<cv:JSONValidator id="JSONV6" required="true" enabled="{cbarg6.selected}" source="{arg6}" property="text" />
<cv:JSONValidator id="JSONV7" required="true" enabled="{cbarg7.selected}" source="{arg7}" property="text" />
</mx:Array>
<mx:HBox width="100%" height="550">
<mx:TabNavigator id="maintabs" height="100%" width="100%" >
<mx:TabNavigator label="Connect" id="loginType" borderStyle="solid" height="100%" width="100%">
<mx:Panel label="Use Token" id="panelConnectToken">
<mx:HBox width="100%">
<mx:Label text="Token"/>
<mx:TextInput id="token" text="" width="100%"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="Remember"/>
<mx:CheckBox id="remembertoken" width="100%"/>
</mx:HBox>
<mx:Label id="urllabel1" text="URL :" />
<mx:HBox width="100%">
<mx:Spacer width="100%" />
<mx:Button label="Connect" click="doConnectToken()"/>
<mx:Spacer width="100%" />
</mx:HBox>
</mx:Panel>
<mx:Panel label="Use Username and Password" id="panelConnectUsername">
<mx:HBox width="100%">
<mx:Label text="Username"/>
<mx:TextInput id="username" text="" width="100%"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="Password"/>
<mx:TextInput id="password" text="" displayAsPassword="true" width="100%"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="Remember"/>
<mx:CheckBox id="rememberpassword" width="100%"/>
</mx:HBox>
<mx:Label id="urllabel2" text="URL :" />
<mx:HBox width="100%">
<mx:Spacer width="100%" />
<mx:Button label="Connect" click="doConnectUsername()"/>
<mx:Spacer width="100%" />
</mx:HBox>
</mx:Panel>
</mx:TabNavigator>
<mx:Panel label="Service Browser" width="100%" height="100%" layout="vertical" title="Moodle AMF Service Browser" enabled="false" id="panelDebug">
<mx:HBox width="100%">
<mx:Label text="Func "/>
<mx:ComboBox id="func" change="reloadArgs()">
</mx:ComboBox>
</mx:HBox>
<mx:TextArea id="methodDescription" text="" width="100%" height="150"/>
<mx:HBox width="100%">
<mx:Label id="larg1" text="Arg 1"/>
<mx:CheckBox id="cbarg1" click="toggleCheckBoxes(1)"/>
<mx:TextInput id="arg1" toolTip="{argumentToolTip}" width="100%" enabled="{cbarg1.selected}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label id="larg2" text="Arg 2"/>
<mx:CheckBox id="cbarg2" click="toggleCheckBoxes(2)"/>
<mx:TextInput id="arg2" toolTip="{argumentToolTip}" width="100%" enabled="{cbarg2.selected}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label id="larg3" text="Arg 3"/>
<mx:CheckBox id="cbarg3" click="toggleCheckBoxes(3)"/>
<mx:TextInput id="arg3" toolTip="{argumentToolTip}" width="100%" enabled="{cbarg3.selected}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label id="larg4" text="Arg 4"/>
<mx:CheckBox id="cbarg4" click="toggleCheckBoxes(4)"/>
<mx:TextInput id="arg4" toolTip="{argumentToolTip}" width="100%" enabled="{cbarg4.selected}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label id="larg5" text="Arg 5"/>
<mx:CheckBox id="cbarg5" click="toggleCheckBoxes(5)"/>
<mx:TextInput id="arg5" toolTip="{argumentToolTip}" width="100%" enabled="{cbarg5.selected}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label id="larg6" text="Arg 6"/>
<mx:CheckBox id="cbarg6" click="toggleCheckBoxes(6)"/>
<mx:TextInput id="arg6" toolTip="{argumentToolTip}" width="100%" enabled="{cbarg6.selected}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label id="larg7" text="Arg 7"/>
<mx:CheckBox id="cbarg7" click="toggleCheckBoxes(7)"/>
<mx:TextInput id="arg7" toolTip="{argumentToolTip}" width="100%" enabled="{cbarg7.selected}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Button id="call" label="Call" click="execute()"/>
<mx:Button label="Clear" click="clear()"/>
<mx:Button label="Scroll to bottom of debug output" click="goBottom()"/>
</mx:HBox>
</mx:Panel>
</mx:TabNavigator>
</mx:HBox>
<mx:HBox width="100%" height="100%">
<mx:TextArea id="output" width="100%" height="100%"/>
</mx:HBox>
</mx:Application>

View File

@ -1,40 +0,0 @@
package customValidators
{
import com.adobe.serialization.json.JSON;
import com.adobe.serialization.json.JSONParseError;
import mx.validators.ValidationResult;
import mx.validators.Validator;
import nl.demonsters.debugger.MonsterDebugger;
public class JSONValidator extends Validator
{
// Define Array for the return value of doValidation().
private var errors:Array;
public function JSONValidator()
{
super();
}
override protected function doValidation(value:Object):Array {
var JSONstring:String = String(value);
errors = [];
if (JSONstring != ''){
try {
JSON.decode(JSONstring);
} catch (err:Error){
errors.push(new ValidationResult(true, null, "JSON decode failed",
"Not able to decode this JSON."));
}
}
if (this.required && JSONstring == ''){
errors.push(new ValidationResult(true, null, "Required",
"You must enter a value for this argument - for a string argument an empty string can be entered as \"\" or you can disable an optional argument."));
}
return errors;
}
}
}

View File

@ -1,8 +0,0 @@
AMFTester.mxml can be compiled as a Flex application in Flex builder or using the Flex SDK.
Copy the following into a Flex project source folder :
* customValidators folder and contents
* AMFTester.mxml
Then you need to use either the compiled Flex library or the source for the open source library as3corelib available here : http://code.google.com/p/as3corelib/downloads/list

View File

@ -1,67 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// 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/>.
/**
* Index page of the AMF test client
*
* @package webservice_amf
* @copyright 2009 Jamie Pratt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require "../../../config.php";
require_once($CFG->libdir . '/adminlib.php');
admin_externalpage_setup('externalservice');
//page nav bar
$PAGE->set_url('/webservice/amf/testclient/index.php');
$node = $PAGE->settingsnav->find('testclient', navigation_node::TYPE_SETTING);
if ($node) {
$node->make_active();
}
$PAGE->navbar->add(get_string('amftestclient', 'webservice'));
$PAGE->set_title('Test Client');
$PAGE->set_heading('Test Client');
echo $OUTPUT->header();
$url = $CFG->wwwroot.'/webservice/amf/testclient/AMFTester.swf';
$output = <<<OET
<div id="moodletestclient">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="1000">
<param name="movie" value="$url" />
<param name="base" value="." />
<param name="allowscriptaccess" value="sameDomain" />
<param name="FlashVars" value="rooturl=$CFG->wwwroot" />
<!--[if !IE]><!-->
<object type="application/x-shockwave-flash" data="$url" width="100%" height="1000">
<param name="base" value="." />
<param name="allowscriptaccess" value="sameDomain" />
<param name="FlashVars" value="rooturl=$CFG->wwwroot" />
<!--<![endif]-->
<p>You need to install Flash 9.0</p>
<!--[if !IE]><!-->
</object>
<!--<![endif]-->
</object>
</span>
OET;
echo $output;
echo $OUTPUT->footer();

View File

@ -1,30 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// 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/>.
/**
* Version details
*
* @package webservice_amf
* @copyright 2009 Petr Skodak
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2015111600; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2015111000; // Requires this Moodle version
$plugin->component = 'webservice_amf'; // Full name of the plugin (used for diagnostics)

View File

@ -755,7 +755,7 @@ class webservice_access_exception extends moodle_exception {
/**
* Check if a protocol is enabled
*
* @param string $protocol name of WS protocol ('rest', 'soap', 'xmlrpc', 'amf'...)
* @param string $protocol name of WS protocol ('rest', 'soap', 'xmlrpc'...)
* @return bool true if the protocol is enabled
*/
function webservice_protocol_is_enabled($protocol) {
@ -1108,7 +1108,7 @@ abstract class webservice_server implements webservice_server_interface {
*/
abstract class webservice_zend_server extends webservice_server {
/** @var string Name of the zend server class : Zend_Amf_Server, moodle_zend_soap_server, Zend_Soap_AutoDiscover, ...*/
/** @var string Name of the zend server class : moodle_zend_soap_server, Zend_Soap_AutoDiscover, ...*/
protected $zend_class;
/** @var stdClass Zend server instance */
@ -1412,8 +1412,7 @@ class '.$classname.' {
/**
* You can override this function in your child class to add extra code into the dynamically
* created service class. For example it is used in the amf server to cast types of parameters and to
* cast the return value to the types as specified in the return value description.
* created service class.
*
* @param stdClass $function a record from external_function
* @param array $params web service function parameters

View File

@ -10,6 +10,8 @@ This information is intended for authors of webservices, not people writing webs
"[methodname]" does not exist') are no longer used which may display a different error message depending
on the string returned by the getMessage() method of the thrown exception.
* Support for the AMF protocol has been dropped completely.
=== 3.0 ===
* WS protocols webservice/myprotocol:use capabilities were defined with a high riskbitmask value