MDL-78129 communication_matrix: Persist any user with a non-moodle power level

This commit is contained in:
Andrew Nicols
2023-09-22 10:44:04 +08:00
parent 01a3461bbb
commit 07e0094f8c
3 changed files with 51 additions and 9 deletions
@@ -563,14 +563,22 @@ class communication_feature implements
/**
* Set the matrix power level with the room.
*
* Users with a non-moodle power level are not typically removed unless specified in the $forceremoval param.
* Matrix Admin users are never removed.
*
* @param array $forceremoval The users to force removal from the room, even if they have a custom power level
*/
private function set_matrix_power_levels(): void {
private function set_matrix_power_levels(
array $forceremoval = [],
): void {
// Get the current power levels.
$currentpowerlevels = $this->get_current_powerlevel_data();
$currentuserpowerlevels = (array) $currentpowerlevels->users ?? [];
// Get all the current users who need to be in the room.
$userlist = $this->processor->get_all_userids_for_instance();
// Translate the user ids to matrix user ids.
$userlist = array_combine(
array_map(
@@ -589,15 +597,21 @@ class communication_feature implements
fn($level) => $level !== matrix_constants::POWER_LEVEL_DEFAULT,
);
// Keep current room admins without changing them.
$currentadmins = array_filter(
$currentuserpowerlevels,
fn($level) => $level >= matrix_constants::POWER_LEVEL_MAXIMUM,
);
foreach ($currentadmins as $userid => $level) {
// Keep current room admins, and users which don't use our MODERATOR power level without changing them.
$staticusers = $this->get_users_with_custom_power_level($currentuserpowerlevels);
foreach ($staticusers as $userid => $level) {
$newuserpowerlevels[$userid] = $level;
}
if (!empty($forceremoval)) {
// Remove the users from the power levels if they are not admins.
foreach ($forceremoval as $userid) {
if ($newuserpowerlevels < matrix_constants::POWER_LEVEL_MAXIMUM) {
unset($newuserpowerlevels[$userid]);
}
}
}
if (!$this->power_levels_changed($currentuserpowerlevels, $newuserpowerlevels)) {
// No changes to make.
return;
@@ -611,6 +625,29 @@ class communication_feature implements
);
}
/**
* Filter the list of users provided to remove those with a moodle-related power level.
*
* @param array $users
* @return array
*/
private function get_users_with_custom_power_level(array $users): array {
return array_filter(
$users,
function ($level): bool {
switch ($level) {
case matrix_constants::POWER_LEVEL_DEFAULT:
case matrix_constants::POWER_LEVEL_MOODLE_SITE_ADMIN:
case matrix_constants::POWER_LEVEL_MOODLE_MODERATOR:
return false;
default:
return true;
}
},
);
}
/**
* Check whether power levels have changed compared with the proposed power levels.
*
@@ -703,7 +740,7 @@ class communication_feature implements
$powerlevel = matrix_constants::POWER_LEVEL_DEFAULT;
if (has_capability('communication/matrix:moderator', $context, $userid)) {
$powerlevel = matrix_constants::POWER_LEVEL_MODERATOR;
$powerlevel = matrix_constants::POWER_LEVEL_MOODLE_MODERATOR;
}
// If site admin, override all caps.
@@ -35,6 +35,11 @@ class matrix_constants {
*/
public const POWER_LEVEL_MODERATOR = 50;
/**
* User moderator power level for matrix.
*/
public const POWER_LEVEL_MOODLE_MODERATOR = 51;
/**
* User power level for matrix associated to moodle site admins. It is a custom power level for site admins.
*/
@@ -478,7 +478,7 @@ class communication_feature_test extends \advanced_testcase {
// Test if the power level is set according to the context.
$this->assertEquals(
matrix_constants::POWER_LEVEL_MODERATOR,
matrix_constants::POWER_LEVEL_MOODLE_MODERATOR,
$communicationprocessor->get_room_provider()->get_user_allowed_power_level($user1->id)
);
$this->assertEquals(