Completed
Push — master ( 32c9ae...514091 )
by Jesus
04:47
created

bbb_broker.php ➔ bigbluebuttonbn_broker_meeting_end()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 3
nop 2
dl 0
loc 22
rs 8.9197
c 0
b 0
f 0
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
/**
18
 * Intermediator for managing actions executed by the BigBlueButton server.
19
 *
20
 * @author    Jesus Federico  (jesus [at] blindsidenetworks [dt] com)
21
 * @copyright 2015-2017 Blindside Networks Inc
22
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v2 or later
23
 */
24
25
require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
26
require_once(dirname(__FILE__).'/locallib.php');
27
28
use \Firebase\JWT\JWT;
29
30
global $PAGE, $USER, $CFG, $SESSION, $DB;
31
32
$params['action'] = optional_param('action', '', PARAM_TEXT);
33
$params['callback'] = optional_param('callback', '', PARAM_TEXT);
34
$params['id'] = optional_param('id', '', PARAM_TEXT);
35
$params['idx'] = optional_param('idx', '', PARAM_TEXT);
36
$params['bigbluebuttonbn'] = optional_param('bigbluebuttonbn', 0, PARAM_INT);
37
$params['signed_parameters'] = optional_param('signed_parameters', '', PARAM_TEXT);
38
$params['forced'] = optional_param('forced', 'false', PARAM_TEXT);
39
$params['meta'] = optional_param('meta', '', PARAM_TEXT);
40
41
if (empty($params['action'])) {
42
    header('HTTP/1.0 400 Bad Request. Parameter ['.$params['action'].'] was not included');
43
    return;
44
}
45
46
$error = bigbluebuttonbn_broker_validate_parameters($params);
47
if (!empty($error)) {
48
    header('HTTP/1.0 400 Bad Request. '.$error);
49
    return;
50
}
51
52
if (isset($params['bigbluebuttonbn']) && $params['bigbluebuttonbn'] != 0) {
53
    $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', array('id' => $params['bigbluebuttonbn']), '*', MUST_EXIST);
54
    $course = $DB->get_record('course', array('id' => $bigbluebuttonbn->course), '*', MUST_EXIST);
55
    $cm = get_coursemodule_from_instance('bigbluebuttonbn', $bigbluebuttonbn->id, $course->id, false, MUST_EXIST);
56
    $context = context_module::instance($cm->id);
57
}
58
59
if ($params['action'] != 'recording_ready' && $params['action'] != 'live_session_events') {
60
    if (!isset($SESSION->bigbluebuttonbn_bbbsession) || is_null($SESSION->bigbluebuttonbn_bbbsession)) {
61
        header('HTTP/1.0 400 Bad Request. No session variable set');
62
        return;
63
    }
64
    $bbbsession = $SESSION->bigbluebuttonbn_bbbsession;
65
}
66
67
if (!isloggedin() && $PAGE->course->id == SITEID) {
68
    $userid = guest_user()->id;
69
} else {
70
    $userid = $USER->id;
71
}
72
$hascourseaccess = ($PAGE->course->id == SITEID) || can_access_course($PAGE->course, $userid);
73
74
if (!$hascourseaccess) {
75
    header('HTTP/1.0 401 Unauthorized');
76
    return;
77
}
78
79
$type = null;
80
if (isset($bbbsession['bigbluebuttonbn']->type)) {
81
    $type = $bbbsession['bigbluebuttonbn']->type;
82
}
83
84
$typeprofiles = bigbluebuttonbn_get_instance_type_profiles();
85
$enabledfeatures = bigbluebuttonbn_get_enabled_features($typeprofiles, $type);
86
try {
87
    header('Content-Type: application/javascript; charset=utf-8');
88
    $a = strtolower($params['action']);
89
    if ($a == 'meeting_info') {
90
        $meetinginfo = bigbluebuttonbn_broker_meeting_info($bbbsession, $params, ($params['forced'] == 'true'));
91
        echo $meetinginfo;
92
        return;
93
    }
94
95
    if ($a == 'meeting_end') {
96
        $meetingend = bigbluebuttonbn_broker_meeting_end($bbbsession, $params);
97
        echo $meetingend;
98
        return;
99
    }
100
101
    if ($a == 'recording_play') {
102
        $recordingplay = bigbluebuttonbn_broker_recording_play($bbbsession, $params, $enabledfeatures['showroom']);
103
        echo $recordingplay;
104
        return;
105
    }
106
107
    if ($a == 'recording_links') {
108
        $recordinglinks = bigbluebuttonbn_broker_recording_links($bbbsession, $params);
109
        echo $recordinglinks;
110
        return;
111
    }
112
113
    if ($a == 'recording_info') {
114
        $recordinginfo = bigbluebuttonbn_broker_recording_info($bbbsession, $params, $enabledfeatures['showroom']);
115
        echo $recordinginfo;
116
        return;
117
    }
118
119
    if ($a == 'recording_publish' || $a == 'recording_unpublish' || $a == 'recording_delete' || $a == 'recording_edit') {
120
        $recordingaction = bigbluebuttonbn_broker_recording_action($bbbsession, $params, $enabledfeatures['showroom']);
121
        echo $recordingaction;
122
        return;
123
    }
124
125
    if ($a == 'recording_import') {
126
        echo bigbluebuttonbn_broker_recording_import($bbbsession, $params);
127
        return;
128
    }
129
130
    if ($a == 'recording_ready') {
131
        bigbluebuttonbn_broker_recording_ready($params, $bigbluebuttonbn);
132
        return;
133
    }
134
135
    if ($a == 'live_session_events') {
136
        bigbluebuttonbn_broker_live_session_events($params, $bigbluebuttonbn, $cm);
137
        return;
138
    }
139
140
    header('HTTP/1.0 400 Bad request. The action '. $a . ' doesn\'t exist');
141
    return;
142
143
} catch (Exception $e) {
144
    header('HTTP/1.0 500 Internal Server Error. '.$e->getMessage());
145
    return;
146
}
147
148
function bigbluebuttonbn_broker_meeting_info($bbbsession, $params, $forced) {
149
    $callbackresponse = array();
150
151
    $info = bigbluebuttonbn_get_meeting_info($params['id'], $forced);
152
    $callbackresponse['info'] = $info;
153
154
    $running = false;
155
    if ($info['returncode'] == 'SUCCESS') {
156
        $running = ($info['running'] === 'true');
157
    }
158
    $callbackresponse['running'] = $running;
159
160
    $status = array();
161
    $status["join_url"] = $bbbsession['joinURL'];
162
    $status["join_button_text"] = get_string('view_conference_action_join', 'bigbluebuttonbn');
163
    $status["end_button_text"] = get_string('view_conference_action_end', 'bigbluebuttonbn');
164
165
    $participantcount = 0;
166
    if (isset($info['participantCount'])) {
167
        $participantcount = $info['participantCount'];
168
    }
169
    $canjoin = bigbluebuttonbn_broker_meeting_info_can_join($bbbsession, $running, $participantcount);
170
    $status["can_join"] = $canjoin["can_join"];
171
    $status["message"] = $canjoin["message"];
172
173
    $canend = bigbluebuttonbn_broker_meeting_info_can_end($bbbsession, $running);
174
    $status["can_end"] = $canend["can_end"];
175
176
    $callbackresponse['status'] = $status;
177
178
    $callbackresponsedata = json_encode($callbackresponse);
179
    return "{$params['callback']}({$callbackresponsedata});";
180
}
181
182
function bigbluebuttonbn_broker_meeting_info_can_join($bbbsession, $running, $participantcount) {
183
    $status = array("can_join" => false);
184
    if ($running) {
185
        $status["message"] = get_string('view_error_userlimit_reached', 'bigbluebuttonbn');
186 View Code Duplication
        if ($bbbsession['userlimit'] == 0 || $participantcount < $bbbsession['userlimit']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
187
            $status["message"] = get_string('view_message_conference_in_progress', 'bigbluebuttonbn');
188
            $status["can_join"] = true;
189
        }
190
        return $status;
191
    }
192
193
    // If user is administrator, moderator or if is viewer and no waiting is required.
194
    $status["message"] = get_string('view_message_conference_wait_for_moderator', 'bigbluebuttonbn');
195 View Code Duplication
    if ($bbbsession['administrator'] || $bbbsession['moderator'] || !$bbbsession['wait']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
196
        $status["message"] = get_string('view_message_conference_room_ready', 'bigbluebuttonbn');
197
        $status["can_join"] = true;
198
    }
199
    return $status;
200
}
201
202
function bigbluebuttonbn_broker_meeting_info_can_end($bbbsession, $running) {
203
    $status = array("can_end" => false);
204
    if ($running && ($bbbsession['administrator'] || $bbbsession['moderator'])) {
205
        $status["can_end"] = true;
206
    }
207
    return $status;
208
}
209
210
function bigbluebuttonbn_broker_meeting_end($bbbsession, $params) {
211
212
    if (!$bbbsession['administrator'] && !$bbbsession['moderator']) {
213
        header('HTTP/1.0 401 Unauthorized. User not authorized to execute end command');
214
        return;
215
    }
216
217
    $callbackresponse = array('status' => true);
218
219
    // Execute the end command.
220
    bigbluebuttonbn_end_meeting($params['id'], $bbbsession['modPW']);
221
    // Moodle event logger: Create an event for meeting ended.
222
    if (isset($bigbluebuttonbn)) {
223
        bigbluebuttonbn_event_log(BIGBLUEBUTTON_EVENT_MEETING_ENDED, $bbbsession['bigbluebuttonbn'],
224
            $bbbsession['cm']);
225
    }
226
    // Update the cache.
227
    bigbluebuttonbn_get_meeting_info($params['id'], BIGBLUEBUTTONBN_FORCED);
228
229
    $callbackresponsedata = json_encode($callbackresponse);
230
    return "{$params['callback']}({$callbackresponsedata});";
231
}
232
233
function bigbluebuttonbn_broker_recording_links($bbbsession, $params) {
234
235
    if (!$bbbsession['managerecordings']) {
236
        header('HTTP/1.0 401 Unauthorized. User not authorized to execute end command');
237
        return;
238
    }
239
240
    $callbackresponse = array('status' => false);
241
242
    if (isset($params['id']) && $params['id'] != '') {
243
        $importedall = bigbluebuttonbn_get_recording_imported_instances($params['id']);
244
        $callbackresponse['status'] = true;
245
        $callbackresponse['links'] = count($importedall);
246
    }
247
    $callbackresponsedata = json_encode($callbackresponse);
248
    return "{$params['callback']}({$callbackresponsedata});";
249
}
250
251
function bigbluebuttonbn_broker_recording_info($bbbsession, $params, $showroom) {
252
253
    if (!$bbbsession['managerecordings']) {
254
        header('HTTP/1.0 401 Unauthorized. User not authorized to execute end command');
255
        return;
256
    }
257
258
    $callbackresponse = array('status' => false);
259
260
    $courseid = $bbbsession['course']->id;
261
    $bigbluebuttonbnid = null;
262
    if ($showroom) {
263
        $bigbluebuttonbnid = $bbbsession['bigbluebuttonbn']->id;
264
    }
265
    $includedeleted = $bbbsession['bigbluebuttonbn']->recordings_deleted_activities;
266
    // Retrieve the array of imported recordings.
267
    $recordings = bigbluebuttonbn_get_recordings($courseid, $bigbluebuttonbnid, $showroom, $includedeleted);
268
    if (array_key_exists($params['id'], $recordings)) {
269
        // Look up for an update on the imported recording.
270 View Code Duplication
        if (!array_key_exists('messageKey', $recordings[$params['id']])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
271
            // The recording was found.
272
            $callbackresponse = bigbluebuttonbn_broker_recording_info_current($recordings[$params['id']], $params);
273
        }
274
        $callbackresponsedata = json_encode($callbackresponse);
275
        return "{$params['callback']}({$callbackresponsedata});";
276
    }
277
278
    // As the recordingid was not identified as imported recording link, look up for a real recording.
279
    $recordings = bigbluebuttonbn_get_recordings_array($params['idx'], $params['id']);
280 View Code Duplication
    if (array_key_exists($params['id'], $recordings)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
281
        // The recording was found.
282
        $callbackresponse = bigbluebuttonbn_broker_recording_info_current($recordings[$params['id']], $params);
283
    }
284
    $callbackresponsedata = json_encode($callbackresponse);
285
    return "{$params['callback']}({$callbackresponsedata});";
286
}
287
288
function bigbluebuttonbn_broker_recording_info_current($recording, $params) {
289
    $callbackresponse['status'] = true;
290
    $callbackresponse['published'] = (string) $recording['published'];
291
    if (!isset($params['meta'])) {
292
        return $callbackresponse;
293
    }
294
295
    $meta = json_decode($params['meta'], true);
296
    foreach (array_keys($meta) as $key) {
297
        if (isset($recording[$key])) {
298
            $callbackresponse[$key] = $recording[$key];
299
        }
300
    }
301
    return $callbackresponse;
302
}
303
304
function bigbluebuttonbn_broker_recording_play($bbbsession, $params, $showroom) {
0 ignored issues
show
Unused Code introduced by
The parameter $showroom is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
305
    $action = strtolower($params['action']);
306
    $events = bigbluebuttonbn_events_action();
307
308
    // Excecute action.
309
    $eventlog = $events[$action];
310
    // Moodle event logger: Create an event for action performed on recording.
311
    bigbluebuttonbn_event_log($eventlog, $bbbsession['bigbluebuttonbn'], $bbbsession['cm'],
312
        ['other' => $params['id']]);
313
314
    $callbackresponsedata = json_encode(array('status' => true));
315
    return "{$params['callback']}({$callbackresponsedata});";
316
}
317
318
function bigbluebuttonbn_broker_recording_action($bbbsession, $params, $showroom) {
319
    if (!$bbbsession['managerecordings']) {
320
        header('HTTP/1.0 401 Unauthorized. User not authorized to execute end command');
321
        return;
322
    }
323
324
    // Retrieve array of recordings that includes real and imported.
325
    $bigbluebuttonbnid = null;
326
    if ($showroom) {
327
        $bigbluebuttonbnid = $bbbsession['bigbluebuttonbn']->id;
328
    }
329
    $recordings = bigbluebuttonbn_get_recordings($bbbsession['course']->id, $bigbluebuttonbnid, $showroom,
330
        $bbbsession['bigbluebuttonbn']->recordings_deleted_activities);
331
332
    $action = strtolower($params['action']);
333
    $events = bigbluebuttonbn_events_action();
334
335
    // Excecute action.
336
    $eventlog = $events[$action];
337
    $callbackresponse = bigbluebuttonbn_broker_recording_action_perform($action, $bbbsession, $params, $recordings);
338
    if ($callbackresponse['status']) {
339
        // Moodle event logger: Create an event for action performed on recording.
340
        bigbluebuttonbn_event_log($eventlog, $bbbsession['bigbluebuttonbn'], $bbbsession['cm'],
341
            ['other' => $params['id']]);
342
    }
343
344
    $callbackresponsedata = json_encode($callbackresponse);
345
    return "{$params['callback']}({$callbackresponsedata});";
346
}
347
348
function bigbluebuttonbn_broker_recording_action_perform($action, $bbbsession, $params, $recordings) {
349
    if ($action == 'recording_publish') {
350
        return bigbluebuttonbn_broker_recording_action_publish($bbbsession, $params, $recordings);
351
    }
352
    if ($action == 'recording_unpublish') {
353
        return bigbluebuttonbn_broker_recording_action_unpublish($bbbsession, $params, $recordings);
354
    }
355
    if ($action == 'recording_edit') {
356
        return bigbluebuttonbn_broker_recording_action_edit($bbbsession, $params, $recordings);
357
    }
358
    if ($action == 'recording_delete') {
359
        return bigbluebuttonbn_broker_recording_action_delete($bbbsession, $params, $recordings);
360
    }
361
}
362
363
function bigbluebuttonbn_broker_recording_action_publish($bbbsession, $params, $recordings) {
364
    $status = true;
365
    if (bigbluebuttonbn_broker_recording_is_imported($recordings, $params['id'])) {
366
        // Execute publish on imported recording link, if the real recording is published.
367
        $realrecordings = bigbluebuttonbn_get_recordings_array(
368
            $recordings[$params['id']]['meetingID'], $recordings[$params['id']]['recordID']);
369
        $status = ($realrecordings[$params['id']]['published'] === 'true');
370
        if ($status) {
371
            // Only if the physical recording is published, execute publish on imported recording link.
372
            bigbluebuttonbn_publish_recording_imported($params['id'], $bbbsession['bigbluebuttonbn']->id, true);
373
        }
374
    } else {
375
        // As the recordingid was not identified as imported recording link, execute publish on a real recording.
376
        bigbluebuttonbn_publish_recordings($params['id'], 'true');
377
    }
378
379
    $response = array('status' => $status);
380
    if (!$status) {
381
        $response['message'] = get_string('view_recording_publish_link_error', 'bigbluebuttonbn');
382
    }
383
    return $response;
384
}
385
386
function bigbluebuttonbn_broker_recording_action_unpublish($bbbsession, $params, $recordings) {
387
    global $DB;
388
389 View Code Duplication
    if (bigbluebuttonbn_broker_recording_is_imported($recordings, $params['id'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
390
        // Execute unpublish on imported recording link.
391
        return array(
392
          'status' => bigbluebuttonbn_publish_recording_imported(
393
              $params['id'], $bbbsession['bigbluebuttonbn']->id, false
394
            )
395
          );
396
    }
397
398
    // As the recordingid was not identified as imported recording link, execute unpublish on a real recording.
399
    // First: Unpublish imported links associated to the recording.
400
    $importedall = bigbluebuttonbn_get_recording_imported_instances($params['id']);
401
402
    if ($importedall > 0) {
403
        foreach ($importedall as $key => $record) {
404
            $meta = json_decode($record->meta, true);
405
            // Prepare data for the update.
406
            $meta['recording']['published'] = 'false';
407
            $importedall[$key]->meta = json_encode($meta);
408
409
            // Proceed with the update.
410
            $DB->update_record('bigbluebuttonbn_logs', $importedall[$key]);
411
        }
412
    }
413
    // Second: Execute the real unpublish.
414
    return array(
415
      'status' => bigbluebuttonbn_publish_recordings($params['id'], 'false')
416
      );
417
}
418
419
function bigbluebuttonbn_broker_recording_action_edit($bbbsession, $params, $recordings) {
420
    if (bigbluebuttonbn_broker_recording_is_imported($recordings, $params['id'])) {
421
        // Execute update on imported recording link.
422
        return array(
423
          'status' => bigbluebuttonbn_update_recording_imported(
424
              $params['id'], $bbbsession['bigbluebuttonbn']->id, json_decode($params['meta'], true)
425
            )
426
          );
427
    }
428
429
    // As the recordingid was not identified as imported recording link, execute update on a real recording.
430
    // (No need to update imported links as the update only affects the actual recording).
431
    // Execute update on actual recording.
432
    return array(
433
      'status' => bigbluebuttonbn_update_recordings($params['id'], json_decode($params['meta']))
434
      );
435
}
436
437
function bigbluebuttonbn_broker_recording_action_delete($bbbsession, $params, $recordings) {
438
    global $DB;
439
440 View Code Duplication
    if (bigbluebuttonbn_broker_recording_is_imported($recordings, $params['id'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
441
        // Execute delete on imported recording link.
442
        return array(
443
          'status' => bigbluebuttonbn_delete_recording_imported(
444
              $params['id'], $bbbsession['bigbluebuttonbn']->id
445
            )
446
          );
447
    }
448
449
    // As the recordingid was not identified as imported recording link, execute delete on a real recording.
450
    // Delete imported links associated to the recording.
451
    $importedall = bigbluebuttonbn_get_recording_imported_instances($params['id']);
452
453
    if ($importedall > 0) {
454
        foreach (array_keys($importedall) as $key) {
455
            // Execute delete on imported links.
456
            $DB->delete_records('bigbluebuttonbn_logs', array('id' => $key));
457
        }
458
    }
459
    // Execute the actual delete.
460
    return array(
461
      'status' => bigbluebuttonbn_delete_recordings($params['id'])
462
      );
463
}
464
465
function bigbluebuttonbn_broker_recording_ready($params, $bigbluebuttonbn) {
466
467
    // Decodes the received JWT string.
468
    try {
469
        $decodedparameters = JWT::decode($params['signed_parameters'], bigbluebuttonbn_get_cfg_shared_secret(),
470
            array('HS256'));
471
    } catch (Exception $e) {
472
        $error = 'Caught exception: '.$e->getMessage();
473
        header('HTTP/1.0 400 Bad Request. '.$error);
474
        return;
475
    }
476
477
    // Validate that the bigbluebuttonbn activity corresponds to the meeting_id received.
478
    $meetingidelements = explode('[', $decodedparameters->meeting_id);
479
    $meetingidelements = explode('-', $meetingidelements[0]);
480
481
    if (!isset($bigbluebuttonbn) || $bigbluebuttonbn->meetingid != $meetingidelements[0]) {
482
        header('HTTP/1.0 410 Gone. The activity may have been deleted');
483
        return;
484
    }
485
486
    // Sends the messages.
487
    try {
488
        bigbluebuttonbn_send_notification_recording_ready($bigbluebuttonbn);
489
        header('HTTP/1.0 202 Accepted');
490
    } catch (Exception $e) {
491
        $error = 'Caught exception: '.$e->getMessage();
492
        header('HTTP/1.0 503 Service Unavailable. '.$error);
493
    }
494
}
495
496
function bigbluebuttonbn_broker_recording_import($bbbsession, $params) {
497
    global $SESSION;
498
499
    if (!$bbbsession['managerecordings']) {
500
        header('HTTP/1.0 401 Unauthorized. User not authorized to execute end command');
501
        return;
502
    }
503
504
    $importrecordings = $SESSION->bigbluebuttonbn_importrecordings;
505
    if (!isset($importrecordings[$params['id']])) {
506
        $error = "Recording {$params['id']} could not be found. It can not be imported";
507
        header('HTTP/1.0 404 Not found. '.$error);
508
        return;
509
    }
510
511
    $callbackresponse = array('status' => true);
512
513
    $importrecordings[$params['id']]['imported'] = true;
514
    $overrides = array('meetingid' => $importrecordings[$params['id']]['meetingID']);
515
    $meta = '{"recording":'.json_encode($importrecordings[$params['id']]).'}';
516
    bigbluebuttonbn_logs($bbbsession, BIGBLUEBUTTONBN_LOG_EVENT_IMPORT, $overrides, $meta);
517
    // Moodle event logger: Create an event for recording imported.
518
    if (isset($bbbsession['bigbluebutton']) && isset($bbbsession['cm'])) {
519
        bigbluebuttonbn_event_log(BIGBLUEBUTTON_EVENT_RECORDING_IMPORTED, $bbbsession['bigbluebuttonbn'],
520
            $bbbsession['cm'], ['other' => $params['id']]);
521
    }
522
523
    $callbackresponsedata = json_encode($callbackresponse);
524
    return "{$params['callback']}({$callbackresponsedata});";
525
}
526
527
function bigbluebuttonbn_broker_live_session_events($params, $bigbluebuttonbn, $cm) {
528
    // Decodes the received JWT string.
529
    try {
530
        $decodedparameters = JWT::decode($params['signed_parameters'], bigbluebuttonbn_get_cfg_shared_secret(),
531
            array('HS256'));
532
    } catch (Exception $e) {
533
        $error = 'Caught exception: '.$e->getMessage();
534
        header('HTTP/1.0 400 Bad Request. '.$error);
535
        return;
536
    }
537
538
    // Validate that the bigbluebuttonbn activity corresponds to the meeting_id received.
539
    $meetingidelements = explode('[', $decodedparameters->meeting_id);
540
    $meetingidelements = explode('-', $meetingidelements[0]);
541
542
    if (!isset($bigbluebuttonbn) || $bigbluebuttonbn->meetingid != $meetingidelements[0]) {
543
        header('HTTP/1.0 410 Gone. The activity may have been deleted');
544
        return;
545
    }
546
547
    // Store the events.
548
    try {
549
        foreach ($decodedparameters->events as $event) {
550
            bigbluebuttonbn_live_session_event_log($event, $bigbluebuttonbn, $cm);
551
        }
552
        header('HTTP/1.0 202 Accepted');
553
    } catch (Exception $e) {
554
        $error = "Caught exception: {$e->getMessage()}";
555
        header("HTTP/1.0 503 Service Unavailable. {$error}");
556
    }
557
}
558
559
function bigbluebuttonbn_broker_validate_parameters($params) {
560
    $requiredparams = bigbluebuttonbn_broker_required_parameters();
561
562
    if (!isset($params['callback'])) {
563
        return 'This call must include a javascript callback.';
564
    }
565
566
    if (!isset($params['action'])) {
567
        return 'Action parameter must be included.';
568
    }
569
570
    $action = strtolower($params['action']);
571
    if (!array_key_exists($action, $requiredparams)) {
572
        return 'Action '.$params['action'].' can not be performed.';
573
    }
574
575
    return bigbluebuttonbn_broker_validate_parameters_message($params, $requiredparams[$action]);
576
}
577
578
function bigbluebuttonbn_broker_validate_parameters_message($params, $requiredparams) {
579
    foreach ($requiredparams as $param => $message) {
580
        if (!array_key_exists($param, $params) || $params[$param] == '') {
581
            return $message;
582
        }
583
    }
584
}
585
586
function bigbluebuttonbn_broker_required_parameters() {
587
    $params['server_ping'] = ['id' => 'The meetingID must be specified.'];
588
    $params['meeting_info'] = ['id' => 'The meetingID must be specified.'];
589
    $params['meeting_end'] = ['id' => 'The meetingID must be specified.'];
590
    $params['recording_play'] = ['id' => 'The recordingID must be specified.'];
591
    $params['recording_info'] = ['id' => 'The recordingID must be specified.'];
592
    $params['recording_links'] = ['id' => 'The recordingID must be specified.'];
593
    $params['recording_publish'] = ['id' => 'The recordingID must be specified.'];
594
    $params['recording_unpublish'] = ['id' => 'The recordingID must be specified.'];
595
    $params['recording_delete'] = ['id' => 'The recordingID must be specified.'];
596
    $params['recording_protect'] = ['id' => 'The recordingID must be specified.'];
597
    $params['recording_unprotect'] = ['id' => 'The recordingID must be specified.'];
598
    $params['recording_edit'] = ['id' => 'The recordingID must be specified.',
599
            'meta' => 'A meta parameter should be included'];
600
    $params['recording_import'] = ['id' => 'The recordingID must be specified.'];
601
    $params['recording_ready'] = [
602
            'signed_parameters' => 'A JWT encoded string must be included as [signed_parameters].'
603
          ];
604
    $params['live_session_events'] = [
605
            'signed_parameters' => 'A JWT encoded string must be included as [signed_parameters].'
606
          ];
607
    return $params;
608
}
609
610
function bigbluebuttonbn_broker_recording_is_imported($recordings, $recordingid) {
611
    return (isset($recordings[$recordingid]) && isset($recordings[$recordingid]['imported']));
612
}
613