Skip to content

Commit

Permalink
Merge branch 'MOODLE_401_STABLE' of git://git.moodle.org/moodle into …
Browse files Browse the repository at this point in the history
…IOMAD_401_STABLE
  • Loading branch information
turf212 committed Jun 10, 2024
2 parents 2c096cf + c8c84b4 commit afbe36b
Show file tree
Hide file tree
Showing 44 changed files with 1,020 additions and 127 deletions.
4 changes: 2 additions & 2 deletions admin/tool/mobile/classes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -419,13 +419,13 @@ public static function get_autologin_key() {
public static function get_qrlogin_key(stdClass $mobilesettings) {
global $USER;
// Delete previous keys.
delete_user_key('tool_mobile', $USER->id);
delete_user_key('tool_mobile/qrlogin', $USER->id);

// Create a new key.
$iprestriction = !empty($mobilesettings->qrsameipcheck) ? getremoteaddr(null) : null;
$qrkeyttl = !empty($mobilesettings->qrkeyttl) ? $mobilesettings->qrkeyttl : self::LOGIN_QR_KEY_TTL;
$validuntil = time() + $qrkeyttl;
return create_user_key('tool_mobile', $USER->id, null, $iprestriction, $validuntil);
return create_user_key('tool_mobile/qrlogin', $USER->id, null, $iprestriction, $validuntil);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions admin/tool/mobile/classes/external.php
Original file line number Diff line number Diff line change
Expand Up @@ -649,8 +649,8 @@ public static function get_tokens_for_qr_login($qrloginkey, $userid) {
api::check_autologin_prerequisites($params['userid']); // Checks https, avoid site admins using this...

// Validate and delete the key.
$key = validate_user_key($params['qrloginkey'], 'tool_mobile', null);
delete_user_key('tool_mobile', $params['userid']);
$key = validate_user_key($params['qrloginkey'], 'tool_mobile/qrlogin', null);
delete_user_key('tool_mobile/qrlogin', $params['userid']);

// Double check key belong to user.
if ($key->userid != $params['userid']) {
Expand Down
7 changes: 6 additions & 1 deletion admin/tool/mobile/classes/privacy/provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public static function get_contexts_for_userid(int $userid) : contextlist {
FROM {user_private_key} k
JOIN {user} u ON k.userid = u.id
JOIN {context} ctx ON ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel
WHERE k.userid = :userid AND k.script = 'tool_mobile'";
WHERE k.userid = :userid AND (k.script = 'tool_mobile' OR k.script = 'tool_mobile/qrlogin')";
$params = ['userid' => $userid, 'contextlevel' => CONTEXT_USER];
$contextlist = new contextlist();
$contextlist->add_from_sql($sql, $params);
Expand All @@ -88,6 +88,7 @@ public static function get_users_in_context(userlist $userlist) {

// Add users based on userkey.
\core_userkey\privacy\provider::get_user_contexts_with_script($userlist, $context, 'tool_mobile');
\core_userkey\privacy\provider::get_user_contexts_with_script($userlist, $context, 'tool_mobile/qrlogin');
}

/**
Expand All @@ -108,6 +109,7 @@ public static function export_user_data(approved_contextlist $contextlist) {
}
// Export associated userkeys.
\core_userkey\privacy\provider::export_userkeys($context, [], 'tool_mobile');
\core_userkey\privacy\provider::export_userkeys($context, [], 'tool_mobile/qrlogin');
}
/**
* Export all user preferences for the plugin.
Expand Down Expand Up @@ -138,6 +140,7 @@ public static function delete_data_for_all_users_in_context(\context $context) {
$userid = $context->instanceid;
// Delete all the userkeys.
\core_userkey\privacy\provider::delete_userkeys('tool_mobile', $userid);
\core_userkey\privacy\provider::delete_userkeys('tool_mobile/qrlogin', $userid);
}
/**
* Delete all user data for the specified user, in the specified contexts.
Expand All @@ -158,6 +161,7 @@ public static function delete_data_for_user(approved_contextlist $contextlist) {
$userid = $context->instanceid;
// Delete all the userkeys.
\core_userkey\privacy\provider::delete_userkeys('tool_mobile', $userid);
\core_userkey\privacy\provider::delete_userkeys('tool_mobile/qrlogin', $userid);
}

/**
Expand All @@ -178,5 +182,6 @@ public static function delete_data_for_users(approved_userlist $userlist) {

// Delete all the userkeys.
\core_userkey\privacy\provider::delete_userkeys('tool_mobile', $userid);
\core_userkey\privacy\provider::delete_userkeys('tool_mobile/qrlogin', $userid);
}
}
8 changes: 8 additions & 0 deletions admin/tool/mobile/launch.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@
throw new moodle_exception('servicenotavailable', 'webservice');
}

// If the user is using the inapp (embedded) browser, we need to set the Secure and Partitioned attributes to the session cookie.
if (\core_useragent::is_moodle_app()) {
\core\session\utility\cookie_helper::add_attributes_to_cookie_response_header(
"MoodleSession{$CFG->sessioncookie}",
['Secure', 'Partitioned'],
);
}

require_login(0, false);

// Require an active user: not guest, not suspended.
Expand Down
12 changes: 9 additions & 3 deletions admin/tool/mobile/tests/privacy/provider_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ public function test_get_users_in_context() {
$context1 = \context_user::instance($user1->id);
$context2 = \context_user::instance($user2->id);
$key1 = get_user_key('tool_mobile', $user1->id);
$key2 = get_user_key('tool_mobile', $user2->id);
$key2 = get_user_key('tool_mobile/qrlogin', $user1->id);
$key3 = get_user_key('tool_mobile', $user2->id);

// Ensure only user1 is found in context1.
$userlist = new \core_privacy\local\request\userlist($context1, $component);
Expand Down Expand Up @@ -174,12 +175,15 @@ public function test_delete_data_for_users() {
$context1 = \context_user::instance($user1->id);
$context2 = \context_user::instance($user2->id);
$keyvalue1 = get_user_key('tool_mobile', $user1->id);
$keyvalue2 = get_user_key('tool_mobile', $user2->id);
$keyvalue2 = get_user_key('tool_mobile/qrlogin', $user1->id);
$keyvalue3 = get_user_key('tool_mobile', $user2->id);
$key1 = $DB->get_record('user_private_key', ['value' => $keyvalue1]);

// Before deletion, we should have 2 user_private_keys.
// Before deletion, we should have 2 user_private_keys for tool_mobile and one for tool_mobile/qrlogin.
$count = $DB->count_records('user_private_key', ['script' => 'tool_mobile']);
$this->assertEquals(2, $count);
$count = $DB->count_records('user_private_key', ['script' => 'tool_mobile/qrlogin']);
$this->assertEquals(1, $count);

// Ensure deleting wrong user in the user context does nothing.
$approveduserids = [$user2->id];
Expand All @@ -197,6 +201,8 @@ public function test_delete_data_for_users() {
// Ensure only user1's data is deleted, user2's remains.
$count = $DB->count_records('user_private_key', ['script' => 'tool_mobile']);
$this->assertEquals(1, $count);
$count = $DB->count_records('user_private_key', ['script' => 'tool_mobile/qrlogin']);
$this->assertEquals(0, $count);

$params = ['script' => $component];
$userid = $DB->get_field_select('user_private_key', 'userid', 'script = :script', $params);
Expand Down
2 changes: 1 addition & 1 deletion admin/tool/moodlenet/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
}
redirect($url);
} else if ($continue) {
confirm_sesskey();
require_sesskey();

// Handle backups.
if (strtolower($importinfo->get_resource()->get_extension()) == 'mbz') {
Expand Down
2 changes: 1 addition & 1 deletion admin/tool/moodlenet/options.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
}

if ($import && $module) {
confirm_sesskey();
require_sesskey();

$handlerinfo = $handlerregistry->get_resource_handler_for_mod_and_strategy($importinfo->get_resource(), $module, $strategy);
if (is_null($handlerinfo)) {
Expand Down
2 changes: 1 addition & 1 deletion blocks/recentlyaccesseditems/classes/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static function get_recent_items(int $limit = 0) {
FROM {block_recentlyaccesseditems} rai
JOIN {course} c ON c.id = rai.courseid
WHERE userid = :userid
ORDER BY rai.timeaccess DESC";
ORDER BY rai.timeaccess DESC, rai.id DESC";
$records = $DB->get_records_sql($sql, $paramsql);
$order = 0;

Expand Down
12 changes: 12 additions & 0 deletions calendar/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -3555,6 +3555,18 @@ function ($event) {
}
}

// Check if $data has events.
if (isset($data->events)) {
// Let's check and sanitize all "name" in $data->events before it's sent to front end.
foreach ($data->events as $d) {
$name = $d->name ?? null;
// Encode special characters if our decoded name does not match the original name.
if ($name && (html_entity_decode($name) !== $name)) {
$d->name = htmlspecialchars(html_entity_decode($name), ENT_QUOTES, 'utf-8');
}
}
}

return [$data, $template];
}

Expand Down
2 changes: 1 addition & 1 deletion course/downloadcontent.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

// If download confirmed, prepare and start the zipstream of the course download content.
if ($isdownload) {
confirm_sesskey();
require_sesskey();

$exportoptions = null;

Expand Down
91 changes: 87 additions & 4 deletions course/tests/behat/activity_chooser.feature
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ Feature: Display and choose from the available activities in course
| username | firstname | lastname | email |
| teacher | Teacher | 1 | teacher@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course | C | topics |
| fullname | shortname | format | startdate |
| Course | C | topics | |
| Course 2 | C2 | weeks | 95713920 |
And the following "course enrolments" exist:
| user | course | role |
| teacher | C | editingteacher |
| user | course | role |
| teacher | C | editingteacher |
| teacher | C2 | editingteacher |
And the following config values are set as admin:
| enablemoodlenet | 0 | tool_moodlenet |
And I log in as "teacher"
Expand Down Expand Up @@ -44,6 +46,12 @@ Feature: Display and choose from the available activities in course
When I click on "Information about the Assignment activity" "button" in the "Add an activity or resource" "dialogue"
Then I should see "Assignment" in the "help" "core_course > Activity chooser screen"
And I should see "The assignment activity module enables a teacher to communicate tasks, collect work and provide grades and feedback."
# Confirm show summary also works for weekly format course
And I am on "C2" course homepage with editing mode on
And I click on "Add an activity or resource" "button" in the "13 January - 19 January" "section"
And I click on "Information about the Assignment activity" "button" in the "Add an activity or resource" "dialogue"
And I should see "Assignment" in the "help" "core_course > Activity chooser screen"
And I should see "The assignment activity module enables a teacher to communicate tasks, collect work and provide grades and feedback."

Scenario: Hide summary
Given I click on "Add an activity or resource" "button" in the "Topic 1" "section"
Expand All @@ -55,6 +63,15 @@ Feature: Display and choose from the available activities in course
And "help" "core_course > Activity chooser screen" should not be visible
And "Back" "button" should not exist in the "modules" "core_course > Activity chooser screen"
And I should not see "The assignment activity module enables a teacher to communicate tasks, collect work and provide grades and feedback." in the "Add an activity or resource" "dialogue"
# Confirm hide summary also works for weekly format course
And I am on "C2" course homepage with editing mode on
And I click on "Add an activity or resource" "button" in the "13 January - 19 January" "section"
And I click on "Information about the Assignment activity" "button" in the "Add an activity or resource" "dialogue"
And I click on "Back" "button" in the "help" "core_course > Activity chooser screen"
And "modules" "core_course > Activity chooser screen" should be visible
And "help" "core_course > Activity chooser screen" should not be visible
And "Back" "button" should not exist in the "modules" "core_course > Activity chooser screen"
And I should not see "The assignment activity module enables a teacher to communicate tasks, collect work and provide grades and feedback." in the "Add an activity or resource" "dialogue"

Scenario: View recommended activities
When I log out
Expand Down Expand Up @@ -189,3 +206,69 @@ Feature: Display and choose from the available activities in course
Then I should not see "All" in the "Add an activity or resource" "dialogue"
And I should see "Activities" in the "Add an activity or resource" "dialogue"
And I should see "Resources" in the "Add an activity or resource" "dialogue"

Scenario: Teacher can navigate through activity chooser in Topics format course
When I click on "Add an activity or resource" "button" in the "Topic 1" "section"
Then I should see "All" in the "Add an activity or resource" "dialogue"
And I press the tab key
And I press the tab key
And I press the tab key
And I press the tab key
# Confirm right key works
And I press the right key
And I press the right key
And the focused element is "Chat" "menuitem" in the "Add an activity or resource" "dialogue"
# Confirm left key works
And I press the left key
And the focused element is "Book" "menuitem" in the "Add an activity or resource" "dialogue"
# Confirm clicking "x" button closes modal
And I click on "Close" "button" in the "Add an activity or resource" "dialogue"
And "Add an activity or resource" "dialogue" should not be visible
And I click on "Add an activity or resource" "button" in the "Topic 1" "section"
# Confirm escape key closes the modal
And I press the escape key
And "Add an activity or resource" "dialogue" should not be visible

Scenario: Teacher can navigate through activity chooser in Weekly format course
Given I am on "C2" course homepage with editing mode on
When I click on "Add an activity or resource" "button" in the "13 January - 19 January" "section"
Then I should see "All" in the "Add an activity or resource" "dialogue"
And I press the tab key
And I press the tab key
And I press the tab key
And I press the tab key
# Confirm right key works
And I press the right key
And I press the right key
And the focused element is "Chat" "menuitem" in the "Add an activity or resource" "dialogue"
# Confirm left key works
And I press the left key
And the focused element is "Book" "menuitem" in the "Add an activity or resource" "dialogue"
# Confirm clicking "x" button closes modal
And I click on "Close" "button" in the "Add an activity or resource" "dialogue"
And "Add an activity or resource" "dialogue" should not be visible
And I click on "Add an activity or resource" "button" in the "13 January - 19 January" "section"
# Confirm escape key closes the modal
And I press the escape key
And "Add an activity or resource" "dialogue" should not be visible

Scenario: Teacher can access 'More help' from activity information in activity chooser
Given I click on "Add an activity or resource" "button" in the "Topic 1" "section"
When I click on "Information about the Assignment activity" "button" in the "Add an activity or resource" "dialogue"
# Confirm more help link exists
Then "More help" "link" should exist
# Confirm that corresponding help icon exist
And ".iconhelp" "css_element" should exist
# Confirm that link opens in new window
And "Opens in new window" "link" should be visible
# Confirm the same behaviour for weekly format course
And I am on "C2" course homepage with editing mode on
And I click on "Add an activity or resource" "button" in the "13 January - 19 January" "section"
And I should see "All" in the "Add an activity or resource" "dialogue"
And I click on "Information about the Assignment activity" "button" in the "Add an activity or resource" "dialogue"
# Confirm more help link exists
And "More help" "link" should exist
# Confirm that corresponding help icon exist
And ".iconhelp" "css_element" should exist
# Confirm that link opens in new window
And "Opens in new window" "link" should be visible
Loading

0 comments on commit afbe36b

Please sign in to comment.