feat: incoming invites over federation
parent
b0ea692706
commit
8773e5013d
|
@ -1625,7 +1625,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma"
|
name = "ruma"
|
||||||
version = "0.0.2"
|
version = "0.0.2"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assign",
|
"assign",
|
||||||
"js_int",
|
"js_int",
|
||||||
|
@ -1645,7 +1645,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-api"
|
name = "ruma-api"
|
||||||
version = "0.17.0-alpha.2"
|
version = "0.17.0-alpha.2"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
@ -1660,7 +1660,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-api-macros"
|
name = "ruma-api-macros"
|
||||||
version = "0.17.0-alpha.2"
|
version = "0.17.0-alpha.2"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -1671,7 +1671,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-appservice-api"
|
name = "ruma-appservice-api"
|
||||||
version = "0.2.0-alpha.2"
|
version = "0.2.0-alpha.2"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ruma-api",
|
"ruma-api",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
|
@ -1685,7 +1685,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-client-api"
|
name = "ruma-client-api"
|
||||||
version = "0.10.0-alpha.2"
|
version = "0.10.0-alpha.2"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assign",
|
"assign",
|
||||||
"http",
|
"http",
|
||||||
|
@ -1704,7 +1704,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-common"
|
name = "ruma-common"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"js_int",
|
"js_int",
|
||||||
|
@ -1720,7 +1720,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-events"
|
name = "ruma-events"
|
||||||
version = "0.22.0-alpha.2"
|
version = "0.22.0-alpha.2"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
|
@ -1734,7 +1734,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-events-macros"
|
name = "ruma-events-macros"
|
||||||
version = "0.22.0-alpha.2"
|
version = "0.22.0-alpha.2"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -1745,7 +1745,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-federation-api"
|
name = "ruma-federation-api"
|
||||||
version = "0.1.0-alpha.1"
|
version = "0.1.0-alpha.1"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-api",
|
"ruma-api",
|
||||||
|
@ -1760,7 +1760,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identifiers"
|
name = "ruma-identifiers"
|
||||||
version = "0.18.1"
|
version = "0.18.1"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"paste",
|
"paste",
|
||||||
"rand",
|
"rand",
|
||||||
|
@ -1774,7 +1774,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identifiers-macros"
|
name = "ruma-identifiers-macros"
|
||||||
version = "0.18.1"
|
version = "0.18.1"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1785,12 +1785,12 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identifiers-validation"
|
name = "ruma-identifiers-validation"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identity-service-api"
|
name = "ruma-identity-service-api"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ruma-api",
|
"ruma-api",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
|
@ -1803,7 +1803,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-push-gateway-api"
|
name = "ruma-push-gateway-api"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-api",
|
"ruma-api",
|
||||||
|
@ -1818,7 +1818,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-serde"
|
name = "ruma-serde"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"itoa",
|
"itoa",
|
||||||
|
@ -1831,7 +1831,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-serde-macros"
|
name = "ruma-serde-macros"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -1842,7 +1842,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-signatures"
|
name = "ruma-signatures"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/ruma/ruma?rev=a310ccc318a4eb51062923d570d5a86c1468e8a1#a310ccc318a4eb51062923d570d5a86c1468e8a1"
|
source = "git+https://github.com/timokoesters/ruma?rev=b11de1e1f9d3c15267d09617131cf217f8277fa4#b11de1e1f9d3c15267d09617131cf217f8277fa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.13.0",
|
"base64 0.13.0",
|
||||||
"ring",
|
"ring",
|
||||||
|
@ -2120,7 +2120,7 @@ checksum = "3015a7d0a5fd5105c91c3710d42f9ccf0abfb287d62206484dcc67f9569a6483"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "state-res"
|
name = "state-res"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/timokoesters/state-res?rev=1ec42ea2fc0b0728bf027a5899839ad94bb3091b#1ec42ea2fc0b0728bf027a5899839ad94bb3091b"
|
source = "git+https://github.com/timokoesters/state-res?rev=2e90b36babeb0d6b99ce8d4b513302a25dcdffc1#2e90b36babeb0d6b99ce8d4b513302a25dcdffc1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools 0.10.0",
|
"itertools 0.10.0",
|
||||||
"log",
|
"log",
|
||||||
|
|
|
@ -18,12 +18,12 @@ rocket = { git = "https://github.com/SergioBenitez/Rocket.git", rev = "93e62c86e
|
||||||
#rocket = { git = "https://github.com/timokoesters/Rocket.git", branch = "empty_parameters", default-features = false, features = ["tls"] }
|
#rocket = { git = "https://github.com/timokoesters/Rocket.git", branch = "empty_parameters", default-features = false, features = ["tls"] }
|
||||||
|
|
||||||
# Used for matrix spec type definitions and helpers
|
# Used for matrix spec type definitions and helpers
|
||||||
ruma = { git = "https://github.com/ruma/ruma", rev = "a310ccc318a4eb51062923d570d5a86c1468e8a1", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "unstable-pre-spec", "unstable-exhaustive-types"] }
|
#ruma = { git = "https://github.com/ruma/ruma", rev = "a310ccc318a4eb51062923d570d5a86c1468e8a1", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "unstable-pre-spec", "unstable-exhaustive-types"] }
|
||||||
#ruma = { git = "https://github.com/DevinR528/ruma", features = ["rand", "client-api", "federation-api", "push-gateway-api", "unstable-exhaustive-types", "unstable-pre-spec", "unstable-synapse-quirks"], branch = "verified-export" }
|
ruma = { git = "https://github.com/timokoesters/ruma", rev = "b11de1e1f9d3c15267d09617131cf217f8277fa4", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "unstable-pre-spec", "unstable-exhaustive-types"] }
|
||||||
#ruma = { path = "../ruma/ruma", features = ["unstable-exhaustive-types", "rand", "client-api", "federation-api", "push-gateway-api", "unstable-pre-spec", "unstable-synapse-quirks"] }
|
#ruma = { path = "../ruma/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "unstable-pre-spec", "unstable-exhaustive-types"] }
|
||||||
|
|
||||||
# Used when doing state resolution
|
# Used when doing state resolution
|
||||||
state-res = { git = "https://github.com/timokoesters/state-res", rev = "1ec42ea2fc0b0728bf027a5899839ad94bb3091b", features = ["unstable-pre-spec"] }
|
state-res = { git = "https://github.com/timokoesters/state-res", rev = "2e90b36babeb0d6b99ce8d4b513302a25dcdffc1", features = ["unstable-pre-spec"] }
|
||||||
#state-res = { path = "../state-res", features = ["unstable-pre-spec"] }
|
#state-res = { path = "../state-res", features = ["unstable-pre-spec"] }
|
||||||
|
|
||||||
# Used for long polling and federation sender, should be the same as rocket::tokio
|
# Used for long polling and federation sender, should be the same as rocket::tokio
|
||||||
|
|
|
@ -617,11 +617,11 @@ pub async fn deactivate_route(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leave all joined rooms and reject all invitations
|
// Leave all joined rooms and reject all invitations
|
||||||
for room_id in db
|
for room_id in db.rooms.rooms_joined(&sender_user).chain(
|
||||||
.rooms
|
db.rooms
|
||||||
.rooms_joined(&sender_user)
|
.rooms_invited(&sender_user)
|
||||||
.chain(db.rooms.rooms_invited(&sender_user))
|
.map(|t| t.map(|(r, _)| r)),
|
||||||
{
|
) {
|
||||||
let room_id = room_id?;
|
let room_id = room_id?;
|
||||||
let event = member::MemberEventContent {
|
let event = member::MemberEventContent {
|
||||||
membership: member::MembershipState::Leave,
|
membership: member::MembershipState::Leave,
|
||||||
|
|
|
@ -599,6 +599,8 @@ async fn join_room_by_id_helper(
|
||||||
Error::BadServerResponse("Invalid user id in send_join response.")
|
Error::BadServerResponse("Invalid user id in send_join response.")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let invite_state = Vec::new(); // TODO add a few important events
|
||||||
|
|
||||||
// Update our membership info, we do this here incase a user is invited
|
// Update our membership info, we do this here incase a user is invited
|
||||||
// and immediately leaves we need the DB to record the invite event for auth
|
// and immediately leaves we need the DB to record the invite event for auth
|
||||||
db.rooms.update_membership(
|
db.rooms.update_membership(
|
||||||
|
@ -616,6 +618,7 @@ async fn join_room_by_id_helper(
|
||||||
Error::BadServerResponse("Invalid membership state content.")
|
Error::BadServerResponse("Invalid membership state content.")
|
||||||
})?,
|
})?,
|
||||||
&pdu.sender,
|
&pdu.sender,
|
||||||
|
Some(invite_state),
|
||||||
&db.account_data,
|
&db.account_data,
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -588,44 +588,23 @@ pub async fn sync_events_route(
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut invited_rooms = BTreeMap::new();
|
let mut invited_rooms = BTreeMap::new();
|
||||||
for room_id in db.rooms.rooms_invited(&sender_user) {
|
for result in db.rooms.rooms_invited(&sender_user) {
|
||||||
let room_id = room_id?;
|
let (room_id, invite_state_events) = result?;
|
||||||
let mut invited_since_last_sync = false;
|
let invite_count = db.rooms.get_invite_count(&room_id, &sender_user)?;
|
||||||
for pdu in db.rooms.pdus_since(&sender_user, &room_id, since)? {
|
|
||||||
let (_, pdu) = pdu?;
|
|
||||||
if pdu.kind == EventType::RoomMember && pdu.state_key == Some(sender_user.to_string()) {
|
|
||||||
let content = serde_json::from_value::<
|
|
||||||
Raw<ruma::events::room::member::MemberEventContent>,
|
|
||||||
>(pdu.content.clone())
|
|
||||||
.expect("Raw::from_value always works")
|
|
||||||
.deserialize()
|
|
||||||
.map_err(|_| Error::bad_database("Invalid PDU in database."))?;
|
|
||||||
|
|
||||||
if content.membership == MembershipState::Invite {
|
// Invited before last sync
|
||||||
invited_since_last_sync = true;
|
if Some(since) >= invite_count {
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !invited_since_last_sync {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let invited_room = sync_events::InvitedRoom {
|
invited_rooms.insert(
|
||||||
invite_state: sync_events::InviteState {
|
room_id.clone(),
|
||||||
events: db
|
sync_events::InvitedRoom {
|
||||||
.rooms
|
invite_state: sync_events::InviteState {
|
||||||
.room_state_full(&room_id)?
|
events: invite_state_events,
|
||||||
.into_iter()
|
},
|
||||||
.map(|(_, pdu)| pdu.to_stripped_state_event())
|
|
||||||
.collect(),
|
|
||||||
},
|
},
|
||||||
};
|
);
|
||||||
|
|
||||||
if !invited_room.is_empty() {
|
|
||||||
invited_rooms.insert(room_id.clone(), invited_room);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for user_id in left_encrypted_users {
|
for user_id in left_encrypted_users {
|
||||||
|
|
|
@ -161,8 +161,8 @@ impl Database {
|
||||||
userroomid_joined: db.open_tree("userroomid_joined")?,
|
userroomid_joined: db.open_tree("userroomid_joined")?,
|
||||||
roomuserid_joined: db.open_tree("roomuserid_joined")?,
|
roomuserid_joined: db.open_tree("roomuserid_joined")?,
|
||||||
roomuseroncejoinedids: db.open_tree("roomuseroncejoinedids")?,
|
roomuseroncejoinedids: db.open_tree("roomuseroncejoinedids")?,
|
||||||
userroomid_invited: db.open_tree("userroomid_invited")?,
|
userroomid_invitestate: db.open_tree("userroomid_invitestate")?,
|
||||||
roomuserid_invited: db.open_tree("roomuserid_invited")?,
|
roomuserid_invitecount: db.open_tree("roomuserid_invitecount")?,
|
||||||
userroomid_left: db.open_tree("userroomid_left")?,
|
userroomid_left: db.open_tree("userroomid_left")?,
|
||||||
|
|
||||||
statekey_shortstatekey: db.open_tree("statekey_shortstatekey")?,
|
statekey_shortstatekey: db.open_tree("statekey_shortstatekey")?,
|
||||||
|
@ -236,7 +236,11 @@ impl Database {
|
||||||
);
|
);
|
||||||
|
|
||||||
futures.push(self.rooms.userroomid_joined.watch_prefix(&userid_prefix));
|
futures.push(self.rooms.userroomid_joined.watch_prefix(&userid_prefix));
|
||||||
futures.push(self.rooms.userroomid_invited.watch_prefix(&userid_prefix));
|
futures.push(
|
||||||
|
self.rooms
|
||||||
|
.userroomid_invitestate
|
||||||
|
.watch_prefix(&userid_prefix),
|
||||||
|
);
|
||||||
futures.push(self.rooms.userroomid_left.watch_prefix(&userid_prefix));
|
futures.push(self.rooms.userroomid_left.watch_prefix(&userid_prefix));
|
||||||
|
|
||||||
// Events for rooms we are in
|
// Events for rooms we are in
|
||||||
|
|
|
@ -216,11 +216,11 @@ pub async fn send_push_notice(
|
||||||
notify = Some(n);
|
notify = Some(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
if notify == Some(true) {
|
if notify == Some(true) {
|
||||||
send_notice(unread, pusher, tweaks, pdu, db).await?;
|
send_notice(unread, pusher, tweaks, pdu, db).await?;
|
||||||
}
|
}
|
||||||
// Else the event triggered no actions
|
// Else the event triggered no actions
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,10 @@ use ruma::{
|
||||||
events::{
|
events::{
|
||||||
ignored_user_list,
|
ignored_user_list,
|
||||||
room::{create::CreateEventContent, member, message},
|
room::{create::CreateEventContent, member, message},
|
||||||
EventType,
|
AnyStrippedStateEvent, EventType,
|
||||||
},
|
},
|
||||||
serde::{to_canonical_value, CanonicalJsonObject, CanonicalJsonValue, Raw},
|
serde::{to_canonical_value, CanonicalJsonObject, CanonicalJsonValue, Raw},
|
||||||
EventId, RoomAliasId, RoomId, RoomVersionId, ServerName, UserId,
|
uint, EventId, RoomAliasId, RoomId, RoomVersionId, ServerName, UserId,
|
||||||
};
|
};
|
||||||
use sled::IVec;
|
use sled::IVec;
|
||||||
use state_res::{Event, StateMap};
|
use state_res::{Event, StateMap};
|
||||||
|
@ -51,8 +51,8 @@ pub struct Rooms {
|
||||||
pub(super) userroomid_joined: sled::Tree,
|
pub(super) userroomid_joined: sled::Tree,
|
||||||
pub(super) roomuserid_joined: sled::Tree,
|
pub(super) roomuserid_joined: sled::Tree,
|
||||||
pub(super) roomuseroncejoinedids: sled::Tree,
|
pub(super) roomuseroncejoinedids: sled::Tree,
|
||||||
pub(super) userroomid_invited: sled::Tree,
|
pub(super) userroomid_invitestate: sled::Tree,
|
||||||
pub(super) roomuserid_invited: sled::Tree,
|
pub(super) roomuserid_invitecount: sled::Tree,
|
||||||
pub(super) userroomid_left: sled::Tree,
|
pub(super) userroomid_left: sled::Tree,
|
||||||
|
|
||||||
/// Remember the current state hash of a room.
|
/// Remember the current state hash of a room.
|
||||||
|
@ -145,12 +145,12 @@ impl Rooms {
|
||||||
|
|
||||||
/// Returns a single PDU from `room_id` with key (`event_type`, `state_key`).
|
/// Returns a single PDU from `room_id` with key (`event_type`, `state_key`).
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn state_get(
|
pub fn state_get_id(
|
||||||
&self,
|
&self,
|
||||||
shortstatehash: u64,
|
shortstatehash: u64,
|
||||||
event_type: &EventType,
|
event_type: &EventType,
|
||||||
state_key: &str,
|
state_key: &str,
|
||||||
) -> Result<Option<PduEvent>> {
|
) -> Result<Option<EventId>> {
|
||||||
let mut key = event_type.as_ref().as_bytes().to_vec();
|
let mut key = event_type.as_ref().as_bytes().to_vec();
|
||||||
key.push(0xff);
|
key.push(0xff);
|
||||||
key.extend_from_slice(&state_key.as_bytes());
|
key.extend_from_slice(&state_key.as_bytes());
|
||||||
|
@ -161,7 +161,8 @@ impl Rooms {
|
||||||
let mut stateid = shortstatehash.to_be_bytes().to_vec();
|
let mut stateid = shortstatehash.to_be_bytes().to_vec();
|
||||||
stateid.extend_from_slice(&shortstatekey);
|
stateid.extend_from_slice(&shortstatekey);
|
||||||
|
|
||||||
self.stateid_shorteventid
|
Ok(self
|
||||||
|
.stateid_shorteventid
|
||||||
.get(&stateid)?
|
.get(&stateid)?
|
||||||
.map(|bytes| self.shorteventid_eventid.get(&bytes).ok().flatten())
|
.map(|bytes| self.shorteventid_eventid.get(&bytes).ok().flatten())
|
||||||
.flatten()
|
.flatten()
|
||||||
|
@ -178,13 +179,24 @@ impl Rooms {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|r| r.ok())
|
.map(|r| r.ok())
|
||||||
.flatten()
|
.flatten())
|
||||||
.map_or(Ok(None), |event_id| self.get_pdu(&event_id))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a single PDU from `room_id` with key (`event_type`, `state_key`).
|
||||||
|
#[tracing::instrument(skip(self))]
|
||||||
|
pub fn state_get(
|
||||||
|
&self,
|
||||||
|
shortstatehash: u64,
|
||||||
|
event_type: &EventType,
|
||||||
|
state_key: &str,
|
||||||
|
) -> Result<Option<PduEvent>> {
|
||||||
|
self.state_get_id(shortstatehash, event_type, state_key)?
|
||||||
|
.map_or(Ok(None), |event_id| self.get_pdu(&event_id))
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the state hash for this pdu.
|
/// Returns the state hash for this pdu.
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn pdu_shortstatehash(&self, event_id: &EventId) -> Result<Option<u64>> {
|
pub fn pdu_shortstatehash(&self, event_id: &EventId) -> Result<Option<u64>> {
|
||||||
|
@ -354,6 +366,21 @@ impl Rooms {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a single PDU from `room_id` with key (`event_type`, `state_key`).
|
||||||
|
#[tracing::instrument(skip(self))]
|
||||||
|
pub fn room_state_get_id(
|
||||||
|
&self,
|
||||||
|
room_id: &RoomId,
|
||||||
|
event_type: &EventType,
|
||||||
|
state_key: &str,
|
||||||
|
) -> Result<Option<EventId>> {
|
||||||
|
if let Some(current_shortstatehash) = self.current_shortstatehash(room_id)? {
|
||||||
|
self.state_get_id(current_shortstatehash, event_type, state_key)
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a single PDU from `room_id` with key (`event_type`, `state_key`).
|
/// Returns a single PDU from `room_id` with key (`event_type`, `state_key`).
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn room_state_get(
|
pub fn room_state_get(
|
||||||
|
@ -395,7 +422,7 @@ impl Rooms {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the json of a pdu.
|
/// Returns the json of a pdu.
|
||||||
pub fn get_pdu_json(&self, event_id: &EventId) -> Result<Option<serde_json::Value>> {
|
pub fn get_pdu_json(&self, event_id: &EventId) -> Result<Option<CanonicalJsonObject>> {
|
||||||
self.eventid_pduid
|
self.eventid_pduid
|
||||||
.get(event_id.as_bytes())?
|
.get(event_id.as_bytes())?
|
||||||
.map_or_else::<Result<_>, _, _>(
|
.map_or_else::<Result<_>, _, _>(
|
||||||
|
@ -666,29 +693,64 @@ impl Rooms {
|
||||||
// if the state_key fails
|
// if the state_key fails
|
||||||
let target_user_id = UserId::try_from(state_key.clone())
|
let target_user_id = UserId::try_from(state_key.clone())
|
||||||
.expect("This state_key was previously validated");
|
.expect("This state_key was previously validated");
|
||||||
|
|
||||||
|
let membership = serde_json::from_value::<member::MembershipState>(
|
||||||
|
pdu.content
|
||||||
|
.get("membership")
|
||||||
|
.ok_or_else(|| {
|
||||||
|
Error::BadRequest(
|
||||||
|
ErrorKind::InvalidParam,
|
||||||
|
"Invalid member event content",
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
.map_err(|_| {
|
||||||
|
Error::BadRequest(
|
||||||
|
ErrorKind::InvalidParam,
|
||||||
|
"Invalid membership state content.",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let invite_state = match membership {
|
||||||
|
member::MembershipState::Invite => {
|
||||||
|
let mut state = Vec::new();
|
||||||
|
// Add recommended events
|
||||||
|
if let Some(e) =
|
||||||
|
self.room_state_get(&pdu.room_id, &EventType::RoomJoinRules, "")?
|
||||||
|
{
|
||||||
|
state.push(e.to_stripped_state_event());
|
||||||
|
}
|
||||||
|
if let Some(e) = self.room_state_get(
|
||||||
|
&pdu.room_id,
|
||||||
|
&EventType::RoomCanonicalAlias,
|
||||||
|
"",
|
||||||
|
)? {
|
||||||
|
state.push(e.to_stripped_state_event());
|
||||||
|
}
|
||||||
|
if let Some(e) =
|
||||||
|
self.room_state_get(&pdu.room_id, &EventType::RoomAvatar, "")?
|
||||||
|
{
|
||||||
|
state.push(e.to_stripped_state_event());
|
||||||
|
}
|
||||||
|
if let Some(e) =
|
||||||
|
self.room_state_get(&pdu.room_id, &EventType::RoomName, "")?
|
||||||
|
{
|
||||||
|
state.push(e.to_stripped_state_event());
|
||||||
|
}
|
||||||
|
Some(state)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
// Update our membership info, we do this here incase a user is invited
|
// Update our membership info, we do this here incase a user is invited
|
||||||
// and immediately leaves we need the DB to record the invite event for auth
|
// and immediately leaves we need the DB to record the invite event for auth
|
||||||
self.update_membership(
|
self.update_membership(
|
||||||
&pdu.room_id,
|
&pdu.room_id,
|
||||||
&target_user_id,
|
&target_user_id,
|
||||||
serde_json::from_value::<member::MembershipState>(
|
membership,
|
||||||
pdu.content
|
|
||||||
.get("membership")
|
|
||||||
.ok_or_else(|| {
|
|
||||||
Error::BadRequest(
|
|
||||||
ErrorKind::InvalidParam,
|
|
||||||
"Invalid member event content",
|
|
||||||
)
|
|
||||||
})?
|
|
||||||
.clone(),
|
|
||||||
)
|
|
||||||
.map_err(|_| {
|
|
||||||
Error::BadRequest(
|
|
||||||
ErrorKind::InvalidParam,
|
|
||||||
"Invalid membership state content.",
|
|
||||||
)
|
|
||||||
})?,
|
|
||||||
&pdu.sender,
|
&pdu.sender,
|
||||||
|
invite_state,
|
||||||
&db.account_data,
|
&db.account_data,
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
@ -1044,10 +1106,10 @@ impl Rooms {
|
||||||
// Our depth is the maximum depth of prev_events + 1
|
// Our depth is the maximum depth of prev_events + 1
|
||||||
let depth = prev_events
|
let depth = prev_events
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|event_id| Some(self.get_pdu_json(event_id).ok()??.get("depth")?.as_u64()?))
|
.filter_map(|event_id| Some(self.get_pdu(event_id).ok()??.depth))
|
||||||
.max()
|
.max()
|
||||||
.unwrap_or(0_u64)
|
.unwrap_or(uint!(0))
|
||||||
+ 1;
|
+ uint!(1);
|
||||||
|
|
||||||
let mut unsigned = unsigned.unwrap_or_default();
|
let mut unsigned = unsigned.unwrap_or_default();
|
||||||
if let Some(state_key) = &state_key {
|
if let Some(state_key) = &state_key {
|
||||||
|
@ -1071,9 +1133,7 @@ impl Rooms {
|
||||||
content,
|
content,
|
||||||
state_key,
|
state_key,
|
||||||
prev_events,
|
prev_events,
|
||||||
depth: depth
|
depth,
|
||||||
.try_into()
|
|
||||||
.map_err(|_| Error::bad_database("Depth is invalid"))?,
|
|
||||||
auth_events: auth_events
|
auth_events: auth_events
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, pdu)| pdu.event_id.clone())
|
.map(|(_, pdu)| pdu.event_id.clone())
|
||||||
|
@ -1384,6 +1444,7 @@ impl Rooms {
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
membership: member::MembershipState,
|
membership: member::MembershipState,
|
||||||
sender: &UserId,
|
sender: &UserId,
|
||||||
|
invite_state: Option<Vec<Raw<AnyStrippedStateEvent>>>,
|
||||||
account_data: &super::account_data::AccountData,
|
account_data: &super::account_data::AccountData,
|
||||||
globals: &super::globals::Globals,
|
globals: &super::globals::Globals,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -1487,8 +1548,8 @@ impl Rooms {
|
||||||
self.roomserverids.insert(&roomserver_id, &[])?;
|
self.roomserverids.insert(&roomserver_id, &[])?;
|
||||||
self.userroomid_joined.insert(&userroom_id, &[])?;
|
self.userroomid_joined.insert(&userroom_id, &[])?;
|
||||||
self.roomuserid_joined.insert(&roomuser_id, &[])?;
|
self.roomuserid_joined.insert(&roomuser_id, &[])?;
|
||||||
self.userroomid_invited.remove(&userroom_id)?;
|
self.userroomid_invitestate.remove(&userroom_id)?;
|
||||||
self.roomuserid_invited.remove(&roomuser_id)?;
|
self.roomuserid_invitecount.remove(&roomuser_id)?;
|
||||||
self.userroomid_left.remove(&userroom_id)?;
|
self.userroomid_left.remove(&userroom_id)?;
|
||||||
}
|
}
|
||||||
member::MembershipState::Invite => {
|
member::MembershipState::Invite => {
|
||||||
|
@ -1508,8 +1569,13 @@ impl Rooms {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.roomserverids.insert(&roomserver_id, &[])?;
|
self.roomserverids.insert(&roomserver_id, &[])?;
|
||||||
self.userroomid_invited.insert(&userroom_id, &[])?;
|
self.userroomid_invitestate.insert(
|
||||||
self.roomuserid_invited.insert(&roomuser_id, &[])?;
|
&userroom_id,
|
||||||
|
serde_json::to_vec(&invite_state.unwrap_or_default())
|
||||||
|
.expect("state to bytes always works"),
|
||||||
|
)?;
|
||||||
|
self.roomuserid_invitecount
|
||||||
|
.insert(&roomuser_id, &globals.next_count()?.to_be_bytes())?;
|
||||||
self.userroomid_joined.remove(&userroom_id)?;
|
self.userroomid_joined.remove(&userroom_id)?;
|
||||||
self.roomuserid_joined.remove(&roomuser_id)?;
|
self.roomuserid_joined.remove(&roomuser_id)?;
|
||||||
self.userroomid_left.remove(&userroom_id)?;
|
self.userroomid_left.remove(&userroom_id)?;
|
||||||
|
@ -1526,8 +1592,8 @@ impl Rooms {
|
||||||
self.userroomid_left.insert(&userroom_id, &[])?;
|
self.userroomid_left.insert(&userroom_id, &[])?;
|
||||||
self.userroomid_joined.remove(&userroom_id)?;
|
self.userroomid_joined.remove(&userroom_id)?;
|
||||||
self.roomuserid_joined.remove(&roomuser_id)?;
|
self.roomuserid_joined.remove(&roomuser_id)?;
|
||||||
self.userroomid_invited.remove(&userroom_id)?;
|
self.userroomid_invitestate.remove(&userroom_id)?;
|
||||||
self.roomuserid_invited.remove(&roomuser_id)?;
|
self.roomuserid_invitecount.remove(&roomuser_id)?;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -1797,7 +1863,7 @@ impl Rooms {
|
||||||
let mut prefix = room_id.as_bytes().to_vec();
|
let mut prefix = room_id.as_bytes().to_vec();
|
||||||
prefix.push(0xff);
|
prefix.push(0xff);
|
||||||
|
|
||||||
self.roomuserid_invited
|
self.roomuserid_invitecount
|
||||||
.scan_prefix(prefix)
|
.scan_prefix(prefix)
|
||||||
.keys()
|
.keys()
|
||||||
.map(|key| {
|
.map(|key| {
|
||||||
|
@ -1816,6 +1882,22 @@ impl Rooms {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over all invited members of a room.
|
||||||
|
#[tracing::instrument(skip(self))]
|
||||||
|
pub fn get_invite_count(&self, room_id: &RoomId, user_id: &UserId) -> Result<Option<u64>> {
|
||||||
|
let mut key = room_id.as_bytes().to_vec();
|
||||||
|
key.push(0xff);
|
||||||
|
key.extend_from_slice(user_id.as_bytes());
|
||||||
|
|
||||||
|
self.roomuserid_invitecount
|
||||||
|
.get(key)?
|
||||||
|
.map_or(Ok(None), |bytes| {
|
||||||
|
Ok(Some(utils::u64_from_bytes(&bytes).map_err(|_| {
|
||||||
|
Error::bad_database("Invalid invitecount in db.")
|
||||||
|
})?))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all rooms this user joined.
|
/// Returns an iterator over all rooms this user joined.
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn rooms_joined(&self, user_id: &UserId) -> impl Iterator<Item = Result<RoomId>> {
|
pub fn rooms_joined(&self, user_id: &UserId) -> impl Iterator<Item = Result<RoomId>> {
|
||||||
|
@ -1840,27 +1922,32 @@ impl Rooms {
|
||||||
|
|
||||||
/// Returns an iterator over all rooms a user was invited to.
|
/// Returns an iterator over all rooms a user was invited to.
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn rooms_invited(&self, user_id: &UserId) -> impl Iterator<Item = Result<RoomId>> {
|
pub fn rooms_invited(
|
||||||
|
&self,
|
||||||
|
user_id: &UserId,
|
||||||
|
) -> impl Iterator<Item = Result<(RoomId, Vec<Raw<AnyStrippedStateEvent>>)>> {
|
||||||
let mut prefix = user_id.as_bytes().to_vec();
|
let mut prefix = user_id.as_bytes().to_vec();
|
||||||
prefix.push(0xff);
|
prefix.push(0xff);
|
||||||
|
|
||||||
self.userroomid_invited
|
self.userroomid_invitestate.scan_prefix(prefix).map(|r| {
|
||||||
.scan_prefix(prefix)
|
let (key, state) = r?;
|
||||||
.keys()
|
let room_id = RoomId::try_from(
|
||||||
.map(|key| {
|
utils::string_from_bytes(
|
||||||
Ok(RoomId::try_from(
|
&key.rsplit(|&b| b == 0xff)
|
||||||
utils::string_from_bytes(
|
.next()
|
||||||
&key?
|
.expect("rsplit always returns an element"),
|
||||||
.rsplit(|&b| b == 0xff)
|
|
||||||
.next()
|
|
||||||
.expect("rsplit always returns an element"),
|
|
||||||
)
|
|
||||||
.map_err(|_| {
|
|
||||||
Error::bad_database("Room ID in userroomid_invited is invalid unicode.")
|
|
||||||
})?,
|
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("Room ID in userroomid_invited is invalid."))?)
|
.map_err(|_| {
|
||||||
})
|
Error::bad_database("Room ID in userroomid_invited is invalid unicode.")
|
||||||
|
})?,
|
||||||
|
)
|
||||||
|
.map_err(|_| Error::bad_database("Room ID in userroomid_invited is invalid."))?;
|
||||||
|
|
||||||
|
let state = serde_json::from_slice(&state)
|
||||||
|
.map_err(|_| Error::bad_database("Invalid state in userroomid_invitestate."))?;
|
||||||
|
|
||||||
|
Ok((room_id, state))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all rooms a user left.
|
/// Returns an iterator over all rooms a user left.
|
||||||
|
@ -1906,7 +1993,7 @@ impl Rooms {
|
||||||
userroom_id.push(0xff);
|
userroom_id.push(0xff);
|
||||||
userroom_id.extend_from_slice(room_id.as_bytes());
|
userroom_id.extend_from_slice(room_id.as_bytes());
|
||||||
|
|
||||||
Ok(self.userroomid_invited.get(userroom_id)?.is_some())
|
Ok(self.userroomid_invitestate.get(userroom_id)?.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_left(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> {
|
pub fn is_left(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> {
|
||||||
|
|
|
@ -167,6 +167,7 @@ fn setup_rocket() -> (rocket::Rocket, Config) {
|
||||||
server_server::get_event_route,
|
server_server::get_event_route,
|
||||||
server_server::get_missing_events_route,
|
server_server::get_missing_events_route,
|
||||||
server_server::get_room_state_ids_route,
|
server_server::get_room_state_ids_route,
|
||||||
|
server_server::create_invite_route,
|
||||||
server_server::get_profile_information_route,
|
server_server::get_profile_information_route,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,20 +10,24 @@ use ruma::{
|
||||||
federation::{
|
federation::{
|
||||||
directory::{get_public_rooms, get_public_rooms_filtered},
|
directory::{get_public_rooms, get_public_rooms_filtered},
|
||||||
discovery::{
|
discovery::{
|
||||||
get_remote_server_keys, get_server_keys,
|
get_remote_server_keys, get_server_keys, get_server_version, ServerSigningKeys,
|
||||||
get_server_version::v1 as get_server_version, ServerSigningKeys, VerifyKey,
|
VerifyKey,
|
||||||
},
|
},
|
||||||
event::{get_event, get_missing_events, get_room_state_ids},
|
event::{get_event, get_missing_events, get_room_state_ids},
|
||||||
|
membership::create_invite,
|
||||||
query::get_profile_information,
|
query::get_profile_information,
|
||||||
transactions::send_transaction_message,
|
transactions::send_transaction_message,
|
||||||
},
|
},
|
||||||
OutgoingRequest,
|
OutgoingRequest,
|
||||||
},
|
},
|
||||||
directory::{IncomingFilter, IncomingRoomNetwork},
|
directory::{IncomingFilter, IncomingRoomNetwork},
|
||||||
events::{room::create::CreateEventContent, EventType},
|
events::{
|
||||||
|
room::{create::CreateEventContent, member::MembershipState},
|
||||||
|
EventType,
|
||||||
|
},
|
||||||
serde::{to_canonical_value, Raw},
|
serde::{to_canonical_value, Raw},
|
||||||
signatures::CanonicalJsonValue,
|
signatures::CanonicalJsonValue,
|
||||||
EventId, RoomId, ServerName, ServerSigningKeyId, UserId,
|
EventId, RoomId, RoomVersionId, ServerName, ServerSigningKeyId, UserId,
|
||||||
};
|
};
|
||||||
use state_res::{Event, EventMap, StateMap};
|
use state_res::{Event, EventMap, StateMap};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -332,13 +336,13 @@ pub async fn request_well_known(
|
||||||
#[tracing::instrument(skip(db))]
|
#[tracing::instrument(skip(db))]
|
||||||
pub fn get_server_version_route(
|
pub fn get_server_version_route(
|
||||||
db: State<'_, Database>,
|
db: State<'_, Database>,
|
||||||
) -> ConduitResult<get_server_version::Response> {
|
) -> ConduitResult<get_server_version::v1::Response> {
|
||||||
if !db.globals.allow_federation() {
|
if !db.globals.allow_federation() {
|
||||||
return Err(Error::bad_config("Federation is disabled."));
|
return Err(Error::bad_config("Federation is disabled."));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(get_server_version::Response {
|
Ok(get_server_version::v1::Response {
|
||||||
server: Some(get_server_version::Server {
|
server: Some(get_server_version::v1::Server {
|
||||||
name: Some("Conduit".to_owned()),
|
name: Some("Conduit".to_owned()),
|
||||||
version: Some(env!("CARGO_PKG_VERSION").to_owned()),
|
version: Some(env!("CARGO_PKG_VERSION").to_owned()),
|
||||||
}),
|
}),
|
||||||
|
@ -1406,12 +1410,9 @@ pub fn get_event_route<'a>(
|
||||||
origin: db.globals.server_name().to_owned(),
|
origin: db.globals.server_name().to_owned(),
|
||||||
origin_server_ts: SystemTime::now(),
|
origin_server_ts: SystemTime::now(),
|
||||||
pdu: PduEvent::convert_to_outgoing_federation_event(
|
pdu: PduEvent::convert_to_outgoing_federation_event(
|
||||||
serde_json::from_value(
|
db.rooms
|
||||||
db.rooms
|
.get_pdu_json(&body.event_id)?
|
||||||
.get_pdu_json(&body.event_id)?
|
.ok_or(Error::BadRequest(ErrorKind::NotFound, "Event not found."))?,
|
||||||
.ok_or(Error::BadRequest(ErrorKind::NotFound, "Event not found."))?,
|
|
||||||
)
|
|
||||||
.map_err(|_| Error::bad_database("Invalid pdu in database."))?,
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
|
@ -1438,9 +1439,10 @@ pub fn get_missing_events_route<'a>(
|
||||||
if let Some(pdu) = db.rooms.get_pdu_json(&queued_events[i])? {
|
if let Some(pdu) = db.rooms.get_pdu_json(&queued_events[i])? {
|
||||||
if body.earliest_events.contains(
|
if body.earliest_events.contains(
|
||||||
&serde_json::from_value(
|
&serde_json::from_value(
|
||||||
pdu.get("event_id")
|
serde_json::to_value(pdu.get("event_id").cloned().ok_or_else(|| {
|
||||||
.cloned()
|
Error::bad_database("Event in db has no event_id field.")
|
||||||
.ok_or_else(|| Error::bad_database("Event in db has no event_id field."))?,
|
})?)
|
||||||
|
.expect("canonical json is valid json value"),
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("Invalid event_id field in pdu in db."))?,
|
.map_err(|_| Error::bad_database("Invalid event_id field in pdu in db."))?,
|
||||||
) {
|
) {
|
||||||
|
@ -1449,16 +1451,14 @@ pub fn get_missing_events_route<'a>(
|
||||||
}
|
}
|
||||||
queued_events.extend_from_slice(
|
queued_events.extend_from_slice(
|
||||||
&serde_json::from_value::<Vec<EventId>>(
|
&serde_json::from_value::<Vec<EventId>>(
|
||||||
pdu.get("prev_events").cloned().ok_or_else(|| {
|
serde_json::to_value(pdu.get("prev_events").cloned().ok_or_else(|| {
|
||||||
Error::bad_database("Invalid prev_events field of pdu in db.")
|
Error::bad_database("Event in db has no prev_events field.")
|
||||||
})?,
|
})?)
|
||||||
|
.expect("canonical json is valid json value"),
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("Invalid prev_events content in pdu in db."))?,
|
.map_err(|_| Error::bad_database("Invalid prev_events content in pdu in db."))?,
|
||||||
);
|
);
|
||||||
events.push(PduEvent::convert_to_outgoing_federation_event(
|
events.push(PduEvent::convert_to_outgoing_federation_event(pdu));
|
||||||
serde_json::from_value(pdu)
|
|
||||||
.map_err(|_| Error::bad_database("Invalid pdu in database."))?,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
@ -1518,6 +1518,93 @@ pub fn get_room_state_ids_route<'a>(
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "conduit_bin",
|
||||||
|
put("/_matrix/federation/v2/invite/<_>/<_>", data = "<body>")
|
||||||
|
)]
|
||||||
|
#[tracing::instrument(skip(db, body))]
|
||||||
|
pub fn create_invite_route<'a>(
|
||||||
|
db: State<'a, Database>,
|
||||||
|
body: Ruma<create_invite::v2::Request>,
|
||||||
|
) -> ConduitResult<create_invite::v2::Response> {
|
||||||
|
if body.room_version < RoomVersionId::Version6 {
|
||||||
|
return Err(Error::BadRequest(
|
||||||
|
ErrorKind::IncompatibleRoomVersion {
|
||||||
|
room_version: body.room_version.clone(),
|
||||||
|
},
|
||||||
|
"Server does not support this room version.",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut signed_event = utils::to_canonical_object(&body.event)
|
||||||
|
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invite event is invalid."))?;
|
||||||
|
|
||||||
|
ruma::signatures::hash_and_sign_event(
|
||||||
|
db.globals.server_name().as_str(),
|
||||||
|
db.globals.keypair(),
|
||||||
|
&mut signed_event,
|
||||||
|
&body.room_version,
|
||||||
|
)
|
||||||
|
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Failed to sign event."))?;
|
||||||
|
|
||||||
|
let sender = serde_json::from_value(
|
||||||
|
serde_json::to_value(
|
||||||
|
signed_event
|
||||||
|
.get("sender")
|
||||||
|
.ok_or_else(|| {
|
||||||
|
Error::BadRequest(ErrorKind::InvalidParam, "Event had no sender field.")
|
||||||
|
})?
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
.expect("CanonicalJsonValue to serde_json::Value always works"),
|
||||||
|
)
|
||||||
|
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "sender is not a user id."))?;
|
||||||
|
let invited_user = serde_json::from_value(
|
||||||
|
serde_json::to_value(
|
||||||
|
signed_event
|
||||||
|
.get("state_key")
|
||||||
|
.ok_or_else(|| {
|
||||||
|
Error::BadRequest(ErrorKind::InvalidParam, "Event had no state_key field.")
|
||||||
|
})?
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
.expect("CanonicalJsonValue to serde_json::Value always works"),
|
||||||
|
)
|
||||||
|
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "state_key is not a user id."))?;
|
||||||
|
|
||||||
|
let mut invite_state = body.invite_room_state.clone();
|
||||||
|
|
||||||
|
let mut event = serde_json::from_str::<serde_json::Map<String, serde_json::Value>>(
|
||||||
|
&body.event.json().to_string(),
|
||||||
|
)
|
||||||
|
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid invite event bytes."))?;
|
||||||
|
|
||||||
|
event.insert("event_id".to_owned(), "$dummy".into());
|
||||||
|
invite_state.push(
|
||||||
|
serde_json::from_value::<PduEvent>(event.into())
|
||||||
|
.map_err(|e| {
|
||||||
|
warn!("Invalid invite event: {}", e);
|
||||||
|
Error::BadRequest(ErrorKind::InvalidParam, "Invalid invite event.")
|
||||||
|
})?
|
||||||
|
.to_stripped_state_event(),
|
||||||
|
);
|
||||||
|
|
||||||
|
db.rooms.update_membership(
|
||||||
|
&body.room_id,
|
||||||
|
&invited_user,
|
||||||
|
MembershipState::Invite,
|
||||||
|
&sender,
|
||||||
|
Some(invite_state),
|
||||||
|
&db.account_data,
|
||||||
|
&db.globals,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(create_invite::v2::Response {
|
||||||
|
event: PduEvent::convert_to_outgoing_federation_event(signed_event),
|
||||||
|
}
|
||||||
|
.into())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "conduit_bin",
|
feature = "conduit_bin",
|
||||||
get("/_matrix/federation/v1/query/profile", data = "<body>")
|
get("/_matrix/federation/v1/query/profile", data = "<body>")
|
||||||
|
|
Loading…
Reference in New Issue