diff --git a/Cargo.lock b/Cargo.lock
index ed20ca37..6571f7cd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1547,7 +1547,6 @@ dependencies = [
[[package]]
name = "ruma"
version = "0.0.1"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"ruma-api",
"ruma-appservice-api",
@@ -1563,7 +1562,6 @@ dependencies = [
[[package]]
name = "ruma-api"
version = "0.17.0-alpha.1"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"http",
"percent-encoding",
@@ -1578,7 +1576,6 @@ dependencies = [
[[package]]
name = "ruma-api-macros"
version = "0.17.0-alpha.1"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@@ -1589,7 +1586,6 @@ dependencies = [
[[package]]
name = "ruma-appservice-api"
version = "0.2.0-alpha.1"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"ruma-api",
"ruma-common",
@@ -1602,7 +1598,6 @@ dependencies = [
[[package]]
name = "ruma-client-api"
version = "0.10.0-alpha.1"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"assign",
"http",
@@ -1621,7 +1616,6 @@ dependencies = [
[[package]]
name = "ruma-common"
version = "0.2.0"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"js_int",
"ruma-api",
@@ -1635,7 +1629,6 @@ dependencies = [
[[package]]
name = "ruma-events"
version = "0.22.0-alpha.1"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"js_int",
"ruma-common",
@@ -1650,7 +1643,6 @@ dependencies = [
[[package]]
name = "ruma-events-macros"
version = "0.22.0-alpha.1"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@@ -1661,7 +1653,6 @@ dependencies = [
[[package]]
name = "ruma-federation-api"
version = "0.0.3"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"js_int",
"ruma-api",
@@ -1676,7 +1667,6 @@ dependencies = [
[[package]]
name = "ruma-identifiers"
version = "0.17.4"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"rand",
"ruma-identifiers-macros",
@@ -1688,7 +1678,6 @@ dependencies = [
[[package]]
name = "ruma-identifiers-macros"
version = "0.17.4"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"proc-macro2",
"quote",
@@ -1699,7 +1688,6 @@ dependencies = [
[[package]]
name = "ruma-identifiers-validation"
version = "0.1.1"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"serde",
"strum",
@@ -1708,7 +1696,6 @@ dependencies = [
[[package]]
name = "ruma-serde"
version = "0.2.3"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"form_urlencoded",
"itoa",
@@ -1720,7 +1707,6 @@ dependencies = [
[[package]]
name = "ruma-signatures"
version = "0.6.0-dev.1"
-source = "git+https://github.com/timokoesters/ruma?branch=timo-fed-fixes#47fab87325b71b7f6c2fb3cd276d1f813e42abf7"
dependencies = [
"base64",
"ring",
@@ -1970,7 +1956,6 @@ checksum = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028"
[[package]]
name = "state-res"
version = "0.1.0"
-source = "git+https://github.com/timokoesters/state-res?branch=spec-comp#d11a3feb5307715ab5d86af8f25d4bccfee6264b"
dependencies = [
"itertools",
"js_int",
diff --git a/src/client_server/account.rs b/src/client_server/account.rs
index 7e0f942e..66b4a62a 100644
--- a/src/client_server/account.rs
+++ b/src/client_server/account.rs
@@ -1,3 +1,5 @@
+use std::{collections::BTreeMap, convert::TryInto};
+
use super::{State, DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH};
use crate::{pdu::PduBuilder, utils, ConduitResult, Database, Error, Ruma};
use ruma::{
@@ -11,8 +13,11 @@ use ruma::{
uiaa::{AuthFlow, UiaaInfo},
},
},
- events::{room::member, EventType},
- UserId,
+ events::{
+ room::canonical_alias, room::guest_access, room::history_visibility, room::join_rules,
+ room::member, room::name, room::topic, EventType,
+ },
+ RoomAliasId, RoomId, RoomVersionId, UserId,
};
use register::RegistrationKind;
@@ -73,7 +78,7 @@ pub fn get_register_available_route(
feature = "conduit_bin",
post("/_matrix/client/r0/register", data = "
")
)]
-pub fn register_route(
+pub async fn register_route(
db: State<'_, Database>,
body: Ruma>,
) -> ConduitResult {
@@ -202,6 +207,265 @@ pub fn register_route(
body.initial_device_display_name.clone(),
)?;
+ // If this is the first user on this server, create the admins room
+ if db.users.count() == 1 {
+ // Create a user for the server
+ let conduit_user = UserId::parse_with_server_name("conduit", db.globals.server_name())
+ .expect("@conduit:server_name is valid");
+
+ db.users.create(&conduit_user, "")?;
+
+ let room_id = RoomId::new(db.globals.server_name());
+
+ let mut content = ruma::events::room::create::CreateEventContent::new(conduit_user.clone());
+ content.federate = true;
+ content.predecessor = None;
+ content.room_version = RoomVersionId::Version6;
+
+ // 1. The room create event
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomCreate,
+ content: serde_json::to_value(content).expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &conduit_user,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+
+ // 2. Make conduit bot join
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(member::MemberEventContent {
+ membership: member::MembershipState::Join,
+ displayname: None,
+ avatar_url: None,
+ is_direct: None,
+ third_party_invite: None,
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(conduit_user.to_string()),
+ redacts: None,
+ },
+ &conduit_user,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+
+ // 3. Power levels
+ let mut users = BTreeMap::new();
+ users.insert(conduit_user.clone(), 100.into());
+ users.insert(user_id.clone(), 100.into());
+
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomPowerLevels,
+ content: serde_json::to_value(
+ ruma::events::room::power_levels::PowerLevelsEventContent {
+ ban: 50.into(),
+ events: BTreeMap::new(),
+ events_default: 0.into(),
+ invite: 50.into(),
+ kick: 50.into(),
+ redact: 50.into(),
+ state_default: 50.into(),
+ users,
+ users_default: 0.into(),
+ notifications: ruma::events::room::power_levels::NotificationPowerLevels {
+ room: 50.into(),
+ },
+ },
+ )
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &conduit_user,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+
+ // 4.1 Join Rules
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomJoinRules,
+ content: serde_json::to_value(join_rules::JoinRulesEventContent::new(
+ join_rules::JoinRule::Invite,
+ ))
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &conduit_user,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+
+ // 4.2 History Visibility
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomHistoryVisibility,
+ content: serde_json::to_value(
+ history_visibility::HistoryVisibilityEventContent::new(
+ history_visibility::HistoryVisibility::Shared,
+ ),
+ )
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &conduit_user,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+
+ // 4.3 Guest Access
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomGuestAccess,
+ content: serde_json::to_value(guest_access::GuestAccessEventContent::new(
+ guest_access::GuestAccess::Forbidden,
+ ))
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &conduit_user,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+
+ // 6. Events implied by name and topic
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomName,
+ content: serde_json::to_value(
+ name::NameEventContent::new("Admin Room".to_owned()).map_err(|_| {
+ Error::BadRequest(ErrorKind::InvalidParam, "Name is invalid.")
+ })?,
+ )
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &conduit_user,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomTopic,
+ content: serde_json::to_value(topic::TopicEventContent {
+ topic: format!("Manage {}", db.globals.server_name()),
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &conduit_user,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+
+ // Room alias
+ let alias: RoomAliasId = format!("#admins:{}", db.globals.server_name())
+ .try_into()
+ .expect("#admins:server_name is a valid alias name");
+
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomCanonicalAlias,
+ content: serde_json::to_value(canonical_alias::CanonicalAliasEventContent {
+ 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,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+
+ db.rooms.set_alias(&alias, Some(&room_id), &db.globals)?;
+
+ // Invite and join the real user
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(member::MemberEventContent {
+ membership: member::MembershipState::Invite,
+ displayname: None,
+ avatar_url: None,
+ is_direct: None,
+ third_party_invite: None,
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(user_id.to_string()),
+ redacts: None,
+ },
+ &conduit_user,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(member::MemberEventContent {
+ membership: member::MembershipState::Join,
+ displayname: None,
+ avatar_url: None,
+ is_direct: None,
+ third_party_invite: None,
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(user_id.to_string()),
+ redacts: None,
+ },
+ &user_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+ }
+
Ok(register::Response {
access_token: Some(token),
user_id,
@@ -354,23 +618,20 @@ pub async fn deactivate_route(
third_party_invite: None,
};
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(event)
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(sender_id.to_string()),
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(event).expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(sender_id.to_string()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
}
// Remove devices and mark account as deactivated
diff --git a/src/client_server/membership.rs b/src/client_server/membership.rs
index 628045de..526e82f1 100644
--- a/src/client_server/membership.rs
+++ b/src/client_server/membership.rs
@@ -108,22 +108,20 @@ pub async fn leave_room_route(
event.membership = member::MembershipState::Leave;
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(event).expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(sender_id.to_string()),
- redacts: None,
- },
- &sender_id,
- &body.room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(event).expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(sender_id.to_string()),
+ redacts: None,
+ },
+ &sender_id,
+ &body.room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
Ok(leave_room::Response::new().into())
}
@@ -139,29 +137,27 @@ pub async fn invite_user_route(
let sender_id = body.sender_id.as_ref().expect("user is authenticated");
if let invite_user::IncomingInvitationRecipient::UserId { user_id } = &body.recipient {
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(member::MemberEventContent {
- membership: member::MembershipState::Invite,
- displayname: db.users.displayname(&user_id)?,
- avatar_url: db.users.avatar_url(&user_id)?,
- is_direct: None,
- third_party_invite: None,
- })
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(user_id.to_string()),
- redacts: None,
- },
- &sender_id,
- &body.room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(member::MemberEventContent {
+ membership: member::MembershipState::Invite,
+ displayname: db.users.displayname(&user_id)?,
+ avatar_url: db.users.avatar_url(&user_id)?,
+ is_direct: None,
+ third_party_invite: None,
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(user_id.to_string()),
+ redacts: None,
+ },
+ &sender_id,
+ &body.room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
Ok(invite_user::Response.into())
} else {
@@ -199,22 +195,20 @@ pub async fn kick_user_route(
event.membership = ruma::events::room::member::MembershipState::Leave;
// TODO: reason
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(event).expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(body.user_id.to_string()),
- redacts: None,
- },
- &sender_id,
- &body.room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(event).expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(body.user_id.to_string()),
+ redacts: None,
+ },
+ &sender_id,
+ &body.room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
Ok(kick_user::Response::new().into())
}
@@ -257,22 +251,20 @@ pub async fn ban_user_route(
},
)?;
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(event).expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(body.user_id.to_string()),
- redacts: None,
- },
- &sender_id,
- &body.room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(event).expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(body.user_id.to_string()),
+ redacts: None,
+ },
+ &sender_id,
+ &body.room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
Ok(ban_user::Response::new().into())
}
@@ -306,22 +298,20 @@ pub async fn unban_user_route(
event.membership = ruma::events::room::member::MembershipState::Leave;
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(event).expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(body.user_id.to_string()),
- redacts: None,
- },
- &sender_id,
- &body.room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(event).expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(body.user_id.to_string()),
+ redacts: None,
+ },
+ &sender_id,
+ &body.room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
Ok(unban_user::Response::new().into())
}
@@ -640,6 +630,7 @@ async fn join_room_by_id_helper(
&serde_json::to_value(&**pdu).expect("PDU is valid value"),
&db.globals,
&db.account_data,
+ &db.sending,
)?;
if state_events.contains(ev_id) {
@@ -657,23 +648,20 @@ async fn join_room_by_id_helper(
third_party_invite: None,
};
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(event)
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(sender_id.to_string()),
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(event).expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(sender_id.to_string()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
}
Ok(join_room_by_id::Response::new(room_id.clone()).into())
diff --git a/src/client_server/message.rs b/src/client_server/message.rs
index 5a4488fe..c32bd687 100644
--- a/src/client_server/message.rs
+++ b/src/client_server/message.rs
@@ -49,29 +49,26 @@ pub async fn send_message_event_route(
let mut unsigned = serde_json::Map::new();
unsigned.insert("transaction_id".to_owned(), body.txn_id.clone().into());
- let event_id = db
- .rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: body.content.event_type().into(),
- content: serde_json::from_str(
- body.json_body
- .as_ref()
- .ok_or(Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?
- .get(),
- )
- .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?,
- unsigned: Some(unsigned),
- state_key: None,
- redacts: None,
- },
- &sender_id,
- &body.room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ let event_id = db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: body.content.event_type().into(),
+ content: serde_json::from_str(
+ body.json_body
+ .as_ref()
+ .ok_or(Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?
+ .get(),
+ )
+ .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?,
+ unsigned: Some(unsigned),
+ state_key: None,
+ redacts: None,
+ },
+ &sender_id,
+ &body.room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
db.transaction_ids
.add_txnid(sender_id, device_id, &body.txn_id, event_id.as_bytes())?;
diff --git a/src/client_server/profile.rs b/src/client_server/profile.rs
index 686d4c3e..9c6bd512 100644
--- a/src/client_server/profile.rs
+++ b/src/client_server/profile.rs
@@ -31,43 +31,41 @@ pub async fn set_displayname_route(
// Send a new membership event and presence update into all joined rooms
for room_id in db.rooms.rooms_joined(&sender_id) {
let room_id = room_id?;
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(ruma::events::room::member::MemberEventContent {
- displayname: body.displayname.clone(),
- ..serde_json::from_value::>(
- db.rooms
- .room_state_get(
- &room_id,
- &EventType::RoomMember,
- &sender_id.to_string(),
- )?
- .ok_or_else(|| {
- Error::bad_database(
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(ruma::events::room::member::MemberEventContent {
+ displayname: body.displayname.clone(),
+ ..serde_json::from_value::>(
+ db.rooms
+ .room_state_get(
+ &room_id,
+ &EventType::RoomMember,
+ &sender_id.to_string(),
+ )?
+ .ok_or_else(|| {
+ Error::bad_database(
"Tried to send displayname update for user not in the room.",
)
- })?
- .content
- .clone(),
- )
- .expect("from_value::> can never fail")
- .deserialize()
- .map_err(|_| Error::bad_database("Database contains invalid PDU."))?
- })
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(sender_id.to_string()),
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ })?
+ .content
+ .clone(),
+ )
+ .expect("from_value::> can never fail")
+ .deserialize()
+ .map_err(|_| Error::bad_database("Database contains invalid PDU."))?
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(sender_id.to_string()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
// Presence update
db.rooms.edus.update_presence(
@@ -125,43 +123,41 @@ pub async fn set_avatar_url_route(
// Send a new membership event and presence update into all joined rooms
for room_id in db.rooms.rooms_joined(&sender_id) {
let room_id = room_id?;
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(ruma::events::room::member::MemberEventContent {
- avatar_url: body.avatar_url.clone(),
- ..serde_json::from_value::>(
- db.rooms
- .room_state_get(
- &room_id,
- &EventType::RoomMember,
- &sender_id.to_string(),
- )?
- .ok_or_else(|| {
- Error::bad_database(
- "Tried to send avatar url update for user not in the room.",
- )
- })?
- .content
- .clone(),
- )
- .expect("from_value::> can never fail")
- .deserialize()
- .map_err(|_| Error::bad_database("Database contains invalid PDU."))?
- })
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(sender_id.to_string()),
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(ruma::events::room::member::MemberEventContent {
+ avatar_url: body.avatar_url.clone(),
+ ..serde_json::from_value::>(
+ db.rooms
+ .room_state_get(
+ &room_id,
+ &EventType::RoomMember,
+ &sender_id.to_string(),
+ )?
+ .ok_or_else(|| {
+ Error::bad_database(
+ "Tried to send avatar url update for user not in the room.",
+ )
+ })?
+ .content
+ .clone(),
+ )
+ .expect("from_value::> can never fail")
+ .deserialize()
+ .map_err(|_| Error::bad_database("Database contains invalid PDU."))?
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(sender_id.to_string()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
// Presence update
db.rooms.edus.update_presence(
diff --git a/src/client_server/redact.rs b/src/client_server/redact.rs
index 24df8dd7..b13cd802 100644
--- a/src/client_server/redact.rs
+++ b/src/client_server/redact.rs
@@ -18,26 +18,23 @@ pub async fn redact_event_route(
) -> ConduitResult {
let sender_id = body.sender_id.as_ref().expect("user is authenticated");
- let event_id = db
- .rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomRedaction,
- content: serde_json::to_value(redaction::RedactionEventContent {
- reason: body.reason.clone(),
- })
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: None,
- redacts: Some(body.event_id.clone()),
- },
- &sender_id,
- &body.room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ let event_id = db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomRedaction,
+ content: serde_json::to_value(redaction::RedactionEventContent {
+ reason: body.reason.clone(),
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: None,
+ redacts: Some(body.event_id.clone()),
+ },
+ &sender_id,
+ &body.room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
Ok(redact_event::Response { event_id }.into())
}
diff --git a/src/client_server/room.rs b/src/client_server/room.rs
index d21148bb..28d30e29 100644
--- a/src/client_server/room.rs
+++ b/src/client_server/room.rs
@@ -53,47 +53,43 @@ pub async fn create_room_route(
content.room_version = RoomVersionId::Version6;
// 1. The room create event
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomCreate,
- content: serde_json::to_value(content).expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some("".to_owned()),
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomCreate,
+ content: serde_json::to_value(content).expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
// 2. Let the room creator join
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(member::MemberEventContent {
- membership: member::MembershipState::Join,
- displayname: db.users.displayname(&sender_id)?,
- avatar_url: db.users.avatar_url(&sender_id)?,
- is_direct: Some(body.is_direct),
- third_party_invite: None,
- })
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(sender_id.to_string()),
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(member::MemberEventContent {
+ membership: member::MembershipState::Join,
+ displayname: db.users.displayname(&sender_id)?,
+ avatar_url: db.users.avatar_url(&sender_id)?,
+ is_direct: Some(body.is_direct),
+ third_party_invite: None,
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(sender_id.to_string()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
// 3. Power levels
let mut users = BTreeMap::new();
@@ -123,22 +119,20 @@ pub async fn create_room_route(
})
.expect("event is valid, we just created it")
};
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomPowerLevels,
- content: power_levels_content,
- unsigned: None,
- state_key: Some("".to_owned()),
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomPowerLevels,
+ content: power_levels_content,
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
// 4. Events set by preset
@@ -149,84 +143,76 @@ pub async fn create_room_route(
});
// 4.1 Join Rules
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomJoinRules,
- content: match preset {
- create_room::RoomPreset::PublicChat => serde_json::to_value(
- join_rules::JoinRulesEventContent::new(join_rules::JoinRule::Public),
- )
- .expect("event is valid, we just created it"),
- // according to spec "invite" is the default
- _ => serde_json::to_value(join_rules::JoinRulesEventContent::new(
- join_rules::JoinRule::Invite,
- ))
- .expect("event is valid, we just created it"),
- },
- unsigned: None,
- state_key: Some("".to_owned()),
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
-
- // 4.2 History Visibility
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomHistoryVisibility,
- content: serde_json::to_value(
- history_visibility::HistoryVisibilityEventContent::new(
- history_visibility::HistoryVisibility::Shared,
- ),
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomJoinRules,
+ content: match preset {
+ create_room::RoomPreset::PublicChat => serde_json::to_value(
+ join_rules::JoinRulesEventContent::new(join_rules::JoinRule::Public),
)
.expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some("".to_owned()),
- redacts: None,
+ // according to spec "invite" is the default
+ _ => serde_json::to_value(join_rules::JoinRulesEventContent::new(
+ join_rules::JoinRule::Invite,
+ ))
+ .expect("event is valid, we just created it"),
},
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
+
+ // 4.2 History Visibility
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomHistoryVisibility,
+ content: serde_json::to_value(history_visibility::HistoryVisibilityEventContent::new(
+ history_visibility::HistoryVisibility::Shared,
+ ))
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
// 4.3 Guest Access
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomGuestAccess,
- content: match preset {
- create_room::RoomPreset::PublicChat => {
- serde_json::to_value(guest_access::GuestAccessEventContent::new(
- guest_access::GuestAccess::Forbidden,
- ))
- .expect("event is valid, we just created it")
- }
- _ => serde_json::to_value(guest_access::GuestAccessEventContent::new(
- guest_access::GuestAccess::CanJoin,
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomGuestAccess,
+ content: match preset {
+ create_room::RoomPreset::PublicChat => {
+ serde_json::to_value(guest_access::GuestAccessEventContent::new(
+ guest_access::GuestAccess::Forbidden,
))
- .expect("event is valid, we just created it"),
- },
- unsigned: None,
- state_key: Some("".to_owned()),
- redacts: None,
+ .expect("event is valid, we just created it")
+ }
+ _ => serde_json::to_value(guest_access::GuestAccessEventContent::new(
+ guest_access::GuestAccess::CanJoin,
+ ))
+ .expect("event is valid, we just created it"),
},
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
// 5. Events listed in initial_state
for event in &body.initial_state {
@@ -240,90 +226,82 @@ pub async fn create_room_route(
continue;
}
- db.rooms
- .build_and_append_pdu(
- pdu_builder,
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ pdu_builder,
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
}
// 6. Events implied by name and topic
if let Some(name) = &body.name {
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomName,
- content: serde_json::to_value(
- name::NameEventContent::new(name.clone()).map_err(|_| {
- Error::BadRequest(ErrorKind::InvalidParam, "Name is invalid.")
- })?,
- )
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some("".to_owned()),
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomName,
+ content: serde_json::to_value(
+ name::NameEventContent::new(name.clone()).map_err(|_| {
+ Error::BadRequest(ErrorKind::InvalidParam, "Name is invalid.")
+ })?,
+ )
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
}
if let Some(topic) = &body.topic {
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomTopic,
- content: serde_json::to_value(topic::TopicEventContent {
- topic: topic.clone(),
- })
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some("".to_owned()),
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomTopic,
+ content: serde_json::to_value(topic::TopicEventContent {
+ topic: topic.clone(),
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
}
// 7. Events implied by invite (and TODO: invite_3pid)
for user in &body.invite {
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(member::MemberEventContent {
- membership: member::MembershipState::Invite,
- displayname: db.users.displayname(&user)?,
- avatar_url: db.users.avatar_url(&user)?,
- is_direct: Some(body.is_direct),
- third_party_invite: None,
- })
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(user.to_string()),
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(member::MemberEventContent {
+ membership: member::MembershipState::Invite,
+ displayname: db.users.displayname(&user)?,
+ avatar_url: db.users.avatar_url(&user)?,
+ is_direct: Some(body.is_direct),
+ third_party_invite: None,
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(user.to_string()),
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
}
// Homeserver specific stuff
@@ -395,29 +373,24 @@ pub async fn upgrade_room_route(
// Send a m.room.tombstone event to the old room to indicate that it is not intended to be used any further
// Fail if the sender does not have the required permissions
- let tombstone_event_id = db
- .rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomTombstone,
- content: serde_json::to_value(
- ruma::events::room::tombstone::TombstoneEventContent {
- body: "This room has been replaced".to_string(),
- replacement_room: replacement_room.clone(),
- },
- )
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some("".to_owned()),
- redacts: None,
- },
- sender_id,
- &body.room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ let tombstone_event_id = db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomTombstone,
+ content: serde_json::to_value(ruma::events::room::tombstone::TombstoneEventContent {
+ body: "This room has been replaced".to_string(),
+ replacement_room: replacement_room.clone(),
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ sender_id,
+ &body.room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
// Get the old room federations status
let federate = serde_json::from_value::>(
@@ -444,48 +417,44 @@ pub async fn upgrade_room_route(
create_event_content.room_version = new_version;
create_event_content.predecessor = predecessor;
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomCreate,
- content: serde_json::to_value(create_event_content)
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some("".to_owned()),
- redacts: None,
- },
- sender_id,
- &replacement_room,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomCreate,
+ content: serde_json::to_value(create_event_content)
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ sender_id,
+ &replacement_room,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
// Join the new room
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomMember,
- content: serde_json::to_value(member::MemberEventContent {
- membership: member::MembershipState::Join,
- displayname: db.users.displayname(&sender_id)?,
- avatar_url: db.users.avatar_url(&sender_id)?,
- is_direct: None,
- third_party_invite: None,
- })
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some(sender_id.to_string()),
- redacts: None,
- },
- sender_id,
- &replacement_room,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMember,
+ content: serde_json::to_value(member::MemberEventContent {
+ membership: member::MembershipState::Join,
+ displayname: db.users.displayname(&sender_id)?,
+ avatar_url: db.users.avatar_url(&sender_id)?,
+ is_direct: None,
+ third_party_invite: None,
+ })
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some(sender_id.to_string()),
+ redacts: None,
+ },
+ sender_id,
+ &replacement_room,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
// Recommended transferable state events list from the specs
let transferable_state_events = vec![
@@ -507,22 +476,20 @@ pub async fn upgrade_room_route(
None => continue, // Skipping missing events.
};
- db.rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type,
- content: event_content,
- unsigned: None,
- state_key: Some("".to_owned()),
- redacts: None,
- },
- sender_id,
- &replacement_room,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type,
+ content: event_content,
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ sender_id,
+ &replacement_room,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
}
// Moves any local aliases to the new room
@@ -552,24 +519,21 @@ pub async fn upgrade_room_route(
power_levels_event_content.invite = new_level;
// Modify the power levels in the old room to prevent sending of events and inviting new users
- let _ = db
- .rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: EventType::RoomPowerLevels,
- content: serde_json::to_value(power_levels_event_content)
- .expect("event is valid, we just created it"),
- unsigned: None,
- state_key: Some("".to_owned()),
- redacts: None,
- },
- sender_id,
- &body.room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await;
+ let _ = db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomPowerLevels,
+ content: serde_json::to_value(power_levels_event_content)
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: Some("".to_owned()),
+ redacts: None,
+ },
+ sender_id,
+ &body.room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
// Return the replacement room id
Ok(upgrade_room::Response { replacement_room }.into())
diff --git a/src/client_server/state.rs b/src/client_server/state.rs
index 46182a12..1e13b42f 100644
--- a/src/client_server/state.rs
+++ b/src/client_server/state.rs
@@ -213,23 +213,20 @@ pub async fn send_state_event_for_key_helper(
}
}
- let event_id = db
- .rooms
- .build_and_append_pdu(
- PduBuilder {
- event_type: content.event_type().into(),
- content: json,
- unsigned: None,
- state_key,
- redacts: None,
- },
- &sender_id,
- &room_id,
- &db.globals,
- &db.sending,
- &db.account_data,
- )
- .await?;
+ let event_id = db.rooms.build_and_append_pdu(
+ PduBuilder {
+ event_type: content.event_type().into(),
+ content: json,
+ unsigned: None,
+ state_key,
+ redacts: None,
+ },
+ &sender_id,
+ &room_id,
+ &db.globals,
+ &db.sending,
+ &db.account_data,
+ )?;
Ok(event_id)
}
diff --git a/src/database/rooms.rs b/src/database/rooms.rs
index 108edb5d..ab05b390 100644
--- a/src/database/rooms.rs
+++ b/src/database/rooms.rs
@@ -10,7 +10,7 @@ use ruma::{
events::{
ignored_user_list,
room::{
- member,
+ member, message,
power_levels::{self, PowerLevelsEventContent},
},
EventType,
@@ -440,6 +440,7 @@ impl Rooms {
pdu_json: &serde_json::Value,
globals: &super::globals::Globals,
account_data: &super::account_data::AccountData,
+ sending: &super::sending::Sending,
) -> Result> {
self.replace_pdu_leaves(&pdu.room_id, &pdu.event_id)?;
@@ -452,7 +453,8 @@ impl Rooms {
self.edus
.private_read_set(&pdu.room_id, &pdu.sender, index, &globals)?;
- let mut pdu_id = pdu.room_id.as_bytes().to_vec();
+ let room_id = pdu.room_id.clone();
+ let mut pdu_id = room_id.as_bytes().to_vec();
pdu_id.push(0xff);
pdu_id.extend_from_slice(&index.to_be_bytes());
@@ -503,6 +505,45 @@ impl Rooms {
key.extend_from_slice(&pdu_id);
self.tokenids.insert(key, &[])?;
}
+
+ if body.starts_with(&format!("@conduit:{}: ", globals.server_name()))
+ && self
+ .id_from_alias(
+ &format!("#admins:{}", globals.server_name())
+ .try_into()
+ .expect("#admins:server_name is a valid room alias"),
+ )?
+ .as_ref()
+ == Some(&pdu.room_id)
+ {
+ let mut parts = body.split_whitespace().skip(1);
+ if let Some(command) = parts.next() {
+ let args = parts.collect::>();
+
+ self.build_and_append_pdu(
+ PduBuilder {
+ event_type: EventType::RoomMessage,
+ content: serde_json::to_value(
+ message::TextMessageEventContent {
+ body: format!("Command: {}, Args: {:?}", command, args),
+ formatted: None,
+ relates_to: None,
+ },
+ )
+ .expect("event is valid, we just created it"),
+ unsigned: None,
+ state_key: None,
+ redacts: None,
+ },
+ &UserId::try_from(format!("@conduit:{}", globals.server_name()))
+ .expect("@conduit:server_name is valid"),
+ &room_id,
+ &globals,
+ &sending,
+ &account_data,
+ )?;
+ }
+ }
}
}
_ => {}
@@ -570,7 +611,7 @@ impl Rooms {
}
/// Creates a new persisted data unit and adds it to a room.
- pub async fn build_and_append_pdu(
+ pub fn build_and_append_pdu(
&self,
pdu_builder: PduBuilder,
sender: &UserId,
@@ -793,7 +834,7 @@ impl Rooms {
.expect("json is object")
.insert("event_id".to_owned(), pdu.event_id.to_string().into());
- let pdu_id = self.append_pdu(&pdu, &pdu_json, globals, account_data)?;
+ let pdu_id = self.append_pdu(&pdu, &pdu_json, globals, account_data, sending)?;
self.append_to_state(&pdu_id, &pdu)?;
diff --git a/src/database/users.rs b/src/database/users.rs
index 2e26c1ea..0d35e362 100644
--- a/src/database/users.rs
+++ b/src/database/users.rs
@@ -57,6 +57,11 @@ impl Users {
Ok(())
}
+ /// Returns the number of users registered on this server.
+ pub fn count(&self) -> usize {
+ self.userid_password.iter().count()
+ }
+
/// Find out which user an access token belongs to.
pub fn find_from_token(&self, token: &str) -> Result