diff --git a/src/service/rooms/state_accessor/mod.rs b/src/service/rooms/state_accessor/mod.rs index 37eeb7e5..57fbcd77 100644 --- a/src/service/rooms/state_accessor/mod.rs +++ b/src/service/rooms/state_accessor/mod.rs @@ -18,9 +18,11 @@ use ruma::{ }, EventId, OwnedServerName, OwnedUserId, RoomId, ServerName, UserId, }; +use serde_json::value::to_raw_value; +use tokio::sync::MutexGuard; use tracing::{error, warn}; -use crate::{services, Error, PduEvent, Result}; +use crate::{service::pdu::PduBuilder, services, Error, PduEvent, Result}; pub struct Service { pub db: &'static dyn Data, @@ -269,4 +271,25 @@ impl Service { .map_err(|_| Error::bad_database("Invalid room member event in database.")) }) } + + pub async fn user_can_invite( + &self, room_id: &RoomId, sender: &UserId, target_user: &UserId, state_lock: &MutexGuard<'_, ()>, + ) -> Result { + let content = to_raw_value(&RoomMemberEventContent::new(MembershipState::Invite)) + .expect("Event content always serializes"); + + let new_event = PduBuilder { + event_type: ruma::events::TimelineEventType::RoomMember, + content, + unsigned: None, + state_key: Some(target_user.into()), + redacts: None, + }; + + Ok(services() + .rooms + .timeline + .create_hash_and_sign_event(new_event, sender, room_id, state_lock) + .is_ok()) + } }