Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class auth_plugin_mumie extends auth_plugin_base {

/**
* The name of the component. Used by the configuration.
*/
Expand All @@ -60,8 +59,10 @@ public function prelogout_hook() {
global $CFG;
$tokentable = "auth_mumie_sso_tokens";

if ($DB->get_record($tokentable, ['the_user' => $USER->id])
|| $DB->get_record($tokentable, ['the_user' => auth_mumie_get_hashed_id($USER->id)])) {
if (
$DB->get_record($tokentable, ['the_user' => $USER->id])
|| $DB->get_record($tokentable, ['the_user' => auth_mumie_get_hashed_id($USER->id)])
) {
$redirecturl = "{$CFG->wwwroot}/auth/mumie/prelogout.php?sesskey={$USER->sesskey}&logoutUrl="
. json_encode(auth_mumie\mumie_server::get_all_logout_urls())
. "&redirect=" . urlencode("{$CFG->wwwroot}/login/logout.php?sesskey={$USER->sesskey}");
Expand Down
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All important changes to this plugin will be documented in this file

## TODO
### Added
- SSO when opening the Multi Problem Selector for the Problem Pool

## [v1.8.0] - 2025-05-15
### Changed
- **Code style revised:** Refactored code to comply with moodle-plugin-ci ^4 formatting standards
Expand Down
4 changes: 2 additions & 2 deletions classes/cryptography/mumie_cryptographic_key.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ public function create() {
public function update() {
global $DB;
$DB->update_record(
self::MUMIE_CRYPTOGRAPHIC_KEY_TABLE,
["name" => $this->name, "keyvalue" => $this->keyvalue, "id" => $this->id]
self::MUMIE_CRYPTOGRAPHIC_KEY_TABLE,
["name" => $this->name, "keyvalue" => $this->keyvalue, "id" => $this->id]
);
}

Expand Down
2 changes: 1 addition & 1 deletion classes/cryptography/mumie_cryptography_service.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public static function ensure_key_pair_exist(): void {
*/
public static function sign_data(string ...$data): string {
self::ensure_key_pair_exist();
openssl_sign(implode("", $data), $signeddata, self::get_private_key()->get_keyvalue(), OPENSSL_ALGO_SHA512);
openssl_sign(implode("", $data), $signeddata, self::get_private_key()->get_keyvalue(), OPENSSL_ALGO_SHA512);
return base64_encode($signeddata);
}

Expand Down
2 changes: 1 addition & 1 deletion classes/mumie_problem.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public function __construct($task) {
* @return mumie_problem
*/
public static function from_task_db_object($data) {
$task = new \stdClass;
$task = new \stdClass();
$task->link = \mod_mumie\locallib::remove_params_from_url($data->taskurl);
$headline = [((object)["language" => $data->language, "name" => $data->name])];
$task->headline = $headline;
Expand Down
2 changes: 1 addition & 1 deletion classes/mumie_server.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public function get_logout_url() {
* Get URL for XAPI grades
*/
public function get_grade_sync_url() {
return $this->urlprefix. 'public/xapi?v=' . self::MUMIE_GRADE_SYNC_VERSION;
return $this->urlprefix . 'public/xapi?v=' . self::MUMIE_GRADE_SYNC_VERSION;
}

/**
Expand Down
19 changes: 9 additions & 10 deletions classes/privacy/provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
*/
class provider implements
\core_privacy\local\metadata\provider,
\core_privacy\local\request\plugin\provider,
\core_privacy\local\request\core_userlist_provider {
\core_privacy\local\request\core_userlist_provider,
\core_privacy\local\request\plugin\provider {
/**
* Returns meta data about this system.
*
Expand Down Expand Up @@ -104,7 +104,7 @@ public static function get_contexts_for_userid(int $userid): contextlist {
}

if (count($courseids) > 0) {
list($insql, $inparams) = $DB->get_in_or_equal($courseids);
[$insql, $inparams] = $DB->get_in_or_equal($courseids);

$sql = "SELECT c.id
FROM {context} c
Expand Down Expand Up @@ -163,19 +163,18 @@ public static function export_user_data(approved_contextlist $contextlist) {
$records = $DB->get_records('auth_mumie_id_hashes', ['the_user' =>
$contextlist->get_user()->id]);
$hashes = array_map(
function($record) {
function ($record) {
return $record->hash;
},
$records
);
if ($context->contextlevel == CONTEXT_COURSE ) {
if ($context->contextlevel == CONTEXT_COURSE) {
self::export_id_hashes($hashes, $context);
}

if ($context->contextlevel == CONTEXT_USER) {
self::export_sso_tokens($hashes, $context);
}

}
}

Expand Down Expand Up @@ -213,7 +212,7 @@ private static function export_id_hashes(array $hashes, \context $context) {
private static function export_sso_tokens(array $hashes, \context $context) {
global $DB;

list($insql, $inparams) = $DB->get_in_or_equal($hashes);
[$insql, $inparams] = $DB->get_in_or_equal($hashes);

$sql = "SELECT * FROM {auth_mumie_sso_tokens}
WHERE the_user $insql";
Expand Down Expand Up @@ -290,11 +289,11 @@ public static function delete_data_for_users(approved_userlist $userlist) {
private static function delete_in_course_context(\context $context, array $userids) {
global $DB;
$courseid = $context->__get("instanceid");
list($insql, $inparams) = $DB->get_in_or_equal($userids);
[$insql, $inparams] = $DB->get_in_or_equal($userids);
$sql = "SELECT * FROM {auth_mumie_id_hashes} WHERE the_user $insql";
$records = $DB->get_records_sql($sql, $inparams);
foreach ($records as $record) {
if (strpos($record->hash, "@gradepool{$courseid}@") !== false ) {
if (strpos($record->hash, "@gradepool{$courseid}@") !== false) {
$DB->delete_records('auth_mumie_id_hashes', ['the_user' => $record->the_user, 'hash' => $record->hash]);
$DB->delete_records('auth_mumie_sso_tokens', ['the_user' => $record->hash]);
}
Expand All @@ -313,7 +312,7 @@ private static function delete_in_user_context(\context $context, array $userids
if (!is_a($context, \context_user::class)) {
return;
}
list($insql, $inparams) = $DB->get_in_or_equal($userids);
[$insql, $inparams] = $DB->get_in_or_equal($userids);
$sql = "SELECT * FROM {auth_mumie_id_hashes} WHERE the_user $insql";
$records = $DB->get_records_sql($sql, $inparams);
foreach ($records as $record) {
Expand Down
1 change: 0 additions & 1 deletion classes/sso/hash/hashing_service.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,4 @@ private static function get_hash_with_suffix(string $user, \stdClass $mumietask)
}
return $hash;
}

}
2 changes: 1 addition & 1 deletion classes/sso/sso_service.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private static function get_launch_form(sso_token $token, \stdClass $mumietask,
* @return bool
*/
private static function include_signed_deadline(string $problempath, int $deadline): bool {
return substr( $problempath, 0, 10 ) === self::WORKSHEET_PREFIX
return substr($problempath, 0, 10) === self::WORKSHEET_PREFIX
&& $deadline > 0;
}
}
6 changes: 4 additions & 2 deletions classes/sso/token/sso_token.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ public function create(): void {
"the_user" => $this->user,
"token" => $this->token,
"timecreated" => $this->timecreated,
]);
]
);
}

/**
Expand All @@ -98,7 +99,8 @@ public function update(): void {
"token" => $this->token,
"timecreated" => $this->timecreated,
"id" => $this->id,
]);
]
);
}

/**
Expand Down
1 change: 0 additions & 1 deletion externallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class auth_mumie_external extends external_api {

/**
* Describes the parameters for submit_mumieserver_form webservice.
* @return external_function_parameters
Expand Down
1 change: 0 additions & 1 deletion lang/en/auth_mumie.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,3 @@
$string['privacy:metadata:auth_mumie_tokens:tableexplanation'] = 'Details of SSO tokens used to log into MUMIE/Lemon servers';
$string['privacy:metadata:auth_mumie_tokens:timecreated'] = 'The timestamp of the user\'s last Single Sign On attempt';
$string['privacy:metadata:auth_mumie_tokens:token'] = 'Token used to verify a user\'s Single Sign On attempt to MUMIE/Lemon servers.';

1 change: 0 additions & 1 deletion mumieserver_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mumieserver_form extends moodleform {

/**
* Define fields and default values for the mumie server form
* @return void
Expand Down
17 changes: 14 additions & 3 deletions problem_selector.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,26 @@ function selection_input(?string $selection): string {
* @param string $problemlang The problem language
* @param string $origin The origin of the request
* @param string|null $selection The potential selection
* @param bool $multiselect Whether to open the selector in multi-select mode
*
* @return string The HTML representation of the problem selector form
* @throws \dml_exception
*/
function open_problem_selector(\stdClass $user, string $serverurl, string $gradingtype, string $problemlang,
string $origin, ?string $selection): string {
function open_problem_selector(
\stdClass $user,
string $serverurl,
string $gradingtype,
string $problemlang,
string $origin,
?string $selection,
bool $multiselect = false
): string {
$problemselectorurl = get_config('auth_mumie', 'mumie_problem_selector_url');
$mumieuser = mumie_user_service::get_problem_selector_user($user->id);
$ssotoken = token_service::generate_sso_token($mumieuser);
$org = get_config("auth_mumie", "mumie_org");
$selectioninput = selection_input($selection);
$multiselectinput = $multiselect ? "<input type='hidden' name='multiSelect' value='true'/>" : '';

return "
<form id='mumie_problem_selector_form' name='mumie_problem_selector_form'
Expand All @@ -77,6 +86,7 @@ function open_problem_selector(\stdClass $user, string $serverurl, string $gradi
<input type='hidden' name='problemLang' id='problemLang' type ='text' value='{$problemlang}'/>
<input type='hidden' name='origin' id='origin' type ='text' value='{$origin}'/>
{$selectioninput}
{$multiselectinput}
</form>
<script>
document.forms['mumie_problem_selector_form'].submit();
Expand All @@ -94,8 +104,9 @@ function open_problem_selector(\stdClass $user, string $serverurl, string $gradi
$origin = required_param('origin', PARAM_URL);
$contextid = required_param('contextid', PARAM_INT);
$selection = optional_param('selection', null, PARAM_STRINGID);
$multiselect = optional_param('multiselect', false, PARAM_BOOL);

$context = \context::instance_by_id($contextid);
require_capability('auth/mumie:ssotoproblemselector', $context);

echo open_problem_selector($USER, $serverurl, $gradingtype, $problemlang, $origin, $selection);
echo open_problem_selector($USER, $serverurl, $gradingtype, $problemlang, $origin, $selection, $multiselect);
45 changes: 21 additions & 24 deletions tests/privacy_provider_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
* @coversDefaultClass \auth_mumie\privacy\provider
*/
final class privacy_provider_test extends \core_privacy\tests\provider_testcase {

/**
* Test: get_contexts_for_userid returns no data for user without logins.
*
Expand Down Expand Up @@ -134,18 +133,18 @@ public function test_export_user_data_no_data(): void {
$user1 = $this->getDataGenerator()->create_user();

$approvedcontextlist1 = new \core_privacy\tests\request\approved_contextlist(
\core_user::get_user($user1->id),
'core_course',
[]
\core_user::get_user($user1->id),
'core_course',
[]
);
provider::export_user_data($approvedcontextlist1);
$writer = writer::with_context(\context_system::instance());
$this->assertFalse($writer->has_any_data_in_any_context());

$approvedcontextlist2 = new \core_privacy\tests\request\approved_contextlist(
\core_user::get_user($user1->id),
'core_user',
[]
\core_user::get_user($user1->id),
'core_user',
[]
);
provider::export_user_data($approvedcontextlist2);
$writer = writer::with_context(\context_system::instance());
Expand Down Expand Up @@ -173,12 +172,12 @@ public function test_delete_data_for_user(): void {
$this->create_login($user2, $course1);

$contextlist = new approved_contextlist(
$user1,
'core_course',
[
\context_course::instance($course1->id)->id,
\context_course::instance($course2->id)->id,
]
$user1,
'core_course',
[
\context_course::instance($course1->id)->id,
\context_course::instance($course2->id)->id,
]
);
provider::delete_data_for_user($contextlist);

Expand All @@ -190,15 +189,14 @@ public function test_delete_data_for_user(): void {
$this->create_login($user3);

$contextlist = new approved_contextlist(
$user3,
'core_user',
[context_user::instance($user3->id)->id]
$user3,
'core_user',
[context_user::instance($user3->id)->id]
);
provider::delete_data_for_user($contextlist);

$this->assertEquals([$user2->id], $DB->get_fieldset_select('auth_mumie_id_hashes', 'the_user', ''));
$this->assertCount(1, $DB->get_records('auth_mumie_sso_tokens', []));

}

/**
Expand All @@ -224,9 +222,9 @@ public function test_delete_data_for_users(): void {
$coursectx1 = context_course::instance($course1->id);

$approveduserlist1 = new \core_privacy\local\request\approved_userlist(
$coursectx1,
'core_course',
[$user1->id, $user2->id]
$coursectx1,
'core_course',
[$user1->id, $user2->id]
);

provider::delete_data_for_users($approveduserlist1);
Expand All @@ -240,9 +238,9 @@ public function test_delete_data_for_users(): void {

$userctx1 = context_user::instance($user1->id);
$approveduserlist2 = new \core_privacy\local\request\approved_userlist(
$userctx1,
'core_user',
[$user1->id, $user2->id]
$userctx1,
'core_user',
[$user1->id, $user2->id]
);

provider::delete_data_for_users($approveduserlist2);
Expand Down Expand Up @@ -313,5 +311,4 @@ protected function create_login($user, $course = null): void {

$DB->insert_record('auth_mumie_sso_tokens', (array) $ssotoken);
}

}
Loading