mirror of
https://gitlab.com/famedly/conduit.git
synced 2024-12-27 04:53:50 +03:00
feat: admin room
This commit is contained in:
parent
0d6159c2da
commit
bcd1fe1856
12 changed files with 864 additions and 574 deletions
15
Cargo.lock
generated
15
Cargo.lock
generated
|
@ -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",
|
||||
|
|
|
@ -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 = "<body>")
|
||||
)]
|
||||
pub fn register_route(
|
||||
pub async fn register_route(
|
||||
db: State<'_, Database>,
|
||||
body: Ruma<register::Request<'_>>,
|
||||
) -> ConduitResult<register::Response> {
|
||||
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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())?;
|
||||
|
|
|
@ -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::<Raw<_>>(
|
||||
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::<Raw<_>>(
|
||||
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::<Raw<..>> 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::<Raw<..>> 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::<Raw<_>>(
|
||||
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::<Raw<..>> 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::<Raw<_>>(
|
||||
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::<Raw<..>> 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(
|
||||
|
|
|
@ -18,26 +18,23 @@ pub async fn redact_event_route(
|
|||
) -> ConduitResult<redact_event::Response> {
|
||||
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())
|
||||
}
|
||||
|
|
|
@ -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::<Raw<ruma::events::room::create::CreateEventContent>>(
|
||||
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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<Vec<u8>> {
|
||||
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::<Vec<_>>();
|
||||
|
||||
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)?;
|
||||
|
||||
|
|
|
@ -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<Option<(UserId, String)>> {
|
||||
self.token_userdeviceid
|
||||
|
|
|
@ -126,6 +126,7 @@ fn setup_rocket() -> rocket::Rocket {
|
|||
server_server::get_public_rooms_filtered_route,
|
||||
server_server::send_transaction_message_route,
|
||||
server_server::get_missing_events_route,
|
||||
server_server::get_profile_information_route,
|
||||
],
|
||||
)
|
||||
.attach(AdHoc::on_attach("Config", |mut rocket| async {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{client_server, ConduitResult, Database, Error, PduEvent, Result, Ruma};
|
||||
use get_profile_information::v1::ProfileField;
|
||||
use http::header::{HeaderValue, AUTHORIZATION, HOST};
|
||||
use log::warn;
|
||||
use rocket::{get, post, put, response::content::Json, State};
|
||||
|
@ -10,6 +11,7 @@ use ruma::{
|
|||
get_server_keys, get_server_version::v1 as get_server_version, ServerKey, VerifyKey,
|
||||
},
|
||||
event::get_missing_events,
|
||||
query::get_profile_information,
|
||||
transactions::send_transaction_message,
|
||||
},
|
||||
OutgoingRequest,
|
||||
|
@ -362,9 +364,9 @@ pub fn send_transaction_message_route<'a>(
|
|||
let pdu = serde_json::from_value::<PduEvent>(value.clone())
|
||||
.expect("all ruma pdus are conduit pdus");
|
||||
if db.rooms.exists(&pdu.room_id)? {
|
||||
let pdu_id = db
|
||||
.rooms
|
||||
.append_pdu(&pdu, &value, &db.globals, &db.account_data)?;
|
||||
let pdu_id =
|
||||
db.rooms
|
||||
.append_pdu(&pdu, &value, &db.globals, &db.account_data, &db.sending)?;
|
||||
db.rooms.append_to_state(&pdu_id, &pdu)?;
|
||||
}
|
||||
}
|
||||
|
@ -416,3 +418,59 @@ pub fn get_missing_events_route<'a>(
|
|||
|
||||
Ok(get_missing_events::v1::Response { events }.into())
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "conduit_bin",
|
||||
get("/_matrix/federation/v1/query/profile", data = "<body>")
|
||||
)]
|
||||
pub fn get_profile_information_route<'a>(
|
||||
db: State<'a, Database>,
|
||||
body: Ruma<get_profile_information::v1::Request<'_>>,
|
||||
) -> ConduitResult<get_profile_information::v1::Response> {
|
||||
let mut displayname = None;
|
||||
let mut avatar_url = None;
|
||||
|
||||
match body.field {
|
||||
Some(ProfileField::DisplayName) => displayname = db.users.displayname(&body.user_id)?,
|
||||
Some(ProfileField::AvatarUrl) => avatar_url = db.users.avatar_url(&body.user_id)?,
|
||||
None => {
|
||||
displayname = db.users.displayname(&body.user_id)?;
|
||||
avatar_url = db.users.avatar_url(&body.user_id)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(get_profile_information::v1::Response {
|
||||
displayname,
|
||||
avatar_url,
|
||||
}
|
||||
.into())
|
||||
}
|
||||
|
||||
/*
|
||||
#[cfg_attr(
|
||||
feature = "conduit_bin",
|
||||
get("/_matrix/federation/v2/invite/<_>/<_>", data = "<body>")
|
||||
)]
|
||||
pub fn get_user_devices_route<'a>(
|
||||
db: State<'a, Database>,
|
||||
body: Ruma<membership::v1::Request<'_>>,
|
||||
) -> ConduitResult<get_profile_information::v1::Response> {
|
||||
let mut displayname = None;
|
||||
let mut avatar_url = None;
|
||||
|
||||
match body.field {
|
||||
Some(ProfileField::DisplayName) => displayname = db.users.displayname(&body.user_id)?,
|
||||
Some(ProfileField::AvatarUrl) => avatar_url = db.users.avatar_url(&body.user_id)?,
|
||||
None => {
|
||||
displayname = db.users.displayname(&body.user_id)?;
|
||||
avatar_url = db.users.avatar_url(&body.user_id)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(get_profile_information::v1::Response {
|
||||
displayname,
|
||||
avatar_url,
|
||||
}
|
||||
.into())
|
||||
}
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue