|
|
|
|
@ -1,7 +1,7 @@
|
|
|
|
|
use std::{ |
|
|
|
|
collections::BTreeMap, |
|
|
|
|
convert::{TryFrom, TryInto}, |
|
|
|
|
sync::{Arc, RwLock}, |
|
|
|
|
sync::Arc, |
|
|
|
|
time::Instant, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
@ -26,7 +26,7 @@ use ruma::{
|
|
|
|
|
EventId, OwnedRoomAliasId, OwnedRoomId, RoomAliasId, RoomId, RoomVersionId, ServerName, UserId, |
|
|
|
|
}; |
|
|
|
|
use serde_json::value::to_raw_value; |
|
|
|
|
use tokio::sync::{mpsc, Mutex, MutexGuard}; |
|
|
|
|
use tokio::sync::{mpsc, Mutex, RwLock}; |
|
|
|
|
|
|
|
|
|
use crate::{ |
|
|
|
|
api::client_server::{leave_all_rooms, AUTO_GEN_PASSWORD_LENGTH}, |
|
|
|
|
@ -215,27 +215,6 @@ impl Service {
|
|
|
|
|
.expect("@conduit:server_name is valid"); |
|
|
|
|
|
|
|
|
|
if let Ok(Some(conduit_room)) = services().admin.get_admin_room() { |
|
|
|
|
let send_message = |message: RoomMessageEventContent, |
|
|
|
|
mutex_lock: &MutexGuard<'_, ()>| { |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomMessage, |
|
|
|
|
content: to_raw_value(&message) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: None, |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&conduit_room, |
|
|
|
|
mutex_lock, |
|
|
|
|
) |
|
|
|
|
.unwrap(); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
loop { |
|
|
|
|
tokio::select! { |
|
|
|
|
Some(event) = receiver.recv() => { |
|
|
|
|
@ -248,16 +227,30 @@ impl Service {
|
|
|
|
|
services().globals |
|
|
|
|
.roomid_mutex_state |
|
|
|
|
.write() |
|
|
|
|
.unwrap() |
|
|
|
|
.await |
|
|
|
|
.entry(conduit_room.to_owned()) |
|
|
|
|
.or_default(), |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
let state_lock = mutex_state.lock().await; |
|
|
|
|
|
|
|
|
|
send_message(message_content, &state_lock); |
|
|
|
|
|
|
|
|
|
drop(state_lock); |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomMessage, |
|
|
|
|
content: to_raw_value(&message_content) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: None, |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&conduit_room, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await.unwrap(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -425,11 +418,7 @@ impl Service {
|
|
|
|
|
Err(e) => RoomMessageEventContent::text_plain(e.to_string()), |
|
|
|
|
}, |
|
|
|
|
AdminCommand::IncomingFederation => { |
|
|
|
|
let map = services() |
|
|
|
|
.globals |
|
|
|
|
.roomid_federationhandletime |
|
|
|
|
.read() |
|
|
|
|
.unwrap(); |
|
|
|
|
let map = services().globals.roomid_federationhandletime.read().await; |
|
|
|
|
let mut msg: String = format!("Handling {} incoming pdus:\n", map.len()); |
|
|
|
|
|
|
|
|
|
for (r, (e, i)) in map.iter() { |
|
|
|
|
@ -543,7 +532,7 @@ impl Service {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
AdminCommand::MemoryUsage => { |
|
|
|
|
let response1 = services().memory_usage(); |
|
|
|
|
let response1 = services().memory_usage().await; |
|
|
|
|
let response2 = services().globals.db.memory_usage(); |
|
|
|
|
|
|
|
|
|
RoomMessageEventContent::text_plain(format!( |
|
|
|
|
@ -556,7 +545,7 @@ impl Service {
|
|
|
|
|
RoomMessageEventContent::text_plain("Done.") |
|
|
|
|
} |
|
|
|
|
AdminCommand::ClearServiceCaches { amount } => { |
|
|
|
|
services().clear_caches(amount); |
|
|
|
|
services().clear_caches(amount).await; |
|
|
|
|
|
|
|
|
|
RoomMessageEventContent::text_plain("Done.") |
|
|
|
|
} |
|
|
|
|
@ -797,7 +786,7 @@ impl Service {
|
|
|
|
|
.fetch_required_signing_keys(&value, &pub_key_map) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
let pub_key_map = pub_key_map.read().unwrap(); |
|
|
|
|
let pub_key_map = pub_key_map.read().await; |
|
|
|
|
match ruma::signatures::verify_json(&pub_key_map, &value) { |
|
|
|
|
Ok(_) => RoomMessageEventContent::text_plain("Signature correct"), |
|
|
|
|
Err(e) => RoomMessageEventContent::text_plain(format!( |
|
|
|
|
@ -913,7 +902,7 @@ impl Service {
|
|
|
|
|
.globals |
|
|
|
|
.roomid_mutex_state |
|
|
|
|
.write() |
|
|
|
|
.unwrap() |
|
|
|
|
.await |
|
|
|
|
.entry(room_id.clone()) |
|
|
|
|
.or_default(), |
|
|
|
|
); |
|
|
|
|
@ -932,164 +921,202 @@ impl Service {
|
|
|
|
|
content.room_version = services().globals.default_room_version(); |
|
|
|
|
|
|
|
|
|
// 1. The room create event
|
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomCreate, |
|
|
|
|
content: to_raw_value(&content).expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomCreate, |
|
|
|
|
content: to_raw_value(&content).expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
// 2. Make conduit bot join
|
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomMember, |
|
|
|
|
content: to_raw_value(&RoomMemberEventContent { |
|
|
|
|
membership: MembershipState::Join, |
|
|
|
|
displayname: None, |
|
|
|
|
avatar_url: None, |
|
|
|
|
is_direct: None, |
|
|
|
|
third_party_invite: None, |
|
|
|
|
blurhash: None, |
|
|
|
|
reason: None, |
|
|
|
|
join_authorized_via_users_server: None, |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some(conduit_user.to_string()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomMember, |
|
|
|
|
content: to_raw_value(&RoomMemberEventContent { |
|
|
|
|
membership: MembershipState::Join, |
|
|
|
|
displayname: None, |
|
|
|
|
avatar_url: None, |
|
|
|
|
is_direct: None, |
|
|
|
|
third_party_invite: None, |
|
|
|
|
blurhash: None, |
|
|
|
|
reason: None, |
|
|
|
|
join_authorized_via_users_server: None, |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some(conduit_user.to_string()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
// 3. Power levels
|
|
|
|
|
let mut users = BTreeMap::new(); |
|
|
|
|
users.insert(conduit_user.clone(), 100.into()); |
|
|
|
|
|
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomPowerLevels, |
|
|
|
|
content: to_raw_value(&RoomPowerLevelsEventContent { |
|
|
|
|
users, |
|
|
|
|
..Default::default() |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomPowerLevels, |
|
|
|
|
content: to_raw_value(&RoomPowerLevelsEventContent { |
|
|
|
|
users, |
|
|
|
|
..Default::default() |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
// 4.1 Join Rules
|
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomJoinRules, |
|
|
|
|
content: to_raw_value(&RoomJoinRulesEventContent::new(JoinRule::Invite)) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomJoinRules, |
|
|
|
|
content: to_raw_value(&RoomJoinRulesEventContent::new(JoinRule::Invite)) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
// 4.2 History Visibility
|
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomHistoryVisibility, |
|
|
|
|
content: to_raw_value(&RoomHistoryVisibilityEventContent::new( |
|
|
|
|
HistoryVisibility::Shared, |
|
|
|
|
)) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomHistoryVisibility, |
|
|
|
|
content: to_raw_value(&RoomHistoryVisibilityEventContent::new( |
|
|
|
|
HistoryVisibility::Shared, |
|
|
|
|
)) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
// 4.3 Guest Access
|
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomGuestAccess, |
|
|
|
|
content: to_raw_value(&RoomGuestAccessEventContent::new(GuestAccess::Forbidden)) |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomGuestAccess, |
|
|
|
|
content: to_raw_value(&RoomGuestAccessEventContent::new( |
|
|
|
|
GuestAccess::Forbidden, |
|
|
|
|
)) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
// 5. Events implied by name and topic
|
|
|
|
|
let room_name = format!("{} Admin Room", services().globals.server_name()); |
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomName, |
|
|
|
|
content: to_raw_value(&RoomNameEventContent::new(room_name)) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomName, |
|
|
|
|
content: to_raw_value(&RoomNameEventContent::new(room_name)) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomTopic, |
|
|
|
|
content: to_raw_value(&RoomTopicEventContent { |
|
|
|
|
topic: format!("Manage {}", services().globals.server_name()), |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomTopic, |
|
|
|
|
content: to_raw_value(&RoomTopicEventContent { |
|
|
|
|
topic: format!("Manage {}", services().globals.server_name()), |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
// 6. Room alias
|
|
|
|
|
let alias: OwnedRoomAliasId = format!("#admins:{}", services().globals.server_name()) |
|
|
|
|
.try_into() |
|
|
|
|
.expect("#admins:server_name is a valid alias name"); |
|
|
|
|
|
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomCanonicalAlias, |
|
|
|
|
content: to_raw_value(&RoomCanonicalAliasEventContent { |
|
|
|
|
alias: Some(alias.clone()), |
|
|
|
|
alt_aliases: Vec::new(), |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomCanonicalAlias, |
|
|
|
|
content: to_raw_value(&RoomCanonicalAliasEventContent { |
|
|
|
|
alias: Some(alias.clone()), |
|
|
|
|
alt_aliases: Vec::new(), |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
services().rooms.alias.set_alias(&alias, &room_id)?; |
|
|
|
|
|
|
|
|
|
@ -1125,7 +1152,7 @@ impl Service {
|
|
|
|
|
.globals |
|
|
|
|
.roomid_mutex_state |
|
|
|
|
.write() |
|
|
|
|
.unwrap() |
|
|
|
|
.await |
|
|
|
|
.entry(room_id.clone()) |
|
|
|
|
.or_default(), |
|
|
|
|
); |
|
|
|
|
@ -1137,72 +1164,84 @@ impl Service {
|
|
|
|
|
.expect("@conduit:server_name is valid"); |
|
|
|
|
|
|
|
|
|
// Invite and join the real user
|
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomMember, |
|
|
|
|
content: to_raw_value(&RoomMemberEventContent { |
|
|
|
|
membership: MembershipState::Invite, |
|
|
|
|
displayname: None, |
|
|
|
|
avatar_url: None, |
|
|
|
|
is_direct: None, |
|
|
|
|
third_party_invite: None, |
|
|
|
|
blurhash: None, |
|
|
|
|
reason: None, |
|
|
|
|
join_authorized_via_users_server: None, |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some(user_id.to_string()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomMember, |
|
|
|
|
content: to_raw_value(&RoomMemberEventContent { |
|
|
|
|
membership: MembershipState::Join, |
|
|
|
|
displayname: Some(displayname), |
|
|
|
|
avatar_url: None, |
|
|
|
|
is_direct: None, |
|
|
|
|
third_party_invite: None, |
|
|
|
|
blurhash: None, |
|
|
|
|
reason: None, |
|
|
|
|
join_authorized_via_users_server: None, |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some(user_id.to_string()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
user_id, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomMember, |
|
|
|
|
content: to_raw_value(&RoomMemberEventContent { |
|
|
|
|
membership: MembershipState::Invite, |
|
|
|
|
displayname: None, |
|
|
|
|
avatar_url: None, |
|
|
|
|
is_direct: None, |
|
|
|
|
third_party_invite: None, |
|
|
|
|
blurhash: None, |
|
|
|
|
reason: None, |
|
|
|
|
join_authorized_via_users_server: None, |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some(user_id.to_string()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomMember, |
|
|
|
|
content: to_raw_value(&RoomMemberEventContent { |
|
|
|
|
membership: MembershipState::Join, |
|
|
|
|
displayname: Some(displayname), |
|
|
|
|
avatar_url: None, |
|
|
|
|
is_direct: None, |
|
|
|
|
third_party_invite: None, |
|
|
|
|
blurhash: None, |
|
|
|
|
reason: None, |
|
|
|
|
join_authorized_via_users_server: None, |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some(user_id.to_string()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
user_id, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
// Set power level
|
|
|
|
|
let mut users = BTreeMap::new(); |
|
|
|
|
users.insert(conduit_user.to_owned(), 100.into()); |
|
|
|
|
users.insert(user_id.to_owned(), 100.into()); |
|
|
|
|
|
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomPowerLevels, |
|
|
|
|
content: to_raw_value(&RoomPowerLevelsEventContent { |
|
|
|
|
users, |
|
|
|
|
..Default::default() |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
services() |
|
|
|
|
.rooms |
|
|
|
|
.timeline |
|
|
|
|
.build_and_append_pdu( |
|
|
|
|
PduBuilder { |
|
|
|
|
event_type: TimelineEventType::RoomPowerLevels, |
|
|
|
|
content: to_raw_value(&RoomPowerLevelsEventContent { |
|
|
|
|
users, |
|
|
|
|
..Default::default() |
|
|
|
|
}) |
|
|
|
|
.expect("event is valid, we just created it"), |
|
|
|
|
unsigned: None, |
|
|
|
|
state_key: Some("".to_owned()), |
|
|
|
|
redacts: None, |
|
|
|
|
}, |
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
) |
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
// Send welcome message
|
|
|
|
|
services().rooms.timeline.build_and_append_pdu( |
|
|
|
|
@ -1220,7 +1259,7 @@ impl Service {
|
|
|
|
|
&conduit_user, |
|
|
|
|
&room_id, |
|
|
|
|
&state_lock, |
|
|
|
|
)?; |
|
|
|
|
).await?; |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
|