From f69a420be1017f15514fc3b1f4a59d02a5f08eae Mon Sep 17 00:00:00 2001 From: meirzamoodle Date: Wed, 14 Jun 2023 09:34:14 +0700 Subject: [PATCH] MDL-76656 webservice: generated token can only read once Generated tokens should only read once. Therefore removing the token column at the table view of the manage tokens page and the user's page. The token should not be able to search. --- admin/templates/webservice_token_new.mustache | 47 +++++++++++++++++++ admin/tests/behat/manage_tokens.feature | 44 +++++++++++++---- admin/webservice/tokens.php | 25 ++++++++-- lang/en/external.php | 1 + lang/en/webservice.php | 6 +++ lib/db/install.xml | 3 +- lib/db/upgrade.php | 19 ++++++++ lib/external/classes/privacy/provider.php | 2 + lib/external/classes/util.php | 32 +++++++++++-- lib/upgrade.txt | 3 ++ version.php | 2 +- webservice/classes/token_filter.php | 6 +-- webservice/classes/token_form.php | 10 ++++ webservice/classes/token_table.php | 28 ++++++++--- webservice/lib.php | 13 +++-- webservice/renderer.php | 10 ++-- webservice/tests/externallib_test.php | 3 ++ webservice/tests/generator/lib.php | 4 +- webservice/tests/lib_test.php | 1 + 19 files changed, 220 insertions(+), 39 deletions(-) create mode 100644 admin/templates/webservice_token_new.mustache diff --git a/admin/templates/webservice_token_new.mustache b/admin/templates/webservice_token_new.mustache new file mode 100644 index 00000000000..a063b651d8e --- /dev/null +++ b/admin/templates/webservice_token_new.mustache @@ -0,0 +1,47 @@ +{{! + 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 . +}} +{{! + @template core_admin/webservice_token_new + + This is the template for displaying the newly created webservice token. + + Context variable required for this template: + * token - Token value + + Example context (json): + { + "token": "ef9ee4d0c6eed5eab8453a63b93b5b8b" + } +}} + +
+
+
{{#str}}tokennewmessage, webservice{{/str}}
+
+
+
{{tokenname}}
+
+
{{token}}
+ +
+
+
+ +{{#js}} + require(['core/copy_to_clipboard']); +{{/js}} diff --git a/admin/tests/behat/manage_tokens.feature b/admin/tests/behat/manage_tokens.feature index 400fe181b76..1544f7f3428 100644 --- a/admin/tests/behat/manage_tokens.feature +++ b/admin/tests/behat/manage_tokens.feature @@ -19,19 +19,31 @@ Feature: Manage external services tokens And I am on site homepage And I navigate to "Server > Web services > Manage tokens" in site administration And I press "Create token" + And I set the field "Name" to "Webservice1" And I set the field "User" to "Firstname1 Lastname1" And I set the field "Service" to "Moodle mobile web service" And I set the field "IP restriction" to "127.0.0.1" When I press "Save changes" - Then I should see "Moodle mobile web service" in the "Firstname1 Lastname1" "table_row" - And I should see "127.0.0.1" in the "Firstname1 Lastname1" "table_row" - And I click on "Delete" "link" in the "Firstname1 Lastname1" "table_row" + Then I should see "Firstname1 Lastname1" in the "Webservice1" "table_row" + And I should see "127.0.0.1" in the "Webservice1" "table_row" + + # Verify the message and the "Copy to clipboard" button. + And I should see "Copy the token now. It won't be shown again once you leave this page." + And "Copy to clipboard" "button" should exist + + # New token can only read once. + And I reload the page + And I should not see "Copy the token now. It won't be shown again once you leave this page." + And "Copy to clipboard" "button" should not exist + + # Delete token. + And I click on "Delete" "link" in the "Webservice1" "table_row" And I should see "Do you really want to delete this web service token for Firstname1 Lastname1 on the service Moodle mobile web service?" And I press "Delete" - And "Firstname1 Lastname1" "table_row" should not exist + And "Webservice1" "table_row" should not exist @javascript @skip_chrome_zerosize - Scenario: Tokens can be filtered by user and by service + Scenario: Tokens can be filtered by name (case-insensitive), by user and by service Given the following "core_webservice > Service" exists: | name | Site information | | shortname | siteinfo | @@ -40,10 +52,10 @@ Feature: Manage external services tokens | service | siteinfo | | functions | core_webservice_get_site_info | And the following "core_webservice > Tokens" exist: - | user | service | - | user2 | siteinfo | - | user3 | moodle_mobile_app | - | user4 | siteinfo | + | user | service | name | + | user2 | siteinfo | WEBservice1 | + | user3 | moodle_mobile_app | webservicE3 | + | user4 | siteinfo | New service2 | When I log in as "admin" And I navigate to "Server > Web services > Manage tokens" in site administration @@ -53,6 +65,20 @@ Feature: Manage external services tokens And I should see "Moodle mobile web service" in the "Firstname3 Lastname3" "table_row" And I should see "Site information" in the "Firstname4 Lastname4" "table_row" + # Filter tokens by by name (case-insensitive). + And I click on "Tokens filter" "link" + And I set the field "Name" to "webservice" + And I press "Show only matching tokens" + And I should see "Site information" in the "Firstname2 Lastname2" "table_row" + And I should see "Moodle mobile web service" in the "Firstname3 Lastname3" "table_row" + And "Firstname4 Lastname4" "table_row" should not exist + + # Reset the filter. + And I press "Show all tokens" + And I should see "Site information" in the "Firstname2 Lastname2" "table_row" + And I should see "Moodle mobile web service" in the "Firstname3 Lastname3" "table_row" + And I should see "Site information" in the "Firstname4 Lastname4" "table_row" + # Filter tokens by user (note we can select the user by the identity field here). When I click on "Tokens filter" "link" And I set the field "User" to "user2@example.com" diff --git a/admin/webservice/tokens.php b/admin/webservice/tokens.php index cd9903c5f35..0f8c03d3527 100644 --- a/admin/webservice/tokens.php +++ b/admin/webservice/tokens.php @@ -30,7 +30,7 @@ require_once($CFG->dirroot . '/webservice/lib.php'); $action = optional_param('action', '', PARAM_ALPHANUMEXT); $tokenid = optional_param('tokenid', '', PARAM_SAFEDIR); $confirm = optional_param('confirm', 0, PARAM_BOOL); -$ftoken = optional_param('ftoken', '', PARAM_ALPHANUM); +$fname = optional_param('fname', '', PARAM_ALPHANUM); $fusers = optional_param_array('fusers', [], PARAM_INT); $fservices = optional_param_array('fservices', [], PARAM_INT); @@ -74,7 +74,8 @@ if ($action === 'create') { $data->user, context_system::instance(), $data->validuntil, - $data->iprestriction + $data->iprestriction, + $data->name ); redirect($PAGE->url); } @@ -127,7 +128,7 @@ if ($action === 'delete') { // Pre-populate the form with the values that come as a part of the URL - typically when using the table_sql control // links. $filterdata = (object)[ - 'token' => $ftoken, + 'name' => $fname, 'users' => $fusers, 'services' => $fservices, ]; @@ -150,12 +151,28 @@ echo $OUTPUT->heading(get_string('managetokens', 'core_webservice')); echo html_writer::div($OUTPUT->render(new single_button(new moodle_url($PAGE->url, ['action' => 'create']), get_string('createtoken', 'core_webservice'), 'get', single_button::BUTTON_PRIMARY)), 'my-3'); +if (!empty($SESSION->webservicenewlycreatedtoken)) { + $webservicemanager = new webservice(); + $newtoken = $webservicemanager->get_created_by_user_ws_token( + $USER->id, + $SESSION->webservicenewlycreatedtoken + ); + if ($newtoken) { + // Unset the session variable. + unset($SESSION->webservicenewlycreatedtoken); + // Display the newly created token. + echo $OUTPUT->render_from_template( + 'core_admin/webservice_token_new', ['token' => $newtoken->token, 'tokenname' => $newtoken->tokenname] + ); + } +} + $filter->display(); $table = new \core_webservice\token_table('webservicetokens', $filterdata); // In order to not lose the filter form values by clicking the table control links, make them part of the table's baseurl. -$baseurl = new moodle_url($PAGE->url, ['ftoken' => $filterdata->token]); +$baseurl = new moodle_url($PAGE->url, ['fname' => $filterdata->name]); foreach ($filterdata->users as $i => $userid) { $baseurl->param("fusers[{$i}]", $userid); diff --git a/lang/en/external.php b/lang/en/external.php index a8b2d56b734..7d02ab9997b 100644 --- a/lang/en/external.php +++ b/lang/en/external.php @@ -31,6 +31,7 @@ $string['privacy:metadata:tokens'] = 'A record of tokens for interacting with Mo $string['privacy:metadata:tokens:creatorid'] = 'The ID of the user who created the token'; $string['privacy:metadata:tokens:iprestriction'] = 'IP restricted to use this token'; $string['privacy:metadata:tokens:lastaccess'] = 'The date when the token was last used'; +$string['privacy:metadata:tokens:name'] = 'The token name'; $string['privacy:metadata:tokens:privatetoken'] = 'A more private token occasionally used to validate certain operations, such as SSO'; $string['privacy:metadata:tokens:timecreated'] = 'The date when the token was created'; $string['privacy:metadata:tokens:token'] = 'The user\'s token'; diff --git a/lang/en/webservice.php b/lang/en/webservice.php index 5f45015d89e..0d0dfeb8519 100644 --- a/lang/en/webservice.php +++ b/lang/en/webservice.php @@ -191,11 +191,16 @@ $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. WARNING: The functions that you test WILL BE EXECUTED, so be careful what you choose to test!'; $string['token'] = 'Token'; $string['tokenauthlog'] = 'Token authentication'; +$string['tokencopied'] = 'Text copied to clipboard.'; $string['tokencreatedbyadmin'] = 'Can only be reset by administrator (*)'; $string['tokencreator'] = 'Creator'; $string['tokenfilter'] = 'Tokens filter'; $string['tokenfiltersubmit'] = 'Show only matching tokens'; $string['tokenfilterreset'] = 'Show all tokens'; +$string['tokenname'] = 'Name'; +$string['tokennamehint'] = 'If you don\'t enter a name then a random name will be used.'; +$string['tokennameprefix'] = 'Webservice-{$a}'; +$string['tokennewmessage'] = 'Copy the token now. It won\'t be shown again once you leave this page.'; $string['unknownoptionkey'] = 'Unknown option key ({$a})'; $string['unnamedstringparam'] = 'A string parameter is unnamed.'; $string['updateusersettings'] = 'Update'; @@ -210,6 +215,7 @@ $string['usernotallowed'] = 'The user is not allowed for this service. First you $string['userservices'] = 'User services: {$a}'; $string['usersettingssaved'] = 'User settings saved'; $string['validuntil'] = 'Valid until'; +$string['validuntil_empty'] = 'This token has no expiration date.'; $string['validuntil_help'] = 'If set, the service will be inactivated after this date for this user.'; $string['webservice'] = 'Web service'; $string['webservices'] = 'Web services'; diff --git a/lib/db/install.xml b/lib/db/install.xml index 5c0f16874df..bebdd926af4 100644 --- a/lib/db/install.xml +++ b/lib/db/install.xml @@ -1,5 +1,5 @@ - @@ -2902,6 +2902,7 @@ + diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index f9429b7d325..25e9ed1e270 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -3314,5 +3314,24 @@ privatefiles,moodle|/user/files.php'; upgrade_main_savepoint(true, 2023062200.00); } + if ($oldversion < 2023062300.01) { + // Define field name to be added to external_tokens. + $table = new xmldb_table('external_tokens'); + $field = new xmldb_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'lastaccess'); + // Conditionally launch add field name. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + // Update the old external tokens. + $sql = 'UPDATE {external_tokens} + SET name = ' . $DB->sql_concat( + // We only need the prefix, so leave the third param with an empty string. + "'" . get_string('tokennameprefix', 'webservice', '') . "'", + "id"); + $DB->execute($sql); + // Main savepoint reached. + upgrade_main_savepoint(true, 2023062300.01); + } + return true; } diff --git a/lib/external/classes/privacy/provider.php b/lib/external/classes/privacy/provider.php index 437e19ad907..5a930a2668c 100644 --- a/lib/external/classes/privacy/provider.php +++ b/lib/external/classes/privacy/provider.php @@ -56,6 +56,7 @@ class provider implements 'validuntil' => 'privacy:metadata:tokens:validuntil', 'timecreated' => 'privacy:metadata:tokens:timecreated', 'lastaccess' => 'privacy:metadata:tokens:lastaccess', + 'name' => 'privacy:metadata:tokens:name', ], 'privacy:metadata:tokens'); $collection->add_database_table('external_services_users', [ @@ -293,6 +294,7 @@ class provider implements 'valid_until' => $record->validuntil ? transform::datetime($record->validuntil) : null, 'created_on' => transform::datetime($record->timecreated), 'last_access' => $record->lastaccess ? transform::datetime($record->lastaccess) : null, + 'name' => $record->name, ]; } diff --git a/lib/external/classes/util.php b/lib/external/classes/util.php index c9240ff0b1c..ab4d3385368 100644 --- a/lib/external/classes/util.php +++ b/lib/external/classes/util.php @@ -173,6 +173,7 @@ class util { * @param context $context * @param int $validuntil date when the token expired * @param string $iprestriction allowed ip - if 0 or empty then all ips are allowed + * @param string $name token name as a note or token identity at the table view. * @return string generated token */ public static function generate_token( @@ -181,9 +182,10 @@ class util { int $userid, context $context, int $validuntil = 0, - string $iprestriction = '' + string $iprestriction = '', + string $name = '' ): string { - global $DB, $USER; + global $DB, $USER, $SESSION; // Make sure the token doesn't exist (even if it should be almost impossible with the random generation). $numtries = 0; @@ -220,7 +222,17 @@ class util { // Generate the private token, it must be transmitted only via https. $newtoken->privatetoken = random_string(64); - $DB->insert_record('external_tokens', $newtoken); + + if (!$name) { + // Generate a token name. + $name = self::generate_token_name(); + } + $newtoken->name = $name; + + $tokenid = $DB->insert_record('external_tokens', $newtoken); + // Create new session to hold newly created token ID. + $SESSION->webservicenewlycreatedtoken = $tokenid; + return $newtoken->token; } @@ -399,6 +411,7 @@ class util { $token->iprestriction = null; $token->sid = null; $token->lastaccess = null; + $token->name = self::generate_token_name(); // Generate the private token, it must be transmitted only via https. $token->privatetoken = random_string(64); $token->id = $DB->insert_record('external_tokens', $token); @@ -619,4 +632,17 @@ class util { $DB->delete_records('external_services', ['component' => $component]); $DB->delete_records('external_functions', ['component' => $component]); } + + /** + * Generate token name. + * + * @return string + */ + public static function generate_token_name(): string { + return get_string( + 'tokennameprefix', + 'webservice', + random_string(5) + ); + } } diff --git a/lib/upgrade.txt b/lib/upgrade.txt index 333a6708329..580e984ba08 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -30,6 +30,9 @@ information provided here is intended especially for developers. - core_useragent::get_device_type_cfg_var_name() - theme_is_device_locked() - theme_get_locked_theme_for_device() +* Addition of new 'name' field in the external_tokens table. +* \core_external\util::generate_token() has a new optional argument "name" used as a token name. +* Introduce a new public function \core_external\util::generate_token_name() === 4.2 === diff --git a/version.php b/version.php index 2d71bd2f467..01fe2ce5f42 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2023062300.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2023062300.01; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes. $release = '4.3dev (Build: 20230623)'; // Human-friendly version name diff --git a/webservice/classes/token_filter.php b/webservice/classes/token_filter.php index 16c6d1a4204..df600177ae3 100644 --- a/webservice/classes/token_filter.php +++ b/webservice/classes/token_filter.php @@ -51,9 +51,9 @@ class token_filter extends moodleform { $mform->setExpanded('tokenfilter', true); } - // Token. - $mform->addElement('text', 'token', get_string('token', 'core_webservice'), ['size' => 32]); - $mform->setType('token', PARAM_ALPHANUM); + // Token name. + $mform->addElement('text', 'name', get_string('tokenname', 'core_webservice'), ['size' => 32]); + $mform->setType('name', PARAM_TEXT); // User selector. $attributes = [ diff --git a/webservice/classes/token_form.php b/webservice/classes/token_form.php index 4c8e7b2bdf7..057f2d6508c 100644 --- a/webservice/classes/token_form.php +++ b/webservice/classes/token_form.php @@ -26,6 +26,8 @@ namespace core_webservice; use core_user; +use DateInterval; +use DateTime; /** * Form to create and edit a web service token. @@ -49,6 +51,10 @@ class token_form extends \moodleform { $mform->addElement('header', 'token', get_string('token', 'webservice')); + $mform->addElement('text', 'name', get_string('tokenname', 'webservice')); + $mform->setType('name', PARAM_TEXT); + $mform->addElement('static', 'tokennamehint', '', get_string('tokennamehint', 'webservice')); + // User selector. $attributes = [ 'multiple' => false, @@ -90,6 +96,10 @@ class token_form extends \moodleform { $mform->addElement('date_selector', 'validuntil', get_string('validuntil', 'webservice'), array('optional' => true)); + // Expires in 30 days. + $expires = new DateTime(); + $expires->add(new DateInterval("P30D")); + $mform->setDefault('validuntil', $expires->getTimestamp()); $mform->setType('validuntil', PARAM_INT); $mform->addElement('hidden', 'action'); diff --git a/webservice/classes/token_table.php b/webservice/classes/token_table.php index 5643fae7ae7..84737c46c9e 100644 --- a/webservice/classes/token_table.php +++ b/webservice/classes/token_table.php @@ -79,8 +79,8 @@ class token_table extends \table_sql { $headers = []; $columns = []; - $headers[] = get_string('token', 'webservice'); - $columns[] = 'token'; + $headers[] = get_string('tokenname', 'webservice'); + $columns[] = 'name'; $headers[] = get_string('user'); $columns[] = 'fullname'; $headers[] = get_string('service', 'webservice'); @@ -132,7 +132,7 @@ class token_table extends \table_sql { */ public function col_validuntil($data) { if (empty($data->validuntil)) { - return ''; + return get_string('validuntil_empty', 'webservice'); } else { return userdate($data->validuntil, get_string('strftimedatetime', 'langconfig')); } @@ -184,8 +184,12 @@ class token_table extends \table_sql { * * @param \stdClass $data Data for the current row * @return string Content for the column + * + * @deprecated since Moodle 4.2 MDL-76656. Please do not use this function any more. */ public function col_token($data) { + debugging('The function ' . __FUNCTION__ . '() is deprecated - please do not use it any more. ', DEBUG_DEVELOPER); + global $USER; // Hide the token if it wasn't created by the current user. if ($data->creatorid != $USER->id) { @@ -195,6 +199,16 @@ class token_table extends \table_sql { return $data->token; } + /** + * Generate the name column. + * + * @param \stdClass $data Data for the current row + * @return string Content for the column + */ + public function col_name($data) { + return $data->name; + } + /** * Generate the creator column. * @@ -267,7 +281,7 @@ class token_table extends \table_sql { $params = ['tokenmode' => EXTERNAL_TOKEN_PERMANENT]; - $selectfields = "SELECT t.id, t.token, t.iprestriction, t.validuntil, t.creatorid, + $selectfields = "SELECT t.id, t.name, t.iprestriction, t.validuntil, t.creatorid, u.id AS userid, $usernamefields, s.id AS serviceid, s.name AS servicename, s.shortname AS serviceshortname, $creatorfields "; @@ -286,9 +300,9 @@ class token_table extends \table_sql { $params['userid'] = $USER->id; } - if ($this->filterdata->token !== '') { - $sql .= " AND " . $DB->sql_like("t.token", ":token"); - $params['token'] = "%" . $DB->sql_like_escape($this->filterdata->token) . "%"; + if ($this->filterdata->name !== '') { + $sql .= " AND " . $DB->sql_like("t.name", ":name", false, false); + $params['name'] = "%" . $DB->sql_like_escape($this->filterdata->name) . "%"; } if (!empty($this->filterdata->users)) { diff --git a/webservice/lib.php b/webservice/lib.php index 6ff9d67ad3b..59c82800001 100644 --- a/webservice/lib.php +++ b/webservice/lib.php @@ -372,6 +372,7 @@ class webservice { $newtoken->contextid = context_system::instance()->id; $newtoken->creatorid = $userid; $newtoken->timecreated = time(); + $newtoken->name = \core_external\util::generate_token_name(); // Generate the private token, it must be transmitted only via https. $newtoken->privatetoken = random_string(64); @@ -395,7 +396,8 @@ class webservice { global $DB; //here retrieve token list (including linked users firstname/lastname and linked services name) $sql = "SELECT - t.id, t.creatorid, t.token, u.firstname, u.lastname, s.id as wsid, s.name, s.enabled, s.restrictedusers, t.validuntil + t.id, t.creatorid, t.name as tokenname, u.firstname, u.lastname, + s.id as wsid, s.name as servicename, s.enabled, s.restrictedusers, t.validuntil FROM {external_tokens} t, {user} u, {external_services} s WHERE @@ -422,7 +424,7 @@ class webservice { public function get_created_by_user_ws_token($userid, $tokenid) { global $DB; $sql = "SELECT - t.id, t.token, u.firstname, u.lastname, s.name + t.id, t.token, t.name AS tokenname, u.firstname, u.lastname, s.name FROM {external_tokens} t, {user} u, {external_services} s WHERE @@ -861,9 +863,10 @@ class webservice { public static function get_active_tokens($userid) { global $DB; - $sql = 'SELECT t.*, s.name as servicename FROM {external_tokens} t JOIN - {external_services} s ON t.externalserviceid = s.id WHERE - t.userid = :userid AND (COALESCE(t.validuntil, 0) = 0 OR t.validuntil > :now)'; + $sql = 'SELECT t.id, t.creatorid, t.externalserviceid, t.name AS tokenname, t.validuntil, s.name AS servicename + FROM {external_tokens} t + JOIN {external_services} s ON t.externalserviceid = s.id + WHERE t.userid = :userid AND (COALESCE(t.validuntil, 0) = 0 OR t.validuntil > :now)'; $params = array('userid' => $userid, 'now' => time()); return $DB->get_records_sql($sql, $params); } diff --git a/webservice/renderer.php b/webservice/renderer.php index a016c5f0a76..0698d830f8d 100644 --- a/webservice/renderer.php +++ b/webservice/renderer.php @@ -290,7 +290,7 @@ class core_webservice_renderer extends plugin_renderer_base { // display strings $stroperation = get_string('operation', 'webservice'); - $strtoken = get_string('key', 'webservice'); + $strtoken = get_string('tokenname', 'webservice'); $strservice = get_string('service', 'webservice'); $strcreator = get_string('tokencreator', 'webservice'); $strcontext = get_string('context', 'webservice'); @@ -338,11 +338,11 @@ class core_webservice_renderer extends plugin_renderer_base { $validuntil = userdate($token->validuntil, get_string('strftimedatetime', 'langconfig')); } - $tokenname = $token->name; - if (!$token->enabled) { //that is the (1 token-1ws) related ws is not enabled. - $tokenname = ''.$token->name.''; + $servicename = $token->servicename; + if (!$token->enabled) { // That is the (1 token-1ws) related ws is not enabled. + $servicename = ''.$token->servicename.''; } - $row = array($token->token, $tokenname, $validuntil, $creatoratag, $reset); + $row = array($token->tokenname, $servicename, $validuntil, $creatoratag, $reset); if ($documentation) { $doclink = new moodle_url('/webservice/wsdoc.php', diff --git a/webservice/tests/externallib_test.php b/webservice/tests/externallib_test.php index d4f9e425c86..2d1f791d8e7 100644 --- a/webservice/tests/externallib_test.php +++ b/webservice/tests/externallib_test.php @@ -86,6 +86,7 @@ class externallib_test extends externallib_advanced_testcase { $externaltoken->contextid = 1; $externaltoken->creatorid = $USER->id; $externaltoken->timecreated = time(); + $externaltoken->name = \core_external\util::generate_token_name(); $DB->insert_record('external_tokens', $externaltoken); $siteinfo = \core_webservice_external::get_site_info(); @@ -154,6 +155,7 @@ class externallib_test extends externallib_advanced_testcase { $externaltoken->contextid = 1; $externaltoken->creatorid = $USER->id; $externaltoken->timecreated = time(); + $externaltoken->name = \core_external\util::generate_token_name(); $DB->insert_record('external_tokens', $externaltoken); // Set a home page by user preferences. @@ -260,6 +262,7 @@ class externallib_test extends externallib_advanced_testcase { $externaltoken->contextid = 1; $externaltoken->creatorid = $USER->id; $externaltoken->timecreated = time(); + $externaltoken->name = \core_external\util::generate_token_name(); $DB->insert_record('external_tokens', $externaltoken); // Execution should complete. diff --git a/webservice/tests/generator/lib.php b/webservice/tests/generator/lib.php index dacd3647738..a61919b7d1d 100644 --- a/webservice/tests/generator/lib.php +++ b/webservice/tests/generator/lib.php @@ -118,6 +118,7 @@ class core_webservice_generator extends component_generator_base { 'context' => context_system::instance(), 'validuntil' => 0, 'iprestriction' => '', + 'name' => '', ]; foreach ($optionalfields as $fieldname => $value) { @@ -134,7 +135,8 @@ class core_webservice_generator extends component_generator_base { $data['userid'], $data['context'], $data['validuntil'], - $data['iprestriction'] + $data['iprestriction'], + $data['name'] ); } } diff --git a/webservice/tests/lib_test.php b/webservice/tests/lib_test.php index 6b6c913226d..059eb5723df 100644 --- a/webservice/tests/lib_test.php +++ b/webservice/tests/lib_test.php @@ -87,6 +87,7 @@ class lib_test extends \advanced_testcase { $externaltoken->contextid = 1; $externaltoken->creatorid = $USER->id; $externaltoken->timecreated = time(); + $externaltoken->name = \core_external\util::generate_token_name(); $DB->insert_record('external_tokens', $externaltoken); // Add a function to the service.