Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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 core_external\external_api;
24
use core_external\external_function_parameters;
25
use core_external\external_single_structure;
26
use core_external\external_value;
27
use invalid_parameter_exception;
28
use mod_quiz\quiz_settings;
29
use quizaccess_seb\event\access_prevented;
30
use quizaccess_seb\seb_access_manager;
31
 
32
/**
33
 * Validate browser exam key and config key.
34
 *
35
 * @package    quizaccess_seb
36
 * @author     Andrew Madden <andrewmadden@catalyst-au.net>
37
 * @copyright  2021 Catalyst IT
38
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39
 */
40
class validate_quiz_keys extends external_api {
41
 
42
    /**
43
     * External function parameters.
44
     *
45
     * @return external_function_parameters
46
     */
47
    public static function execute_parameters(): external_function_parameters {
48
        return new external_function_parameters([
49
           'cmid' => new external_value(PARAM_INT, 'Course module ID',
50
                VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
51
           'url' => new external_value(PARAM_URL, 'Page URL to check',
52
                VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
53
           'configkey' => new external_value(PARAM_ALPHANUMEXT, 'SEB config key',
54
                VALUE_DEFAULT, null),
55
           'browserexamkey' => new external_value(PARAM_ALPHANUMEXT, 'SEB browser exam key',
56
                VALUE_DEFAULT, null),
57
        ]);
58
    }
59
 
60
    /**
61
     * Validate a SEB config key or browser exam key.
62
     *
63
     * @param string $cmid Course module ID.
64
     * @param string $url URL of the page on which the SEB JS API generated the keys.
65
     * @param string|null $configkey A SEB config key hash. Includes URL in the hash.
66
     * @param string|null $browserexamkey A SEB browser exam key hash. Includes the URL in the hash.
67
     * @return array
68
     */
69
    public static function execute(string $cmid, string $url, ?string $configkey = null, ?string $browserexamkey = null): array {
70
        list(
71
                'cmid' => $cmid,
72
                'url' => $url,
73
                'configkey' => $configkey,
74
                'browserexamkey' => $browserexamkey
75
            ) = self::validate_parameters(self::execute_parameters(), [
76
            'cmid' => $cmid,
77
            'url' => $url,
78
            'configkey' => $configkey,
79
            'browserexamkey' => $browserexamkey,
80
        ]);
81
 
82
        self::validate_context(\context_module::instance($cmid));
83
 
84
        // At least one SEB key must be provided.
85
        if (empty($configkey) && empty($browserexamkey)) {
86
            throw new invalid_parameter_exception(get_string('error:ws:nokeyprovided', 'quizaccess_seb'));
87
        }
88
 
89
        // Check quiz exists corresponding to cmid.
90
        if (($quizid = self::get_quiz_id($cmid)) === 0) {
91
            throw new invalid_parameter_exception(get_string('error:ws:quiznotexists', 'quizaccess_seb', $cmid));
92
        }
93
 
94
        $result = ['configkey' => true, 'browserexamkey' => true];
95
 
96
        $accessmanager = new seb_access_manager(quiz_settings::create($quizid));
97
 
98
        // Check if there is a valid config key.
99
        if (!$accessmanager->validate_config_key($configkey, $url)) {
100
            access_prevented::create_strict($accessmanager, get_string('invalid_config_key', 'quizaccess_seb'),
101
                    $configkey, $browserexamkey)->trigger();
102
            $result['configkey'] = false;
103
        }
104
 
105
        // Check if there is a valid browser exam key.
106
        if (!$accessmanager->validate_browser_exam_key($browserexamkey, $url)) {
107
            access_prevented::create_strict($accessmanager, get_string('invalid_browser_key', 'quizaccess_seb'),
108
                    $configkey, $browserexamkey)->trigger();
109
            $result['browserexamkey'] = false;
110
        }
111
 
112
        if ($result['configkey'] && $result['browserexamkey']) {
113
            // Set the state of the access for this Moodle session.
114
            $accessmanager->set_session_access(true);
115
        }
116
 
117
        return $result;
118
    }
119
 
120
    /**
121
     * External function returns.
122
     *
123
     * @return external_single_structure
124
     */
125
    public static function execute_returns(): external_single_structure {
126
        return new external_single_structure([
127
            'configkey' => new external_value(PARAM_BOOL, 'Is a provided config key valid?',
128
                    VALUE_REQUIRED, 0, NULL_NOT_ALLOWED),
129
            'browserexamkey' => new external_value(PARAM_BOOL, 'Is a provided browser exam key valid?',
130
                VALUE_REQUIRED, 0, NULL_NOT_ALLOWED)
131
        ]);
132
    }
133
 
134
    /**
135
     * Check if there is a valid quiz corresponding to a course module it.
136
     *
137
     * @param string $cmid Course module ID.
138
     * @return int Returns quiz id if cmid matches valid quiz, or 0 if there is no match.
139
     */
140
    private static function get_quiz_id(string $cmid): int {
141
        $quizid = 0;
142
 
143
        $coursemodule = get_coursemodule_from_id('quiz', $cmid);
144
        if (!empty($coursemodule)) {
145
            $quizid = $coursemodule->instance;
146
        }
147
 
148
        return $quizid;
149
    }
150
}