fix: membership deserializing
This commit is contained in:
		
							parent
							
								
									51aa6448bc
								
							
						
					
					
						commit
						84f4ce73e5
					
				
					 9 changed files with 74 additions and 63 deletions
				
			
		
							
								
								
									
										14
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										14
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							|  | @ -877,9 +877,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" | |||
| 
 | ||||
| [[package]] | ||||
| name = "libc" | ||||
| version = "0.2.92" | ||||
| version = "0.2.93" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "56d855069fafbb9b344c0f962150cd2c1187975cb1c22c1522c240d8c4986714" | ||||
| checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "linked-hash-map" | ||||
|  | @ -2125,7 +2125,7 @@ checksum = "3015a7d0a5fd5105c91c3710d42f9ccf0abfb287d62206484dcc67f9569a6483" | |||
| [[package]] | ||||
| name = "state-res" | ||||
| version = "0.1.0" | ||||
| source = "git+https://github.com/ruma/state-res?rev=af450d0fe2b0e1c890284d0bc3b9d6d4008ac475#af450d0fe2b0e1c890284d0bc3b9d6d4008ac475" | ||||
| source = "git+https://github.com/timokoesters/state-res?rev=1ec42ea2fc0b0728bf027a5899839ad94bb3091b#1ec42ea2fc0b0728bf027a5899839ad94bb3091b" | ||||
| dependencies = [ | ||||
|  "itertools", | ||||
|  "log", | ||||
|  | @ -2578,9 +2578,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "unicode-bidi" | ||||
| version = "0.3.4" | ||||
| version = "0.3.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" | ||||
| checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" | ||||
| dependencies = [ | ||||
|  "matches", | ||||
| ] | ||||
|  | @ -2760,9 +2760,9 @@ checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" | |||
| 
 | ||||
| [[package]] | ||||
| name = "wildmatch" | ||||
| version = "2.0.0" | ||||
| version = "2.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "07ae7ce410f81ba679081aac1d4874f3b1c328535b630209aa5b4cdaaf895e20" | ||||
| checksum = "d6c48bd20df7e4ced539c12f570f937c6b4884928a87fee70a479d72f031d4e0" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "winapi" | ||||
|  |  | |||
|  | @ -23,11 +23,8 @@ ruma = { git = "https://github.com/ruma/ruma", rev = "a310ccc318a4eb51062923d570 | |||
| #ruma = { path = "../ruma/ruma", features = ["unstable-exhaustive-types", "rand", "client-api", "federation-api", "push-gateway-api", "unstable-pre-spec", "unstable-synapse-quirks"] } | ||||
| 
 | ||||
| # Used when doing state resolution | ||||
| state-res = { git = "https://github.com/ruma/state-res", rev = "af450d0fe2b0e1c890284d0bc3b9d6d4008ac475", features = ["unstable-pre-spec"] } | ||||
| # TODO: remove the gen-eventid feature | ||||
| #state-res = { git = "https://github.com/ruma/state-res", branch = "main", features = ["unstable-pre-spec", "gen-eventid"] } | ||||
| #state-res = { git = "https://github.com/ruma/state-res", rev = "1621a491a9e867a1ad4dff9f2f92b0c1e2d44aa0", features = ["unstable-pre-spec", "gen-eventid"] } | ||||
| #state-res = { path = "../state-res", features = ["unstable-pre-spec", "gen-eventid"] } | ||||
| state-res = { git = "https://github.com/timokoesters/state-res", rev = "1ec42ea2fc0b0728bf027a5899839ad94bb3091b", features = ["unstable-pre-spec"] } | ||||
| #state-res = { path = "../state-res", features = ["unstable-pre-spec"] } | ||||
| 
 | ||||
| # Used for long polling and federation sender, should be the same as rocket::tokio | ||||
| tokio = "1.2.0" | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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()?; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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) | ||||
|                 }) | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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<_>>(); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue