fix: membership deserializing

This commit is contained in:
Timo Kösters 2021-04-09 21:38:16 +02:00
parent 51aa6448bc
commit 84f4ce73e5
No known key found for this signature in database
GPG key ID: 24DA7517711A2BA4
9 changed files with 74 additions and 63 deletions

View file

@ -604,12 +604,16 @@ async fn join_room_by_id_helper(
db.rooms.update_membership(
&pdu.room_id,
&target_user_id,
serde_json::from_value::<member::MemberEventContent>(pdu.content.clone())
.map_err(|_| {
Error::BadRequest(
ErrorKind::InvalidParam,
"Invalid member event content.",
)
serde_json::from_value::<member::MembershipState>(
pdu.content
.get("membership")
.ok_or_else(|| {
Error::BadServerResponse("Invalid member event content")
})?
.clone(),
)
.map_err(|_| {
Error::BadServerResponse("Invalid membership state content.")
})?,
&pdu.sender,
&db.account_data,

View file

@ -91,10 +91,24 @@ pub async fn create_room_route(
)?;
// 3. Power levels
// Figure out preset. We need it for preset specific events
let preset = body
.preset
.clone()
.unwrap_or_else(|| match &body.visibility {
room::Visibility::Private => create_room::RoomPreset::PrivateChat,
room::Visibility::Public => create_room::RoomPreset::PublicChat,
room::Visibility::_Custom(_) => create_room::RoomPreset::PrivateChat, // Room visibility should not be custom
});
let mut users = BTreeMap::new();
users.insert(sender_user.clone(), 100.into());
for invite_ in &body.invite {
users.insert(invite_.clone(), 100.into());
if preset == create_room::RoomPreset::TrustedPrivateChat {
for invite_ in &body.invite {
users.insert(invite_.clone(), 100.into());
}
}
let power_levels_content = if let Some(power_levels) = &body.power_level_content_override {
@ -133,16 +147,6 @@ pub async fn create_room_route(
// 4. Events set by preset
// Figure out preset. We need it for preset specific events
let preset = body
.preset
.clone()
.unwrap_or_else(|| match &body.visibility {
room::Visibility::Private => create_room::RoomPreset::PrivateChat,
room::Visibility::Public => create_room::RoomPreset::PublicChat,
room::Visibility::_Custom(s) => create_room::RoomPreset::_Custom(s.into()),
});
// 4.1 Join Rules
db.rooms.build_and_append_pdu(
PduBuilder {

View file

@ -108,7 +108,7 @@ impl Database {
pub async fn load_or_create(config: Config) -> Result<Self> {
let db = sled::Config::default()
.path(&config.database_path)
.cache_capacity(config.cache_capacity as u64)
.cache_capacity(config.cache_capacity as usize)
.use_compression(true)
.open()?;

View file

@ -196,7 +196,7 @@ pub async fn send_push_notice(
let mut notify = None;
let mut tweaks = Vec::new();
for action in ruleset.get_actions(&pdu.to_sync_state_event(), &ctx) {
for action in ruleset.get_actions(&pdu.to_sync_room_event(), &ctx) {
let n = match action {
Action::DontNotify => false,
// TODO: Implement proper support for coalesce

View file

@ -465,7 +465,7 @@ impl Rooms {
/// Returns the pdu.
///
/// This does __NOT__ check the outliers `Tree`.
pub fn get_pdu_from_id(&self, pdu_id: &IVec) -> Result<Option<PduEvent>> {
pub fn get_pdu_from_id(&self, pdu_id: &[u8]) -> Result<Option<PduEvent>> {
self.pduid_pdu.get(pdu_id)?.map_or(Ok(None), |pdu| {
Ok(Some(
serde_json::from_slice(&pdu)
@ -671,11 +671,21 @@ impl Rooms {
self.update_membership(
&pdu.room_id,
&target_user_id,
serde_json::from_value::<member::MemberEventContent>(pdu.content.clone())
.map_err(|_| {
serde_json::from_value::<member::MembershipState>(
pdu.content
.get("membership")
.ok_or_else(|| {
Error::BadRequest(
ErrorKind::InvalidParam,
"Invalid member event content",
)
})?
.clone(),
)
.map_err(|_| {
Error::BadRequest(
ErrorKind::InvalidParam,
"Invalid member event content.",
"Invalid membership state content.",
)
})?,
&pdu.sender,
@ -895,19 +905,14 @@ impl Rooms {
.scan_prefix(&old_shortstatehash)
.filter_map(|pdu| pdu.map_err(|e| error!("{}", e)).ok())
// Chop the old_shortstatehash out leaving behind the short state key
.map(|(k, v)| {
(
k.subslice(old_shortstatehash.len(), k.len() - old_shortstatehash.len()),
v,
)
})
.collect::<HashMap<IVec, IVec>>()
.map(|(k, v)| (k[old_shortstatehash.len()..].to_vec(), v))
.collect::<HashMap<Vec<u8>, IVec>>()
} else {
HashMap::new()
};
if let Some(state_key) = &new_pdu.state_key {
let mut new_state: HashMap<IVec, IVec> = old_state;
let mut new_state: HashMap<Vec<u8>, IVec> = old_state;
let mut new_state_key = new_pdu.kind.as_ref().as_bytes().to_vec();
new_state_key.push(0xff);
@ -935,7 +940,7 @@ impl Rooms {
}
};
new_state.insert(shortstatekey.into(), shorteventid.into());
new_state.insert(shortstatekey, shorteventid.into());
let new_state_hash = self.calculate_hash(
&new_state
@ -1377,13 +1382,11 @@ impl Rooms {
&self,
room_id: &RoomId,
user_id: &UserId,
member_content: member::MemberEventContent,
membership: member::MembershipState,
sender: &UserId,
account_data: &super::account_data::AccountData,
globals: &super::globals::Globals,
) -> Result<()> {
let membership = member_content.membership;
let mut roomserver_id = room_id.as_bytes().to_vec();
roomserver_id.push(0xff);
roomserver_id.extend_from_slice(user_id.server_name().as_bytes());
@ -1633,7 +1636,7 @@ impl Rooms {
&'a self,
room_id: &RoomId,
search_string: &str,
) -> Result<(impl Iterator<Item = IVec> + 'a, Vec<String>)> {
) -> Result<(impl Iterator<Item = Vec<u8>> + 'a, Vec<String>)> {
let mut prefix = room_id.as_bytes().to_vec();
prefix.push(0xff);
@ -1661,7 +1664,7 @@ impl Rooms {
.0
+ 1; // +1 because the pdu id starts AFTER the separator
let pdu_id = key.subslice(pduid_index, key.len() - pduid_index);
let pdu_id = key[pduid_index..].to_vec();
Ok::<_, Error>(pdu_id)
})
@ -1700,7 +1703,7 @@ impl Rooms {
.0
+ 1; // +1 because the room id starts AFTER the separator
let room_id = key.subslice(roomid_index, key.len() - roomid_index);
let room_id = key[roomid_index..].to_vec();
Ok::<_, Error>(room_id)
})

View file

@ -47,7 +47,7 @@ impl Sending {
let mut futures = FuturesUnordered::new();
// Retry requests we could not finish yet
let mut current_transactions = HashMap::<OutgoingKind, Vec<IVec>>::new();
let mut current_transactions = HashMap::<OutgoingKind, Vec<Vec<u8>>>::new();
for (key, outgoing_kind, pdu) in servercurrentpdus
.iter()
@ -55,7 +55,7 @@ impl Sending {
.filter_map(|(key, _)| {
Self::parse_servercurrentpdus(&key)
.ok()
.map(|(k, p)| (key, k, p))
.map(|(k, p)| (key, k, p.to_vec()))
})
{
if pdu.is_empty() {
@ -150,7 +150,7 @@ impl Sending {
.keys()
.filter_map(|r| r.ok())
.map(|k| {
k.subslice(prefix.len(), k.len() - prefix.len())
k[prefix.len()..].to_vec()
})
.take(30)
.collect::<Vec<_>>();
@ -211,7 +211,11 @@ impl Sending {
};
},
Some(event) = &mut subscriber => {
if let sled::Event::Insert { key, .. } = event {
for (_tree, key, value_opt) in &event {
if value_opt.is_none() {
continue;
}
let servernamepduid = key.clone();
let exponential_backoff = |(tries, instant): &(u32, Instant)| {
@ -265,7 +269,7 @@ impl Sending {
futures.push(
Self::handle_event(
outgoing_kind,
vec![pdu_id],
vec![pdu_id.to_vec()],
&db,
)
);
@ -310,7 +314,7 @@ impl Sending {
}
#[tracing::instrument]
fn calculate_hash(keys: &[IVec]) -> Vec<u8> {
fn calculate_hash(keys: &[Vec<u8>]) -> Vec<u8> {
// We only hash the pdu's event ids, not the whole pdu
let bytes = keys.join(&0xff);
let hash = digest::digest(&digest::SHA256, &bytes);
@ -320,7 +324,7 @@ impl Sending {
#[tracing::instrument(skip(db))]
async fn handle_event(
kind: OutgoingKind,
pdu_ids: Vec<IVec>,
pdu_ids: Vec<Vec<u8>>,
db: &Database,
) -> std::result::Result<OutgoingKind, (OutgoingKind, Error)> {
match &kind {

View file

@ -2,7 +2,6 @@ use argon2::{Config, Variant};
use cmp::Ordering;
use rand::prelude::*;
use ruma::serde::{try_from_json_map, CanonicalJsonError, CanonicalJsonObject};
use sled::IVec;
use std::{
cmp,
convert::TryInto,
@ -70,10 +69,10 @@ pub fn calculate_hash(password: &str) -> Result<String, argon2::Error> {
argon2::hash_encoded(password.as_bytes(), salt.as_bytes(), &hashing_config)
}
pub fn common_elements(
mut iterators: impl Iterator<Item = impl Iterator<Item = IVec>>,
check_order: impl Fn(&IVec, &IVec) -> Ordering,
) -> Option<impl Iterator<Item = IVec>> {
pub fn common_elements<'a>(
mut iterators: impl Iterator<Item = impl Iterator<Item = Vec<u8>>>,
check_order: impl Fn(&[u8], &[u8]) -> Ordering,
) -> Option<impl Iterator<Item = Vec<u8>>> {
let first_iterator = iterators.next()?;
let mut other_iterators = iterators.map(|i| i.peekable()).collect::<Vec<_>>();