pub fn iterative_auth_check<E: Event>(
        room_id: &RoomId,
        room_version: &RoomVersion,
        events_to_check: &[EventId],
        unconflicted_state: &StateMap<EventId>,
        event_map: &mut EventMap<Arc<E>>,
    ) -> Result<StateMap<EventId>> {
        info!("starting iterative auth check");

        debug!("performing auth checks on {:?}", events_to_check.iter().collect::<Vec<_>>());

        let mut resolved_state = unconflicted_state.clone();

        for event_id in events_to_check.iter() {
            let event = StateResolution::get_or_load_event(room_id, event_id, event_map)?;
            let state_key = event
                .state_key()
                .ok_or_else(|| Error::InvalidPdu("State event had no state key".to_owned()))?;

            let mut auth_events = BTreeMap::new();
            for aid in &event.auth_events() {
                if let Ok(ev) = StateResolution::get_or_load_event(room_id, aid, event_map) {
                    // TODO synapse check "rejected_reason", I'm guessing this is redacted_because
                    // in ruma ??
                    auth_events.insert(
                        (
                            ev.kind(),
                            ev.state_key().ok_or_else(|| {
                                Error::InvalidPdu("State event had no state key".to_owned())
                            })?,
                        ),
                        ev,
                    );
                } else {
                    warn!("auth event id for {} is missing {}", aid, event_id);
                }
            }

            for key in auth_types_for_event(
                &event.kind(),
                event.sender(),
                Some(state_key.clone()),
                event.content(),
            ) {
                if let Some(ev_id) = resolved_state.get(&key) {
                    if let Ok(event) = StateResolution::get_or_load_event(room_id, ev_id, event_map)
                    {
                        // TODO synapse checks `rejected_reason` is None here
                        auth_events.insert(key.clone(), event);
                    }
                }
            }

            debug!("event to check {:?}", event.event_id());

            let most_recent_prev_event = event
                .prev_events()
                .iter()
                .filter_map(|id| StateResolution::get_or_load_event(room_id, id, event_map).ok())
                .next_back();

            // The key for this is (eventType + a state_key of the signed token not sender) so
            // search for it
            let current_third_party = auth_events.iter().find_map(|(_, pdu)| {
                (pdu.kind() == EventType::RoomThirdPartyInvite).then(|| {
                    // TODO no clone, auth_events is borrowed while moved
                    pdu.clone()
                })
            });

            if auth_check(
                room_version,
                &event,
                most_recent_prev_event,
                &auth_events,
                current_third_party,
            )? {
                // add event to resolved state map
                resolved_state.insert((event.kind(), state_key), event_id.clone());
            } else {
                // synapse passes here on AuthError. We do not add this event to resolved_state.
                warn!("event {} failed the authentication check", event_id);
            }

            // TODO: if these functions are ever made async here
            // is a good place to yield every once in a while so other
            // tasks can make progress
        }
        Ok(resolved_state)
    }
/// Check the that each event is authenticated based on the events before it.
///
/// ## Returns
///
/// The `unconflicted_state` combined with the newly auth'ed events. So any event that
/// fails the `event_auth::auth_check` will be excluded from the returned `StateMap<EventId>`.
///
/// For each `events_to_check` event we gather the events needed to auth it from the
/// `event_map` or `store` and verify each event using the `event_auth::auth_check`
/// function.
Check the that each event is authenticated based on the events before it.
Check the that each event is authenticated based on the events before it .
pub fn iterative_auth_check<E: Event>(
        room_id: &RoomId,
        room_version: &RoomVersion,
        events_to_check: &[EventId],
        unconflicted_state: &StateMap<EventId>,
        event_map: &mut EventMap<Arc<E>>,
    ) -> Result<StateMap<EventId>> {
        info!("starting iterative auth check");
        debug!("performing auth checks on {:?}", events_to_check.iter().collect::<Vec<_>>());
        let mut resolved_state = unconflicted_state.clone();
        for event_id in events_to_check.iter() {
            let event = StateResolution::get_or_load_event(room_id, event_id, event_map)?;
            let state_key = event
                .state_key()
                .ok_or_else(|| Error::InvalidPdu("State event had no state key".to_owned()))?;
            let mut auth_events = BTreeMap::new();
            for aid in &event.auth_events() {
                if let Ok(ev) = StateResolution::get_or_load_event(room_id, aid, event_map) {
                    // TODO synapse check "rejected_reason", I'm guessing this is redacted_because
                    // in ruma ??
                    auth_events.insert(
                        (
                            ev.kind(),
                            ev.state_key().ok_or_else(|| {
                                Error::InvalidPdu("State event had no state key".to_owned())
                            })?,
                        ),
                        ev,
                    );
                } else {
                    warn!("auth event id for {} is missing {}", aid, event_id);
                }
            }
            for key in auth_types_for_event(
                &event.kind(),
                event.sender(),
                Some(state_key.clone()),
                event.content(),
            ) {
                if let Some(ev_id) = resolved_state.get(&key) {
                    if let Ok(event) = StateResolution::get_or_load_event(room_id, ev_id, event_map)
                    {
                        // TODO synapse checks `rejected_reason` is None here
                        auth_events.insert(key.clone(), event);
                    }
                }
            }
            debug!("event to check {:?}", event.event_id());
            let most_recent_prev_event = event
                .prev_events()
                .iter()
                .filter_map(|id| StateResolution::get_or_load_event(room_id, id, event_map).ok())
                .next_back();
            // The key for this is (eventType + a state_key of the signed token not sender) so
            // search for it
            let current_third_party = auth_events.iter().find_map(|(_, pdu)| {
                (pdu.kind() == EventType::RoomThirdPartyInvite).then(|| {
                    // TODO no clone, auth_events is borrowed while moved
                    pdu.clone()
                })
            });
            if auth_check(
                room_version,
                &event,
                most_recent_prev_event,
                &auth_events,
                current_third_party,
            )? {
                // add event to resolved state map
                resolved_state.insert((event.kind(), state_key), event_id.clone());
            } else {
                // synapse passes here on AuthError. We do not add this event to resolved_state.
                warn!("event {} failed the authentication check", event_id);
            }
            // TODO: if these functions are ever made async here
            // is a good place to yield every once in a while so other
            // tasks can make progress
        }
        Ok(resolved_state)
    }
pub fn iterative_auth_check < E : Event > ( room_id : & RoomId , room_version : & RoomVersion , events_to_check : & [ EventId ] , unconflicted_state : & StateMap < EventId > , event_map : & mut EventMap < Arc < E > > , ) -> Result < StateMap < EventId > > { info ! ( " " ) ; debug ! ( " " events_to_check iter ( ) collect Vec ( ) ) ; let mut resolved_state = unconflicted_state . clone ( ) ; for event_id in events_to_check . iter ( ) { let event = StateResolution :: get_or_load_event ( room_id , event_id , event_map ) ? ; let state_key = event . state_key ( ) . ok_or_else ( | | Error :: InvalidPdu ( " " . to_owned ( ) ) ) ? ; let mut auth_events = BTreeMap :: new ( ) ; for aid in & event . auth_events ( ) { if let Ok ( ev ) = StateResolution :: get_or_load_event ( room_id , aid , event_map ) { // TODO synapse check "rejected_reason", I'm guessing this is redacted_because // in ruma ?? auth_events . insert ( ( ev . kind ( ) , ev . state_key ( ) . ok_or_else ( | | { Error :: InvalidPdu ( " " . to_owned ( ) ) } ) ? , ) , ev , ) ; } else { warn ! ( " " aid event_id ) ; } } for key in auth_types_for_event ( & event . kind ( ) , event . sender ( ) , Some ( state_key . clone ( ) ) , event . content ( ) , ) { if let Some ( ev_id ) = resolved_state . get ( & key ) { if let Ok ( event ) = StateResolution :: get_or_load_event ( room_id , ev_id , event_map ) { // TODO synapse checks `rejected_reason` is None here auth_events . insert ( key . clone ( ) , event ) ; } } } debug ! ( " " event event_id ( ) ) ; let most_recent_prev_event = event . prev_events ( ) . iter ( ) . filter_map ( | id | StateResolution :: get_or_load_event ( room_id , id , event_map ) . ok ( ) ) . next_back ( ) ; // The key for this is (eventType + a state_key of the signed token not sender) so // search for it let current_third_party = auth_events . iter ( ) . find_map ( | ( _ , pdu ) | { ( pdu . kind ( ) == EventType :: RoomThirdPartyInvite ) . then ( | | { // TODO no clone, auth_events is borrowed while moved pdu . clone ( ) } ) } ) ; if auth_check ( room_version , & event , most_recent_prev_event , & auth_events , current_third_party , ) ? { // add event to resolved state map resolved_state . insert ( ( event . kind ( ) , state_key ) , event_id . clone ( ) ) ; } else { // synapse passes here on AuthError. We do not add this event to resolved_state. warn ! ( " " event_id ) ; } // TODO: if these functions are ever made async here // is a good place to yield every once in a while so other // tasks can make progress } Ok ( resolved_state ) }
Check the that each event is authenticated based on the events before it.
Check the that each event is authenticated based on the events before it .
The `unconflicted_state` combined with the newly auth'ed events. So any event that
fails the `event_auth::auth_check` will be excluded from the returned `StateMap`.

For each `events_to_check` event we gather the events needed to auth it from the
`event_map` or `store` and verify each event using the `event_auth::auth_check`
function.
The ` unconflicted_state ` combined with the newly auth ' ed events . So any event that fails the ` event_auth :: auth_check ` will be excluded from the returned ` StateMap ` . For each ` events_to_check ` event we gather the events needed to auth it from the ` event_map ` or ` store ` and verify each event using the ` event_auth :: auth_check ` function .
room_id
&RoomId
room_version
&RoomVersion
events_to_check
&[EventId]
unconflicted_state
&StateMap<EventId>
event_map
&mut EventMap<Arc<E>>