126 lines
4.7 KiB
PHP
126 lines
4.7 KiB
PHP
<?php
|
|
// Idempotent provisioning of the privileged sync web-service user (wssync)
|
|
// used by the app to mirror chapter progression into Moodle completion.
|
|
// Run: docker cp ops/provision-sync-role.php moodle:/tmp/ &&
|
|
// docker exec -e WSSYNC_PASSWORD=... moodle php /tmp/provision-sync-role.php
|
|
define('CLI_SCRIPT', true);
|
|
require('/var/www/html/config.php');
|
|
require_once($CFG->dirroot.'/user/lib.php');
|
|
require_once($CFG->libdir.'/accesslib.php');
|
|
|
|
$systemcontext = context_system::instance();
|
|
|
|
// 1) Role `wssync` at system context with the exact caps the sync needs.
|
|
$capabilities = [
|
|
'moodle/user:create',
|
|
'moodle/user:viewdetails',
|
|
// Required so core_user_get_users_by_field returns the username/email
|
|
// fields it was queried by (user_get_user_details strips them otherwise
|
|
// and the WS silently returns []).
|
|
'moodle/user:viewalldetails',
|
|
// Required so lookups by field=email get the email field back:
|
|
// outside a course user_get_user_details() only exposes email through
|
|
// the site identity fields ($CFG->showuseridentity includes email),
|
|
// gated by this cap — Task 4 ensureMoodleUser depends on it.
|
|
'moodle/site:viewuseridentity',
|
|
'moodle/user:update',
|
|
'enrol/manual:enrol',
|
|
'moodle/course:overridecompletion',
|
|
'moodle/course:viewparticipants',
|
|
'webservice/rest:use',
|
|
// login/token.php for a non-mobile service requires createtoken (the
|
|
// mobile service only needs createmobiletoken, allowed by default).
|
|
'moodle/webservice:createtoken',
|
|
];
|
|
$role = $DB->get_record('role', ['shortname' => 'wssync']);
|
|
if (!$role) {
|
|
$roleid = create_role('WS Sync', 'wssync',
|
|
'Privileged web-service role for formations-app progression sync', '');
|
|
$role = $DB->get_record('role', ['id' => $roleid], '*', MUST_EXIST);
|
|
echo "role created: {$role->id}\n";
|
|
} else {
|
|
echo "role exists: {$role->id}\n";
|
|
}
|
|
set_role_contextlevels($role->id, [CONTEXT_SYSTEM]);
|
|
foreach ($capabilities as $cap) {
|
|
assign_capability($cap, CAP_ALLOW, $role->id, $systemcontext->id, true);
|
|
echo "cap allowed: {$cap}\n";
|
|
}
|
|
$systemcontext->mark_dirty();
|
|
|
|
// 2) Service user `wssync`
|
|
$username = 'wssync';
|
|
$password = getenv('WSSYNC_PASSWORD');
|
|
if (!$password) { fwrite(STDERR, "WSSYNC_PASSWORD required\n"); exit(1); }
|
|
$user = core_user::get_user_by_username($username);
|
|
if (!$user) {
|
|
$u = new stdClass();
|
|
$u->username = $username;
|
|
$u->password = $password;
|
|
$u->firstname = 'WS';
|
|
$u->lastname = 'Sync';
|
|
$u->email = 'wssync@saillant.cc';
|
|
$u->confirmed = 1;
|
|
$u->mnethostid = $CFG->mnet_localhost_id;
|
|
$uid = user_create_user($u, true, false);
|
|
$user = core_user::get_user($uid);
|
|
echo "user created: {$user->id}\n";
|
|
} else {
|
|
echo "user exists: {$user->id}\n";
|
|
}
|
|
|
|
// 3) Assign the role at system context (idempotent: role_assign checks dups).
|
|
role_assign($role->id, $user->id, $systemcontext->id);
|
|
echo "role assigned at system context\n";
|
|
|
|
// 4) Dedicated external service. The stock moodle_mobile_app service does
|
|
// NOT expose core_completion_override_activity_completion_status, so the
|
|
// sync token must be issued against this service instead
|
|
// (login/token.php?service=formations_sync).
|
|
require_once($CFG->dirroot.'/webservice/lib.php');
|
|
$wsmanager = new webservice();
|
|
$servicefunctions = [
|
|
'core_user_get_users_by_field',
|
|
'core_user_create_users',
|
|
'core_user_update_users',
|
|
'enrol_manual_enrol_users',
|
|
'core_course_get_contents',
|
|
'core_completion_override_activity_completion_status',
|
|
];
|
|
$service = $DB->get_record('external_services', ['shortname' => 'formations_sync']);
|
|
if (!$service) {
|
|
$serviceid = $wsmanager->add_external_service((object)[
|
|
'name' => 'Formations Sync',
|
|
'shortname' => 'formations_sync',
|
|
'enabled' => 1,
|
|
'restrictedusers' => 1,
|
|
'downloadfiles' => 0,
|
|
'uploadfiles' => 0,
|
|
]);
|
|
$service = $DB->get_record('external_services', ['id' => $serviceid], '*', MUST_EXIST);
|
|
echo "service created: {$service->id}\n";
|
|
} else {
|
|
echo "service exists: {$service->id}\n";
|
|
}
|
|
foreach ($servicefunctions as $fn) {
|
|
if (!$DB->record_exists('external_services_functions',
|
|
['externalserviceid' => $service->id, 'functionname' => $fn])) {
|
|
$wsmanager->add_external_function_to_service($fn, $service->id);
|
|
echo "service fn added: {$fn}\n";
|
|
} else {
|
|
echo "service fn exists: {$fn}\n";
|
|
}
|
|
}
|
|
if (!$DB->record_exists('external_services_users',
|
|
['externalserviceid' => $service->id, 'userid' => $user->id])) {
|
|
$wsmanager->add_ws_authorised_user((object)[
|
|
'externalserviceid' => $service->id,
|
|
'userid' => $user->id,
|
|
]);
|
|
echo "user authorised on service\n";
|
|
} else {
|
|
echo "user already authorised on service\n";
|
|
}
|
|
|
|
echo "OK\n";
|