MCPcopy Create free account
hub / github.com/daodst/chat / processStateBefore

Method processStateBefore

roomserver/internal/input/input_events.go:428–514  ·  view source on GitHub ↗

processStateBefore works out what the state is before the event and then checks the event auths against the state at the time. It also tries to determine what the history visibility was of the event at the time, so that it can be sent in the output event to downstream components. nolint:nakedret

(
	ctx context.Context,
	input *api.InputRoomEvent,
	missingPrev bool,
)

Source from the content-addressed store, hash-verified

426// components.
427// nolint:nakedret
428func (r *Inputer) processStateBefore(
429 ctx context.Context,
430 input *api.InputRoomEvent,
431 missingPrev bool,
432) (historyVisibility gomatrixserverlib.HistoryVisibility, rejectionErr error, err error) {
433 historyVisibility = gomatrixserverlib.HistoryVisibilityJoined // Default to restrictive.
434 event := input.Event.Unwrap()
435 isCreateEvent := event.Type() == gomatrixserverlib.MRoomCreate && event.StateKeyEquals("")
436 var stateBeforeEvent []*gomatrixserverlib.Event
437 switch {
438 case isCreateEvent:
439 // There's no state before a create event so there is nothing
440 // else to do.
441 return
442 case input.HasState:
443 // If we're overriding the state then we need to go and retrieve
444 // them from the database. It's a hard error if they are missing.
445 stateEvents, err := r.DB.EventsFromIDs(ctx, input.StateEventIDs)
446 if err != nil {
447 return "", nil, fmt.Errorf("r.DB.EventsFromIDs: %w", err)
448 }
449 stateBeforeEvent = make([]*gomatrixserverlib.Event, 0, len(stateEvents))
450 for _, entry := range stateEvents {
451 stateBeforeEvent = append(stateBeforeEvent, entry.Event)
452 }
453 case missingPrev:
454 // We don't know all of the prev events, so we can't work out
455 // the state before the event. Reject it in that case.
456 rejectionErr = fmt.Errorf("event %q has missing prev events", event.EventID())
457 return
458 case len(event.PrevEventIDs()) == 0:
459 // There should be prev events since it's not a create event.
460 // A non-create event that claims to have no prev events is
461 // invalid, so reject it.
462 rejectionErr = fmt.Errorf("event %q must have prev events", event.EventID())
463 return
464 default:
465 // For all non-create events, there must be prev events, so we'll
466 // ask the query API for the relevant tuples needed for auth. We
467 // will include the history visibility here even though we don't
468 // actually need it for auth, because we want to send it in the
469 // output events.
470 tuplesNeeded := gomatrixserverlib.StateNeededForAuth([]*gomatrixserverlib.Event{event}).Tuples()
471 tuplesNeeded = append(tuplesNeeded, gomatrixserverlib.StateKeyTuple{
472 EventType: gomatrixserverlib.MRoomHistoryVisibility,
473 StateKey: "",
474 })
475 stateBeforeReq := &api.QueryStateAfterEventsRequest{
476 RoomID: event.RoomID(),
477 PrevEventIDs: event.PrevEventIDs(),
478 StateToFetch: tuplesNeeded,
479 }
480 stateBeforeRes := &api.QueryStateAfterEventsResponse{}
481 if err := r.Queryer.QueryStateAfterEvents(ctx, stateBeforeReq, stateBeforeRes); err != nil {
482 return "", nil, fmt.Errorf("r.Queryer.QueryStateAfterEvents: %w", err)
483 }
484 switch {
485 case !stateBeforeRes.RoomExists:

Callers 1

processRoomEventMethod · 0.95

Calls 3

PrevEventIDsMethod · 0.80
EventsFromIDsMethod · 0.65
QueryStateAfterEventsMethod · 0.65

Tested by

no test coverage detected