From ba224fb42c41a5b14309adb6c609715c467116a3 Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Thu, 16 Jul 2015 14:14:33 +0800 Subject: [PATCH] MDL-50783 Ajax: Configure how to call a webservice through db/service.php Now the db/service.php array can contain these extra keys to provide information on how a webservice may be called: 'ajax' => true (Default is false) Replaces the xx_is_allowed_from_ajax callback. 'loginrequired' => false (Default is true) Means that this webservice can be called through lib/ajax/service-nosession.php which sets NO_MOODLE_COOKIES to true (faster). This is only safe for webservices returning static public data (e.g. get_string). --- .../templatelibrary/amd/build/display.min.js | Bin 1564 -> 1570 bytes .../templatelibrary/amd/build/search.min.js | Bin 764 -> 770 bytes admin/tool/templatelibrary/amd/src/display.js | 2 +- admin/tool/templatelibrary/amd/src/search.js | 2 +- .../tool/templatelibrary/classes/external.php | 18 ---------- admin/tool/templatelibrary/db/services.php | 6 +++- lib/ajax/service-nologin.php | 31 ++++++++++++++++++ lib/ajax/service.php | 5 +-- lib/amd/build/ajax.min.js | Bin 1039 -> 1062 bytes lib/amd/build/str.min.js | Bin 1629 -> 1635 bytes lib/amd/build/templates.min.js | Bin 2410 -> 2413 bytes lib/amd/src/ajax.js | 15 +++++++-- lib/amd/src/str.js | 2 +- lib/amd/src/templates.js | 2 +- lib/classes/output/external.php | 10 ------ lib/db/services.php | 14 +++++--- lib/external/externallib.php | 31 ------------------ lib/externallib.php | 3 ++ tag/classes/external.php | 20 +---------- 19 files changed, 69 insertions(+), 92 deletions(-) create mode 100644 lib/ajax/service-nologin.php diff --git a/admin/tool/templatelibrary/amd/build/display.min.js b/admin/tool/templatelibrary/amd/build/display.min.js index a5bf8ab0ec323c9cb1d026b87b199ea390fd7616..49c0afe59a3b2d244ba4c73cc5d16cd1f6d1bc55 100644 GIT binary patch delta 18 ZcmbQkvxsLyAS;`WqJfU0;p9Np(*Q6@1rh)N delta 11 ScmZ3)GlyqGAnW9C*3$qON(2`G diff --git a/admin/tool/templatelibrary/amd/build/search.min.js b/admin/tool/templatelibrary/amd/build/search.min.js index 062e585ab927694edc77d173cc846e9e67bdf033..869d27b9dccc03472426a313e3eb0d45cf24a230 100644 GIT binary patch delta 19 acmeyv+QhcuG9#OgqJfU0;pWSXnv4KJz6HPl delta 12 TcmZo-`@_27GUMi(jGBx9BJTvn diff --git a/admin/tool/templatelibrary/amd/src/display.js b/admin/tool/templatelibrary/amd/src/display.js index 1585a180bf1..bb2f77a1e4e 100644 --- a/admin/tool/templatelibrary/amd/src/display.js +++ b/admin/tool/templatelibrary/amd/src/display.js @@ -133,7 +133,7 @@ define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates' component: component, template: name } - }]); + }], true, false); // When returns a new promise that is resolved when all the passed in promises are resolved. // The arguments to the done become the values of each resolved promise. diff --git a/admin/tool/templatelibrary/amd/src/search.js b/admin/tool/templatelibrary/amd/src/search.js index d4eefe66c3d..efefb268074 100644 --- a/admin/tool/templatelibrary/amd/src/search.js +++ b/admin/tool/templatelibrary/amd/src/search.js @@ -53,7 +53,7 @@ define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates' args: { component: componentStr, search: searchStr }, done: reloadListTemplate, fail: notification.exception } - ]); + ], true, false); }; var throttle = null; diff --git a/admin/tool/templatelibrary/classes/external.php b/admin/tool/templatelibrary/classes/external.php index 100172b15be..be583a27a4e 100644 --- a/admin/tool/templatelibrary/classes/external.php +++ b/admin/tool/templatelibrary/classes/external.php @@ -63,14 +63,6 @@ class external extends external_api { return new external_function_parameters($params); } - /** - * Expose to AJAX - * @return boolean - */ - public static function list_templates_is_allowed_from_ajax() { - return true; - } - /** * Loads the list of templates. * @param string $component Limit the search to a component. @@ -108,16 +100,6 @@ class external extends external_api { ); } - /** - * Can this function be called directly from ajax? - * - * @return boolean - * @since Moodle 2.9 - */ - public static function load_canonical_template_is_allowed_from_ajax() { - return true; - } - /** * Return a mustache template. * Note - this function differs from the function core_output_load_template diff --git a/admin/tool/templatelibrary/db/services.php b/admin/tool/templatelibrary/db/services.php index c1a9479180d..9dda64761ff 100644 --- a/admin/tool/templatelibrary/db/services.php +++ b/admin/tool/templatelibrary/db/services.php @@ -32,12 +32,16 @@ $functions = array( 'description' => 'List/search templates by component.', 'type' => 'read', 'capabilities'=> '', + 'ajax' => true, + 'loginrequired' => false, ), 'tool_templatelibrary_load_canonical_template' => array( 'classname' => 'tool_templatelibrary\external', 'methodname' => 'load_canonical_template', 'description' => 'Load a canonical template by name (not the theme overidden one).', - 'type' => 'read' + 'type' => 'read', + 'ajax' => true, + 'loginrequired' => false, ), ); diff --git a/lib/ajax/service-nologin.php b/lib/ajax/service-nologin.php new file mode 100644 index 00000000000..7120adec7f2 --- /dev/null +++ b/lib/ajax/service-nologin.php @@ -0,0 +1,31 @@ +. + +/** + * This file is used to call any registered externallib function in Moodle. + * + * It will process more than one request and return more than one response if required. + * It is recommended to add webservice functions and re-use this script instead of + * writing any new custom ajax scripts. + * + * @since Moodle 2.9 + * @package core + * @copyright 2015 Damyon Wiese + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +define('NO_MOODLE_COOKIES', true); +require_once('service.php'); diff --git a/lib/ajax/service.php b/lib/ajax/service.php index 166b8a84e59..366f1ad16ff 100644 --- a/lib/ajax/service.php +++ b/lib/ajax/service.php @@ -32,8 +32,6 @@ define('AJAX_SCRIPT', true); require_once(dirname(__FILE__) . '/../../config.php'); require_once($CFG->libdir . '/externallib.php'); -require_sesskey(); - $rawjson = file_get_contents('php://input'); $requests = json_decode($rawjson, true); @@ -54,6 +52,7 @@ foreach ($requests as $request) { $externalfunctioninfo = external_function_info($methodname); if (!$externalfunctioninfo->allowed_from_ajax) { + error_log('This external function is not available to ajax. Failed to call "' . $methodname . '"'); throw new moodle_exception('servicenotavailable', 'webservice'); } @@ -62,6 +61,8 @@ foreach ($requests as $request) { if (!isloggedin()) { error_log('This external function is not available to public users. Failed to call "' . $methodname . '"'); throw new moodle_exception('servicenotavailable', 'webservice'); + } else { + require_sesskey(); } } diff --git a/lib/amd/build/ajax.min.js b/lib/amd/build/ajax.min.js index 2a80dfe31663e2d2a877ac15c1857e0b0a40d4fe..7ed899b17091ec9c38576630d28cdbe142bed7ec 100644 GIT binary patch delta 420 zcmY+Au};G<5QbH>+#FSvMFm<3vWve<^u@k#-oXSa1t2XK*FytMW zc@8E<9)gD;ZjoB1^L_Sz_xpeAzIQ)9JExG~)hn|-35rgpFl)X${f(qIp}ZGF3zL*G zl!L+UQA))`PD4fJRUy$z87>xqgiMq&=Z0k>NXfndW|N{NuGAP(!bL2s6`V5i_;*AY zX1i(oYtqz57n`=vjp+9exC3a%G5A%xJyu3=|B{x=xya*QN@Aw;KaB&e#uaBlIm=Ym ziVnx4CsLGFnMB1)q;TkB&~)Wy1^)5#X#C;>XC(_%bLHK7kkRJLyE_T3C@X7v$$E{p z=)8Mva-Ap2G(XB delta 400 zcmZ9Iu};G<5QbH{R01KfF(45#RJLkasAGb~!o)z4%2su-;*0I1bt)%8EmhPshfj`+}El2HLESPO!2diRqeOmsKx z@J!p?(dEw7g@NJl7xw^l9Fwqi+f!{ogjcNEte{APjHX;K{%AaK8Xvrcy=5jF#qOt* z2U=EE8>!O`QaJW!$l2D%6JE$)xcVhdGmO_1Jl$}_%3?OXq%ed(W% pNsjksQG)l2kiZejX;~);lqE|@PTju?%LMr+J$6!efu?D2{0$vsh(G`U diff --git a/lib/amd/build/str.min.js b/lib/amd/build/str.min.js index ace0e9383c093b86e8a393772b69d0a65112f836..33d26c9937f1fcb07d386036f5b8727a6bac9643 100644 GIT binary patch delta 19 acmcc1^O$Et0}GpuqJfU0;pPUGyNm!rf(9c1 delta 12 TcmaFNbC+jB1Iy+%mb;7qB)A1A diff --git a/lib/amd/build/templates.min.js b/lib/amd/build/templates.min.js index ed4aa324e9a9cd5ab412991af226cea71273ccf6..c75432be2aa0ecb768847bcaa6a2c322c543c595 100644 GIT binary patch delta 16 XcmaDQ^j2s?9Xqp*qT%K`_BV_GHhTrv delta 12 TcmaDW^h#($9sA}+_BV_GCP4*R diff --git a/lib/amd/src/ajax.js b/lib/amd/src/ajax.js index 2966cb4d877..6b497c35f44 100644 --- a/lib/amd/src/ajax.js +++ b/lib/amd/src/ajax.js @@ -104,9 +104,13 @@ define(['jquery', 'core/config'], function($, config) { * can be attached to the promises returned by this function. * @param {Boolean} async Optional, defaults to true. * If false - this function will not return until the promises are resolved. + * @param {Boolean} loginrequired Optional, defaults to true. + * If false - this function will call the faster nologin ajax script - but + * will fail unless all functions have been marked as 'loginrequired' => false + * in services.php * @return {Promise[]} Array of promises that will be resolved when the ajax call returns. */ - call: function(requests, async) { + call: function(requests, async, loginrequired) { var ajaxRequestData = [], i, promises = []; @@ -144,15 +148,20 @@ define(['jquery', 'core/config'], function($, config) { async: async }; + var script = config.wwwroot + '/lib/ajax/service.php?sesskey=' + config.sesskey; + if (!loginrequired) { + script = config.wwwroot + '/lib/ajax/service-nologin.php?sesskey=' + config.sesskey; + } + // Jquery deprecated done and fail with async=false so we need to do this 2 ways. if (async) { - $.ajax(config.wwwroot + '/lib/ajax/service.php?sesskey=' + config.sesskey, settings) + $.ajax(script, settings) .done(requestSuccess) .fail(requestFail); } else { settings.success = requestSuccess; settings.error = requestFail; - $.ajax(config.wwwroot + '/lib/ajax/service.php?sesskey=' + config.sesskey, settings); + $.ajax(script, settings); } return promises; diff --git a/lib/amd/src/str.js b/lib/amd/src/str.js index d66c164777f..76830d380fd 100644 --- a/lib/amd/src/str.js +++ b/lib/amd/src/str.js @@ -140,7 +140,7 @@ define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage) }); } - var deferreds = ajax.call(ajaxrequests); + var deferreds = ajax.call(ajaxrequests, true, false); $.when.apply(null, deferreds).done( function() { // Turn the list of arguments (unknown length) into a real array. diff --git a/lib/amd/src/templates.js b/lib/amd/src/templates.js index 93ed7d111bc..a152e03fd94 100644 --- a/lib/amd/src/templates.js +++ b/lib/amd/src/templates.js @@ -310,7 +310,7 @@ define([ 'core/mustache', template: name, themename: currentThemeName } - }], async); + }], async, false); promises[0].done( function (templateSource) { diff --git a/lib/classes/output/external.php b/lib/classes/output/external.php index 17b1ca74712..a76248edf96 100644 --- a/lib/classes/output/external.php +++ b/lib/classes/output/external.php @@ -55,16 +55,6 @@ class external extends external_api { ); } - /** - * Can this function be called directly from ajax? - * - * @return boolean - * @since Moodle 2.9 - */ - public static function load_template_is_allowed_from_ajax() { - return true; - } - /** * Return a mustache template, and all the strings it requires. * diff --git a/lib/db/services.php b/lib/db/services.php index 415f0fd5d94..5c2ad25e1ce 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -975,7 +975,8 @@ $functions = array( 'classpath' => 'lib/external/externallib.php', 'description' => 'Return a translated string - similar to core get_string() call', 'type' => 'read', - 'loginrequired' => false + 'loginrequired' => false, + 'ajax' => true, ), 'core_get_strings' => array( @@ -984,7 +985,8 @@ $functions = array( 'classpath' => 'lib/external/externallib.php', 'description' => 'Return some translated strings - like several core get_string() calls', 'type' => 'read', - 'loginrequired' => false + 'loginrequired' => false, + 'ajax' => true, ), 'core_get_component_strings' => array( @@ -994,7 +996,8 @@ $functions = array( 'description' => 'Return all raw strings (with {$a->xxx}) for a specific component - similar to core get_component_strings() call', 'type' => 'read', - 'loginrequired' => false + 'loginrequired' => false, + 'ajax' => true, ), @@ -1033,7 +1036,8 @@ $functions = array( 'methodname' => 'load_template', 'description' => 'Load a template for a renderable', 'type' => 'read', - 'loginrequired' => false + 'loginrequired' => false, + 'ajax' => true, ), // Completion related functions. @@ -1075,6 +1079,7 @@ $functions = array( 'methodname' => 'update_tags', 'description' => 'Updates tags', 'type' => 'write', + 'ajax' => true ), 'core_tag_get_tags' => array( @@ -1082,6 +1087,7 @@ $functions = array( 'methodname' => 'get_tags', 'description' => 'Gets tags by their ids', 'type' => 'read', + 'ajax' => true ), ); diff --git a/lib/external/externallib.php b/lib/external/externallib.php index 1909c2f3fc7..a0526c53379 100644 --- a/lib/external/externallib.php +++ b/lib/external/externallib.php @@ -77,16 +77,6 @@ class core_external extends external_api { return $strparams; } - /** - * Can this function be called directly from ajax? - * - * @return boolean - * @since Moodle 2.9 - */ - public static function get_string_is_allowed_from_ajax() { - return true; - } - /** * Returns description of get_string parameters * @@ -163,17 +153,6 @@ class core_external extends external_api { ); } - /** - * Can this function be called directly from ajax? - * - * @return boolean - * @since Moodle 2.9 - */ - public static function get_strings_is_allowed_from_ajax() { - return true; - } - - /** * Return multiple call to core get_string() * @@ -237,16 +216,6 @@ class core_external extends external_api { ); } - /** - * Can this function be called directly from ajax? - * - * @return boolean - * @since Moodle 2.9 - */ - public static function get_component_strings_is_allowed_from_ajax() { - return true; - } - /** * Return all lang strings of a component - call to core get_component_strings(). * diff --git a/lib/externallib.php b/lib/externallib.php index d392cf1cf2b..951f215636c 100644 --- a/lib/externallib.php +++ b/lib/externallib.php @@ -115,6 +115,9 @@ function external_function_info($function, $strictness=MUST_EXIST) { if (isset($functions[$function->name]['type'])) { $function->type = $functions[$function->name]['type']; } + if (isset($functions[$function->name]['ajax'])) { + $function->allowed_from_ajax = $functions[$function->name]['ajax']; + } if (isset($functions[$function->name]['loginrequired'])) { $function->loginrequired = $functions[$function->name]['loginrequired']; } else { diff --git a/tag/classes/external.php b/tag/classes/external.php index ee8f1a0e3b6..2bb564f335b 100644 --- a/tag/classes/external.php +++ b/tag/classes/external.php @@ -59,15 +59,6 @@ class core_tag_external extends external_api { ); } - /** - * Expose to AJAX - * - * @return boolean - */ - public static function update_tags_is_allowed_from_ajax() { - return true; - } - /** * Update tags * @@ -194,15 +185,6 @@ class core_tag_external extends external_api { ); } - /** - * Expose to AJAX - * - * @return boolean - */ - public static function get_tags_is_allowed_from_ajax() { - return true; - } - /** * Get tags by their ids * @@ -281,4 +263,4 @@ class core_tag_external extends external_api { ) ); } -} \ No newline at end of file +} -- 2.43.0