1
0
Fork 0
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:
Timo Kösters 2020-07-25 22:02:45 +02:00
commit 678f33acf9
13 changed files with 518 additions and 441 deletions

495
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -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" }

View file

@ -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<_>>();

View file

@ -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};

View file

@ -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 {

View file

@ -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},
}; };

View file

@ -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,
) )

View file

@ -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
}) })
} }

View file

@ -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

View file

@ -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)?

View file

@ -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")
} }
} }

View file

@ -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()
} }

View file

@ -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)