add admin command to force demote a local user from a room
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
a65dd6dfb3
commit
895b178720
2 changed files with 81 additions and 2 deletions
|
@ -4,9 +4,13 @@ use api::client::{join_room_by_id_helper, leave_all_rooms, leave_room, update_av
|
|||
use conduit::{error, info, utils, warn, PduBuilder, Result};
|
||||
use ruma::{
|
||||
events::{
|
||||
room::{message::RoomMessageEventContent, redaction::RoomRedactionEventContent},
|
||||
room::{
|
||||
message::RoomMessageEventContent,
|
||||
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
|
||||
redaction::RoomRedactionEventContent,
|
||||
},
|
||||
tag::{TagEvent, TagEventContent, TagInfo},
|
||||
RoomAccountDataEventType, TimelineEventType,
|
||||
RoomAccountDataEventType, StateEventType, TimelineEventType,
|
||||
},
|
||||
EventId, OwnedRoomId, OwnedRoomOrAliasId, OwnedUserId, RoomId,
|
||||
};
|
||||
|
@ -387,6 +391,74 @@ pub(super) async fn force_leave_room(
|
|||
)))
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn force_demote(
|
||||
&self, user_id: String, room_id: OwnedRoomOrAliasId,
|
||||
) -> Result<RoomMessageEventContent> {
|
||||
let user_id = parse_local_user_id(self.services, &user_id)?;
|
||||
let room_id = self.services.rooms.alias.resolve(&room_id).await?;
|
||||
|
||||
assert!(
|
||||
self.services.globals.user_is_local(&user_id),
|
||||
"Parsed user_id must be a local user"
|
||||
);
|
||||
|
||||
let state_lock = self.services.rooms.state.mutex.lock(&room_id).await;
|
||||
|
||||
let room_power_levels = self
|
||||
.services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.room_state_get(&room_id, &StateEventType::RoomPowerLevels, "")?
|
||||
.as_ref()
|
||||
.and_then(|event| serde_json::from_str(event.content.get()).ok()?)
|
||||
.and_then(|content: RoomPowerLevelsEventContent| content.into());
|
||||
|
||||
let user_can_demote_self = room_power_levels
|
||||
.as_ref()
|
||||
.is_some_and(|power_levels_content| {
|
||||
RoomPowerLevels::from(power_levels_content.clone()).user_can_change_user_power_level(&user_id, &user_id)
|
||||
}) || self
|
||||
.services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.room_state_get(&room_id, &StateEventType::RoomCreate, "")?
|
||||
.as_ref()
|
||||
.is_some_and(|event| event.sender == user_id);
|
||||
|
||||
if !user_can_demote_self {
|
||||
return Ok(RoomMessageEventContent::notice_markdown(
|
||||
"User is not allowed to modify their own power levels in the room.",
|
||||
));
|
||||
}
|
||||
|
||||
let mut power_levels_content = room_power_levels.unwrap_or_default();
|
||||
power_levels_content.users.remove(&user_id);
|
||||
|
||||
let event_id = self
|
||||
.services
|
||||
.rooms
|
||||
.timeline
|
||||
.build_and_append_pdu(
|
||||
PduBuilder {
|
||||
event_type: TimelineEventType::RoomPowerLevels,
|
||||
content: to_raw_value(&power_levels_content).expect("event is valid, we just created it"),
|
||||
unsigned: None,
|
||||
state_key: Some(String::new()),
|
||||
redacts: None,
|
||||
timestamp: None,
|
||||
},
|
||||
&user_id,
|
||||
&room_id,
|
||||
&state_lock,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(RoomMessageEventContent::notice_markdown(format!(
|
||||
"User {user_id} demoted themselves to the room default power level in {room_id} - {event_id}"
|
||||
)))
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn make_user_admin(&self, user_id: String) -> Result<RoomMessageEventContent> {
|
||||
let user_id = parse_local_user_id(self.services, &user_id)?;
|
||||
|
|
|
@ -79,6 +79,13 @@ pub(super) enum UserCommand {
|
|||
room_id: OwnedRoomOrAliasId,
|
||||
},
|
||||
|
||||
/// - Forces the specified user to drop their power levels to the room
|
||||
/// default, if their permissions allow and the auth check permits
|
||||
ForceDemote {
|
||||
user_id: String,
|
||||
room_id: OwnedRoomOrAliasId,
|
||||
},
|
||||
|
||||
/// - Grant server-admin privileges to a user.
|
||||
MakeUserAdmin {
|
||||
user_id: String,
|
||||
|
|
Loading…
Add table
Reference in a new issue