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