See Release Notes
Long Term Support Release
Differences Between: [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace quizaccess_seb\external; 18 19 defined('MOODLE_INTERNAL') || die(); 20 21 global $CFG; 22 23 use external_api; 24 use external_function_parameters; 25 use external_single_structure; 26 use external_value; 27 use invalid_parameter_exception; 28 use quiz; 29 use quizaccess_seb\event\access_prevented; 30 use quizaccess_seb\access_manager; 31 32 require_once($CFG->dirroot . '/mod/quiz/accessmanager.php'); 33 require_once($CFG->dirroot . '/mod/quiz/attemptlib.php'); 34 require_once($CFG->libdir . '/externallib.php'); 35 36 /** 37 * Validate browser exam key and config key. 38 * 39 * @package quizaccess_seb 40 * @author Andrew Madden <andrewmadden@catalyst-au.net> 41 * @copyright 2021 Catalyst IT 42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 43 */ 44 class validate_quiz_keys extends external_api { 45 46 /** 47 * External function parameters. 48 * 49 * @return external_function_parameters 50 */ 51 public static function execute_parameters(): external_function_parameters { 52 return new external_function_parameters([ 53 'cmid' => new external_value(PARAM_INT, 'Course module ID', 54 VALUE_REQUIRED, null, NULL_NOT_ALLOWED), 55 'url' => new external_value(PARAM_URL, 'Page URL to check', 56 VALUE_REQUIRED, null, NULL_NOT_ALLOWED), 57 'configkey' => new external_value(PARAM_ALPHANUMEXT, 'SEB config key', 58 VALUE_DEFAULT, null), 59 'browserexamkey' => new external_value(PARAM_ALPHANUMEXT, 'SEB browser exam key', 60 VALUE_DEFAULT, null), 61 ]); 62 } 63 64 /** 65 * Validate a SEB config key or browser exam key. 66 * 67 * @param string $cmid Course module ID. 68 * @param string $url URL of the page on which the SEB JS API generated the keys. 69 * @param string|null $configkey A SEB config key hash. Includes URL in the hash. 70 * @param string|null $browserexamkey A SEB browser exam key hash. Includes the URL in the hash. 71 * @return array 72 */ 73 public static function execute(string $cmid, string $url, ?string $configkey = null, ?string $browserexamkey = null): array { 74 list( 75 'cmid' => $cmid, 76 'url' => $url, 77 'configkey' => $configkey, 78 'browserexamkey' => $browserexamkey 79 ) = self::validate_parameters(self::execute_parameters(), [ 80 'cmid' => $cmid, 81 'url' => $url, 82 'configkey' => $configkey, 83 'browserexamkey' => $browserexamkey, 84 ]); 85 86 self::validate_context(\context_module::instance($cmid)); 87 88 // At least one SEB key must be provided. 89 if (empty($configkey) && empty($browserexamkey)) { 90 throw new invalid_parameter_exception(get_string('error:ws:nokeyprovided', 'quizaccess_seb')); 91 } 92 93 // Check quiz exists corresponding to cmid. 94 if (($quizid = self::get_quiz_id($cmid)) === 0) { 95 throw new invalid_parameter_exception(get_string('error:ws:quiznotexists', 'quizaccess_seb', $cmid)); 96 } 97 98 $result = ['configkey' => true, 'browserexamkey' => true]; 99 100 $accessmanager = new access_manager(quiz::create($quizid)); 101 102 // Check if there is a valid config key. 103 if (!$accessmanager->validate_config_key($configkey, $url)) { 104 access_prevented::create_strict($accessmanager, get_string('invalid_config_key', 'quizaccess_seb'), 105 $configkey, $browserexamkey)->trigger(); 106 $result['configkey'] = false; 107 } 108 109 // Check if there is a valid browser exam key. 110 if (!$accessmanager->validate_browser_exam_key($browserexamkey, $url)) { 111 access_prevented::create_strict($accessmanager, get_string('invalid_browser_key', 'quizaccess_seb'), 112 $configkey, $browserexamkey)->trigger(); 113 $result['browserexamkey'] = false; 114 } 115 116 if ($result['configkey'] && $result['browserexamkey']) { 117 // Set the state of the access for this Moodle session. 118 $accessmanager->set_session_access(true); 119 } 120 121 return $result; 122 } 123 124 /** 125 * External function returns. 126 * 127 * @return external_single_structure 128 */ 129 public static function execute_returns(): external_single_structure { 130 return new external_single_structure([ 131 'configkey' => new external_value(PARAM_BOOL, 'Is a provided config key valid?', 132 VALUE_REQUIRED, 0, NULL_NOT_ALLOWED), 133 'browserexamkey' => new external_value(PARAM_BOOL, 'Is a provided browser exam key valid?', 134 VALUE_REQUIRED, 0, NULL_NOT_ALLOWED) 135 ]); 136 } 137 138 /** 139 * Check if there is a valid quiz corresponding to a course module it. 140 * 141 * @param string $cmid Course module ID. 142 * @return int Returns quiz id if cmid matches valid quiz, or 0 if there is no match. 143 */ 144 private static function get_quiz_id(string $cmid): int { 145 $quizid = 0; 146 147 $coursemodule = get_coursemodule_from_id('quiz', $cmid); 148 if (!empty($coursemodule)) { 149 $quizid = $coursemodule->instance; 150 } 151 152 return $quizid; 153 } 154 } 155
title
Description
Body
title
Description
Body
title
Description
Body
title
Body