91334a46b5
Co-authored-by: Cursor <cursoragent@cursor.com>
264 lines
8.7 KiB
PHP
264 lines
8.7 KiB
PHP
<?php
|
|
// This file is part of Moodle - http://moodle.org/
|
|
//
|
|
// Moodle is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Moodle is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
/**
|
|
* Stepwise Adobe Connect connection tests for admin Ajax UI.
|
|
*
|
|
* @package mod_meetletacbfree
|
|
* @copyright 2026 MeetLet
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
|
|
namespace mod_meetletacbfree\local;
|
|
|
|
defined('MOODLE_INTERNAL') || die();
|
|
|
|
use mod_meetletacbfree\api\client;
|
|
use mod_meetletacbfree\api\service;
|
|
use mod_meetletacbfree\local\usererror;
|
|
use Throwable;
|
|
|
|
/**
|
|
* Runs connection checks one step at a time (session-backed).
|
|
*/
|
|
class conntest_runner {
|
|
public const STEPS = ['login', 'folders', 'user', 'sso', 'cleanup'];
|
|
|
|
/**
|
|
* Reset session scratch data for a new run.
|
|
*/
|
|
public static function reset(): void {
|
|
global $SESSION;
|
|
$SESSION->meetletacbfree_conntest = [
|
|
'service' => null,
|
|
'meetings' => null,
|
|
'scoid' => null,
|
|
'principalid' => null,
|
|
'login' => null,
|
|
'failed' => false,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array{label:string,ok:bool,detail:string,done:bool,step:string}
|
|
*/
|
|
public static function run_step(string $step): array {
|
|
global $SESSION;
|
|
|
|
\mod_meetletacbfree\registration\manager::require_registered();
|
|
|
|
if (empty($SESSION->meetletacbfree_conntest) || $step === 'login') {
|
|
self::reset();
|
|
}
|
|
$state = &$SESSION->meetletacbfree_conntest;
|
|
|
|
if (!config::is_configured()) {
|
|
return [
|
|
'step' => $step,
|
|
'label' => get_string('error', 'meetletacbfree'),
|
|
'ok' => false,
|
|
'detail' => get_string('notconfigured', 'meetletacbfree'),
|
|
'done' => true,
|
|
'abort' => true,
|
|
];
|
|
}
|
|
|
|
try {
|
|
switch ($step) {
|
|
case 'login':
|
|
return self::step_login($state);
|
|
case 'folders':
|
|
return self::step_folders($state);
|
|
case 'user':
|
|
return self::step_user($state);
|
|
case 'sso':
|
|
return self::step_sso($state);
|
|
case 'cleanup':
|
|
return self::step_cleanup($state);
|
|
default:
|
|
return [
|
|
'step' => $step,
|
|
'label' => get_string('error', 'meetletacbfree'),
|
|
'ok' => false,
|
|
'detail' => 'Unknown step',
|
|
'done' => true,
|
|
'abort' => true,
|
|
];
|
|
}
|
|
} catch (Throwable $e) {
|
|
$state['failed'] = true;
|
|
return [
|
|
'step' => $step,
|
|
'label' => get_string('error', 'meetletacbfree'),
|
|
'ok' => false,
|
|
'detail' => $e->getMessage(),
|
|
'done' => false,
|
|
'abort' => true,
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rebuild a fresh service (API client is not serializable in session).
|
|
*/
|
|
protected static function service(): service {
|
|
$service = new service();
|
|
$service->login_admin();
|
|
return $service;
|
|
}
|
|
|
|
protected static function step_login(array &$state): array {
|
|
$service = self::service();
|
|
$state['ok_login'] = true;
|
|
// Logout immediately; later steps re-login.
|
|
$service->logout();
|
|
return [
|
|
'step' => 'login',
|
|
'label' => get_string('testlogin', 'meetletacbfree'),
|
|
'ok' => true,
|
|
'detail' => '',
|
|
'done' => false,
|
|
'abort' => false,
|
|
];
|
|
}
|
|
|
|
protected static function step_folders(array &$state): array {
|
|
$service = self::service();
|
|
$content = $service->get_folder_scoid('content');
|
|
$archives = $service->get_folder_scoid('forced-archives');
|
|
$meetings = $service->get_folder_scoid('meetings');
|
|
$state['meetings'] = $meetings;
|
|
$ok = ($content && $archives && $meetings);
|
|
if (!$ok) {
|
|
$state['failed'] = true;
|
|
}
|
|
$service->logout();
|
|
return [
|
|
'step' => 'folders',
|
|
'label' => get_string('testfolders', 'meetletacbfree'),
|
|
'ok' => (bool)$ok,
|
|
'detail' => "content={$content} · archives={$archives} · meetings={$meetings}",
|
|
'done' => false,
|
|
'abort' => !$ok,
|
|
];
|
|
}
|
|
|
|
protected static function step_user(array &$state): array {
|
|
$service = self::service();
|
|
$meetings = (int)($state['meetings'] ?? 0);
|
|
if (!$meetings) {
|
|
$meetings = (int)$service->get_folder_scoid('meetings');
|
|
$state['meetings'] = $meetings;
|
|
}
|
|
$meeting = (object)[
|
|
'name' => 'meetlet_test_' . time(),
|
|
'starttime' => time(),
|
|
'endtime' => time() + HOURSECS,
|
|
'meeturl' => '',
|
|
'templatescoid' => 0,
|
|
];
|
|
$scoid = $service->create_meeting($meeting, $meetings);
|
|
$user = (object)[
|
|
'id' => random_int(900000000, 999999999),
|
|
'firstname' => 'MeetLet',
|
|
'lastname' => 'Test',
|
|
'username' => 'meetlettest' . random_int(1000, 9999),
|
|
'email' => 'meetlet.test.' . random_int(1000, 9999) . '@example.com',
|
|
];
|
|
$principal = $service->ensure_user($user);
|
|
$assigned = $service->assign_permission($principal->principalid, $scoid, service::ROLE_PRESENTER);
|
|
$state['scoid'] = $scoid;
|
|
$state['principalid'] = $principal->principalid;
|
|
$state['login'] = $principal->login;
|
|
$service->logout();
|
|
if (!$assigned) {
|
|
$state['failed'] = true;
|
|
}
|
|
return [
|
|
'step' => 'user',
|
|
'label' => get_string('testuser', 'meetletacbfree'),
|
|
'ok' => (bool)$assigned,
|
|
'detail' => '',
|
|
'done' => false,
|
|
'abort' => false,
|
|
];
|
|
}
|
|
|
|
protected static function step_sso(array &$state): array {
|
|
$directok = false;
|
|
$directdetail = '';
|
|
try {
|
|
$sso = new client();
|
|
$cookie = $sso->login_external(config::get_admin_login());
|
|
$directok = ($cookie !== '');
|
|
$directdetail = get_string('testsso_direct_ok', 'meetletacbfree');
|
|
} catch (Throwable $e) {
|
|
$msg = $e->getMessage();
|
|
$directdetail = get_string('testsso_direct_fail', 'meetletacbfree', usererror::label('sso_01') . ': ' . $msg);
|
|
}
|
|
if ($directok && !empty($state['login'])) {
|
|
try {
|
|
$sso2 = new client();
|
|
$sso2->login_external($state['login']);
|
|
$directdetail .= ' · ' . get_string('testsso_userok', 'meetletacbfree');
|
|
} catch (Throwable $e) {
|
|
$directdetail .= ' · ' . get_string('testsso_userwarn', 'meetletacbfree');
|
|
}
|
|
}
|
|
|
|
if (!$directok) {
|
|
$state['failed'] = true;
|
|
}
|
|
|
|
return [
|
|
'step' => 'sso',
|
|
'label' => get_string('testsso', 'meetletacbfree'),
|
|
'ok' => $directok,
|
|
'detail' => $directdetail,
|
|
'done' => false,
|
|
'abort' => false,
|
|
];
|
|
}
|
|
|
|
protected static function step_cleanup(array &$state): array {
|
|
$service = self::service();
|
|
$client = $service->get_client();
|
|
$ok = true;
|
|
$detail = '';
|
|
try {
|
|
if (!empty($state['scoid'])) {
|
|
$service->delete_sco((int)$state['scoid']);
|
|
}
|
|
if (!empty($state['principalid'])) {
|
|
$client->request(['action' => 'principals-delete', 'principal-id' => (int)$state['principalid']]);
|
|
}
|
|
} catch (Throwable $e) {
|
|
$ok = false;
|
|
$detail = $e->getMessage();
|
|
}
|
|
$service->logout();
|
|
self::reset();
|
|
return [
|
|
'step' => 'cleanup',
|
|
'label' => get_string('testmeeting', 'meetletacbfree'),
|
|
'ok' => $ok,
|
|
'detail' => $detail,
|
|
'done' => true,
|
|
'abort' => false,
|
|
];
|
|
}
|
|
}
|