mirror of
https://gitlab.com/famedly/conduit.git
synced 2024-12-25 18:34:38 +01:00
Merge pull request 'Moving to ruma-monorepo' (#133) from DevinR528/conduit:ruma-mono into master
Reviewed-on: https://git.koesters.xyz/timo/conduit/pulls/133 Reviewed-by: Timo Kösters <timo@koesters.xyz>
This commit is contained in:
commit
678f33acf9
13 changed files with 518 additions and 441 deletions
495
Cargo.lock
generated
495
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
16
Cargo.toml
16
Cargo.toml
|
@ -27,18 +27,4 @@ reqwest = "0.10.6"
|
||||||
base64 = "0.12.1"
|
base64 = "0.12.1"
|
||||||
thiserror = "1.0.19"
|
thiserror = "1.0.19"
|
||||||
image = { version = "0.23.4", default-features = false, features = ["jpeg", "png", "gif"] }
|
image = { version = "0.23.4", default-features = false, features = ["jpeg", "png", "gif"] }
|
||||||
|
ruma = { git = "https://github.com/ruma/ruma", features = ["rand", "client-api", "federation-api", "unstable-pre-spec", "unstable-synapse-quirks"], rev = "08fbace" }
|
||||||
[dependencies.ruma]
|
|
||||||
git = "https://github.com/timokoesters/ruma"
|
|
||||||
#rev = "baa87104569b45dc07a9a7a16d3c7592ab8f4d6b"
|
|
||||||
#path = "../ruma/ruma"
|
|
||||||
features = ["rand", "client-api", "federation-api"]
|
|
||||||
|
|
||||||
# These are required only until ruma-events and ruma-federation-api are merged into ruma/ruma
|
|
||||||
[patch.crates-io]
|
|
||||||
ruma-common = { git = "https://github.com/timokoesters/ruma" }
|
|
||||||
ruma-serde = { git = "https://github.com/timokoesters/ruma" }
|
|
||||||
ruma-identifiers = { git = "https://github.com/timokoesters/ruma" }
|
|
||||||
#ruma-common = { path = "../ruma/ruma-common" }
|
|
||||||
#ruma-serde = { path = "../ruma/ruma-serde" }
|
|
||||||
#ruma-identifiers = { path = "../ruma/ruma-identifiers" }
|
|
||||||
|
|
|
@ -60,12 +60,12 @@ use ruma::{
|
||||||
unversioned::get_supported_versions,
|
unversioned::get_supported_versions,
|
||||||
},
|
},
|
||||||
events::{
|
events::{
|
||||||
collections::only::Event as EduEvent,
|
|
||||||
room::{
|
room::{
|
||||||
canonical_alias, guest_access, history_visibility, join_rules, member, name, redaction,
|
canonical_alias, guest_access, history_visibility, join_rules, member, name, redaction,
|
||||||
topic,
|
topic,
|
||||||
},
|
},
|
||||||
EventJson, EventType,
|
AnyBasicEvent, AnyEphemeralRoomEvent, AnyEvent, AnySyncEphemeralRoomEvent, EventJson,
|
||||||
|
EventType,
|
||||||
},
|
},
|
||||||
identifiers::{RoomAliasId, RoomId, RoomVersionId, UserId},
|
identifiers::{RoomAliasId, RoomId, RoomVersionId, UserId},
|
||||||
};
|
};
|
||||||
|
@ -169,14 +169,14 @@ pub fn register_route(
|
||||||
if let Some(auth) = &body.auth {
|
if let Some(auth) = &body.auth {
|
||||||
let (worked, uiaainfo) =
|
let (worked, uiaainfo) =
|
||||||
db.uiaa
|
db.uiaa
|
||||||
.try_auth(&user_id, "", auth, &uiaainfo, &db.users, &db.globals)?;
|
.try_auth(&user_id, "".into(), auth, &uiaainfo, &db.users, &db.globals)?;
|
||||||
if !worked {
|
if !worked {
|
||||||
return Err(Error::Uiaa(uiaainfo));
|
return Err(Error::Uiaa(uiaainfo));
|
||||||
}
|
}
|
||||||
// Success!
|
// Success!
|
||||||
} else {
|
} else {
|
||||||
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
|
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
|
||||||
db.uiaa.create(&user_id, "", &uiaainfo)?;
|
db.uiaa.create(&user_id, "".into(), &uiaainfo)?;
|
||||||
return Err(Error::Uiaa(uiaainfo));
|
return Err(Error::Uiaa(uiaainfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ pub fn register_route(
|
||||||
let device_id = body
|
let device_id = body
|
||||||
.device_id
|
.device_id
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| utils::random_string(DEVICE_ID_LENGTH));
|
.unwrap_or_else(|| utils::random_string(DEVICE_ID_LENGTH).into());
|
||||||
|
|
||||||
// Generate new token for the device
|
// Generate new token for the device
|
||||||
let token = utils::random_string(TOKEN_LENGTH);
|
let token = utils::random_string(TOKEN_LENGTH);
|
||||||
|
@ -221,7 +221,7 @@ pub fn register_route(
|
||||||
Ok(register::Response {
|
Ok(register::Response {
|
||||||
access_token: Some(token),
|
access_token: Some(token),
|
||||||
user_id,
|
user_id,
|
||||||
device_id: Some(device_id),
|
device_id: Some(device_id.into()),
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ pub fn login_route(
|
||||||
.body
|
.body
|
||||||
.device_id
|
.device_id
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| utils::random_string(DEVICE_ID_LENGTH));
|
.unwrap_or_else(|| utils::random_string(DEVICE_ID_LENGTH).into());
|
||||||
|
|
||||||
// Generate a new token for the device
|
// Generate a new token for the device
|
||||||
let token = utils::random_string(TOKEN_LENGTH);
|
let token = utils::random_string(TOKEN_LENGTH);
|
||||||
|
@ -286,7 +286,7 @@ pub fn login_route(
|
||||||
user_id,
|
user_id,
|
||||||
access_token: token,
|
access_token: token,
|
||||||
home_server: Some(db.globals.server_name().to_owned()),
|
home_server: Some(db.globals.server_name().to_owned()),
|
||||||
device_id,
|
device_id: device_id.into(),
|
||||||
well_known: None,
|
well_known: None,
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
|
@ -300,7 +300,7 @@ pub fn logout_route(
|
||||||
let user_id = body.user_id.as_ref().expect("user is authenticated");
|
let user_id = body.user_id.as_ref().expect("user is authenticated");
|
||||||
let device_id = body.device_id.as_ref().expect("user is authenticated");
|
let device_id = body.device_id.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
db.users.remove_device(&user_id, &device_id)?;
|
db.users.remove_device(&user_id, device_id)?;
|
||||||
|
|
||||||
Ok(logout::Response.into())
|
Ok(logout::Response.into())
|
||||||
}
|
}
|
||||||
|
@ -340,14 +340,9 @@ pub fn change_password_route(
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(auth) = &body.auth {
|
if let Some(auth) = &body.auth {
|
||||||
let (worked, uiaainfo) = db.uiaa.try_auth(
|
let (worked, uiaainfo) =
|
||||||
&user_id,
|
db.uiaa
|
||||||
&device_id,
|
.try_auth(&user_id, device_id, auth, &uiaainfo, &db.users, &db.globals)?;
|
||||||
auth,
|
|
||||||
&uiaainfo,
|
|
||||||
&db.users,
|
|
||||||
&db.globals,
|
|
||||||
)?;
|
|
||||||
if !worked {
|
if !worked {
|
||||||
return Err(Error::Uiaa(uiaainfo));
|
return Err(Error::Uiaa(uiaainfo));
|
||||||
}
|
}
|
||||||
|
@ -452,11 +447,11 @@ pub fn deactivate_route(
|
||||||
pub fn get_capabilities_route() -> ConduitResult<get_capabilities::Response> {
|
pub fn get_capabilities_route() -> ConduitResult<get_capabilities::Response> {
|
||||||
let mut available = BTreeMap::new();
|
let mut available = BTreeMap::new();
|
||||||
available.insert(
|
available.insert(
|
||||||
RoomVersionId::version_5(),
|
RoomVersionId::Version5,
|
||||||
get_capabilities::RoomVersionStability::Stable,
|
get_capabilities::RoomVersionStability::Stable,
|
||||||
);
|
);
|
||||||
available.insert(
|
available.insert(
|
||||||
RoomVersionId::version_6(),
|
RoomVersionId::Version6,
|
||||||
get_capabilities::RoomVersionStability::Stable,
|
get_capabilities::RoomVersionStability::Stable,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -480,7 +475,7 @@ pub fn get_pushrules_all_route(
|
||||||
) -> ConduitResult<get_pushrules_all::Response> {
|
) -> ConduitResult<get_pushrules_all::Response> {
|
||||||
let user_id = body.user_id.as_ref().expect("user is authenticated");
|
let user_id = body.user_id.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
if let EduEvent::PushRules(pushrules) = db
|
if let AnyEvent::Basic(AnyBasicEvent::PushRules(pushrules)) = db
|
||||||
.account_data
|
.account_data
|
||||||
.get(None, &user_id, &EventType::PushRules)?
|
.get(None, &user_id, &EventType::PushRules)?
|
||||||
.ok_or(Error::BadRequest(
|
.ok_or(Error::BadRequest(
|
||||||
|
@ -594,7 +589,7 @@ pub fn get_global_account_data_route(
|
||||||
) -> ConduitResult<get_global_account_data::Response> {
|
) -> ConduitResult<get_global_account_data::Response> {
|
||||||
let user_id = body.user_id.as_ref().expect("user is authenticated");
|
let user_id = body.user_id.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
let data = db
|
let event = db
|
||||||
.account_data
|
.account_data
|
||||||
.get(
|
.get(
|
||||||
None,
|
None,
|
||||||
|
@ -603,6 +598,9 @@ pub fn get_global_account_data_route(
|
||||||
)?
|
)?
|
||||||
.ok_or(Error::BadRequest(ErrorKind::NotFound, "Data not found."))?;
|
.ok_or(Error::BadRequest(ErrorKind::NotFound, "Data not found."))?;
|
||||||
|
|
||||||
|
let data = serde_json::from_str(event.json().get())
|
||||||
|
.map_err(|_| Error::bad_database("Invalid account data event in db."))?;
|
||||||
|
|
||||||
Ok(get_global_account_data::Response { account_data: data }.into())
|
Ok(get_global_account_data::Response { account_data: data }.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -888,7 +886,7 @@ pub fn get_keys_route(
|
||||||
device_display_name: metadata.display_name,
|
device_display_name: metadata.display_name,
|
||||||
});
|
});
|
||||||
|
|
||||||
container.insert(device_id.to_owned(), keys);
|
container.insert(device_id, keys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
device_keys.insert(user_id.clone(), container);
|
device_keys.insert(user_id.clone(), container);
|
||||||
|
@ -1099,7 +1097,7 @@ pub fn set_read_marker_route(
|
||||||
content: ruma::events::fully_read::FullyReadEventContent {
|
content: ruma::events::fully_read::FullyReadEventContent {
|
||||||
event_id: body.fully_read.clone(),
|
event_id: body.fully_read.clone(),
|
||||||
},
|
},
|
||||||
room_id: Some(body.room_id.clone()),
|
room_id: body.room_id.clone(),
|
||||||
})
|
})
|
||||||
.expect("we just created a valid event")
|
.expect("we just created a valid event")
|
||||||
.as_object_mut()
|
.as_object_mut()
|
||||||
|
@ -1135,10 +1133,12 @@ pub fn set_read_marker_route(
|
||||||
db.rooms.edus.roomlatest_update(
|
db.rooms.edus.roomlatest_update(
|
||||||
&user_id,
|
&user_id,
|
||||||
&body.room_id,
|
&body.room_id,
|
||||||
EduEvent::Receipt(ruma::events::receipt::ReceiptEvent {
|
AnyEvent::Ephemeral(AnyEphemeralRoomEvent::Receipt(
|
||||||
content: receipt_content,
|
ruma::events::receipt::ReceiptEvent {
|
||||||
room_id: None, // None because it can be inferred
|
content: ruma::events::receipt::ReceiptEventContent(receipt_content),
|
||||||
}),
|
room_id: body.room_id.clone(),
|
||||||
|
},
|
||||||
|
)),
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
@ -1181,8 +1181,7 @@ pub fn create_room_route(
|
||||||
) -> ConduitResult<create_room::Response> {
|
) -> ConduitResult<create_room::Response> {
|
||||||
let user_id = body.user_id.as_ref().expect("user is authenticated");
|
let user_id = body.user_id.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
let room_id = RoomId::new(db.globals.server_name())
|
let room_id = RoomId::new(db.globals.server_name());
|
||||||
.map_err(|_| Error::bad_database("Server name is invalid."))?;
|
|
||||||
|
|
||||||
let alias = body
|
let alias = body
|
||||||
.room_alias_name
|
.room_alias_name
|
||||||
|
@ -1203,21 +1202,20 @@ pub fn create_room_route(
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let mut content = ruma::events::room::create::CreateEventContent::new(user_id.clone());
|
||||||
|
content.federate = body.creation_content.as_ref().map_or(true, |c| c.federate);
|
||||||
|
content.predecessor = body
|
||||||
|
.creation_content
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|c| c.predecessor.clone());
|
||||||
|
content.room_version = RoomVersionId::Version6;
|
||||||
|
|
||||||
// 1. The room create event
|
// 1. The room create event
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
room_id.clone(),
|
||||||
user_id.clone(),
|
user_id.clone(),
|
||||||
EventType::RoomCreate,
|
EventType::RoomCreate,
|
||||||
serde_json::to_value(ruma::events::room::create::CreateEventContent {
|
serde_json::to_value(content).expect("event is valid, we just created it"),
|
||||||
creator: user_id.clone(),
|
|
||||||
federate: body.creation_content.as_ref().map_or(true, |c| c.federate),
|
|
||||||
predecessor: body
|
|
||||||
.creation_content
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|c| c.predecessor.clone()),
|
|
||||||
room_version: RoomVersionId::version_6(),
|
|
||||||
})
|
|
||||||
.expect("event is valid, we just created it"),
|
|
||||||
None,
|
None,
|
||||||
Some("".to_owned()),
|
Some("".to_owned()),
|
||||||
None,
|
None,
|
||||||
|
@ -1296,15 +1294,14 @@ pub fn create_room_route(
|
||||||
user_id.clone(),
|
user_id.clone(),
|
||||||
EventType::RoomJoinRules,
|
EventType::RoomJoinRules,
|
||||||
match preset {
|
match preset {
|
||||||
create_room::RoomPreset::PublicChat => {
|
create_room::RoomPreset::PublicChat => serde_json::to_value(
|
||||||
serde_json::to_value(join_rules::JoinRulesEventContent {
|
join_rules::JoinRulesEventContent::new(join_rules::JoinRule::Public),
|
||||||
join_rule: join_rules::JoinRule::Public,
|
)
|
||||||
})
|
.expect("event is valid, we just created it"),
|
||||||
.expect("event is valid, we just created it")
|
// according to spec "invite" is the default
|
||||||
}
|
_ => serde_json::to_value(join_rules::JoinRulesEventContent::new(
|
||||||
_ => serde_json::to_value(join_rules::JoinRulesEventContent {
|
join_rules::JoinRule::Invite,
|
||||||
join_rule: join_rules::JoinRule::Invite,
|
))
|
||||||
})
|
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
|
@ -1318,9 +1315,9 @@ pub fn create_room_route(
|
||||||
room_id.clone(),
|
room_id.clone(),
|
||||||
user_id.clone(),
|
user_id.clone(),
|
||||||
EventType::RoomHistoryVisibility,
|
EventType::RoomHistoryVisibility,
|
||||||
serde_json::to_value(history_visibility::HistoryVisibilityEventContent {
|
serde_json::to_value(history_visibility::HistoryVisibilityEventContent::new(
|
||||||
history_visibility: history_visibility::HistoryVisibility::Shared,
|
history_visibility::HistoryVisibility::Shared,
|
||||||
})
|
))
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
None,
|
None,
|
||||||
Some("".to_owned()),
|
Some("".to_owned()),
|
||||||
|
@ -1334,15 +1331,13 @@ pub fn create_room_route(
|
||||||
user_id.clone(),
|
user_id.clone(),
|
||||||
EventType::RoomGuestAccess,
|
EventType::RoomGuestAccess,
|
||||||
match preset {
|
match preset {
|
||||||
create_room::RoomPreset::PublicChat => {
|
create_room::RoomPreset::PublicChat => serde_json::to_value(
|
||||||
serde_json::to_value(guest_access::GuestAccessEventContent {
|
guest_access::GuestAccessEventContent::new(guest_access::GuestAccess::Forbidden),
|
||||||
guest_access: guest_access::GuestAccess::Forbidden,
|
)
|
||||||
})
|
.expect("event is valid, we just created it"),
|
||||||
.expect("event is valid, we just created it")
|
_ => serde_json::to_value(guest_access::GuestAccessEventContent::new(
|
||||||
}
|
guest_access::GuestAccess::CanJoin,
|
||||||
_ => serde_json::to_value(guest_access::GuestAccessEventContent {
|
))
|
||||||
guest_access: guest_access::GuestAccess::CanJoin,
|
|
||||||
})
|
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
|
@ -1533,7 +1528,7 @@ pub fn get_alias_route(
|
||||||
|
|
||||||
Ok(get_alias::Response {
|
Ok(get_alias::Response {
|
||||||
room_id,
|
room_id,
|
||||||
servers: vec![db.globals.server_name().to_owned()],
|
servers: vec![db.globals.server_name().to_string()],
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
@ -2521,7 +2516,7 @@ pub fn sync_route(
|
||||||
|
|
||||||
let room_events = pdus
|
let room_events = pdus
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|pdu| pdu.to_room_event())
|
.map(|pdu| pdu.to_sync_room_event())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut edus = db
|
let mut edus = db
|
||||||
|
@ -2539,7 +2534,7 @@ pub fn sync_route(
|
||||||
{
|
{
|
||||||
edus.push(
|
edus.push(
|
||||||
serde_json::from_str(
|
serde_json::from_str(
|
||||||
&serde_json::to_string(&EduEvent::Typing(
|
&serde_json::to_string(&AnySyncEphemeralRoomEvent::Typing(
|
||||||
db.rooms.edus.roomactives_all(&room_id)?,
|
db.rooms.edus.roomactives_all(&room_id)?,
|
||||||
))
|
))
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
|
@ -2554,8 +2549,12 @@ pub fn sync_route(
|
||||||
.account_data
|
.account_data
|
||||||
.changes_since(Some(&room_id), &user_id, since)?
|
.changes_since(Some(&room_id), &user_id, since)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, v)| v)
|
.filter_map(|(_, v)| {
|
||||||
.collect(),
|
serde_json::from_str(v.json().get())
|
||||||
|
.map_err(|_| Error::bad_database("Invalid account event in database."))
|
||||||
|
.ok()
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
},
|
},
|
||||||
summary: sync_events::RoomSummary {
|
summary: sync_events::RoomSummary {
|
||||||
heroes,
|
heroes,
|
||||||
|
@ -2567,11 +2566,7 @@ pub fn sync_route(
|
||||||
notification_count,
|
notification_count,
|
||||||
},
|
},
|
||||||
timeline: sync_events::Timeline {
|
timeline: sync_events::Timeline {
|
||||||
limited: if limited || joined_since_last_sync {
|
limited: limited || joined_since_last_sync,
|
||||||
Some(true)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
prev_batch,
|
prev_batch,
|
||||||
events: room_events,
|
events: room_events,
|
||||||
},
|
},
|
||||||
|
@ -2581,7 +2576,7 @@ pub fn sync_route(
|
||||||
db.rooms
|
db.rooms
|
||||||
.room_state_full(&room_id)?
|
.room_state_full(&room_id)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, pdu)| pdu.to_state_event())
|
.map(|(_, pdu)| pdu.to_sync_state_event())
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
|
@ -2601,7 +2596,7 @@ pub fn sync_route(
|
||||||
let pdus = db.rooms.pdus_since(&user_id, &room_id, since)?;
|
let pdus = db.rooms.pdus_since(&user_id, &room_id, since)?;
|
||||||
let room_events = pdus
|
let room_events = pdus
|
||||||
.filter_map(|pdu| pdu.ok()) // Filter out buggy events
|
.filter_map(|pdu| pdu.ok()) // Filter out buggy events
|
||||||
.map(|pdu| pdu.to_room_event())
|
.map(|pdu| pdu.to_sync_room_event())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// TODO: Only until leave point
|
// TODO: Only until leave point
|
||||||
|
@ -2620,7 +2615,7 @@ pub fn sync_route(
|
||||||
{
|
{
|
||||||
edus.push(
|
edus.push(
|
||||||
serde_json::from_str(
|
serde_json::from_str(
|
||||||
&serde_json::to_string(&EduEvent::Typing(
|
&serde_json::to_string(&AnySyncEphemeralRoomEvent::Typing(
|
||||||
db.rooms.edus.roomactives_all(&room_id)?,
|
db.rooms.edus.roomactives_all(&room_id)?,
|
||||||
))
|
))
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
|
@ -2632,7 +2627,7 @@ pub fn sync_route(
|
||||||
let left_room = sync_events::LeftRoom {
|
let left_room = sync_events::LeftRoom {
|
||||||
account_data: sync_events::AccountData { events: Vec::new() },
|
account_data: sync_events::AccountData { events: Vec::new() },
|
||||||
timeline: sync_events::Timeline {
|
timeline: sync_events::Timeline {
|
||||||
limited: Some(false),
|
limited: false,
|
||||||
prev_batch: Some(next_batch.clone()),
|
prev_batch: Some(next_batch.clone()),
|
||||||
events: room_events,
|
events: room_events,
|
||||||
},
|
},
|
||||||
|
@ -2696,8 +2691,12 @@ pub fn sync_route(
|
||||||
.account_data
|
.account_data
|
||||||
.changes_since(None, &user_id, since)?
|
.changes_since(None, &user_id, since)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, v)| v)
|
.filter_map(|(_, v)| {
|
||||||
.collect(),
|
serde_json::from_str(v.json().get())
|
||||||
|
.map_err(|_| Error::bad_database("Invalid account event in database."))
|
||||||
|
.ok()
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
},
|
},
|
||||||
device_lists: sync_events::DeviceLists {
|
device_lists: sync_events::DeviceLists {
|
||||||
changed: if since != 0 {
|
changed: if since != 0 {
|
||||||
|
@ -2839,17 +2838,17 @@ pub fn get_message_events_route(
|
||||||
.clone()
|
.clone()
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid `from` value."))?;
|
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid `from` value."))?;
|
||||||
|
let limit = body
|
||||||
|
.limit
|
||||||
|
.try_into()
|
||||||
|
.map_or(Ok::<_, Error>(10_usize), |l: u32| Ok(l as usize))?;
|
||||||
match body.dir {
|
match body.dir {
|
||||||
get_message_events::Direction::Forward => {
|
get_message_events::Direction::Forward => {
|
||||||
let events_after = db
|
let events_after = db
|
||||||
.rooms
|
.rooms
|
||||||
.pdus_after(&user_id, &body.room_id, from)
|
.pdus_after(&user_id, &body.room_id, from)
|
||||||
// Use limit or else 10
|
// Use limit or else 10
|
||||||
.take(body.limit.map_or(Ok::<_, Error>(10_usize), |l| {
|
.take(limit)
|
||||||
Ok(u32::try_from(l).map_err(|_| {
|
|
||||||
Error::BadRequest(ErrorKind::InvalidParam, "Limit value is invalid.")
|
|
||||||
})? as usize)
|
|
||||||
})?)
|
|
||||||
.filter_map(|r| r.ok()) // Filter out buggy events
|
.filter_map(|r| r.ok()) // Filter out buggy events
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -2880,11 +2879,7 @@ pub fn get_message_events_route(
|
||||||
.rooms
|
.rooms
|
||||||
.pdus_until(&user_id, &body.room_id, from)
|
.pdus_until(&user_id, &body.room_id, from)
|
||||||
// Use limit or else 10
|
// Use limit or else 10
|
||||||
.take(body.limit.map_or(Ok::<_, Error>(10_usize), |l| {
|
.take(limit)
|
||||||
Ok(u32::try_from(l).map_err(|_| {
|
|
||||||
Error::BadRequest(ErrorKind::InvalidParam, "Limit value is invalid.")
|
|
||||||
})? as usize)
|
|
||||||
})?)
|
|
||||||
.filter_map(|r| r.ok()) // Filter out buggy events
|
.filter_map(|r| r.ok()) // Filter out buggy events
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{utils, Error, Result};
|
use crate::{utils, Error, Result};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::error::ErrorKind,
|
api::client::error::ErrorKind,
|
||||||
events::{collections::only::Event as EduEvent, EventJson, EventType},
|
events::{AnyEvent as EduEvent, EventJson, EventType},
|
||||||
identifiers::{RoomId, UserId},
|
identifiers::{RoomId, UserId},
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, convert::TryFrom};
|
use std::{collections::HashMap, convert::TryFrom};
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
use crate::{utils, Error, Result};
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
use crate::{utils, Error, Result};
|
||||||
|
use ruma::identifiers::ServerName;
|
||||||
pub const COUNTER: &str = "c";
|
pub const COUNTER: &str = "c";
|
||||||
|
|
||||||
pub struct Globals {
|
pub struct Globals {
|
||||||
pub(super) globals: sled::Tree,
|
pub(super) globals: sled::Tree,
|
||||||
keypair: ruma::signatures::Ed25519KeyPair,
|
keypair: ruma::signatures::Ed25519KeyPair,
|
||||||
reqwest_client: reqwest::Client,
|
reqwest_client: reqwest::Client,
|
||||||
server_name: String,
|
server_name: Box<ServerName>,
|
||||||
registration_disabled: bool,
|
registration_disabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +29,9 @@ impl Globals {
|
||||||
server_name: config
|
server_name: config
|
||||||
.get_str("server_name")
|
.get_str("server_name")
|
||||||
.unwrap_or("localhost")
|
.unwrap_or("localhost")
|
||||||
.to_owned(),
|
.to_string()
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| Error::BadConfig("Invalid server name found."))?,
|
||||||
registration_disabled: config.get_bool("registration_disabled").unwrap_or(false),
|
registration_disabled: config.get_bool("registration_disabled").unwrap_or(false),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -59,8 +63,8 @@ impl Globals {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn server_name(&self) -> &str {
|
pub fn server_name(&self) -> &ServerName {
|
||||||
&self.server_name
|
self.server_name.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn registration_disabled(&self) -> bool {
|
pub fn registration_disabled(&self) -> bool {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{utils, Error, Result};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::{
|
api::client::{
|
||||||
error::ErrorKind,
|
error::ErrorKind,
|
||||||
r0::backup::{get_backup_keys::Sessions, BackupAlgorithm, KeyData},
|
r0::backup::{BackupAlgorithm, KeyData, Sessions},
|
||||||
},
|
},
|
||||||
identifiers::{RoomId, UserId},
|
identifiers::{RoomId, UserId},
|
||||||
};
|
};
|
||||||
|
|
|
@ -529,7 +529,7 @@ impl Rooms {
|
||||||
auth_events: Vec::new(),
|
auth_events: Vec::new(),
|
||||||
redacts: redacts.clone(),
|
redacts: redacts.clone(),
|
||||||
unsigned,
|
unsigned,
|
||||||
hashes: ruma::api::federation::EventHash {
|
hashes: ruma::events::pdu::EventHash {
|
||||||
sha256: "aaa".to_owned(),
|
sha256: "aaa".to_owned(),
|
||||||
},
|
},
|
||||||
signatures: HashMap::new(),
|
signatures: HashMap::new(),
|
||||||
|
@ -547,7 +547,7 @@ impl Rooms {
|
||||||
|
|
||||||
let mut pdu_json = serde_json::to_value(&pdu).expect("event is valid, we just created it");
|
let mut pdu_json = serde_json::to_value(&pdu).expect("event is valid, we just created it");
|
||||||
ruma::signatures::hash_and_sign_event(
|
ruma::signatures::hash_and_sign_event(
|
||||||
globals.server_name(),
|
globals.server_name().as_str(),
|
||||||
globals.keypair(),
|
globals.keypair(),
|
||||||
&mut pdu_json,
|
&mut pdu_json,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{utils, Error, Result};
|
use crate::{utils, Error, Result};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
events::{collections::only::Event as EduEvent, EventJson},
|
events::{AnyEvent as EduEvent, EventJson, SyncEphemeralRoomEvent},
|
||||||
identifiers::{RoomId, UserId},
|
identifiers::{RoomId, UserId},
|
||||||
};
|
};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
@ -61,7 +61,8 @@ impl RoomEdus {
|
||||||
&self,
|
&self,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
since: u64,
|
since: u64,
|
||||||
) -> Result<impl Iterator<Item = Result<EventJson<EduEvent>>>> {
|
) -> Result<impl Iterator<Item = Result<EventJson<ruma::events::AnySyncEphemeralRoomEvent>>>>
|
||||||
|
{
|
||||||
let mut prefix = room_id.to_string().as_bytes().to_vec();
|
let mut prefix = room_id.to_string().as_bytes().to_vec();
|
||||||
prefix.push(0xff);
|
prefix.push(0xff);
|
||||||
|
|
||||||
|
@ -208,8 +209,10 @@ impl RoomEdus {
|
||||||
.unwrap_or(0))
|
.unwrap_or(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all active events (e.g. typing notifications).
|
pub fn roomactives_all(
|
||||||
pub fn roomactives_all(&self, room_id: &RoomId) -> Result<ruma::events::typing::TypingEvent> {
|
&self,
|
||||||
|
room_id: &RoomId,
|
||||||
|
) -> Result<SyncEphemeralRoomEvent<ruma::events::typing::TypingEventContent>> {
|
||||||
let mut prefix = room_id.to_string().as_bytes().to_vec();
|
let mut prefix = room_id.to_string().as_bytes().to_vec();
|
||||||
prefix.push(0xff);
|
prefix.push(0xff);
|
||||||
|
|
||||||
|
@ -233,9 +236,8 @@ impl RoomEdus {
|
||||||
user_ids.push(user_id?);
|
user_ids.push(user_id?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ruma::events::typing::TypingEvent {
|
Ok(SyncEphemeralRoomEvent {
|
||||||
content: ruma::events::typing::TypingEventContent { user_ids },
|
content: ruma::events::typing::TypingEventContent { user_ids },
|
||||||
room_id: None, // Can be inferred
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use ruma::{
|
||||||
error::ErrorKind,
|
error::ErrorKind,
|
||||||
r0::uiaa::{AuthData, UiaaInfo},
|
r0::uiaa::{AuthData, UiaaInfo},
|
||||||
},
|
},
|
||||||
identifiers::UserId,
|
identifiers::{DeviceId, UserId},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Uiaa {
|
pub struct Uiaa {
|
||||||
|
@ -13,14 +13,19 @@ pub struct Uiaa {
|
||||||
|
|
||||||
impl Uiaa {
|
impl Uiaa {
|
||||||
/// Creates a new Uiaa session. Make sure the session token is unique.
|
/// Creates a new Uiaa session. Make sure the session token is unique.
|
||||||
pub fn create(&self, user_id: &UserId, device_id: &str, uiaainfo: &UiaaInfo) -> Result<()> {
|
pub fn create(
|
||||||
|
&self,
|
||||||
|
user_id: &UserId,
|
||||||
|
device_id: &DeviceId,
|
||||||
|
uiaainfo: &UiaaInfo,
|
||||||
|
) -> Result<()> {
|
||||||
self.update_uiaa_session(user_id, device_id, Some(uiaainfo))
|
self.update_uiaa_session(user_id, device_id, Some(uiaainfo))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_auth(
|
pub fn try_auth(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
device_id: &str,
|
device_id: &DeviceId,
|
||||||
auth: &AuthData,
|
auth: &AuthData,
|
||||||
uiaainfo: &UiaaInfo,
|
uiaainfo: &UiaaInfo,
|
||||||
users: &super::users::Users,
|
users: &super::users::Users,
|
||||||
|
@ -130,7 +135,7 @@ impl Uiaa {
|
||||||
|
|
||||||
// UIAA was successful! Remove this session and return true
|
// UIAA was successful! Remove this session and return true
|
||||||
self.update_uiaa_session(user_id, device_id, None)?;
|
self.update_uiaa_session(user_id, device_id, None)?;
|
||||||
return Ok((true, uiaainfo));
|
Ok((true, uiaainfo))
|
||||||
} else {
|
} else {
|
||||||
panic!("FallbackAcknowledgement is not supported yet");
|
panic!("FallbackAcknowledgement is not supported yet");
|
||||||
}
|
}
|
||||||
|
@ -139,12 +144,12 @@ impl Uiaa {
|
||||||
fn update_uiaa_session(
|
fn update_uiaa_session(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
device_id: &str,
|
device_id: &DeviceId,
|
||||||
uiaainfo: Option<&UiaaInfo>,
|
uiaainfo: Option<&UiaaInfo>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
||||||
userdeviceid.push(0xff);
|
userdeviceid.push(0xff);
|
||||||
userdeviceid.extend_from_slice(device_id.as_bytes());
|
userdeviceid.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
|
|
||||||
if let Some(uiaainfo) = uiaainfo {
|
if let Some(uiaainfo) = uiaainfo {
|
||||||
self.userdeviceid_uiaainfo.insert(
|
self.userdeviceid_uiaainfo.insert(
|
||||||
|
@ -161,12 +166,12 @@ impl Uiaa {
|
||||||
fn get_uiaa_session(
|
fn get_uiaa_session(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
device_id: &str,
|
device_id: &DeviceId,
|
||||||
session: &str,
|
session: &str,
|
||||||
) -> Result<UiaaInfo> {
|
) -> Result<UiaaInfo> {
|
||||||
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
||||||
userdeviceid.push(0xff);
|
userdeviceid.push(0xff);
|
||||||
userdeviceid.extend_from_slice(device_id.as_bytes());
|
userdeviceid.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
|
|
||||||
let uiaainfo = serde_json::from_slice::<UiaaInfo>(
|
let uiaainfo = serde_json::from_slice::<UiaaInfo>(
|
||||||
&self
|
&self
|
||||||
|
|
|
@ -8,8 +8,8 @@ use ruma::{
|
||||||
keys::{AlgorithmAndDeviceId, CrossSigningKey, DeviceKeys, KeyAlgorithm, OneTimeKey},
|
keys::{AlgorithmAndDeviceId, CrossSigningKey, DeviceKeys, KeyAlgorithm, OneTimeKey},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
events::{to_device::AnyToDeviceEvent, EventJson, EventType},
|
events::{AnyToDeviceEvent, EventJson, EventType},
|
||||||
identifiers::UserId,
|
identifiers::{DeviceId, UserId},
|
||||||
};
|
};
|
||||||
use std::{collections::BTreeMap, convert::TryFrom, time::SystemTime};
|
use std::{collections::BTreeMap, convert::TryFrom, time::SystemTime};
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ impl Users {
|
||||||
pub fn create_device(
|
pub fn create_device(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
device_id: &str,
|
device_id: &DeviceId,
|
||||||
token: &str,
|
token: &str,
|
||||||
initial_device_display_name: Option<String>,
|
initial_device_display_name: Option<String>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -177,12 +177,12 @@ impl Users {
|
||||||
|
|
||||||
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
||||||
userdeviceid.push(0xff);
|
userdeviceid.push(0xff);
|
||||||
userdeviceid.extend_from_slice(device_id.as_bytes());
|
userdeviceid.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
|
|
||||||
self.userdeviceid_metadata.insert(
|
self.userdeviceid_metadata.insert(
|
||||||
userdeviceid,
|
userdeviceid,
|
||||||
serde_json::to_string(&Device {
|
serde_json::to_string(&Device {
|
||||||
device_id: device_id.to_owned(),
|
device_id: device_id.into(),
|
||||||
display_name: initial_device_display_name,
|
display_name: initial_device_display_name,
|
||||||
last_seen_ip: None, // TODO
|
last_seen_ip: None, // TODO
|
||||||
last_seen_ts: Some(SystemTime::now()),
|
last_seen_ts: Some(SystemTime::now()),
|
||||||
|
@ -191,16 +191,16 @@ impl Users {
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.set_token(user_id, device_id, token)?;
|
self.set_token(user_id, &device_id, token)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a device from a user.
|
/// Removes a device from a user.
|
||||||
pub fn remove_device(&self, user_id: &UserId, device_id: &str) -> Result<()> {
|
pub fn remove_device(&self, user_id: &UserId, device_id: &DeviceId) -> Result<()> {
|
||||||
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
||||||
userdeviceid.push(0xff);
|
userdeviceid.push(0xff);
|
||||||
userdeviceid.extend_from_slice(device_id.as_bytes());
|
userdeviceid.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
|
|
||||||
// Remove tokens
|
// Remove tokens
|
||||||
if let Some(old_token) = self.userdeviceid_token.remove(&userdeviceid)? {
|
if let Some(old_token) = self.userdeviceid_token.remove(&userdeviceid)? {
|
||||||
|
@ -223,7 +223,7 @@ impl Users {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all device ids of this user.
|
/// Returns an iterator over all device ids of this user.
|
||||||
pub fn all_device_ids(&self, user_id: &UserId) -> impl Iterator<Item = Result<String>> {
|
pub fn all_device_ids(&self, user_id: &UserId) -> impl Iterator<Item = Result<Box<DeviceId>>> {
|
||||||
let mut prefix = user_id.to_string().as_bytes().to_vec();
|
let mut prefix = user_id.to_string().as_bytes().to_vec();
|
||||||
prefix.push(0xff);
|
prefix.push(0xff);
|
||||||
// All devices have metadata
|
// All devices have metadata
|
||||||
|
@ -237,17 +237,16 @@ impl Users {
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("UserDevice ID in db is invalid."))?,
|
.ok_or_else(|| Error::bad_database("UserDevice ID in db is invalid."))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| {
|
.map_err(|_| Error::bad_database("Device ID in userdeviceid_metadata is invalid."))?
|
||||||
Error::bad_database("Device ID in userdeviceid_metadata is invalid.")
|
.into())
|
||||||
})?)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replaces the access token of one device.
|
/// Replaces the access token of one device.
|
||||||
fn set_token(&self, user_id: &UserId, device_id: &str, token: &str) -> Result<()> {
|
fn set_token(&self, user_id: &UserId, device_id: &DeviceId, token: &str) -> Result<()> {
|
||||||
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
||||||
userdeviceid.push(0xff);
|
userdeviceid.push(0xff);
|
||||||
userdeviceid.extend_from_slice(device_id.as_bytes());
|
userdeviceid.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
|
|
||||||
// All devices have metadata
|
// All devices have metadata
|
||||||
assert!(self.userdeviceid_metadata.get(&userdeviceid)?.is_some());
|
assert!(self.userdeviceid_metadata.get(&userdeviceid)?.is_some());
|
||||||
|
@ -268,13 +267,13 @@ impl Users {
|
||||||
pub fn add_one_time_key(
|
pub fn add_one_time_key(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
device_id: &str,
|
device_id: &DeviceId,
|
||||||
one_time_key_key: &AlgorithmAndDeviceId,
|
one_time_key_key: &AlgorithmAndDeviceId,
|
||||||
one_time_key_value: &OneTimeKey,
|
one_time_key_value: &OneTimeKey,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut key = user_id.to_string().as_bytes().to_vec();
|
let mut key = user_id.to_string().as_bytes().to_vec();
|
||||||
key.push(0xff);
|
key.push(0xff);
|
||||||
key.extend_from_slice(device_id.as_bytes());
|
key.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
|
|
||||||
// All devices have metadata
|
// All devices have metadata
|
||||||
// Only existing devices should be able to call this.
|
// Only existing devices should be able to call this.
|
||||||
|
@ -301,12 +300,12 @@ impl Users {
|
||||||
pub fn take_one_time_key(
|
pub fn take_one_time_key(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
device_id: &str,
|
device_id: &DeviceId,
|
||||||
key_algorithm: &KeyAlgorithm,
|
key_algorithm: &KeyAlgorithm,
|
||||||
) -> Result<Option<(AlgorithmAndDeviceId, OneTimeKey)>> {
|
) -> Result<Option<(AlgorithmAndDeviceId, OneTimeKey)>> {
|
||||||
let mut prefix = user_id.to_string().as_bytes().to_vec();
|
let mut prefix = user_id.to_string().as_bytes().to_vec();
|
||||||
prefix.push(0xff);
|
prefix.push(0xff);
|
||||||
prefix.extend_from_slice(device_id.as_bytes());
|
prefix.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
prefix.push(0xff);
|
prefix.push(0xff);
|
||||||
prefix.push(b'"'); // Annoying quotation mark
|
prefix.push(b'"'); // Annoying quotation mark
|
||||||
prefix.extend_from_slice(key_algorithm.to_string().as_bytes());
|
prefix.extend_from_slice(key_algorithm.to_string().as_bytes());
|
||||||
|
@ -337,11 +336,11 @@ impl Users {
|
||||||
pub fn count_one_time_keys(
|
pub fn count_one_time_keys(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
device_id: &str,
|
device_id: &DeviceId,
|
||||||
) -> Result<BTreeMap<KeyAlgorithm, UInt>> {
|
) -> Result<BTreeMap<KeyAlgorithm, UInt>> {
|
||||||
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
||||||
userdeviceid.push(0xff);
|
userdeviceid.push(0xff);
|
||||||
userdeviceid.extend_from_slice(device_id.as_bytes());
|
userdeviceid.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
|
|
||||||
let mut counts = BTreeMap::new();
|
let mut counts = BTreeMap::new();
|
||||||
|
|
||||||
|
@ -370,13 +369,13 @@ impl Users {
|
||||||
pub fn add_device_keys(
|
pub fn add_device_keys(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
device_id: &str,
|
device_id: &DeviceId,
|
||||||
device_keys: &DeviceKeys,
|
device_keys: &DeviceKeys,
|
||||||
globals: &super::globals::Globals,
|
globals: &super::globals::Globals,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
||||||
userdeviceid.push(0xff);
|
userdeviceid.push(0xff);
|
||||||
userdeviceid.extend_from_slice(device_id.as_bytes());
|
userdeviceid.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
|
|
||||||
self.keyid_key.insert(
|
self.keyid_key.insert(
|
||||||
&userdeviceid,
|
&userdeviceid,
|
||||||
|
@ -550,10 +549,14 @@ impl Users {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_device_keys(&self, user_id: &UserId, device_id: &str) -> Result<Option<DeviceKeys>> {
|
pub fn get_device_keys(
|
||||||
|
&self,
|
||||||
|
user_id: &UserId,
|
||||||
|
device_id: &DeviceId,
|
||||||
|
) -> Result<Option<DeviceKeys>> {
|
||||||
let mut key = user_id.to_string().as_bytes().to_vec();
|
let mut key = user_id.to_string().as_bytes().to_vec();
|
||||||
key.push(0xff);
|
key.push(0xff);
|
||||||
key.extend_from_slice(device_id.as_bytes());
|
key.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
|
|
||||||
self.keyid_key.get(key)?.map_or(Ok(None), |bytes| {
|
self.keyid_key.get(key)?.map_or(Ok(None), |bytes| {
|
||||||
Ok(Some(serde_json::from_slice(&bytes).map_err(|_| {
|
Ok(Some(serde_json::from_slice(&bytes).map_err(|_| {
|
||||||
|
@ -633,14 +636,14 @@ impl Users {
|
||||||
&self,
|
&self,
|
||||||
sender: &UserId,
|
sender: &UserId,
|
||||||
target_user_id: &UserId,
|
target_user_id: &UserId,
|
||||||
target_device_id: &str,
|
target_device_id: &DeviceId,
|
||||||
event_type: &EventType,
|
event_type: &EventType,
|
||||||
content: serde_json::Value,
|
content: serde_json::Value,
|
||||||
globals: &super::globals::Globals,
|
globals: &super::globals::Globals,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut key = target_user_id.to_string().as_bytes().to_vec();
|
let mut key = target_user_id.to_string().as_bytes().to_vec();
|
||||||
key.push(0xff);
|
key.push(0xff);
|
||||||
key.extend_from_slice(target_device_id.as_bytes());
|
key.extend_from_slice(target_device_id.as_str().as_bytes());
|
||||||
key.push(0xff);
|
key.push(0xff);
|
||||||
key.extend_from_slice(&globals.next_count()?.to_be_bytes());
|
key.extend_from_slice(&globals.next_count()?.to_be_bytes());
|
||||||
|
|
||||||
|
@ -660,14 +663,14 @@ impl Users {
|
||||||
pub fn take_to_device_events(
|
pub fn take_to_device_events(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
device_id: &str,
|
device_id: &DeviceId,
|
||||||
max: usize,
|
max: usize,
|
||||||
) -> Result<Vec<EventJson<AnyToDeviceEvent>>> {
|
) -> Result<Vec<EventJson<AnyToDeviceEvent>>> {
|
||||||
let mut events = Vec::new();
|
let mut events = Vec::new();
|
||||||
|
|
||||||
let mut prefix = user_id.to_string().as_bytes().to_vec();
|
let mut prefix = user_id.to_string().as_bytes().to_vec();
|
||||||
prefix.push(0xff);
|
prefix.push(0xff);
|
||||||
prefix.extend_from_slice(device_id.as_bytes());
|
prefix.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
prefix.push(0xff);
|
prefix.push(0xff);
|
||||||
|
|
||||||
for result in self.todeviceid_events.scan_prefix(&prefix).take(max) {
|
for result in self.todeviceid_events.scan_prefix(&prefix).take(max) {
|
||||||
|
@ -685,12 +688,12 @@ impl Users {
|
||||||
pub fn update_device_metadata(
|
pub fn update_device_metadata(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
device_id: &str,
|
device_id: &DeviceId,
|
||||||
device: &Device,
|
device: &Device,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
||||||
userdeviceid.push(0xff);
|
userdeviceid.push(0xff);
|
||||||
userdeviceid.extend_from_slice(device_id.as_bytes());
|
userdeviceid.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
|
|
||||||
// Only existing devices should be able to call this.
|
// Only existing devices should be able to call this.
|
||||||
assert!(self.userdeviceid_metadata.get(&userdeviceid)?.is_some());
|
assert!(self.userdeviceid_metadata.get(&userdeviceid)?.is_some());
|
||||||
|
@ -706,10 +709,14 @@ impl Users {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get device metadata.
|
/// Get device metadata.
|
||||||
pub fn get_device_metadata(&self, user_id: &UserId, device_id: &str) -> Result<Option<Device>> {
|
pub fn get_device_metadata(
|
||||||
|
&self,
|
||||||
|
user_id: &UserId,
|
||||||
|
device_id: &DeviceId,
|
||||||
|
) -> Result<Option<Device>> {
|
||||||
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
let mut userdeviceid = user_id.to_string().as_bytes().to_vec();
|
||||||
userdeviceid.push(0xff);
|
userdeviceid.push(0xff);
|
||||||
userdeviceid.extend_from_slice(device_id.as_bytes());
|
userdeviceid.extend_from_slice(device_id.as_str().as_bytes());
|
||||||
|
|
||||||
self.userdeviceid_metadata
|
self.userdeviceid_metadata
|
||||||
.get(&userdeviceid)?
|
.get(&userdeviceid)?
|
||||||
|
|
50
src/pdu.rs
50
src/pdu.rs
|
@ -1,14 +1,12 @@
|
||||||
use crate::{Error, Result};
|
use crate::{Error, Result};
|
||||||
use js_int::UInt;
|
use js_int::UInt;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::federation::EventHash,
|
|
||||||
events::{
|
events::{
|
||||||
collections::all::{RoomEvent, StateEvent},
|
pdu::EventHash, room::member::MemberEventContent, AnyRoomEvent, AnyStateEvent,
|
||||||
room::member::MemberEvent,
|
AnyStrippedStateEvent, AnySyncRoomEvent, AnySyncStateEvent, EventJson, EventType,
|
||||||
stripped::AnyStrippedStateEvent,
|
StateEvent,
|
||||||
EventJson, EventType,
|
|
||||||
},
|
},
|
||||||
identifiers::{EventId, RoomId, UserId},
|
identifiers::{EventId, RoomId, ServerName, UserId},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
@ -19,7 +17,7 @@ pub struct PduEvent {
|
||||||
pub event_id: EventId,
|
pub event_id: EventId,
|
||||||
pub room_id: RoomId,
|
pub room_id: RoomId,
|
||||||
pub sender: UserId,
|
pub sender: UserId,
|
||||||
pub origin: String,
|
pub origin: Box<ServerName>,
|
||||||
pub origin_server_ts: UInt,
|
pub origin_server_ts: UInt,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub kind: EventType,
|
pub kind: EventType,
|
||||||
|
@ -81,24 +79,40 @@ impl PduEvent {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_room_event(&self) -> EventJson<RoomEvent> {
|
pub fn to_sync_room_event(&self) -> EventJson<AnySyncRoomEvent> {
|
||||||
let json = serde_json::to_string(&self).expect("PDUs are always valid");
|
let json = serde_json::to_string(&self).expect("PDUs are always valid");
|
||||||
serde_json::from_str::<EventJson<RoomEvent>>(&json)
|
serde_json::from_str::<AnySyncRoomEvent>(&json)
|
||||||
.expect("EventJson::from_str always works")
|
.map(EventJson::from)
|
||||||
|
.expect("AnySyncRoomEvent can always be built from a full PDU event")
|
||||||
}
|
}
|
||||||
pub fn to_state_event(&self) -> EventJson<StateEvent> {
|
pub fn to_room_event(&self) -> EventJson<AnyRoomEvent> {
|
||||||
let json = serde_json::to_string(&self).expect("PDUs are always valid");
|
let json = serde_json::to_string(&self).expect("PDUs are always valid");
|
||||||
serde_json::from_str::<EventJson<StateEvent>>(&json)
|
serde_json::from_str::<AnyRoomEvent>(&json)
|
||||||
.expect("EventJson::from_str always works")
|
.map(EventJson::from)
|
||||||
|
.expect("AnyRoomEvent can always be built from a full PDU event")
|
||||||
|
}
|
||||||
|
pub fn to_state_event(&self) -> EventJson<AnyStateEvent> {
|
||||||
|
let json = serde_json::to_string(&self).expect("PDUs are always valid");
|
||||||
|
serde_json::from_str::<AnyStateEvent>(&json)
|
||||||
|
.map(EventJson::from)
|
||||||
|
.expect("AnyStateEvent can always be built from a full PDU event")
|
||||||
|
}
|
||||||
|
pub fn to_sync_state_event(&self) -> EventJson<AnySyncStateEvent> {
|
||||||
|
let json = serde_json::to_string(&self).expect("PDUs are always valid");
|
||||||
|
serde_json::from_str::<AnySyncStateEvent>(&json)
|
||||||
|
.map(EventJson::from)
|
||||||
|
.expect("AnySyncStateEvent can always be built from a full PDU event")
|
||||||
}
|
}
|
||||||
pub fn to_stripped_state_event(&self) -> EventJson<AnyStrippedStateEvent> {
|
pub fn to_stripped_state_event(&self) -> EventJson<AnyStrippedStateEvent> {
|
||||||
let json = serde_json::to_string(&self).expect("PDUs are always valid");
|
let json = serde_json::to_string(&self).expect("PDUs are always valid");
|
||||||
serde_json::from_str::<EventJson<AnyStrippedStateEvent>>(&json)
|
serde_json::from_str::<AnyStrippedStateEvent>(&json)
|
||||||
.expect("EventJson::from_str always works")
|
.map(EventJson::from)
|
||||||
|
.expect("AnyStrippedStateEvent can always be built from a full PDU event")
|
||||||
}
|
}
|
||||||
pub fn to_member_event(&self) -> EventJson<MemberEvent> {
|
pub fn to_member_event(&self) -> EventJson<StateEvent<MemberEventContent>> {
|
||||||
let json = serde_json::to_string(&self).expect("PDUs are always valid");
|
let json = serde_json::to_string(&self).expect("PDUs are always valid");
|
||||||
serde_json::from_str::<EventJson<MemberEvent>>(&json)
|
serde_json::from_str::<StateEvent<MemberEventContent>>(&json)
|
||||||
.expect("EventJson::from_str always works")
|
.map(EventJson::from)
|
||||||
|
.expect("StateEvent<MemberEventContent> can always be built from a full PDU event")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,47 @@
|
||||||
|
use js_int::uint;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
events::push_rules::{ConditionalPushRule, PatternedPushRule, PushCondition, Ruleset},
|
|
||||||
identifiers::UserId,
|
identifiers::UserId,
|
||||||
push::{Action, Tweak},
|
push::{
|
||||||
|
Action, ConditionalPushRule, ConditionalPushRuleInit, PatternedPushRule,
|
||||||
|
PatternedPushRuleInit, PushCondition, RoomMemberCountIs, Ruleset, Tweak,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn default_pushrules(user_id: &UserId) -> Ruleset {
|
pub fn default_pushrules(user_id: &UserId) -> Ruleset {
|
||||||
Ruleset {
|
let mut rules = Ruleset::default();
|
||||||
content: vec![contains_user_name_rule(&user_id)],
|
rules.content = vec![contains_user_name_rule(&user_id)];
|
||||||
override_: vec![
|
rules.override_ = vec![
|
||||||
master_rule(),
|
master_rule(),
|
||||||
suppress_notices_rule(),
|
suppress_notices_rule(),
|
||||||
invite_for_me_rule(),
|
invite_for_me_rule(),
|
||||||
member_event_rule(),
|
member_event_rule(),
|
||||||
contains_display_name_rule(),
|
contains_display_name_rule(),
|
||||||
tombstone_rule(),
|
tombstone_rule(),
|
||||||
roomnotif_rule(),
|
roomnotif_rule(),
|
||||||
],
|
];
|
||||||
room: vec![],
|
rules.underride = vec![
|
||||||
sender: vec![],
|
call_rule(),
|
||||||
underride: vec![
|
encrypted_room_one_to_one_rule(),
|
||||||
call_rule(),
|
room_one_to_one_rule(),
|
||||||
encrypted_room_one_to_one_rule(),
|
message_rule(),
|
||||||
room_one_to_one_rule(),
|
encrypted_rule(),
|
||||||
message_rule(),
|
];
|
||||||
encrypted_rule(),
|
rules
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn master_rule() -> ConditionalPushRule {
|
pub fn master_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![Action::DontNotify],
|
actions: vec![Action::DontNotify],
|
||||||
default: true,
|
default: true,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
rule_id: ".m.rule.master".to_owned(),
|
rule_id: ".m.rule.master".to_owned(),
|
||||||
conditions: vec![],
|
conditions: vec![],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn suppress_notices_rule() -> ConditionalPushRule {
|
pub fn suppress_notices_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![Action::DontNotify],
|
actions: vec![Action::DontNotify],
|
||||||
default: true,
|
default: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -49,10 +51,11 @@ pub fn suppress_notices_rule() -> ConditionalPushRule {
|
||||||
pattern: "m.notice".to_owned(),
|
pattern: "m.notice".to_owned(),
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invite_for_me_rule() -> ConditionalPushRule {
|
pub fn invite_for_me_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![
|
actions: vec![
|
||||||
Action::Notify,
|
Action::Notify,
|
||||||
Action::SetTweak(Tweak::Sound("default".to_owned())),
|
Action::SetTweak(Tweak::Sound("default".to_owned())),
|
||||||
|
@ -66,10 +69,11 @@ pub fn invite_for_me_rule() -> ConditionalPushRule {
|
||||||
pattern: "m.invite".to_owned(),
|
pattern: "m.invite".to_owned(),
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn member_event_rule() -> ConditionalPushRule {
|
pub fn member_event_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![Action::DontNotify],
|
actions: vec![Action::DontNotify],
|
||||||
default: true,
|
default: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -79,10 +83,11 @@ pub fn member_event_rule() -> ConditionalPushRule {
|
||||||
pattern: "type".to_owned(),
|
pattern: "type".to_owned(),
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains_display_name_rule() -> ConditionalPushRule {
|
pub fn contains_display_name_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![
|
actions: vec![
|
||||||
Action::Notify,
|
Action::Notify,
|
||||||
Action::SetTweak(Tweak::Sound("default".to_owned())),
|
Action::SetTweak(Tweak::Sound("default".to_owned())),
|
||||||
|
@ -93,10 +98,11 @@ pub fn contains_display_name_rule() -> ConditionalPushRule {
|
||||||
rule_id: ".m.rule.contains_display_name".to_owned(),
|
rule_id: ".m.rule.contains_display_name".to_owned(),
|
||||||
conditions: vec![PushCondition::ContainsDisplayName],
|
conditions: vec![PushCondition::ContainsDisplayName],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tombstone_rule() -> ConditionalPushRule {
|
pub fn tombstone_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(true))],
|
actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(true))],
|
||||||
default: true,
|
default: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -112,10 +118,11 @@ pub fn tombstone_rule() -> ConditionalPushRule {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn roomnotif_rule() -> ConditionalPushRule {
|
pub fn roomnotif_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(true))],
|
actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(true))],
|
||||||
default: true,
|
default: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -130,10 +137,11 @@ pub fn roomnotif_rule() -> ConditionalPushRule {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains_user_name_rule(user_id: &UserId) -> PatternedPushRule {
|
pub fn contains_user_name_rule(user_id: &UserId) -> PatternedPushRule {
|
||||||
PatternedPushRule {
|
PatternedPushRuleInit {
|
||||||
actions: vec![
|
actions: vec![
|
||||||
Action::Notify,
|
Action::Notify,
|
||||||
Action::SetTweak(Tweak::Sound("default".to_owned())),
|
Action::SetTweak(Tweak::Sound("default".to_owned())),
|
||||||
|
@ -144,10 +152,11 @@ pub fn contains_user_name_rule(user_id: &UserId) -> PatternedPushRule {
|
||||||
rule_id: ".m.rule.contains_user_name".to_owned(),
|
rule_id: ".m.rule.contains_user_name".to_owned(),
|
||||||
pattern: user_id.localpart().to_owned(),
|
pattern: user_id.localpart().to_owned(),
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_rule() -> ConditionalPushRule {
|
pub fn call_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![
|
actions: vec![
|
||||||
Action::Notify,
|
Action::Notify,
|
||||||
Action::SetTweak(Tweak::Sound("ring".to_owned())),
|
Action::SetTweak(Tweak::Sound("ring".to_owned())),
|
||||||
|
@ -161,10 +170,11 @@ pub fn call_rule() -> ConditionalPushRule {
|
||||||
pattern: "m.call.invite".to_owned(),
|
pattern: "m.call.invite".to_owned(),
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encrypted_room_one_to_one_rule() -> ConditionalPushRule {
|
pub fn encrypted_room_one_to_one_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![
|
actions: vec![
|
||||||
Action::Notify,
|
Action::Notify,
|
||||||
Action::SetTweak(Tweak::Sound("default".to_owned())),
|
Action::SetTweak(Tweak::Sound("default".to_owned())),
|
||||||
|
@ -174,17 +184,20 @@ pub fn encrypted_room_one_to_one_rule() -> ConditionalPushRule {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
rule_id: ".m.rule.encrypted_room_one_to_one".to_owned(),
|
rule_id: ".m.rule.encrypted_room_one_to_one".to_owned(),
|
||||||
conditions: vec![
|
conditions: vec![
|
||||||
PushCondition::RoomMemberCount { is: "2".to_owned() },
|
PushCondition::RoomMemberCount {
|
||||||
|
is: RoomMemberCountIs::from(uint!(2)..),
|
||||||
|
},
|
||||||
PushCondition::EventMatch {
|
PushCondition::EventMatch {
|
||||||
key: "type".to_owned(),
|
key: "type".to_owned(),
|
||||||
pattern: "m.room.encrypted".to_owned(),
|
pattern: "m.room.encrypted".to_owned(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn room_one_to_one_rule() -> ConditionalPushRule {
|
pub fn room_one_to_one_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![
|
actions: vec![
|
||||||
Action::Notify,
|
Action::Notify,
|
||||||
Action::SetTweak(Tweak::Sound("default".to_owned())),
|
Action::SetTweak(Tweak::Sound("default".to_owned())),
|
||||||
|
@ -194,17 +207,20 @@ pub fn room_one_to_one_rule() -> ConditionalPushRule {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
rule_id: ".m.rule.room_one_to_one".to_owned(),
|
rule_id: ".m.rule.room_one_to_one".to_owned(),
|
||||||
conditions: vec![
|
conditions: vec![
|
||||||
PushCondition::RoomMemberCount { is: "2".to_owned() },
|
PushCondition::RoomMemberCount {
|
||||||
|
is: RoomMemberCountIs::from(uint!(2)..),
|
||||||
|
},
|
||||||
PushCondition::EventMatch {
|
PushCondition::EventMatch {
|
||||||
key: "type".to_owned(),
|
key: "type".to_owned(),
|
||||||
pattern: "m.room.message".to_owned(),
|
pattern: "m.room.message".to_owned(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn message_rule() -> ConditionalPushRule {
|
pub fn message_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(false))],
|
actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(false))],
|
||||||
default: true,
|
default: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -214,10 +230,11 @@ pub fn message_rule() -> ConditionalPushRule {
|
||||||
pattern: "m.room.message".to_owned(),
|
pattern: "m.room.message".to_owned(),
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encrypted_rule() -> ConditionalPushRule {
|
pub fn encrypted_rule() -> ConditionalPushRule {
|
||||||
ConditionalPushRule {
|
ConditionalPushRuleInit {
|
||||||
actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(false))],
|
actions: vec![Action::Notify, Action::SetTweak(Tweak::Highlight(false))],
|
||||||
default: true,
|
default: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -227,4 +244,5 @@ pub fn encrypted_rule() -> ConditionalPushRule {
|
||||||
pattern: "m.room.encrypted".to_owned(),
|
pattern: "m.room.encrypted".to_owned(),
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,10 @@ use rocket::{
|
||||||
Outcome::*,
|
Outcome::*,
|
||||||
Request, State,
|
Request, State,
|
||||||
};
|
};
|
||||||
use ruma::{api::Endpoint, identifiers::UserId};
|
use ruma::{
|
||||||
|
api::Endpoint,
|
||||||
|
identifiers::{DeviceId, UserId},
|
||||||
|
};
|
||||||
use std::{convert::TryInto, io::Cursor, ops::Deref};
|
use std::{convert::TryInto, io::Cursor, ops::Deref};
|
||||||
use tokio::io::AsyncReadExt;
|
use tokio::io::AsyncReadExt;
|
||||||
|
|
||||||
|
@ -18,7 +21,7 @@ const MESSAGE_LIMIT: u64 = 20 * 1024 * 1024; // 20 MB
|
||||||
pub struct Ruma<T> {
|
pub struct Ruma<T> {
|
||||||
pub body: T,
|
pub body: T,
|
||||||
pub user_id: Option<UserId>,
|
pub user_id: Option<UserId>,
|
||||||
pub device_id: Option<String>,
|
pub device_id: Option<Box<DeviceId>>,
|
||||||
pub json_body: Option<Box<serde_json::value::RawValue>>, // This is None when body is not a valid string
|
pub json_body: Option<Box<serde_json::value::RawValue>>, // This is None when body is not a valid string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +66,7 @@ impl<'a, T: Endpoint> FromTransformedData<'a> for Ruma<T> {
|
||||||
match db.users.find_from_token(&token).unwrap() {
|
match db.users.find_from_token(&token).unwrap() {
|
||||||
// TODO: M_UNKNOWN_TOKEN
|
// TODO: M_UNKNOWN_TOKEN
|
||||||
None => return Failure((Status::Unauthorized, ())),
|
None => return Failure((Status::Unauthorized, ())),
|
||||||
Some((user_id, device_id)) => (Some(user_id), Some(device_id)),
|
Some((user_id, device_id)) => (Some(user_id), Some(device_id.into())),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(None, None)
|
(None, None)
|
||||||
|
|
Loading…
Reference in a new issue