Skip to content

Commit ec42a56

Browse files
committed
MDL-72188 quizaccess_seb: Implement Safe Exam Browser JS API.
* Replaces checking header for SEB config keys to assess quiz access. * Adds new web service accessible via Ajax * Forces the use of the new API where available * Stores access in Moodle SESSION for quiz instead of checking every page.
1 parent 16a5169 commit ec42a56

22 files changed

+1045
-68
lines changed

mod/quiz/accessrule/seb/amd/build/validate_quiz_access.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mod/quiz/accessrule/seb/amd/build/validate_quiz_access.min.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mod/quiz/accessrule/seb/amd/build/view.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mod/quiz/accessrule/seb/amd/build/view.min.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// This file is part of Moodle - http://moodle.org/
2+
//
3+
// Moodle is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// Moodle is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU General Public License
14+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
15+
16+
/**
17+
* Validate Safe Exam Browser access keys.
18+
*
19+
* @module quizaccess_seb/validate_quiz_access
20+
* @author Andrew Madden <[email protected]>
21+
* @copyright 2021 Catalyst IT
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
25+
import Ajax from 'core/ajax';
26+
import Notification from "core/notification";
27+
import * as View from 'quizaccess_seb/view';
28+
29+
// SafeExamBrowser object will be automatically initialized if using the SafeExamBrowser application.
30+
window.SafeExamBrowser = window.SafeExamBrowser || null;
31+
32+
/**
33+
* Once the keys are fetched, action checking access.
34+
*/
35+
const safeExamBrowserKeysUpdated = () => {
36+
// Action opening up the quiz.
37+
isQuizAccessValid().then((response) => {
38+
// Show the alert for an extra second to allow user to see it.
39+
setTimeout(View.clearLoadingAlert, 1000);
40+
41+
if (response.valid) {
42+
View.allowAccess();
43+
} else {
44+
View.preventAccess();
45+
}
46+
47+
return response;
48+
}).catch(err => {
49+
Notification.exception(err);
50+
View.preventAccess();
51+
});
52+
};
53+
54+
/**
55+
* Validate keys in Moodle backend.
56+
*
57+
* @return {Promise}
58+
*/
59+
const isQuizAccessValid = () => {
60+
const request = {
61+
methodname: 'quizaccess_seb_validate_quiz_access',
62+
args: {
63+
cmid: M.cfg.contextInstanceId,
64+
url: window.location.href,
65+
configkey: window.SafeExamBrowser.security.configKey,
66+
browserexamkey: window.SafeExamBrowser.security.browserExamKey
67+
},
68+
};
69+
70+
return Ajax.call([request])[0];
71+
};
72+
73+
/**
74+
* Check if the key is not yet set.
75+
*
76+
* @param {string} key config key or browser exam key.
77+
* @return {boolean}
78+
*/
79+
const isKeyEmpty = (key) => {
80+
// If the SafeExamBrowser object is defined, the default 'empty' value of the configKey and browserExamKey is ':'.
81+
return key === ":";
82+
};
83+
84+
/**
85+
* Initialize the process of fetching the keys.
86+
*/
87+
export const init = async() => {
88+
// If the SafeExamBrowser object is instantiated, try and use it to fetch the access keys.
89+
if (window.SafeExamBrowser !== null) {
90+
await View.addLoadingAlert();
91+
// If the SEB keys are already set, we can call our callback directly.
92+
93+
if (!isKeyEmpty(window.SafeExamBrowser.security.configKey) || !isKeyEmpty(window.SafeExamBrowser.security.browserExamKey)) {
94+
safeExamBrowserKeysUpdated();
95+
} else {
96+
window.SafeExamBrowser.security.updateKeys(safeExamBrowserKeysUpdated);
97+
}
98+
}
99+
};
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// This file is part of Moodle - http://moodle.org/
2+
//
3+
// Moodle is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// Moodle is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU General Public License
14+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
15+
16+
/**
17+
* Manage the quiz views.
18+
*
19+
* @module quizaccess_seb/view
20+
* @author Andrew Madden <[email protected]>
21+
* @copyright 2021 Catalyst IT
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
25+
import Notification from "core/notification";
26+
import * as Str from "core/str";
27+
import * as Templates from "core/templates";
28+
29+
/** @var SELECTOR List of CSS selectors. */
30+
const SELECTOR = {
31+
MAIN: '#region-main',
32+
LOADING: '.seb-loading',
33+
};
34+
35+
/** @var Template List of mustache templates. */
36+
const TEMPLATE = {
37+
LOADING: 'quizaccess_seb/loading',
38+
};
39+
40+
/**
41+
* Manages view when access has been granted.
42+
*/
43+
export const allowAccess = () => {
44+
window.location.reload();
45+
};
46+
47+
/**
48+
* Manages view when access has been prevented.
49+
*/
50+
export const preventAccess = () => {
51+
// Give information to end user why access was prevented.
52+
Str.get_strings([
53+
{key: 'invalidkeys', component: 'quizaccess_seb'},
54+
])
55+
.then((Strings) => {
56+
Notification.addNotification({
57+
message: Strings[0],
58+
type: "error"
59+
});
60+
return Strings;
61+
}).catch(Notification.exception);
62+
};
63+
64+
/**
65+
* Add an alert to page to inform that Safe Exam Browser access is being checked.
66+
*
67+
* @return {Promise}
68+
*/
69+
export const addLoadingAlert = () => {
70+
return Templates.render(TEMPLATE.LOADING, {}).then((html, js) => {
71+
const alertRegion = window.document.querySelector(SELECTOR.MAIN);
72+
return Templates.prependNodeContents(alertRegion, html, js);
73+
}).catch(Notification.exception);
74+
};
75+
76+
/**
77+
* Remove the Safe Exam Browser access check alert from the page.
78+
*/
79+
export const clearLoadingAlert = () => {
80+
const alert = window.document.querySelector(SELECTOR.LOADING);
81+
if (alert) {
82+
Templates.replaceNode(alert, '', '');
83+
}
84+
};

0 commit comments

Comments
 (0)