mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-19 22:26:13 -04:00
Add PowerLevels permission checks to room::Joined
… and the FFI `Room`. These were previously already available at the `room::Member` level.
This commit is contained in:
@@ -35,7 +35,7 @@ use super::RUNTIME;
|
||||
use crate::{
|
||||
client::ProgressWatcher,
|
||||
error::{ClientError, RoomError},
|
||||
room_member::RoomMember,
|
||||
room_member::{MessageLikeEventType, RoomMember, StateEventType},
|
||||
timeline::{
|
||||
AudioInfo, FileInfo, ImageInfo, ThumbnailInfo, TimelineDiff, TimelineItem,
|
||||
TimelineListener, VideoInfo,
|
||||
@@ -68,7 +68,7 @@ impl Room {
|
||||
}
|
||||
}
|
||||
|
||||
#[uniffi::export]
|
||||
#[uniffi::export(async_runtime = "tokio")]
|
||||
impl Room {
|
||||
pub fn id(&self) -> String {
|
||||
self.inner.room_id().to_string()
|
||||
@@ -902,6 +902,91 @@ impl Room {
|
||||
Ok(Arc::new(RoomMessageEventContent::new(msgtype)))
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn can_user_redact(&self, user_id: String) -> Result<bool, ClientError> {
|
||||
let room = match &self.inner {
|
||||
SdkRoom::Joined(j) => j.clone(),
|
||||
_ => return Err(anyhow!("Can't check permissions for non joined rooms").into()),
|
||||
};
|
||||
|
||||
let user_id = UserId::parse(&user_id)?;
|
||||
Ok(room.can_user_redact(&user_id).await?)
|
||||
}
|
||||
|
||||
pub async fn can_user_ban(&self, user_id: String) -> Result<bool, ClientError> {
|
||||
let room = match &self.inner {
|
||||
SdkRoom::Joined(j) => j.clone(),
|
||||
_ => return Err(anyhow!("Can't check permissions for non joined rooms").into()),
|
||||
};
|
||||
|
||||
let user_id = UserId::parse(&user_id)?;
|
||||
Ok(room.can_user_ban(&user_id).await?)
|
||||
}
|
||||
|
||||
pub async fn can_user_invite(&self, user_id: String) -> Result<bool, ClientError> {
|
||||
let room = match &self.inner {
|
||||
SdkRoom::Joined(j) => j.clone(),
|
||||
_ => return Err(anyhow!("Can't check permissions for non joined rooms").into()),
|
||||
};
|
||||
|
||||
let user_id = UserId::parse(&user_id)?;
|
||||
Ok(room.can_user_invite(&user_id).await?)
|
||||
}
|
||||
|
||||
pub async fn can_user_kick(&self, user_id: String) -> Result<bool, ClientError> {
|
||||
let room = match &self.inner {
|
||||
SdkRoom::Joined(j) => j.clone(),
|
||||
_ => return Err(anyhow!("Can't check permissions for non joined rooms").into()),
|
||||
};
|
||||
|
||||
let user_id = UserId::parse(&user_id)?;
|
||||
Ok(room.can_user_kick(&user_id).await?)
|
||||
}
|
||||
|
||||
pub async fn can_user_send_state(
|
||||
&self,
|
||||
user_id: String,
|
||||
state_event: StateEventType,
|
||||
) -> Result<bool, ClientError> {
|
||||
let room = match &self.inner {
|
||||
SdkRoom::Joined(j) => j.clone(),
|
||||
_ => return Err(anyhow!("Can't check permissions for non joined rooms").into()),
|
||||
};
|
||||
|
||||
let user_id = UserId::parse(&user_id)?;
|
||||
Ok(room.can_user_send_state(&user_id, state_event.into()).await?)
|
||||
}
|
||||
|
||||
pub async fn can_user_send_message(
|
||||
&self,
|
||||
user_id: String,
|
||||
message: MessageLikeEventType,
|
||||
) -> Result<bool, ClientError> {
|
||||
let room = match &self.inner {
|
||||
SdkRoom::Joined(j) => j.clone(),
|
||||
_ => return Err(anyhow!("Can't check permissions for non joined rooms").into()),
|
||||
};
|
||||
|
||||
let user_id = UserId::parse(&user_id)?;
|
||||
Ok(room.can_user_send_message(&user_id, message.into()).await?)
|
||||
}
|
||||
|
||||
pub async fn can_user_trigger_room_notification(
|
||||
&self,
|
||||
user_id: String,
|
||||
) -> Result<bool, ClientError> {
|
||||
let room = match &self.inner {
|
||||
SdkRoom::Joined(j) => j.clone(),
|
||||
_ => return Err(anyhow!("Can't check permissions for non joined rooms").into()),
|
||||
};
|
||||
|
||||
let user_id = UserId::parse(&user_id)?;
|
||||
Ok(room.can_user_trigger_room_notification(&user_id).await?)
|
||||
}
|
||||
|
||||
pub fn own_user_id(&self) -> String {
|
||||
self.inner.own_user_id().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl Room {
|
||||
|
||||
@@ -28,10 +28,11 @@ use ruma::{
|
||||
avatar::{ImageInfo, RoomAvatarEventContent},
|
||||
message::RoomMessageEventContent,
|
||||
name::RoomNameEventContent,
|
||||
power_levels::RoomPowerLevelsEventContent,
|
||||
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
|
||||
topic::RoomTopicEventContent,
|
||||
},
|
||||
EmptyStateKey, MessageLikeEventContent, StateEventContent,
|
||||
EmptyStateKey, MessageLikeEventContent, MessageLikeEventType, StateEventContent,
|
||||
StateEventType,
|
||||
},
|
||||
serde::Raw,
|
||||
EventId, Int, MxcUri, OwnedEventId, OwnedTransactionId, TransactionId, UserId,
|
||||
@@ -811,12 +812,7 @@ impl Joined {
|
||||
&self,
|
||||
updates: Vec<(&UserId, Int)>,
|
||||
) -> Result<send_state_event::v3::Response> {
|
||||
let raw_pl_event = self
|
||||
.get_state_event_static::<RoomPowerLevelsEventContent>()
|
||||
.await?
|
||||
.ok_or(Error::InsufficientData)?;
|
||||
|
||||
let mut power_levels = raw_pl_event.deserialize()?.power_levels();
|
||||
let mut power_levels = self.get_room_power_levels().await?;
|
||||
|
||||
for (user_id, new_level) in updates {
|
||||
if new_level == power_levels.users_default {
|
||||
@@ -829,6 +825,15 @@ impl Joined {
|
||||
self.send_state_event(RoomPowerLevelsEventContent::from(power_levels)).await
|
||||
}
|
||||
|
||||
async fn get_room_power_levels(&self) -> Result<RoomPowerLevels> {
|
||||
Ok(self
|
||||
.get_state_event_static::<RoomPowerLevelsEventContent>()
|
||||
.await?
|
||||
.ok_or(Error::InsufficientData)?
|
||||
.deserialize()?
|
||||
.power_levels())
|
||||
}
|
||||
|
||||
/// Sets the name of this room.
|
||||
pub async fn set_name(&self, name: Option<String>) -> Result<send_state_event::v3::Response> {
|
||||
self.send_state_event(RoomNameEventContent::new(name)).await
|
||||
@@ -1096,6 +1101,70 @@ impl Joined {
|
||||
|
||||
self.client.send(request, None).await
|
||||
}
|
||||
|
||||
/// Returns true if the user with the given user_id is able to redact
|
||||
/// messages in the room.
|
||||
///
|
||||
/// The call may fail if there is an error in getting the power levels.
|
||||
pub async fn can_user_redact(&self, user_id: &UserId) -> Result<bool> {
|
||||
Ok(self.get_room_power_levels().await?.user_can_redact(user_id))
|
||||
}
|
||||
|
||||
/// Returns true if the user with the given user_id is able to ban in the
|
||||
/// room.
|
||||
///
|
||||
/// The call may fail if there is an error in getting the power levels.
|
||||
pub async fn can_user_ban(&self, user_id: &UserId) -> Result<bool> {
|
||||
Ok(self.get_room_power_levels().await?.user_can_ban(user_id))
|
||||
}
|
||||
|
||||
/// Returns true if the user with the given user_id is able to kick in the
|
||||
/// room.
|
||||
///
|
||||
/// The call may fail if there is an error in getting the power levels.
|
||||
pub async fn can_user_invite(&self, user_id: &UserId) -> Result<bool> {
|
||||
Ok(self.get_room_power_levels().await?.user_can_invite(user_id))
|
||||
}
|
||||
|
||||
/// Returns true if the user with the given user_id is able to kick in the
|
||||
/// room.
|
||||
///
|
||||
/// The call may fail if there is an error in getting the power levels.
|
||||
pub async fn can_user_kick(&self, user_id: &UserId) -> Result<bool> {
|
||||
Ok(self.get_room_power_levels().await?.user_can_kick(user_id))
|
||||
}
|
||||
|
||||
/// Returns true if the user with the given user_id is able to send a
|
||||
/// specific state event type in the room.
|
||||
///
|
||||
/// The call may fail if there is an error in getting the power levels.
|
||||
pub async fn can_user_send_state(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
state_event: StateEventType,
|
||||
) -> Result<bool> {
|
||||
Ok(self.get_room_power_levels().await?.user_can_send_state(user_id, state_event))
|
||||
}
|
||||
|
||||
/// Returns true if the user with the given user_id is able to send a
|
||||
/// specific message type in the room.
|
||||
///
|
||||
/// The call may fail if there is an error in getting the power levels.
|
||||
pub async fn can_user_send_message(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
message: MessageLikeEventType,
|
||||
) -> Result<bool> {
|
||||
Ok(self.get_room_power_levels().await?.user_can_send_message(user_id, message))
|
||||
}
|
||||
|
||||
/// Returns true if the user with the given user_id is able to trigger a
|
||||
/// notification in the room.
|
||||
///
|
||||
/// The call may fail if there is an error in getting the power levels.
|
||||
pub async fn can_user_trigger_room_notification(&self, user_id: &UserId) -> Result<bool> {
|
||||
Ok(self.get_room_power_levels().await?.user_can_trigger_room_notification(user_id))
|
||||
}
|
||||
}
|
||||
|
||||
/// Receipts to send all at once.
|
||||
|
||||
Reference in New Issue
Block a user