feat: presence updates
This commit is contained in:
parent
551308e9a8
commit
ee0d6940bd
5 changed files with 293 additions and 193 deletions
|
@ -12,7 +12,6 @@ use ruma_client_api::{
|
||||||
account::{get_username_availability, register},
|
account::{get_username_availability, register},
|
||||||
alias::get_alias,
|
alias::get_alias,
|
||||||
capabilities::get_capabilities,
|
capabilities::get_capabilities,
|
||||||
to_device::send_event_to_device,
|
|
||||||
config::{get_global_account_data, set_global_account_data},
|
config::{get_global_account_data, set_global_account_data},
|
||||||
directory::{self, get_public_rooms_filtered},
|
directory::{self, get_public_rooms_filtered},
|
||||||
filter::{self, create_filter, get_filter},
|
filter::{self, create_filter, get_filter},
|
||||||
|
@ -34,13 +33,14 @@ use ruma_client_api::{
|
||||||
state::{create_state_event_for_empty_key, create_state_event_for_key},
|
state::{create_state_event_for_empty_key, create_state_event_for_key},
|
||||||
sync::sync_events,
|
sync::sync_events,
|
||||||
thirdparty::get_protocols,
|
thirdparty::get_protocols,
|
||||||
|
to_device::send_event_to_device,
|
||||||
typing::create_typing_event,
|
typing::create_typing_event,
|
||||||
uiaa::{AuthFlow, UiaaInfo, UiaaResponse},
|
uiaa::{AuthFlow, UiaaInfo, UiaaResponse},
|
||||||
user_directory::search_users,
|
user_directory::search_users,
|
||||||
},
|
},
|
||||||
unversioned::get_supported_versions,
|
unversioned::get_supported_versions,
|
||||||
};
|
};
|
||||||
use ruma_events::{collections::only::Event as EduEvent, EventType};
|
use ruma_events::{collections::only::Event as EduEvent, EventJson, EventType};
|
||||||
use ruma_identifiers::{RoomId, UserId};
|
use ruma_identifiers::{RoomId, UserId};
|
||||||
use serde_json::{json, value::RawValue};
|
use serde_json::{json, value::RawValue};
|
||||||
|
|
||||||
|
@ -165,45 +165,45 @@ pub fn register_route(
|
||||||
let token = utils::random_string(TOKEN_LENGTH);
|
let token = utils::random_string(TOKEN_LENGTH);
|
||||||
|
|
||||||
// Add device
|
// Add device
|
||||||
db
|
db.users
|
||||||
.users
|
|
||||||
.create_device(&user_id, &device_id, &token)
|
.create_device(&user_id, &device_id, &token)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Initial data
|
// Initial data
|
||||||
db.account_data.update(
|
db.account_data
|
||||||
None,
|
.update(
|
||||||
&user_id,
|
None,
|
||||||
EduEvent::PushRules(ruma_events::push_rules::PushRulesEvent {
|
&user_id,
|
||||||
content: ruma_events::push_rules::PushRulesEventContent {
|
EduEvent::PushRules(ruma_events::push_rules::PushRulesEvent {
|
||||||
global: ruma_events::push_rules::Ruleset {
|
content: ruma_events::push_rules::PushRulesEventContent {
|
||||||
content: vec![],
|
global: ruma_events::push_rules::Ruleset {
|
||||||
override_rules: vec![],
|
content: vec![],
|
||||||
room: vec![],
|
override_rules: vec![],
|
||||||
sender: vec![],
|
room: vec![],
|
||||||
underride: vec![ruma_events::push_rules::ConditionalPushRule {
|
sender: vec![],
|
||||||
actions: vec![
|
underride: vec![ruma_events::push_rules::ConditionalPushRule {
|
||||||
ruma_events::push_rules::Action::Notify,
|
actions: vec![
|
||||||
ruma_events::push_rules::Action::SetTweak(
|
ruma_events::push_rules::Action::Notify,
|
||||||
ruma_common::push::Tweak::Highlight(false),
|
ruma_events::push_rules::Action::SetTweak(
|
||||||
),
|
ruma_common::push::Tweak::Highlight(false),
|
||||||
],
|
),
|
||||||
default: true,
|
],
|
||||||
enabled: true,
|
default: true,
|
||||||
rule_id: ".m.rule.message".to_owned(),
|
enabled: true,
|
||||||
conditions: vec![ruma_events::push_rules::PushCondition::EventMatch(
|
rule_id: ".m.rule.message".to_owned(),
|
||||||
ruma_events::push_rules::EventMatchCondition {
|
conditions: vec![ruma_events::push_rules::PushCondition::EventMatch(
|
||||||
key: "type".to_owned(),
|
ruma_events::push_rules::EventMatchCondition {
|
||||||
pattern: "m.room.message".to_owned(),
|
key: "type".to_owned(),
|
||||||
},
|
pattern: "m.room.message".to_owned(),
|
||||||
)],
|
},
|
||||||
}],
|
)],
|
||||||
|
}],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}),
|
||||||
}),
|
&db.globals,
|
||||||
&db.globals,
|
)
|
||||||
)
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
MatrixResult(Ok(register::Response {
|
MatrixResult(Ok(register::Response {
|
||||||
access_token: Some(token),
|
access_token: Some(token),
|
||||||
|
@ -220,7 +220,10 @@ pub fn get_login_route() -> MatrixResult<get_login_types::Response> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/_matrix/client/r0/login", data = "<body>")]
|
#[post("/_matrix/client/r0/login", data = "<body>")]
|
||||||
pub fn login_route(db: State<'_, Database>, body: Ruma<login::Request>) -> MatrixResult<login::Response> {
|
pub fn login_route(
|
||||||
|
db: State<'_, Database>,
|
||||||
|
body: Ruma<login::Request>,
|
||||||
|
) -> MatrixResult<login::Response> {
|
||||||
// Validate login method
|
// Validate login method
|
||||||
let user_id =
|
let user_id =
|
||||||
if let (login::UserInfo::MatrixId(mut username), login::LoginInfo::Password { password }) =
|
if let (login::UserInfo::MatrixId(mut username), login::LoginInfo::Password { password }) =
|
||||||
|
@ -280,8 +283,7 @@ pub fn login_route(db: State<'_, Database>, body: Ruma<login::Request>) -> Matri
|
||||||
let token = utils::random_string(TOKEN_LENGTH);
|
let token = utils::random_string(TOKEN_LENGTH);
|
||||||
|
|
||||||
// Add device
|
// Add device
|
||||||
db
|
db.users
|
||||||
.users
|
|
||||||
.create_device(&user_id, &device_id, &token)
|
.create_device(&user_id, &device_id, &token)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -318,7 +320,7 @@ pub fn get_pushrules_all_route() -> MatrixResult<get_pushrules_all::Response> {
|
||||||
vec![push::PushRule {
|
vec![push::PushRule {
|
||||||
actions: vec![
|
actions: vec![
|
||||||
push::Action::Notify,
|
push::Action::Notify,
|
||||||
push::Action::SetTweak(ruma_common::push::Tweak::Highlight(false))
|
push::Action::SetTweak(ruma_common::push::Tweak::Highlight(false)),
|
||||||
],
|
],
|
||||||
default: true,
|
default: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -346,39 +348,40 @@ pub fn set_pushrule_route(
|
||||||
) -> MatrixResult<set_pushrule::Response> {
|
) -> MatrixResult<set_pushrule::Response> {
|
||||||
// TODO
|
// TODO
|
||||||
let user_id = body.user_id.clone().expect("user is authenticated");
|
let user_id = body.user_id.clone().expect("user is authenticated");
|
||||||
db.account_data.update(
|
db.account_data
|
||||||
None,
|
.update(
|
||||||
&user_id,
|
None,
|
||||||
EduEvent::PushRules(ruma_events::push_rules::PushRulesEvent {
|
&user_id,
|
||||||
content: ruma_events::push_rules::PushRulesEventContent {
|
EduEvent::PushRules(ruma_events::push_rules::PushRulesEvent {
|
||||||
global: ruma_events::push_rules::Ruleset {
|
content: ruma_events::push_rules::PushRulesEventContent {
|
||||||
content: vec![],
|
global: ruma_events::push_rules::Ruleset {
|
||||||
override_rules: vec![],
|
content: vec![],
|
||||||
room: vec![],
|
override_rules: vec![],
|
||||||
sender: vec![],
|
room: vec![],
|
||||||
underride: vec![ruma_events::push_rules::ConditionalPushRule {
|
sender: vec![],
|
||||||
actions: vec![
|
underride: vec![ruma_events::push_rules::ConditionalPushRule {
|
||||||
ruma_events::push_rules::Action::Notify,
|
actions: vec![
|
||||||
ruma_events::push_rules::Action::SetTweak(
|
ruma_events::push_rules::Action::Notify,
|
||||||
ruma_common::push::Tweak::Highlight(false),
|
ruma_events::push_rules::Action::SetTweak(
|
||||||
),
|
ruma_common::push::Tweak::Highlight(false),
|
||||||
],
|
),
|
||||||
default: true,
|
],
|
||||||
enabled: true,
|
default: true,
|
||||||
rule_id: ".m.rule.message".to_owned(),
|
enabled: true,
|
||||||
conditions: vec![ruma_events::push_rules::PushCondition::EventMatch(
|
rule_id: ".m.rule.message".to_owned(),
|
||||||
ruma_events::push_rules::EventMatchCondition {
|
conditions: vec![ruma_events::push_rules::PushCondition::EventMatch(
|
||||||
key: "type".to_owned(),
|
ruma_events::push_rules::EventMatchCondition {
|
||||||
pattern: "m.room.message".to_owned(),
|
key: "type".to_owned(),
|
||||||
},
|
pattern: "m.room.message".to_owned(),
|
||||||
)],
|
},
|
||||||
}],
|
)],
|
||||||
|
}],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}),
|
||||||
}),
|
&db.globals,
|
||||||
&db.globals
|
)
|
||||||
)
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
MatrixResult(Ok(set_pushrule::Response))
|
MatrixResult(Ok(set_pushrule::Response))
|
||||||
}
|
}
|
||||||
|
@ -393,9 +396,7 @@ pub fn set_pushrule_enabled_route(
|
||||||
MatrixResult(Ok(set_pushrule_enabled::Response))
|
MatrixResult(Ok(set_pushrule_enabled::Response))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get(
|
#[get("/_matrix/client/r0/user/<_user_id>/filter/<_filter_id>")]
|
||||||
"/_matrix/client/r0/user/<_user_id>/filter/<_filter_id>",
|
|
||||||
)]
|
|
||||||
pub fn get_filter_route(
|
pub fn get_filter_route(
|
||||||
_user_id: String,
|
_user_id: String,
|
||||||
_filter_id: String,
|
_filter_id: String,
|
||||||
|
@ -413,18 +414,14 @@ pub fn get_filter_route(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/_matrix/client/r0/user/<_user_id>/filter")]
|
#[post("/_matrix/client/r0/user/<_user_id>/filter")]
|
||||||
pub fn create_filter_route(
|
pub fn create_filter_route(_user_id: String) -> MatrixResult<create_filter::Response> {
|
||||||
_user_id: String,
|
|
||||||
) -> MatrixResult<create_filter::Response> {
|
|
||||||
// TODO
|
// TODO
|
||||||
MatrixResult(Ok(create_filter::Response {
|
MatrixResult(Ok(create_filter::Response {
|
||||||
filter_id: utils::random_string(10),
|
filter_id: utils::random_string(10),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[put(
|
#[put("/_matrix/client/r0/user/<_user_id>/account_data/<_type>")]
|
||||||
"/_matrix/client/r0/user/<_user_id>/account_data/<_type>",
|
|
||||||
)]
|
|
||||||
pub fn set_global_account_data_route(
|
pub fn set_global_account_data_route(
|
||||||
_user_id: String,
|
_user_id: String,
|
||||||
_type: String,
|
_type: String,
|
||||||
|
@ -432,9 +429,7 @@ pub fn set_global_account_data_route(
|
||||||
MatrixResult(Ok(set_global_account_data::Response))
|
MatrixResult(Ok(set_global_account_data::Response))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get(
|
#[get("/_matrix/client/r0/user/<_user_id>/account_data/<_type>")]
|
||||||
"/_matrix/client/r0/user/<_user_id>/account_data/<_type>",
|
|
||||||
)]
|
|
||||||
pub fn get_global_account_data_route(
|
pub fn get_global_account_data_route(
|
||||||
_user_id: String,
|
_user_id: String,
|
||||||
_type: String,
|
_type: String,
|
||||||
|
@ -460,25 +455,44 @@ pub fn set_displayname_route(
|
||||||
if displayname == "" {
|
if displayname == "" {
|
||||||
db.users.set_displayname(&user_id, None).unwrap();
|
db.users.set_displayname(&user_id, None).unwrap();
|
||||||
} else {
|
} else {
|
||||||
db
|
db.users
|
||||||
.users
|
|
||||||
.set_displayname(&user_id, Some(displayname.clone()))
|
.set_displayname(&user_id, Some(displayname.clone()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a new membership event into all joined rooms
|
// Send a new membership event into all joined rooms
|
||||||
for room_id in db.rooms.rooms_joined(&user_id) {
|
for room_id in db.rooms.rooms_joined(&user_id) {
|
||||||
db.rooms.append_pdu(
|
db.rooms
|
||||||
room_id.unwrap(),
|
.append_pdu(
|
||||||
user_id.clone(),
|
room_id.unwrap(),
|
||||||
EventType::RoomMember,
|
user_id.clone(),
|
||||||
json!({"membership": "join", "displayname": displayname}),
|
EventType::RoomMember,
|
||||||
None,
|
json!({"membership": "join", "displayname": displayname}),
|
||||||
Some(user_id.to_string()),
|
None,
|
||||||
&db.globals
|
Some(user_id.to_string()),
|
||||||
).unwrap();
|
&db.globals,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
// TODO: send a new m.presence event
|
|
||||||
|
// Presence update
|
||||||
|
db.global_edus
|
||||||
|
.update_globallatest(
|
||||||
|
&user_id,
|
||||||
|
EduEvent::Presence(ruma_events::presence::PresenceEvent {
|
||||||
|
content: ruma_events::presence::PresenceEventContent {
|
||||||
|
avatar_url: db.users.avatar_url(&user_id).unwrap(),
|
||||||
|
currently_active: None,
|
||||||
|
displayname: db.users.displayname(&user_id).unwrap(),
|
||||||
|
last_active_ago: Some(utils::millis_since_unix_epoch().try_into().unwrap()),
|
||||||
|
presence: ruma_events::presence::PresenceState::Online,
|
||||||
|
status_msg: None,
|
||||||
|
},
|
||||||
|
sender: user_id.clone(),
|
||||||
|
}),
|
||||||
|
&db.globals,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
} else {
|
} else {
|
||||||
// Send error on None
|
// Send error on None
|
||||||
// Synapse returns a parsing error but the spec doesn't require this
|
// Synapse returns a parsing error but the spec doesn't require this
|
||||||
|
@ -542,8 +556,7 @@ pub fn set_avatar_url_route(
|
||||||
if body.avatar_url == "" {
|
if body.avatar_url == "" {
|
||||||
db.users.set_avatar_url(&user_id, None).unwrap();
|
db.users.set_avatar_url(&user_id, None).unwrap();
|
||||||
} else {
|
} else {
|
||||||
db
|
db.users
|
||||||
.users
|
|
||||||
.set_avatar_url(&user_id, Some(body.avatar_url.clone()))
|
.set_avatar_url(&user_id, Some(body.avatar_url.clone()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// TODO send a new m.room.member join event with the updated avatar_url
|
// TODO send a new m.room.member join event with the updated avatar_url
|
||||||
|
@ -605,11 +618,32 @@ pub fn get_profile_route(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[put("/_matrix/client/r0/presence/<_user_id>/status")]
|
#[put("/_matrix/client/r0/presence/<_user_id>/status", data = "<body>")]
|
||||||
pub fn set_presence_route(
|
pub fn set_presence_route(
|
||||||
|
db: State<'_, Database>,
|
||||||
|
body: Ruma<set_presence::Request>,
|
||||||
_user_id: String,
|
_user_id: String,
|
||||||
) -> MatrixResult<set_presence::Response> {
|
) -> MatrixResult<set_presence::Response> {
|
||||||
// TODO
|
let user_id = body.user_id.clone().expect("user is authenticated");
|
||||||
|
|
||||||
|
db.global_edus
|
||||||
|
.update_globallatest(
|
||||||
|
&user_id,
|
||||||
|
EduEvent::Presence(ruma_events::presence::PresenceEvent {
|
||||||
|
content: ruma_events::presence::PresenceEventContent {
|
||||||
|
avatar_url: db.users.avatar_url(&user_id).unwrap(),
|
||||||
|
currently_active: None,
|
||||||
|
displayname: db.users.displayname(&user_id).unwrap(),
|
||||||
|
last_active_ago: Some(utils::millis_since_unix_epoch().try_into().unwrap()),
|
||||||
|
presence: body.presence,
|
||||||
|
status_msg: body.status_msg.clone(),
|
||||||
|
},
|
||||||
|
sender: user_id.clone(),
|
||||||
|
}),
|
||||||
|
&db.globals,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
MatrixResult(Ok(set_presence::Response))
|
MatrixResult(Ok(set_presence::Response))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,28 +671,27 @@ pub fn set_read_marker_route(
|
||||||
_room_id: String,
|
_room_id: String,
|
||||||
) -> MatrixResult<set_read_marker::Response> {
|
) -> MatrixResult<set_read_marker::Response> {
|
||||||
let user_id = body.user_id.clone().expect("user is authenticated");
|
let user_id = body.user_id.clone().expect("user is authenticated");
|
||||||
db.account_data.update(
|
db.account_data
|
||||||
Some(&body.room_id),
|
.update(
|
||||||
&user_id,
|
Some(&body.room_id),
|
||||||
EduEvent::FullyRead(ruma_events::fully_read::FullyReadEvent {
|
&user_id,
|
||||||
content: ruma_events::fully_read::FullyReadEventContent {
|
EduEvent::FullyRead(ruma_events::fully_read::FullyReadEvent {
|
||||||
event_id: body.fully_read.clone(),
|
content: ruma_events::fully_read::FullyReadEventContent {
|
||||||
},
|
event_id: body.fully_read.clone(),
|
||||||
room_id: Some(body.room_id.clone()),
|
},
|
||||||
}),
|
room_id: Some(body.room_id.clone()),
|
||||||
&db.globals
|
}),
|
||||||
)
|
&db.globals,
|
||||||
.unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
if let Some(event) = &body.read_receipt {
|
if let Some(event) = &body.read_receipt {
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.edus
|
.edus
|
||||||
.room_read_set(
|
.room_read_set(
|
||||||
&body.room_id,
|
&body.room_id,
|
||||||
&user_id,
|
&user_id,
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.get_pdu_count(event)
|
.get_pdu_count(event)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.expect("TODO: what if a client specifies an invalid event"),
|
.expect("TODO: what if a client specifies an invalid event"),
|
||||||
|
@ -680,8 +713,7 @@ pub fn set_read_marker_route(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.edus
|
.edus
|
||||||
.roomlatest_update(
|
.roomlatest_update(
|
||||||
&user_id,
|
&user_id,
|
||||||
|
@ -716,8 +748,7 @@ pub fn create_typing_event_route(
|
||||||
});
|
});
|
||||||
|
|
||||||
if body.typing {
|
if body.typing {
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.edus
|
.edus
|
||||||
.roomactive_add(
|
.roomactive_add(
|
||||||
edu,
|
edu,
|
||||||
|
@ -728,11 +759,7 @@ pub fn create_typing_event_route(
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
} else {
|
} else {
|
||||||
db
|
db.rooms.edus.roomactive_remove(edu, &body.room_id).unwrap();
|
||||||
.rooms
|
|
||||||
.edus
|
|
||||||
.roomactive_remove(edu, &body.room_id)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MatrixResult(Ok(create_typing_event::Response))
|
MatrixResult(Ok(create_typing_event::Response))
|
||||||
|
@ -747,8 +774,7 @@ pub fn create_room_route(
|
||||||
let room_id = RoomId::try_from(db.globals.hostname()).expect("host is valid");
|
let room_id = RoomId::try_from(db.globals.hostname()).expect("host is valid");
|
||||||
let user_id = body.user_id.clone().expect("user is authenticated");
|
let user_id = body.user_id.clone().expect("user is authenticated");
|
||||||
|
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.append_pdu(
|
.append_pdu(
|
||||||
room_id.clone(),
|
room_id.clone(),
|
||||||
user_id.clone(),
|
user_id.clone(),
|
||||||
|
@ -760,8 +786,7 @@ pub fn create_room_route(
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.join(
|
.join(
|
||||||
&room_id,
|
&room_id,
|
||||||
&user_id,
|
&user_id,
|
||||||
|
@ -770,8 +795,7 @@ pub fn create_room_route(
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.append_pdu(
|
.append_pdu(
|
||||||
room_id.clone(),
|
room_id.clone(),
|
||||||
user_id.clone(),
|
user_id.clone(),
|
||||||
|
@ -793,8 +817,7 @@ pub fn create_room_route(
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if let Some(name) = &body.name {
|
if let Some(name) = &body.name {
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.append_pdu(
|
.append_pdu(
|
||||||
room_id.clone(),
|
room_id.clone(),
|
||||||
user_id.clone(),
|
user_id.clone(),
|
||||||
|
@ -808,8 +831,7 @@ pub fn create_room_route(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(topic) = &body.topic {
|
if let Some(topic) = &body.topic {
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.append_pdu(
|
.append_pdu(
|
||||||
room_id.clone(),
|
room_id.clone(),
|
||||||
user_id.clone(),
|
user_id.clone(),
|
||||||
|
@ -823,8 +845,7 @@ pub fn create_room_route(
|
||||||
}
|
}
|
||||||
|
|
||||||
for user in &body.invite {
|
for user in &body.invite {
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.invite(&user_id, &room_id, user, &db.globals)
|
.invite(&user_id, &room_id, user, &db.globals)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -945,8 +966,7 @@ pub fn leave_room_route(
|
||||||
_room_id: String,
|
_room_id: String,
|
||||||
) -> MatrixResult<leave_room::Response> {
|
) -> MatrixResult<leave_room::Response> {
|
||||||
let user_id = body.user_id.clone().expect("user is authenticated");
|
let user_id = body.user_id.clone().expect("user is authenticated");
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.leave(&user_id, &body.room_id, &user_id, &db.globals)
|
.leave(&user_id, &body.room_id, &user_id, &db.globals)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
MatrixResult(Ok(leave_room::Response))
|
MatrixResult(Ok(leave_room::Response))
|
||||||
|
@ -970,8 +990,7 @@ pub fn invite_user_route(
|
||||||
_room_id: String,
|
_room_id: String,
|
||||||
) -> MatrixResult<invite_user::Response> {
|
) -> MatrixResult<invite_user::Response> {
|
||||||
if let invite_user::InvitationRecipient::UserId { user_id } = &body.recipient {
|
if let invite_user::InvitationRecipient::UserId { user_id } = &body.recipient {
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.invite(
|
.invite(
|
||||||
&body.user_id.as_ref().expect("user is authenticated"),
|
&body.user_id.as_ref().expect("user is authenticated"),
|
||||||
&body.room_id,
|
&body.room_id,
|
||||||
|
@ -1069,16 +1088,13 @@ pub fn search_users_route(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/_matrix/client/r0/rooms/<_room_id>/members")]
|
#[get("/_matrix/client/r0/rooms/<_room_id>/members")]
|
||||||
pub fn get_member_events_route(
|
pub fn get_member_events_route(_room_id: String) -> MatrixResult<get_member_events::Response> {
|
||||||
_room_id: String,
|
|
||||||
) -> MatrixResult<get_member_events::Response> {
|
|
||||||
// TODO
|
// TODO
|
||||||
MatrixResult(Ok(get_member_events::Response { chunk: Vec::new() }))
|
MatrixResult(Ok(get_member_events::Response { chunk: Vec::new() }))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/_matrix/client/r0/thirdparty/protocols")]
|
#[get("/_matrix/client/r0/thirdparty/protocols")]
|
||||||
pub fn get_protocols_route(
|
pub fn get_protocols_route() -> MatrixResult<get_protocols::Response> {
|
||||||
) -> MatrixResult<get_protocols::Response> {
|
|
||||||
// TODO
|
// TODO
|
||||||
MatrixResult(Ok(get_protocols::Response {
|
MatrixResult(Ok(get_protocols::Response {
|
||||||
protocols: BTreeMap::new(),
|
protocols: BTreeMap::new(),
|
||||||
|
@ -1114,7 +1130,9 @@ pub fn create_message_event_route(
|
||||||
)
|
)
|
||||||
.expect("message events are always okay");
|
.expect("message events are always okay");
|
||||||
|
|
||||||
MatrixResult(Ok(create_message_event::Response { event_id: Some(event_id) }))
|
MatrixResult(Ok(create_message_event::Response {
|
||||||
|
event_id: Some(event_id),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[put(
|
#[put(
|
||||||
|
@ -1144,7 +1162,9 @@ pub fn create_state_event_for_key_route(
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
MatrixResult(Ok(create_state_event_for_key::Response { event_id: Some(event_id) }))
|
MatrixResult(Ok(create_state_event_for_key::Response {
|
||||||
|
event_id: Some(event_id),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[put(
|
#[put(
|
||||||
|
@ -1173,7 +1193,9 @@ pub fn create_state_event_for_empty_key_route(
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
MatrixResult(Ok(create_state_event_for_empty_key::Response { event_id: Some(event_id) }))
|
MatrixResult(Ok(create_state_event_for_empty_key::Response {
|
||||||
|
event_id: Some(event_id),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/_matrix/client/r0/sync", data = "<body>")]
|
#[get("/_matrix/client/r0/sync", data = "<body>")]
|
||||||
|
@ -1197,7 +1219,8 @@ pub fn sync_route(
|
||||||
|
|
||||||
let mut pdus = db
|
let mut pdus = db
|
||||||
.rooms
|
.rooms
|
||||||
.pdus_since(&room_id, since).unwrap()
|
.pdus_since(&room_id, since)
|
||||||
|
.unwrap()
|
||||||
.map(|r| r.unwrap())
|
.map(|r| r.unwrap())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -1213,16 +1236,12 @@ pub fn sync_route(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let notification_count = if let Some(last_read) = db
|
let notification_count =
|
||||||
.rooms
|
if let Some(last_read) = db.rooms.edus.room_read_get(&room_id, &user_id).unwrap() {
|
||||||
.edus
|
Some((db.rooms.pdus_since(&room_id, last_read).unwrap().count() as u32).into())
|
||||||
.room_read_get(&room_id, &user_id)
|
} else {
|
||||||
.unwrap()
|
None
|
||||||
{
|
};
|
||||||
Some((db.rooms.pdus_since(&room_id, last_read).unwrap().count() as u32).into())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
// They /sync response doesn't always return all messages, so we say the output is
|
// They /sync response doesn't always return all messages, so we say the output is
|
||||||
// limited unless there are enough events
|
// limited unless there are enough events
|
||||||
|
@ -1262,10 +1281,10 @@ pub fn sync_route(
|
||||||
}
|
}
|
||||||
|
|
||||||
edus.extend(
|
edus.extend(
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.edus
|
.edus
|
||||||
.roomlatests_since(&room_id, since).unwrap()
|
.roomlatests_since(&room_id, since)
|
||||||
|
.unwrap()
|
||||||
.map(|r| r.unwrap()),
|
.map(|r| r.unwrap()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1273,8 +1292,10 @@ pub fn sync_route(
|
||||||
room_id.clone().try_into().unwrap(),
|
room_id.clone().try_into().unwrap(),
|
||||||
sync_events::JoinedRoom {
|
sync_events::JoinedRoom {
|
||||||
account_data: Some(sync_events::AccountData {
|
account_data: Some(sync_events::AccountData {
|
||||||
events: db.account_data
|
events: db
|
||||||
.changes_since(Some(&room_id), &user_id, since).unwrap()
|
.account_data
|
||||||
|
.changes_since(Some(&room_id), &user_id, since)
|
||||||
|
.unwrap()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, v)| v)
|
.map(|(_, v)| v)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -1304,8 +1325,7 @@ pub fn sync_route(
|
||||||
// TODO: state before timeline
|
// TODO: state before timeline
|
||||||
state: sync_events::State {
|
state: sync_events::State {
|
||||||
events: if send_full_state {
|
events: if send_full_state {
|
||||||
db
|
db.rooms
|
||||||
.rooms
|
|
||||||
.room_state(&room_id)
|
.room_state(&room_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -1332,17 +1352,12 @@ pub fn sync_route(
|
||||||
let mut edus = db
|
let mut edus = db
|
||||||
.rooms
|
.rooms
|
||||||
.edus
|
.edus
|
||||||
.roomlatests_since(&room_id, since).unwrap()
|
.roomlatests_since(&room_id, since)
|
||||||
|
.unwrap()
|
||||||
.map(|r| r.unwrap())
|
.map(|r| r.unwrap())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
edus.extend(
|
edus.extend(db.rooms.edus.roomactives_all(&room_id).map(|r| r.unwrap()));
|
||||||
db
|
|
||||||
.rooms
|
|
||||||
.edus
|
|
||||||
.roomactives_all(&room_id)
|
|
||||||
.map(|r| r.unwrap()),
|
|
||||||
);
|
|
||||||
|
|
||||||
left_rooms.insert(
|
left_rooms.insert(
|
||||||
room_id.clone().try_into().unwrap(),
|
room_id.clone().try_into().unwrap(),
|
||||||
|
@ -1363,7 +1378,8 @@ pub fn sync_route(
|
||||||
let room_id = room_id.unwrap();
|
let room_id = room_id.unwrap();
|
||||||
let events = db
|
let events = db
|
||||||
.rooms
|
.rooms
|
||||||
.pdus_since(&room_id, since).unwrap()
|
.pdus_since(&room_id, since)
|
||||||
|
.unwrap()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|pdu| pdu.unwrap().to_stripped_state_event())
|
.map(|pdu| pdu.unwrap().to_stripped_state_event())
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -1383,10 +1399,23 @@ pub fn sync_route(
|
||||||
join: joined_rooms,
|
join: joined_rooms,
|
||||||
invite: invited_rooms,
|
invite: invited_rooms,
|
||||||
},
|
},
|
||||||
presence: sync_events::Presence { events: Vec::new() },
|
presence: sync_events::Presence {
|
||||||
|
events: db
|
||||||
|
.global_edus
|
||||||
|
.globallatests_since(since)
|
||||||
|
.unwrap()
|
||||||
|
.map(|edu| {
|
||||||
|
EventJson::<ruma_events::presence::PresenceEvent>::from(
|
||||||
|
edu.unwrap().json().to_owned(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
},
|
||||||
account_data: sync_events::AccountData {
|
account_data: sync_events::AccountData {
|
||||||
events: db.account_data
|
events: db
|
||||||
.changes_since(None, &user_id, since).unwrap()
|
.account_data
|
||||||
|
.changes_since(None, &user_id, since)
|
||||||
|
.unwrap()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, v)| v)
|
.map(|(_, v)| v)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
pub(self) mod account_data;
|
pub(self) mod account_data;
|
||||||
|
pub(self) mod global_edus;
|
||||||
pub(self) mod globals;
|
pub(self) mod globals;
|
||||||
pub(self) mod rooms;
|
pub(self) mod rooms;
|
||||||
pub(self) mod users;
|
pub(self) mod users;
|
||||||
|
@ -11,8 +12,7 @@ pub struct Database {
|
||||||
pub users: users::Users,
|
pub users: users::Users,
|
||||||
pub rooms: rooms::Rooms,
|
pub rooms: rooms::Rooms,
|
||||||
pub account_data: account_data::AccountData,
|
pub account_data: account_data::AccountData,
|
||||||
//pub globalallid_globalall: sled::Tree, // ToDevice, GlobalAllId = UserId + Count
|
pub global_edus: global_edus::GlobalEdus,
|
||||||
//pub globallatestid_globallatest: sled::Tree, // Presence, GlobalLatestId = Count + Type + UserId
|
|
||||||
pub _db: sled::Db,
|
pub _db: sled::Db,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,8 +66,10 @@ impl Database {
|
||||||
account_data: account_data::AccountData {
|
account_data: account_data::AccountData {
|
||||||
roomuserdataid_accountdata: db.open_tree("roomuserdataid_accountdata").unwrap(),
|
roomuserdataid_accountdata: db.open_tree("roomuserdataid_accountdata").unwrap(),
|
||||||
},
|
},
|
||||||
//globalallid_globalall: db.open_tree("globalallid_globalall").unwrap(),
|
global_edus: global_edus::GlobalEdus {
|
||||||
//globallatestid_globallatest: db.open_tree("globallatestid_globallatest").unwrap(),
|
//globalallid_globalall: db.open_tree("globalallid_globalall").unwrap(),
|
||||||
|
globallatestid_globallatest: db.open_tree("globallatestid_globallatest").unwrap(), // Presence
|
||||||
|
},
|
||||||
_db: db,
|
_db: db,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
68
src/database/global_edus.rs
Normal file
68
src/database/global_edus.rs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
use crate::Result;
|
||||||
|
use ruma_events::{collections::only::Event as EduEvent, EventJson};
|
||||||
|
use ruma_identifiers::UserId;
|
||||||
|
|
||||||
|
pub struct GlobalEdus {
|
||||||
|
pub(super) globallatestid_globallatest: sled::Tree, // Presence, GlobalLatestId = Count + UserId
|
||||||
|
//pub globalallid_globalall: sled::Tree, // ToDevice, GlobalAllId = UserId + Count
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GlobalEdus {
|
||||||
|
/// Adds a global event which will be saved until a new event replaces it (e.g. presence updates).
|
||||||
|
pub fn update_globallatest(
|
||||||
|
&self,
|
||||||
|
user_id: &UserId,
|
||||||
|
event: EduEvent,
|
||||||
|
globals: &super::globals::Globals,
|
||||||
|
) -> Result<()> {
|
||||||
|
// Remove old entry
|
||||||
|
if let Some(old) = self
|
||||||
|
.globallatestid_globallatest
|
||||||
|
.iter()
|
||||||
|
.keys()
|
||||||
|
.rev()
|
||||||
|
.filter_map(|r| r.ok())
|
||||||
|
.find(|key| {
|
||||||
|
key.rsplit(|&b| b == 0xff).next().unwrap() == user_id.to_string().as_bytes()
|
||||||
|
})
|
||||||
|
{
|
||||||
|
// This is the old global_latest
|
||||||
|
self.globallatestid_globallatest.remove(old)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut global_latest_id = globals.next_count()?.to_be_bytes().to_vec();
|
||||||
|
global_latest_id.push(0xff);
|
||||||
|
global_latest_id.extend_from_slice(&user_id.to_string().as_bytes());
|
||||||
|
|
||||||
|
self.globallatestid_globallatest
|
||||||
|
.insert(global_latest_id, &*serde_json::to_string(&event)?)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over the most recent presence updates that happened after the event with id `since`.
|
||||||
|
pub fn globallatests_since(
|
||||||
|
&self,
|
||||||
|
since: u64,
|
||||||
|
) -> Result<impl Iterator<Item = Result<EventJson<EduEvent>>>> {
|
||||||
|
let first_possible_edu = since.to_be_bytes().to_vec();
|
||||||
|
|
||||||
|
Ok(self
|
||||||
|
.globallatestid_globallatest
|
||||||
|
.range(&*first_possible_edu..)
|
||||||
|
// Skip the first pdu if it's exactly at since, because we sent that last time
|
||||||
|
.skip(
|
||||||
|
if self
|
||||||
|
.globallatestid_globallatest
|
||||||
|
.get(first_possible_edu)?
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.filter_map(|r| r.ok())
|
||||||
|
.map(|(_, v)| Ok(serde_json::from_slice(&v)?)))
|
||||||
|
}
|
||||||
|
}
|
|
@ -79,14 +79,6 @@ impl RoomEdus {
|
||||||
.map(|(_, v)| Ok(serde_json::from_slice(&v)?)))
|
.map(|(_, v)| Ok(serde_json::from_slice(&v)?)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a vector of the most recent read_receipts in a room that happened after the event with id `since`.
|
|
||||||
pub fn roomlatests_all(
|
|
||||||
&self,
|
|
||||||
room_id: &RoomId,
|
|
||||||
) -> Result<impl Iterator<Item = Result<EventJson<EduEvent>>>> {
|
|
||||||
self.roomlatests_since(room_id, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds an event that will be saved until the `timeout` timestamp (e.g. typing notifications).
|
/// Adds an event that will be saved until the `timeout` timestamp (e.g. typing notifications).
|
||||||
pub fn roomactive_add(
|
pub fn roomactive_add(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -59,7 +59,12 @@ pub async fn send_request<T: Endpoint>(
|
||||||
request_map.insert("destination".to_owned(), destination.into());
|
request_map.insert("destination".to_owned(), destination.into());
|
||||||
|
|
||||||
let mut request_json = request_map.into();
|
let mut request_json = request_map.into();
|
||||||
ruma_signatures::sign_json(db.globals.hostname(), db.globals.keypair(), &mut request_json).unwrap();
|
ruma_signatures::sign_json(
|
||||||
|
db.globals.hostname(),
|
||||||
|
db.globals.keypair(),
|
||||||
|
&mut request_json,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let signatures = request_json["signatures"]
|
let signatures = request_json["signatures"]
|
||||||
.as_object()
|
.as_object()
|
||||||
|
@ -85,7 +90,11 @@ pub async fn send_request<T: Endpoint>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let reqwest_response = db.globals.reqwest_client().execute(http_request.into()).await;
|
let reqwest_response = db
|
||||||
|
.globals
|
||||||
|
.reqwest_client()
|
||||||
|
.execute(http_request.into())
|
||||||
|
.await;
|
||||||
|
|
||||||
// Because reqwest::Response -> http::Response is complicated:
|
// Because reqwest::Response -> http::Response is complicated:
|
||||||
match reqwest_response {
|
match reqwest_response {
|
||||||
|
|
Loading…
Add table
Reference in a new issue