Do not process old membership events.

This commit is contained in:
projectmoon 2020-11-08 20:45:50 +00:00
parent d7aaed9e00
commit a77d066daf
1 changed files with 23 additions and 13 deletions

View File

@ -4,7 +4,7 @@ use log::{debug, error, info, warn};
use matrix_sdk::{ use matrix_sdk::{
self, self,
events::{ events::{
room::member::{MemberEventContent, MembershipState}, room::member::{MemberEventContent, MembershipChange},
room::message::{MessageEventContent, TextMessageEventContent}, room::message::{MessageEventContent, TextMessageEventContent},
StrippedStateEvent, SyncMessageEvent, SyncStateEvent, StrippedStateEvent, SyncMessageEvent, SyncStateEvent,
}, },
@ -16,6 +16,11 @@ use std::clone::Clone;
use std::ops::Sub; use std::ops::Sub;
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
fn check_age(timestamp: &SystemTime, how_far_back: u64) -> bool {
let oldest_timestamp = SystemTime::now().sub(Duration::new(how_far_back, 0));
timestamp > &oldest_timestamp
}
/// Check if a message is recent enough to actually process. If the /// Check if a message is recent enough to actually process. If the
/// message is within "oldest_message_age" seconds, this function /// message is within "oldest_message_age" seconds, this function
/// returns true. If it's older than that, it returns false and logs a /// returns true. If it's older than that, it returns false and logs a
@ -77,31 +82,36 @@ async fn should_process<'a>(
/// Originally adapted from the matrix-rust-sdk examples. /// Originally adapted from the matrix-rust-sdk examples.
#[async_trait] #[async_trait]
impl EventEmitter for DiceBot { impl EventEmitter for DiceBot {
async fn on_room_member( async fn on_room_member(&self, room: SyncRoom, event: &SyncStateEvent<MemberEventContent>) {
&self, if !check_age(&event.origin_server_ts, 2) {
room: SyncRoom, debug!("Ignoring old event: {:#?}", event);
room_member: &SyncStateEvent<MemberEventContent>, return;
) { }
if let SyncRoom::Joined(room) = room {
if let SyncRoom::Joined(room) | SyncRoom::Left(room) = room {
let event_affects_us = if let Some(our_user_id) = self.client.user_id().await { let event_affects_us = if let Some(our_user_id) = self.client.user_id().await {
room_member.state_key == our_user_id event.state_key == our_user_id
} else { } else {
false false
}; };
let adding_user = match room_member.content.membership { use MembershipChange::*;
MembershipState::Join => true, let adding_user = match event.membership_change() {
MembershipState::Leave | MembershipState::Ban => false, Joined => true,
Banned | Left | Kicked | KickedAndBanned => false,
_ => return, _ => return,
}; };
//Clone to avoid holding lock. //Clone to avoid holding lock.
let room = room.read().await.clone(); let room = room.read().await.clone();
let (room_id, username) = (room.room_id.as_str(), &room_member.state_key); let (room_id, username) = (room.room_id.as_str(), &event.state_key);
let result = if event_affects_us && !adding_user { let result = if event_affects_us && !adding_user {
info!("Clearing all information for room ID {}", room_id); info!("Clearing all information for room ID {}", room_id);
self.db.rooms.clear_info(room_id) self.db.rooms.clear_info(room_id)
} else if event_affects_us && adding_user {
info!("Joined room {}; recording user information", room_id);
Ok(())
} else if !event_affects_us && adding_user { } else if !event_affects_us && adding_user {
info!("Adding user {} to room ID {}", username, room_id); info!("Adding user {} to room ID {}", username, room_id);
self.db.rooms.add_user_to_room(username, room_id) self.db.rooms.add_user_to_room(username, room_id)
@ -109,7 +119,7 @@ impl EventEmitter for DiceBot {
info!("Removing user {} from room ID {}", username, room_id); info!("Removing user {} from room ID {}", username, room_id);
self.db.rooms.remove_user_from_room(username, room_id) self.db.rooms.remove_user_from_room(username, room_id)
} else { } else {
debug!("Ignoring a room member event: {:#?}", room_member); debug!("Ignoring a room member event: {:#?}", event);
Ok(()) Ok(())
}; };