Add apply_event function testing if a given event will pass auth

This commit is contained in:
Devin Ragotzy 2020-12-07 16:51:31 -05:00
parent ea7dc52daf
commit c6a108631d
2 changed files with 75 additions and 1 deletions

View File

@ -37,6 +37,51 @@ pub type EventMap<T> = BTreeMap<EventId, T>;
pub struct StateResolution;
impl StateResolution {
/// Check if the `incoming_event` can be included in the given `current_state`.
///
/// This will authenticate the event against the current state of the room. It
/// is important that the `current_state` argument is accurate and complete.
pub fn apply_event(
room_id: &RoomId,
room_version: &RoomVersionId,
incoming_event: Arc<StateEvent>,
current_state: &StateMap<EventId>,
event_map: Option<EventMap<Arc<StateEvent>>>,
store: &dyn StateStore,
) -> Result<bool> {
tracing::info!("Applying a single event, state resolution starting");
let ev = incoming_event;
let mut event_map = if let Some(ev_map) = event_map {
ev_map
} else {
EventMap::new()
};
let prev_event = if let Some(id) = ev.prev_event_ids().first() {
store.get_event(room_id, id).ok()
} else {
None
};
let mut auth_events = StateMap::new();
for key in event_auth::auth_types_for_event(
ev.kind(),
ev.sender(),
Some(ev.state_key()),
ev.content().clone(),
) {
if let Some(ev_id) = current_state.get(&key) {
if let Some(event) =
StateResolution::get_or_load_event(room_id, ev_id, &mut event_map, store)
{
// TODO synapse checks `rejected_reason` is None here
auth_events.insert(key.clone(), event);
}
}
}
event_auth::auth_check(room_version, &ev, prev_event, auth_events, None)
}
/// Resolve sets of state events as they come in. Internally `StateResolution` builds a graph
/// and an auth chain to allow for state conflict resolution.
///

View File

@ -354,7 +354,7 @@ fn do_check(
let resolved = StateResolution::resolve(
&room_id(),
&RoomVersionId::Version1,
&RoomVersionId::Version6,
&state_sets,
Some(event_map.clone()),
&store,
@ -398,6 +398,35 @@ fn do_check(
&auth_events,
prev_events,
);
// This can be used to sort of test this function
// match StateResolution::apply_event(
// &room_id(),
// &RoomVersionId::Version6,
// Arc::clone(&event),
// &state_after,
// Some(event_map.clone()),
// &store,
// ) {
// Ok(res) => {
// println!(
// "res contains: {} passed: {} for {}\n{:?}",
// state_after
// .get(&(event.kind(), event.state_key()))
// .map(|id| id == &ev_id)
// .unwrap_or_default(),
// res,
// event.event_id().as_str(),
// event
// .prev_event_ids()
// .iter()
// .map(|id| id.to_string())
// .collect::<Vec<_>>()
// );
// }
// Err(e) => panic!("resolution for {} failed: {}", node, e),
// }
// we have to update our store, an actual user of this lib would
// be giving us state from a DB.
//