fix: don't send new events from left rooms
This commit is contained in:
		
							parent
							
								
									2f5df4aac9
								
							
						
					
					
						commit
						0762196963
					
				
					 6 changed files with 79 additions and 48 deletions
				
			
		|  | @ -103,6 +103,7 @@ pub async fn leave_room_route( | |||
|                 ErrorKind::BadState, | ||||
|                 "Cannot leave a room you are not a member of.", | ||||
|             ))? | ||||
|             .1 | ||||
|             .content, | ||||
|     ) | ||||
|     .expect("from_value::<Raw<..>> can never fail") | ||||
|  | @ -193,6 +194,7 @@ pub async fn kick_user_route( | |||
|                 ErrorKind::BadState, | ||||
|                 "Cannot kick member that's not in the room.", | ||||
|             ))? | ||||
|             .1 | ||||
|             .content, | ||||
|     ) | ||||
|     .expect("Raw::from_value always works") | ||||
|  | @ -249,7 +251,7 @@ pub async fn ban_user_route( | |||
|                 is_direct: None, | ||||
|                 third_party_invite: None, | ||||
|             }), | ||||
|             |event| { | ||||
|             |(_, event)| { | ||||
|                 let mut event = | ||||
|                     serde_json::from_value::<Raw<member::MemberEventContent>>(event.content) | ||||
|                         .expect("Raw::from_value always works") | ||||
|  | @ -301,6 +303,7 @@ pub async fn unban_user_route( | |||
|                 ErrorKind::BadState, | ||||
|                 "Cannot unban a user who is not banned.", | ||||
|             ))? | ||||
|             .1 | ||||
|             .content, | ||||
|     ) | ||||
|     .expect("from_value::<Raw<..>> can never fail") | ||||
|  |  | |||
|  | @ -48,6 +48,7 @@ pub async fn set_displayname_route( | |||
|                                     "Tried to send displayname update for user not in the room.", | ||||
|                                 ) | ||||
|                             })? | ||||
|                             .1 | ||||
|                             .content | ||||
|                             .clone(), | ||||
|                     ) | ||||
|  | @ -142,6 +143,7 @@ pub async fn set_avatar_url_route( | |||
|                                     "Tried to send avatar url update for user not in the room.", | ||||
|                                 ) | ||||
|                             })? | ||||
|                             .1 | ||||
|                             .content | ||||
|                             .clone(), | ||||
|                     ) | ||||
|  |  | |||
|  | @ -395,6 +395,7 @@ pub async fn upgrade_room_route( | |||
|         db.rooms | ||||
|             .room_state_get(&body.room_id, &EventType::RoomCreate, "")? | ||||
|             .ok_or_else(|| Error::bad_database("Found room without m.room.create event."))? | ||||
|             .1 | ||||
|             .content, | ||||
|     ) | ||||
|     .expect("Raw::from_value always works") | ||||
|  | @ -470,7 +471,7 @@ pub async fn upgrade_room_route( | |||
|     // Replicate transferable state events to the new room
 | ||||
|     for event_type in transferable_state_events { | ||||
|         let event_content = match db.rooms.room_state_get(&body.room_id, &event_type, "")? { | ||||
|             Some(v) => v.content.clone(), | ||||
|             Some((_, v)) => v.content.clone(), | ||||
|             None => continue, // Skipping missing events.
 | ||||
|         }; | ||||
| 
 | ||||
|  | @ -502,6 +503,7 @@ pub async fn upgrade_room_route( | |||
|             db.rooms | ||||
|                 .room_state_get(&body.room_id, &EventType::RoomPowerLevels, "")? | ||||
|                 .ok_or_else(|| Error::bad_database("Found room without m.room.create event."))? | ||||
|                 .1 | ||||
|                 .content, | ||||
|         ) | ||||
|         .expect("database contains invalid PDU") | ||||
|  |  | |||
|  | @ -109,7 +109,7 @@ pub async fn get_state_events_route( | |||
|         if !matches!( | ||||
|             db.rooms | ||||
|                 .room_state_get(&body.room_id, &EventType::RoomHistoryVisibility, "")? | ||||
|                 .map(|event| { | ||||
|                 .map(|(_, event)| { | ||||
|                     serde_json::from_value::<HistoryVisibilityEventContent>(event.content) | ||||
|                         .map_err(|_| { | ||||
|                             Error::bad_database( | ||||
|  | @ -154,7 +154,7 @@ pub async fn get_state_events_for_key_route( | |||
|         if !matches!( | ||||
|             db.rooms | ||||
|                 .room_state_get(&body.room_id, &EventType::RoomHistoryVisibility, "")? | ||||
|                 .map(|event| { | ||||
|                 .map(|(_, event)| { | ||||
|                     serde_json::from_value::<HistoryVisibilityEventContent>(event.content) | ||||
|                         .map_err(|_| { | ||||
|                             Error::bad_database( | ||||
|  | @ -178,7 +178,8 @@ pub async fn get_state_events_for_key_route( | |||
|         .ok_or(Error::BadRequest( | ||||
|             ErrorKind::NotFound, | ||||
|             "State event not found.", | ||||
|         ))?; | ||||
|         ))? | ||||
|         .1; | ||||
| 
 | ||||
|     Ok(get_state_events_for_key::Response { | ||||
|         content: serde_json::value::to_raw_value(&event.content) | ||||
|  | @ -203,7 +204,7 @@ pub async fn get_state_events_for_empty_key_route( | |||
|         if !matches!( | ||||
|             db.rooms | ||||
|                 .room_state_get(&body.room_id, &EventType::RoomHistoryVisibility, "")? | ||||
|                 .map(|event| { | ||||
|                 .map(|(_, event)| { | ||||
|                     serde_json::from_value::<HistoryVisibilityEventContent>(event.content) | ||||
|                         .map_err(|_| { | ||||
|                             Error::bad_database( | ||||
|  | @ -227,7 +228,8 @@ pub async fn get_state_events_for_empty_key_route( | |||
|         .ok_or(Error::BadRequest( | ||||
|             ErrorKind::NotFound, | ||||
|             "State event not found.", | ||||
|         ))?; | ||||
|         ))? | ||||
|         .1; | ||||
| 
 | ||||
|     Ok(get_state_events_for_empty_key::Response { | ||||
|         content: serde_json::value::to_raw_value(&event) | ||||
|  |  | |||
|  | @ -440,23 +440,8 @@ pub async fn sync_events_route( | |||
|     let mut left_rooms = BTreeMap::new(); | ||||
|     for room_id in db.rooms.rooms_left(&sender_user) { | ||||
|         let room_id = room_id?; | ||||
|         let pdus = db.rooms.pdus_since(&sender_user, &room_id, since)?; | ||||
|         let room_events = pdus | ||||
|             .filter_map(|pdu| pdu.ok()) // Filter out buggy events
 | ||||
|             .map(|(_, pdu)| pdu.to_sync_room_event()) | ||||
|             .collect(); | ||||
| 
 | ||||
|         let left_room = sync_events::LeftRoom { | ||||
|             account_data: sync_events::AccountData { events: Vec::new() }, | ||||
|             timeline: sync_events::Timeline { | ||||
|                 limited: false, | ||||
|                 prev_batch: Some(next_batch.clone()), | ||||
|                 events: room_events, | ||||
|             }, | ||||
|             state: sync_events::State { events: Vec::new() }, | ||||
|         }; | ||||
| 
 | ||||
|         let since_member = db | ||||
|         let since_member = if let Some(since_member) = db | ||||
|             .rooms | ||||
|             .pdus_after(sender_user, &room_id, since) | ||||
|             .next() | ||||
|  | @ -475,20 +460,25 @@ pub async fn sync_events_route( | |||
|                     .ok_or_else(|| Error::bad_database("State hash in db doesn't have a state.")) | ||||
|                     .ok() | ||||
|             }) | ||||
|             .and_then(|pdu| { | ||||
|             .and_then(|(pdu_id, pdu)| { | ||||
|                 serde_json::from_value::<Raw<ruma::events::room::member::MemberEventContent>>( | ||||
|                     pdu.content, | ||||
|                     pdu.content.clone(), | ||||
|                 ) | ||||
|                 .expect("Raw::from_value always works") | ||||
|                 .deserialize() | ||||
|                 .map_err(|_| Error::bad_database("Invalid PDU in database.")) | ||||
|                 .map(|content| (pdu_id, pdu, content)) | ||||
|                 .ok() | ||||
|             }); | ||||
|             }) { | ||||
|             since_member | ||||
|         } else { | ||||
|             // We couldn't find the since_member event. This is very weird - we better abort
 | ||||
|             continue; | ||||
|         }; | ||||
| 
 | ||||
|         let left_since_last_sync = | ||||
|             since_member.map_or(false, |member| member.membership == MembershipState::Join); | ||||
|         let left_since_last_sync = since_member.2.membership == MembershipState::Join; | ||||
| 
 | ||||
|         if left_since_last_sync { | ||||
|         let left_room = if left_since_last_sync { | ||||
|             device_list_left.extend( | ||||
|                 db.rooms | ||||
|                     .room_members(&room_id) | ||||
|  | @ -503,7 +493,35 @@ pub async fn sync_events_route( | |||
|                         !share_encrypted_room(&db, sender_user, user_id, &room_id) | ||||
|                     }), | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|             let pdus = db.rooms.pdus_since(&sender_user, &room_id, since)?; | ||||
|             let mut room_events = pdus | ||||
|                 .filter_map(|pdu| pdu.ok()) // Filter out buggy events
 | ||||
|                 .take_while(|(pdu_id, _)| since_member.0 != pdu_id) | ||||
|                 .map(|(_, pdu)| pdu.to_sync_room_event()) | ||||
|                 .collect::<Vec<_>>(); | ||||
|             room_events.push(since_member.1.to_sync_room_event()); | ||||
| 
 | ||||
|             sync_events::LeftRoom { | ||||
|                 account_data: sync_events::AccountData { events: Vec::new() }, | ||||
|                 timeline: sync_events::Timeline { | ||||
|                     limited: false, | ||||
|                     prev_batch: Some(next_batch.clone()), | ||||
|                     events: room_events, | ||||
|                 }, | ||||
|                 state: sync_events::State { events: Vec::new() }, | ||||
|             } | ||||
|         } else { | ||||
|             sync_events::LeftRoom { | ||||
|                 account_data: sync_events::AccountData { events: Vec::new() }, | ||||
|                 timeline: sync_events::Timeline { | ||||
|                     limited: false, | ||||
|                     prev_batch: Some(next_batch.clone()), | ||||
|                     events: Vec::new(), | ||||
|                 }, | ||||
|                 state: sync_events::State { events: Vec::new() }, | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         if !left_room.is_empty() { | ||||
|             left_rooms.insert(room_id.clone(), left_room); | ||||
|  |  | |||
|  | @ -169,7 +169,7 @@ impl Rooms { | |||
|         state_hash: &StateHashId, | ||||
|         event_type: &EventType, | ||||
|         state_key: &str, | ||||
|     ) -> Result<Option<PduEvent>> { | ||||
|     ) -> Result<Option<(IVec, PduEvent)>> { | ||||
|         let mut key = state_hash.to_vec(); | ||||
|         key.push(0xff); | ||||
|         key.extend_from_slice(&event_type.to_string().as_bytes()); | ||||
|  | @ -177,14 +177,15 @@ impl Rooms { | |||
|         key.extend_from_slice(&state_key.as_bytes()); | ||||
| 
 | ||||
|         self.stateid_pduid.get(&key)?.map_or(Ok(None), |pdu_id| { | ||||
|             Ok::<_, Error>(Some( | ||||
|             Ok::<_, Error>(Some(( | ||||
|                 pdu_id.clone(), | ||||
|                 serde_json::from_slice::<PduEvent>( | ||||
|                     &self.pduid_pdu.get(pdu_id)?.ok_or_else(|| { | ||||
|                     &self.pduid_pdu.get(&pdu_id)?.ok_or_else(|| { | ||||
|                         Error::bad_database("PDU in state not found in database.") | ||||
|                     })?, | ||||
|                 ) | ||||
|                 .map_err(|_| Error::bad_database("Invalid PDU bytes in room state."))?, | ||||
|             )) | ||||
|             ))) | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|  | @ -216,7 +217,7 @@ impl Rooms { | |||
| 
 | ||||
|         let mut events = StateMap::new(); | ||||
|         for (event_type, state_key) in auth_events { | ||||
|             if let Some(pdu) = self.room_state_get(room_id, &event_type, &state_key)? { | ||||
|             if let Some((_, pdu)) = self.room_state_get(room_id, &event_type, &state_key)? { | ||||
|                 events.insert((event_type, state_key), pdu); | ||||
|             } | ||||
|         } | ||||
|  | @ -299,7 +300,7 @@ impl Rooms { | |||
|         room_id: &RoomId, | ||||
|         event_type: &EventType, | ||||
|         state_key: &str, | ||||
|     ) -> Result<Option<PduEvent>> { | ||||
|     ) -> Result<Option<(IVec, PduEvent)>> { | ||||
|         if let Some(current_state_hash) = self.current_state_hash(room_id)? { | ||||
|             self.state_get(¤t_state_hash, event_type, state_key) | ||||
|         } else { | ||||
|  | @ -653,7 +654,7 @@ impl Rooms { | |||
|                                 }, | ||||
|                         }) | ||||
|                     }, | ||||
|                     |power_levels| { | ||||
|                     |(_, power_levels)| { | ||||
|                         Ok(serde_json::from_value::<Raw<PowerLevelsEventContent>>( | ||||
|                             power_levels.content, | ||||
|                         ) | ||||
|  | @ -664,15 +665,18 @@ impl Rooms { | |||
|                 )?; | ||||
|             let sender_membership = self | ||||
|                 .room_state_get(&room_id, &EventType::RoomMember, &sender.to_string())? | ||||
|                 .map_or(Ok::<_, Error>(member::MembershipState::Leave), |pdu| { | ||||
|                     Ok( | ||||
|                         serde_json::from_value::<Raw<member::MemberEventContent>>(pdu.content) | ||||
|                             .expect("Raw::from_value always works.") | ||||
|                             .deserialize() | ||||
|                             .map_err(|_| Error::bad_database("Invalid Member event in db."))? | ||||
|                             .membership, | ||||
|                     ) | ||||
|                 })?; | ||||
|                 .map_or( | ||||
|                     Ok::<_, Error>(member::MembershipState::Leave), | ||||
|                     |(_, pdu)| { | ||||
|                         Ok( | ||||
|                             serde_json::from_value::<Raw<member::MemberEventContent>>(pdu.content) | ||||
|                                 .expect("Raw::from_value always works.") | ||||
|                                 .deserialize() | ||||
|                                 .map_err(|_| Error::bad_database("Invalid Member event in db."))? | ||||
|                                 .membership, | ||||
|                         ) | ||||
|                     }, | ||||
|                 )?; | ||||
| 
 | ||||
|             let sender_power = power_levels.users.get(&sender).map_or_else( | ||||
|                 || { | ||||
|  | @ -759,7 +763,7 @@ impl Rooms { | |||
| 
 | ||||
|         let mut unsigned = unsigned.unwrap_or_default(); | ||||
|         if let Some(state_key) = &state_key { | ||||
|             if let Some(prev_pdu) = self.room_state_get(&room_id, &event_type, &state_key)? { | ||||
|             if let Some((_, prev_pdu)) = self.room_state_get(&room_id, &event_type, &state_key)? { | ||||
|                 unsigned.insert("prev_content".to_owned(), prev_pdu.content); | ||||
|                 unsigned.insert( | ||||
|                     "prev_sender".to_owned(), | ||||
|  | @ -1017,7 +1021,7 @@ impl Rooms { | |||
|                     // Check if the room has a predecessor
 | ||||
|                     if let Some(predecessor) = self | ||||
|                         .room_state_get(&room_id, &EventType::RoomCreate, "")? | ||||
|                         .and_then(|create| { | ||||
|                         .and_then(|(_, create)| { | ||||
|                             serde_json::from_value::< | ||||
|                                 Raw<ruma::events::room::create::CreateEventContent>, | ||||
|                             >(create.content) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue