mirror of
https://github.com/element-hq/dendrite.git
synced 2025-09-13 21:02:25 +03:00
Various fixes in fetchAuthEvents
(#3447)
This might fix issues with state events gone missing. --------- Co-authored-by: Neil Alexander <neilalexander@users.noreply.github.com> [skip ci]
This commit is contained in:
parent
23e097c3f0
commit
e8b1a89ff6
4 changed files with 41 additions and 29 deletions
|
@ -205,9 +205,27 @@ func (r *Inputer) processRoomEvent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that the auth events of the event are known.
|
||||||
|
// If they aren't then we will ask the federation API for them.
|
||||||
|
authEvents, _ := gomatrixserverlib.NewAuthEvents(nil)
|
||||||
|
knownEvents := map[string]*types.Event{}
|
||||||
|
if err = r.fetchAuthEvents(ctx, logger, roomInfo, virtualHost, headered, authEvents, knownEvents, serverRes.ServerNames); err != nil {
|
||||||
|
return fmt.Errorf("r.fetchAuthEvents: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
isRejected := false
|
isRejected := false
|
||||||
var rejectionErr error
|
var rejectionErr error
|
||||||
|
|
||||||
|
// Check if the event is allowed by its auth events. If it isn't then
|
||||||
|
// we consider the event to be "rejected" — it will still be persisted.
|
||||||
|
if err = gomatrixserverlib.Allowed(event, authEvents, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) {
|
||||||
|
return r.Queryer.QueryUserIDForSender(ctx, roomID, senderID)
|
||||||
|
}); err != nil {
|
||||||
|
isRejected = true
|
||||||
|
rejectionErr = err
|
||||||
|
logger.WithError(rejectionErr).Warnf("Event %s not allowed by auth events", event.EventID())
|
||||||
|
}
|
||||||
|
|
||||||
// At this point we are checking whether we know all of the prev events, and
|
// At this point we are checking whether we know all of the prev events, and
|
||||||
// if we know the state before the prev events. This is necessary before we
|
// if we know the state before the prev events. This is necessary before we
|
||||||
// try to do `calculateAndSetState` on the event later, otherwise it will fail
|
// try to do `calculateAndSetState` on the event later, otherwise it will fail
|
||||||
|
@ -283,24 +301,6 @@ func (r *Inputer) processRoomEvent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the auth events of the event are known.
|
|
||||||
// If they aren't then we will ask the federation API for them.
|
|
||||||
authEvents, _ := gomatrixserverlib.NewAuthEvents(nil)
|
|
||||||
knownEvents := map[string]*types.Event{}
|
|
||||||
if err = r.fetchAuthEvents(ctx, logger, roomInfo, virtualHost, headered, authEvents, knownEvents, serverRes.ServerNames); err != nil {
|
|
||||||
return fmt.Errorf("r.fetchAuthEvents: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the event is allowed by its auth events. If it isn't then
|
|
||||||
// we consider the event to be "rejected" — it will still be persisted.
|
|
||||||
if err = gomatrixserverlib.Allowed(event, authEvents, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) {
|
|
||||||
return r.Queryer.QueryUserIDForSender(ctx, roomID, senderID)
|
|
||||||
}); err != nil {
|
|
||||||
isRejected = true
|
|
||||||
rejectionErr = err
|
|
||||||
logger.WithError(rejectionErr).Warnf("Event %s not allowed by auth events", event.EventID())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accumulate the auth event NIDs.
|
// Accumulate the auth event NIDs.
|
||||||
authEventIDs := event.AuthEventIDs()
|
authEventIDs := event.AuthEventIDs()
|
||||||
authEventNIDs := make([]types.EventNID, 0, len(authEventIDs))
|
authEventNIDs := make([]types.EventNID, 0, len(authEventIDs))
|
||||||
|
@ -323,7 +323,7 @@ func (r *Inputer) processRoomEvent(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if !knownEvents[authEventID].Rejected {
|
||||||
authEventNIDs = append(authEventNIDs, knownEvents[authEventID].EventNID)
|
authEventNIDs = append(authEventNIDs, knownEvents[authEventID].EventNID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -704,15 +704,14 @@ func (r *Inputer) fetchAuthEvents(
|
||||||
}
|
}
|
||||||
ev := authEvents[0]
|
ev := authEvents[0]
|
||||||
|
|
||||||
isRejected := false
|
|
||||||
if roomInfo != nil {
|
if roomInfo != nil {
|
||||||
isRejected, err = r.DB.IsEventRejected(ctx, roomInfo.RoomNID, ev.EventID())
|
ev.Rejected, err = r.DB.IsEventRejected(ctx, roomInfo.RoomNID, ev.EventID())
|
||||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||||
return fmt.Errorf("r.DB.IsEventRejected failed: %w", err)
|
return fmt.Errorf("r.DB.IsEventRejected failed: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
known[authEventID] = &ev // don't take the pointer of the iterated event
|
known[authEventID] = &ev // don't take the pointer of the iterated event
|
||||||
if !isRejected {
|
if !ev.Rejected {
|
||||||
if err = auth.AddEvent(ev.PDU); err != nil {
|
if err = auth.AddEvent(ev.PDU); err != nil {
|
||||||
return fmt.Errorf("auth.AddEvent: %w", err)
|
return fmt.Errorf("auth.AddEvent: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -744,8 +743,13 @@ func (r *Inputer) fetchAuthEvents(
|
||||||
return fmt.Errorf("no servers provided event auth for event ID %q, tried servers %v", event.EventID(), servers)
|
return fmt.Errorf("no servers provided event auth for event ID %q, tried servers %v", event.EventID(), servers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start with a clean state and see if we can auth with what the remote
|
||||||
|
// server told us. Otherwise earlier topologically sorted events could
|
||||||
|
// fail to be authed by more recent referenced ones.
|
||||||
|
auth.Clear()
|
||||||
|
|
||||||
// Reuse these to reduce allocations.
|
// Reuse these to reduce allocations.
|
||||||
authEventNIDs := make([]types.EventNID, 0, 5)
|
_authEventNIDs := [5]types.EventNID{}
|
||||||
isRejected := false
|
isRejected := false
|
||||||
nextAuthEvent:
|
nextAuthEvent:
|
||||||
for _, authEvent := range gomatrixserverlib.ReverseTopologicalOrdering(
|
for _, authEvent := range gomatrixserverlib.ReverseTopologicalOrdering(
|
||||||
|
@ -755,7 +759,11 @@ nextAuthEvent:
|
||||||
// If we already know about this event from the database then we don't
|
// If we already know about this event from the database then we don't
|
||||||
// need to store it again or do anything further with it, so just skip
|
// need to store it again or do anything further with it, so just skip
|
||||||
// over it rather than wasting cycles.
|
// over it rather than wasting cycles.
|
||||||
if ev, ok := known[authEvent.EventID()]; ok && ev != nil {
|
if ev, ok := known[authEvent.EventID()]; ok && ev != nil && !ev.Rejected {
|
||||||
|
// Need to add to the auth set for the next event being processed.
|
||||||
|
if err := auth.AddEvent(authEvent); err != nil {
|
||||||
|
return fmt.Errorf("auth.AddEvent: %w", err)
|
||||||
|
}
|
||||||
continue nextAuthEvent
|
continue nextAuthEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,11 +778,11 @@ nextAuthEvent:
|
||||||
|
|
||||||
// In order to store the new auth event, we need to know its auth chain
|
// In order to store the new auth event, we need to know its auth chain
|
||||||
// as NIDs for the `auth_event_nids` column. Let's see if we can find those.
|
// as NIDs for the `auth_event_nids` column. Let's see if we can find those.
|
||||||
authEventNIDs = authEventNIDs[:0]
|
authEventNIDs := _authEventNIDs[:0]
|
||||||
for _, eventID := range authEvent.AuthEventIDs() {
|
for _, eventID := range authEvent.AuthEventIDs() {
|
||||||
knownEvent, ok := known[eventID]
|
knownEvent, ok := known[eventID]
|
||||||
if !ok {
|
if !ok {
|
||||||
continue nextAuthEvent
|
return fmt.Errorf("auth event ID %s not known but should be", eventID)
|
||||||
}
|
}
|
||||||
authEventNIDs = append(authEventNIDs, knownEvent.EventNID)
|
authEventNIDs = append(authEventNIDs, knownEvent.EventNID)
|
||||||
}
|
}
|
||||||
|
@ -821,6 +829,7 @@ nextAuthEvent:
|
||||||
// Now we know about this event, it was stored and the signatures were OK.
|
// Now we know about this event, it was stored and the signatures were OK.
|
||||||
known[authEvent.EventID()] = &types.Event{
|
known[authEvent.EventID()] = &types.Event{
|
||||||
EventNID: eventNID,
|
EventNID: eventNID,
|
||||||
|
Rejected: isRejected,
|
||||||
PDU: authEvent,
|
PDU: authEvent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,6 +228,7 @@ func (s StateAtEventAndReferences) EventIDs() string {
|
||||||
// It is when performing bulk event lookup in the database.
|
// It is when performing bulk event lookup in the database.
|
||||||
type Event struct {
|
type Event struct {
|
||||||
EventNID EventNID
|
EventNID EventNID
|
||||||
|
Rejected bool
|
||||||
gomatrixserverlib.PDU
|
gomatrixserverlib.PDU
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,3 +18,7 @@ Leaves are present in non-gapped incremental syncs
|
||||||
|
|
||||||
# We don't have any state to calculate m.room.guest_access when accepting invites
|
# We don't have any state to calculate m.room.guest_access when accepting invites
|
||||||
Guest users can accept invites to private rooms over federation
|
Guest users can accept invites to private rooms over federation
|
||||||
|
|
||||||
|
# Tests Synapse specific behavior
|
||||||
|
/state returns M_NOT_FOUND for an outlier
|
||||||
|
/state_ids returns M_NOT_FOUND for an outlier
|
|
@ -774,8 +774,6 @@ Remote user can backfill in a room with version 10
|
||||||
Can reject invites over federation for rooms with version 10
|
Can reject invites over federation for rooms with version 10
|
||||||
Can receive redactions from regular users over federation in room version 10
|
Can receive redactions from regular users over federation in room version 10
|
||||||
New federated private chats get full presence information (SYN-115)
|
New federated private chats get full presence information (SYN-115)
|
||||||
/state returns M_NOT_FOUND for an outlier
|
|
||||||
/state_ids returns M_NOT_FOUND for an outlier
|
|
||||||
Outbound federation requests missing prev_events and then asks for /state_ids and resolves the state
|
Outbound federation requests missing prev_events and then asks for /state_ids and resolves the state
|
||||||
Invited user can reject invite for empty room
|
Invited user can reject invite for empty room
|
||||||
Invited user can reject local invite after originator leaves
|
Invited user can reject local invite after originator leaves
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue