mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
MDL-76583 core_external: Migrate token functions class
This commit is contained in:
parent
7d079e82e1
commit
7f5fb6a592
272
lib/external/classes/util.php
vendored
272
lib/external/classes/util.php
vendored
@ -16,9 +16,14 @@
|
||||
|
||||
namespace core_external;
|
||||
|
||||
use context;
|
||||
use context_course;
|
||||
use context_helper;
|
||||
use context_system;
|
||||
use core_user;
|
||||
use moodle_exception;
|
||||
use moodle_url;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Utility functions for the external API.
|
||||
@ -144,4 +149,271 @@ class util {
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create and return a session linked token. Token to be used for html embedded client apps that want to communicate
|
||||
* with the Moodle server through web services. The token is linked to the current session for the current page request.
|
||||
* It is expected this will be called in the script generating the html page that is embedding the client app and that the
|
||||
* returned token will be somehow passed into the client app being embedded in the page.
|
||||
*
|
||||
* @param int $tokentype EXTERNAL_TOKEN_EMBEDDED|EXTERNAL_TOKEN_PERMANENT
|
||||
* @param stdClass|int $serviceorid service linked to the token
|
||||
* @param int $userid user linked to the token
|
||||
* @param context $contextorid
|
||||
* @param int $validuntil date when the token expired
|
||||
* @param string $iprestriction allowed ip - if 0 or empty then all ips are allowed
|
||||
* @return string generated token
|
||||
*/
|
||||
public static function generate_token(
|
||||
int $tokentype,
|
||||
stdClass $service,
|
||||
int $userid,
|
||||
context $contextorid,
|
||||
int $validuntil = 0,
|
||||
string $iprestriction = ''
|
||||
): string {
|
||||
global $DB, $USER;
|
||||
|
||||
// Make sure the token doesn't exist (even if it should be almost impossible with the random generation).
|
||||
$numtries = 0;
|
||||
do {
|
||||
$numtries ++;
|
||||
$generatedtoken = md5(uniqid((string) rand(), true));
|
||||
if ($numtries > 5) {
|
||||
throw new moodle_exception('tokengenerationfailed');
|
||||
}
|
||||
} while ($DB->record_exists('external_tokens', ['token' => $generatedtoken]));
|
||||
$newtoken = (object) [
|
||||
'token' => $generatedtoken,
|
||||
];
|
||||
|
||||
if (empty($service->requiredcapability) || has_capability($service->requiredcapability, $context, $userid)) {
|
||||
$newtoken->externalserviceid = $service->id;
|
||||
} else {
|
||||
throw new moodle_exception('nocapabilitytousethisservice');
|
||||
}
|
||||
|
||||
$newtoken->tokentype = $tokentype;
|
||||
$newtoken->userid = $userid;
|
||||
if ($tokentype == EXTERNAL_TOKEN_EMBEDDED) {
|
||||
$newtoken->sid = session_id();
|
||||
}
|
||||
|
||||
$newtoken->contextid = $context->id;
|
||||
$newtoken->creatorid = $USER->id;
|
||||
$newtoken->timecreated = time();
|
||||
$newtoken->validuntil = $validuntil;
|
||||
if (!empty($iprestriction)) {
|
||||
$newtoken->iprestriction = $iprestriction;
|
||||
}
|
||||
|
||||
// Generate the private token, it must be transmitted only via https.
|
||||
$newtoken->privatetoken = random_string(64);
|
||||
$DB->insert_record('external_tokens', $newtoken);
|
||||
return $newtoken->token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a service by its id.
|
||||
*
|
||||
* @param int $serviceid
|
||||
* @return stdClass
|
||||
*/
|
||||
public static function get_service_by_id(int $serviceid): stdClass {
|
||||
global $DB;
|
||||
|
||||
return $DB->get_record('external_services', ['id' => $serviceid], '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a service by its name.
|
||||
*
|
||||
* @param string $name The service name.
|
||||
* @return stdClass
|
||||
*/
|
||||
public static function get_service_by_name(string $name): stdClass {
|
||||
global $DB;
|
||||
|
||||
return $DB->get_record('external_services', ['name' => $name], '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the last time a token was sent and trigger the \core\event\webservice_token_sent event.
|
||||
*
|
||||
* This function is used when a token is generated by the user via login/token.php or admin/tool/mobile/launch.php.
|
||||
* In order to protect the privatetoken, we remove it from the event params.
|
||||
*
|
||||
* @param stdClass $token token object
|
||||
*/
|
||||
public static function log_token_request(stdClass $token): void {
|
||||
global $DB, $USER;
|
||||
|
||||
$token->privatetoken = null;
|
||||
|
||||
// Log token access.
|
||||
$DB->set_field('external_tokens', 'lastaccess', time(), ['id' => $token->id]);
|
||||
|
||||
$event = \core\event\webservice_token_sent::create([
|
||||
'objectid' => $token->id,
|
||||
]);
|
||||
$event->add_record_snapshot('external_tokens', $token);
|
||||
$event->trigger();
|
||||
|
||||
// Check if we need to notify the user about the new login via token.
|
||||
$loginip = getremoteaddr();
|
||||
if ($USER->lastip === $loginip) {
|
||||
return;
|
||||
}
|
||||
|
||||
$shouldskip = WS_SERVER || CLI_SCRIPT || !NO_MOODLE_COOKIES;
|
||||
if ($shouldskip && !PHPUNIT_TEST) {
|
||||
return;
|
||||
}
|
||||
|
||||
$useragent = \core_useragent::get_user_agent_string();
|
||||
$ismoodleapp = \core_useragent::is_moodle_app();
|
||||
|
||||
// Schedule adhoc task to sent a login notification to the user.
|
||||
$task = new \core\task\send_login_notifications();
|
||||
$task->set_userid($USER->id);
|
||||
$logintime = time();
|
||||
$task->set_custom_data([
|
||||
'useragent' => \core_useragent::get_user_agent_string(),
|
||||
'ismoodleapp' => \core_useragent::is_moodle_app(),
|
||||
'loginip' => $loginip,
|
||||
'logintime' => $logintime,
|
||||
]);
|
||||
$task->set_component('core');
|
||||
// We need sometime so the mobile app will send to Moodle the device information after login.
|
||||
$task->set_next_run_time(time() + (2 * MINSECS));
|
||||
\core\task\manager::reschedule_or_queue_adhoc_task($task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate or return an existing token for the current authenticated user.
|
||||
* This function is used for creating a valid token for users authenticathing via places, including:
|
||||
* - login/token.php
|
||||
* - admin/tool/mobile/launch.php.
|
||||
*
|
||||
* @param stdClass $service external service object
|
||||
* @return stdClass token object
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function generate_token_for_current_user(stdClass $service) {
|
||||
global $DB, $USER, $CFG;
|
||||
|
||||
core_user::require_active_user($USER, true, true);
|
||||
|
||||
// Check if there is any required system capability.
|
||||
if ($service->requiredcapability && !has_capability($service->requiredcapability, context_system::instance())) {
|
||||
throw new moodle_exception('missingrequiredcapability', 'webservice', '', $service->requiredcapability);
|
||||
}
|
||||
|
||||
// Specific checks related to user restricted service.
|
||||
if ($service->restrictedusers) {
|
||||
$authoriseduser = $DB->get_record('external_services_users', [
|
||||
'externalserviceid' => $service->id,
|
||||
'userid' => $USER->id,
|
||||
]);
|
||||
|
||||
if (empty($authoriseduser)) {
|
||||
throw new moodle_exception('usernotallowed', 'webservice', '', $service->shortname);
|
||||
}
|
||||
|
||||
if (!empty($authoriseduser->validuntil) && $authoriseduser->validuntil < time()) {
|
||||
throw new moodle_exception('invalidtimedtoken', 'webservice');
|
||||
}
|
||||
|
||||
if (!empty($authoriseduser->iprestriction) && !address_in_subnet(getremoteaddr(), $authoriseduser->iprestriction)) {
|
||||
throw new moodle_exception('invalidiptoken', 'webservice');
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a token has already been created for this user and this service.
|
||||
$conditions = [
|
||||
'userid' => $USER->id,
|
||||
'externalserviceid' => $service->id,
|
||||
'tokentype' => EXTERNAL_TOKEN_PERMANENT,
|
||||
];
|
||||
$tokens = $DB->get_records('external_tokens', $conditions, 'timecreated ASC');
|
||||
|
||||
// A bit of sanity checks.
|
||||
foreach ($tokens as $key => $token) {
|
||||
|
||||
// Checks related to a specific token. (script execution continue).
|
||||
$unsettoken = false;
|
||||
// If sid is set then there must be a valid associated session no matter the token type.
|
||||
if (!empty($token->sid)) {
|
||||
if (!\core\session\manager::session_exists($token->sid)) {
|
||||
// This token will never be valid anymore, delete it.
|
||||
$DB->delete_records('external_tokens', ['sid' => $token->sid]);
|
||||
$unsettoken = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove token is not valid anymore.
|
||||
if (!empty($token->validuntil) && $token->validuntil < time()) {
|
||||
$DB->delete_records('external_tokens', ['token' => $token->token, 'tokentype' => EXTERNAL_TOKEN_PERMANENT]);
|
||||
$unsettoken = true;
|
||||
}
|
||||
|
||||
// Remove token if its IP is restricted.
|
||||
if (isset($token->iprestriction) && !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
|
||||
$unsettoken = true;
|
||||
}
|
||||
|
||||
if ($unsettoken) {
|
||||
unset($tokens[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// If some valid tokens exist then use the most recent.
|
||||
if (count($tokens) > 0) {
|
||||
$token = array_pop($tokens);
|
||||
} else {
|
||||
$context = context_system::instance();
|
||||
$isofficialservice = $service->shortname == MOODLE_OFFICIAL_MOBILE_SERVICE;
|
||||
|
||||
if (
|
||||
($isofficialservice && has_capability('moodle/webservice:createmobiletoken', $context)) ||
|
||||
(!is_siteadmin($USER) && has_capability('moodle/webservice:createtoken', $context))
|
||||
) {
|
||||
|
||||
// Create a new token.
|
||||
$token = new stdClass;
|
||||
$token->token = md5(uniqid((string) rand(), true));
|
||||
$token->userid = $USER->id;
|
||||
$token->tokentype = EXTERNAL_TOKEN_PERMANENT;
|
||||
$token->contextid = context_system::instance()->id;
|
||||
$token->creatorid = $USER->id;
|
||||
$token->timecreated = time();
|
||||
$token->externalserviceid = $service->id;
|
||||
// By default tokens are valid for 12 weeks.
|
||||
$token->validuntil = $token->timecreated + $CFG->tokenduration;
|
||||
$token->iprestriction = null;
|
||||
$token->sid = null;
|
||||
$token->lastaccess = null;
|
||||
// Generate the private token, it must be transmitted only via https.
|
||||
$token->privatetoken = random_string(64);
|
||||
$token->id = $DB->insert_record('external_tokens', $token);
|
||||
|
||||
$eventtoken = clone $token;
|
||||
$eventtoken->privatetoken = null;
|
||||
$params = [
|
||||
'objectid' => $eventtoken->id,
|
||||
'relateduserid' => $USER->id,
|
||||
'other' => [
|
||||
'auto' => true,
|
||||
],
|
||||
];
|
||||
$event = \core\event\webservice_token_created::create($params);
|
||||
$event->add_record_snapshot('external_tokens', $eventtoken);
|
||||
$event->trigger();
|
||||
} else {
|
||||
throw new moodle_exception('cannotcreatetoken', 'webservice', '', $service->shortname);
|
||||
}
|
||||
}
|
||||
return $token;
|
||||
}
|
||||
}
|
||||
|
34
lib/external/tests/util_test.php
vendored
34
lib/external/tests/util_test.php
vendored
@ -119,7 +119,7 @@ class util_test extends \advanced_testcase {
|
||||
$courseids = [$c1->id, $c2->id, $c3->id];
|
||||
|
||||
$this->setAdminUser();
|
||||
[$courses, $warnings] = \external_util::validate_courses($courseids);
|
||||
[$courses, $warnings] = util::validate_courses($courseids);
|
||||
$this->assertEmpty($warnings);
|
||||
$this->assertCount(3, $courses);
|
||||
$this->assertArrayHasKey($c1->id, $courses);
|
||||
@ -130,7 +130,7 @@ class util_test extends \advanced_testcase {
|
||||
$this->assertEquals($c3->id, $courses[$c3->id]->id);
|
||||
|
||||
$this->setUser($u1);
|
||||
[$courses, $warnings] = \external_util::validate_courses($courseids);
|
||||
[$courses, $warnings] = util::validate_courses($courseids);
|
||||
$this->assertCount(2, $warnings);
|
||||
$this->assertEquals($c2->id, $warnings[0]['itemid']);
|
||||
$this->assertEquals($c3->id, $warnings[1]['itemid']);
|
||||
@ -146,7 +146,7 @@ class util_test extends \advanced_testcase {
|
||||
*
|
||||
* @covers \core_external\util::get_area_files
|
||||
*/
|
||||
public function test_external_util_get_area_files(): void {
|
||||
public function test_get_area_files(): void {
|
||||
global $CFG, $DB;
|
||||
|
||||
$this->DB = $DB;
|
||||
@ -195,4 +195,32 @@ class util_test extends \advanced_testcase {
|
||||
$files = util::get_area_files($context, $component, $filearea, $itemid);
|
||||
$this->assertEquals($expectedfiles, $files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test default time for user created tokens.
|
||||
*
|
||||
* @covers \core_external\util::generate_token_for_current_user
|
||||
*/
|
||||
public function test_user_created_tokens_duration(): void {
|
||||
global $CFG, $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$CFG->enablewebservices = 1;
|
||||
$CFG->enablemobilewebservice = 1;
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$service = $DB->get_record('external_services', ['shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE, 'enabled' => 1]);
|
||||
|
||||
$this->setUser($user1);
|
||||
$timenow = time();
|
||||
$token = util::generate_token_for_current_user($service);
|
||||
$this->assertGreaterThanOrEqual($timenow + $CFG->tokenduration, $token->validuntil);
|
||||
|
||||
// Change token default time.
|
||||
$this->setUser($user2);
|
||||
set_config('tokenduration', DAYSECS);
|
||||
$token = util::external_generate_token_for_current_user($service);
|
||||
$timenow = time();
|
||||
$this->assertLessThanOrEqual($timenow + DAYSECS, $token->validuntil);
|
||||
}
|
||||
}
|
||||
|
@ -48,54 +48,31 @@ class_alias(\core_external\external_settings::class, 'external_settings');
|
||||
* @param int $validuntil date when the token expired
|
||||
* @param string $iprestriction allowed ip - if 0 or empty then all ips are allowed
|
||||
* @return string generated token
|
||||
* @author 2010 Jamie Pratt
|
||||
* @since Moodle 2.0
|
||||
*/
|
||||
function external_generate_token($tokentype, $serviceorid, $userid, $contextorid, $validuntil=0, $iprestriction=''){
|
||||
global $DB, $USER;
|
||||
// make sure the token doesn't exist (even if it should be almost impossible with the random generation)
|
||||
$numtries = 0;
|
||||
do {
|
||||
$numtries ++;
|
||||
$generatedtoken = md5(uniqid(rand(),1));
|
||||
if ($numtries > 5){
|
||||
throw new moodle_exception('tokengenerationfailed');
|
||||
}
|
||||
} while ($DB->record_exists('external_tokens', array('token'=>$generatedtoken)));
|
||||
$newtoken = new stdClass();
|
||||
$newtoken->token = $generatedtoken;
|
||||
if (!is_object($serviceorid)){
|
||||
$service = $DB->get_record('external_services', array('id' => $serviceorid));
|
||||
function external_generate_token($tokentype, $serviceorid, $userid, $contextorid, $validuntil = 0, $iprestriction = '') {
|
||||
if (is_numeric($serviceorid)) {
|
||||
$service = util::get_service_by_id($serviceorid);
|
||||
} else if (is_string($serviceorid)) {
|
||||
$service = util::get_service_by_name($serviceorid);
|
||||
} else {
|
||||
$service = $serviceorid;
|
||||
}
|
||||
if (!is_object($contextorid)){
|
||||
|
||||
if (!is_object($contextorid)) {
|
||||
$context = context::instance_by_id($contextorid, MUST_EXIST);
|
||||
} else {
|
||||
$context = $contextorid;
|
||||
}
|
||||
if (empty($service->requiredcapability) || has_capability($service->requiredcapability, $context, $userid)) {
|
||||
$newtoken->externalserviceid = $service->id;
|
||||
} else {
|
||||
throw new moodle_exception('nocapabilitytousethisservice');
|
||||
}
|
||||
$newtoken->tokentype = $tokentype;
|
||||
$newtoken->userid = $userid;
|
||||
if ($tokentype == EXTERNAL_TOKEN_EMBEDDED){
|
||||
$newtoken->sid = session_id();
|
||||
}
|
||||
|
||||
$newtoken->contextid = $context->id;
|
||||
$newtoken->creatorid = $USER->id;
|
||||
$newtoken->timecreated = time();
|
||||
$newtoken->validuntil = $validuntil;
|
||||
if (!empty($iprestriction)) {
|
||||
$newtoken->iprestriction = $iprestriction;
|
||||
}
|
||||
// Generate the private token, it must be transmitted only via https.
|
||||
$newtoken->privatetoken = random_string(64);
|
||||
$DB->insert_record('external_tokens', $newtoken);
|
||||
return $newtoken->token;
|
||||
return util::generate_token(
|
||||
$tokentype,
|
||||
$service,
|
||||
$userid,
|
||||
$context,
|
||||
$validuntil,
|
||||
$iprestriction
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,10 +86,15 @@ function external_generate_token($tokentype, $serviceorid, $userid, $contextorid
|
||||
* @return int returns token id.
|
||||
* @since Moodle 2.0
|
||||
*/
|
||||
function external_create_service_token($servicename, $context){
|
||||
global $USER, $DB;
|
||||
$service = $DB->get_record('external_services', array('name'=>$servicename), '*', MUST_EXIST);
|
||||
return external_generate_token(EXTERNAL_TOKEN_EMBEDDED, $service, $USER->id, $context, 0);
|
||||
function external_create_service_token($servicename, $contextid) {
|
||||
global $USER;
|
||||
|
||||
return util::generate_token(
|
||||
EXTERNAL_TOKEN_EMBEDDED,
|
||||
util::get_service_by_name($servicename),
|
||||
$USER->id,
|
||||
\context::instance_by_id($contextid)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -281,119 +263,9 @@ function external_format_text($text, $textformat, $contextorid, $component = nul
|
||||
* @param stdClass $service external service object
|
||||
* @return stdClass token object
|
||||
* @since Moodle 3.2
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
function external_generate_token_for_current_user($service) {
|
||||
global $DB, $USER, $CFG;
|
||||
|
||||
core_user::require_active_user($USER, true, true);
|
||||
|
||||
// Check if there is any required system capability.
|
||||
if ($service->requiredcapability and !has_capability($service->requiredcapability, context_system::instance())) {
|
||||
throw new moodle_exception('missingrequiredcapability', 'webservice', '', $service->requiredcapability);
|
||||
}
|
||||
|
||||
// Specific checks related to user restricted service.
|
||||
if ($service->restrictedusers) {
|
||||
$authoriseduser = $DB->get_record('external_services_users',
|
||||
array('externalserviceid' => $service->id, 'userid' => $USER->id));
|
||||
|
||||
if (empty($authoriseduser)) {
|
||||
throw new moodle_exception('usernotallowed', 'webservice', '', $service->shortname);
|
||||
}
|
||||
|
||||
if (!empty($authoriseduser->validuntil) and $authoriseduser->validuntil < time()) {
|
||||
throw new moodle_exception('invalidtimedtoken', 'webservice');
|
||||
}
|
||||
|
||||
if (!empty($authoriseduser->iprestriction) and !address_in_subnet(getremoteaddr(), $authoriseduser->iprestriction)) {
|
||||
throw new moodle_exception('invalidiptoken', 'webservice');
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a token has already been created for this user and this service.
|
||||
$conditions = array(
|
||||
'userid' => $USER->id,
|
||||
'externalserviceid' => $service->id,
|
||||
'tokentype' => EXTERNAL_TOKEN_PERMANENT
|
||||
);
|
||||
$tokens = $DB->get_records('external_tokens', $conditions, 'timecreated ASC');
|
||||
|
||||
// A bit of sanity checks.
|
||||
foreach ($tokens as $key => $token) {
|
||||
|
||||
// Checks related to a specific token. (script execution continue).
|
||||
$unsettoken = false;
|
||||
// If sid is set then there must be a valid associated session no matter the token type.
|
||||
if (!empty($token->sid)) {
|
||||
if (!\core\session\manager::session_exists($token->sid)) {
|
||||
// This token will never be valid anymore, delete it.
|
||||
$DB->delete_records('external_tokens', array('sid' => $token->sid));
|
||||
$unsettoken = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove token is not valid anymore.
|
||||
if (!empty($token->validuntil) and $token->validuntil < time()) {
|
||||
$DB->delete_records('external_tokens', array('token' => $token->token, 'tokentype' => EXTERNAL_TOKEN_PERMANENT));
|
||||
$unsettoken = true;
|
||||
}
|
||||
|
||||
// Remove token if its IP is restricted.
|
||||
if (isset($token->iprestriction) and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
|
||||
$unsettoken = true;
|
||||
}
|
||||
|
||||
if ($unsettoken) {
|
||||
unset($tokens[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// If some valid tokens exist then use the most recent.
|
||||
if (count($tokens) > 0) {
|
||||
$token = array_pop($tokens);
|
||||
} else {
|
||||
$context = context_system::instance();
|
||||
$isofficialservice = $service->shortname == MOODLE_OFFICIAL_MOBILE_SERVICE;
|
||||
|
||||
if (($isofficialservice and has_capability('moodle/webservice:createmobiletoken', $context)) or
|
||||
(!is_siteadmin($USER) && has_capability('moodle/webservice:createtoken', $context))) {
|
||||
|
||||
// Create a new token.
|
||||
$token = new stdClass;
|
||||
$token->token = md5(uniqid(rand(), 1));
|
||||
$token->userid = $USER->id;
|
||||
$token->tokentype = EXTERNAL_TOKEN_PERMANENT;
|
||||
$token->contextid = context_system::instance()->id;
|
||||
$token->creatorid = $USER->id;
|
||||
$token->timecreated = time();
|
||||
$token->externalserviceid = $service->id;
|
||||
// By default tokens are valid for 12 weeks.
|
||||
$token->validuntil = $token->timecreated + $CFG->tokenduration;
|
||||
$token->iprestriction = null;
|
||||
$token->sid = null;
|
||||
$token->lastaccess = null;
|
||||
// Generate the private token, it must be transmitted only via https.
|
||||
$token->privatetoken = random_string(64);
|
||||
$token->id = $DB->insert_record('external_tokens', $token);
|
||||
|
||||
$eventtoken = clone $token;
|
||||
$eventtoken->privatetoken = null;
|
||||
$params = array(
|
||||
'objectid' => $eventtoken->id,
|
||||
'relateduserid' => $USER->id,
|
||||
'other' => array(
|
||||
'auto' => true
|
||||
)
|
||||
);
|
||||
$event = \core\event\webservice_token_created::create($params);
|
||||
$event->add_record_snapshot('external_tokens', $eventtoken);
|
||||
$event->trigger();
|
||||
} else {
|
||||
throw new moodle_exception('cannotcreatetoken', 'webservice', '', $service->shortname);
|
||||
}
|
||||
}
|
||||
return $token;
|
||||
return util::generate_token_for_current_user($service);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -405,37 +277,6 @@ function external_generate_token_for_current_user($service) {
|
||||
* @param stdClass $token token object
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
function external_log_token_request($token) {
|
||||
global $DB, $USER;
|
||||
|
||||
$token->privatetoken = null;
|
||||
|
||||
// Log token access.
|
||||
$DB->set_field('external_tokens', 'lastaccess', time(), array('id' => $token->id));
|
||||
|
||||
$params = array(
|
||||
'objectid' => $token->id,
|
||||
);
|
||||
$event = \core\event\webservice_token_sent::create($params);
|
||||
$event->add_record_snapshot('external_tokens', $token);
|
||||
$event->trigger();
|
||||
|
||||
// Check if we need to notify the user about the new login via token.
|
||||
$loginip = getremoteaddr();
|
||||
if ($USER->lastip != $loginip &&
|
||||
((!WS_SERVER && !CLI_SCRIPT && NO_MOODLE_COOKIES) || PHPUNIT_TEST)) {
|
||||
|
||||
$logintime = time();
|
||||
$useragent = \core_useragent::get_user_agent_string();
|
||||
$ismoodleapp = \core_useragent::is_moodle_app();
|
||||
|
||||
// Schedule adhoc task to sent a login notification to the user.
|
||||
$task = new \core\task\send_login_notifications();
|
||||
$task->set_userid($USER->id);
|
||||
$task->set_custom_data(compact('ismoodleapp', 'useragent', 'loginip', 'logintime'));
|
||||
$task->set_component('core');
|
||||
// We need sometime so the mobile app will send to Moodle the device information after login.
|
||||
$task->set_next_run_time($logintime + (2 * MINSECS));
|
||||
\core\task\manager::reschedule_or_queue_adhoc_task($task);
|
||||
}
|
||||
function external_log_token_request($token): void {
|
||||
util::log_token_request($token);
|
||||
}
|
||||
|
@ -170,32 +170,6 @@ class externallib_test extends \advanced_testcase {
|
||||
$settings->set_raw($currentraw);
|
||||
$settings->set_filter($currentfilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test default time for user created tokens.
|
||||
*/
|
||||
public function test_user_created_tokens_duration() {
|
||||
global $CFG, $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$CFG->enablewebservices = 1;
|
||||
$CFG->enablemobilewebservice = 1;
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$service = $DB->get_record('external_services', array('shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE, 'enabled' => 1));
|
||||
|
||||
$this->setUser($user1);
|
||||
$timenow = time();
|
||||
$token = external_generate_token_for_current_user($service);
|
||||
$this->assertGreaterThanOrEqual($timenow + $CFG->tokenduration, $token->validuntil);
|
||||
|
||||
// Change token default time.
|
||||
$this->setUser($user2);
|
||||
set_config('tokenduration', DAYSECS);
|
||||
$token = external_generate_token_for_current_user($service);
|
||||
$timenow = time();
|
||||
$this->assertLessThanOrEqual($timenow + DAYSECS, $token->validuntil);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user