mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-07-31 21:32:46 +00:00
Refactor StoreEvent
, add MaybeRedactEvent
, create an EventDatabase
(#2989)
This PR changes the following: - `StoreEvent` now only stores an event (and possibly prev event), instead of also doing redactions - Adds a `MaybeRedactEvent` (pulled out from `StoreEvent`), which should be called after storing events - a few other things
This commit is contained in:
parent
1aa70b0f56
commit
6c20f8f742
34 changed files with 488 additions and 420 deletions
|
@ -67,7 +67,7 @@ func CheckForSoftFail(
|
|||
stateNeeded := gomatrixserverlib.StateNeededForAuth([]*gomatrixserverlib.Event{event.Unwrap()})
|
||||
|
||||
// Load the actual auth events from the database.
|
||||
authEvents, err := loadAuthEvents(ctx, db, roomInfo.RoomNID, stateNeeded, authStateEntries)
|
||||
authEvents, err := loadAuthEvents(ctx, db, roomInfo, stateNeeded, authStateEntries)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("loadAuthEvents: %w", err)
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ func CheckForSoftFail(
|
|||
func CheckAuthEvents(
|
||||
ctx context.Context,
|
||||
db storage.RoomDatabase,
|
||||
roomNID types.RoomNID,
|
||||
roomInfo *types.RoomInfo,
|
||||
event *gomatrixserverlib.HeaderedEvent,
|
||||
authEventIDs []string,
|
||||
) ([]types.EventNID, error) {
|
||||
|
@ -100,7 +100,7 @@ func CheckAuthEvents(
|
|||
stateNeeded := gomatrixserverlib.StateNeededForAuth([]*gomatrixserverlib.Event{event.Unwrap()})
|
||||
|
||||
// Load the actual auth events from the database.
|
||||
authEvents, err := loadAuthEvents(ctx, db, roomNID, stateNeeded, authStateEntries)
|
||||
authEvents, err := loadAuthEvents(ctx, db, roomInfo, stateNeeded, authStateEntries)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loadAuthEvents: %w", err)
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ func (ae *authEvents) lookupEvent(typeNID types.EventTypeNID, stateKey string) *
|
|||
func loadAuthEvents(
|
||||
ctx context.Context,
|
||||
db state.StateResolutionStorage,
|
||||
roomNID types.RoomNID,
|
||||
roomInfo *types.RoomInfo,
|
||||
needed gomatrixserverlib.StateNeeded,
|
||||
state []types.StateEntry,
|
||||
) (result authEvents, err error) {
|
||||
|
@ -216,7 +216,7 @@ func loadAuthEvents(
|
|||
eventNIDs = append(eventNIDs, eventNID)
|
||||
}
|
||||
}
|
||||
if result.events, err = db.Events(ctx, roomNID, eventNIDs); err != nil {
|
||||
if result.events, err = db.Events(ctx, roomInfo, eventNIDs); err != nil {
|
||||
return
|
||||
}
|
||||
roomID := ""
|
||||
|
|
|
@ -85,7 +85,7 @@ func IsServerCurrentlyInRoom(ctx context.Context, db storage.Database, serverNam
|
|||
return false, err
|
||||
}
|
||||
|
||||
events, err := db.Events(ctx, info.RoomNID, eventNIDs)
|
||||
events, err := db.Events(ctx, info, eventNIDs)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ func IsInvitePending(
|
|||
// only keep the "m.room.member" events with a "join" membership. These events are returned.
|
||||
// Returns an error if there was an issue fetching the events.
|
||||
func GetMembershipsAtState(
|
||||
ctx context.Context, db storage.RoomDatabase, roomNID types.RoomNID, stateEntries []types.StateEntry, joinedOnly bool,
|
||||
ctx context.Context, db storage.RoomDatabase, roomInfo *types.RoomInfo, stateEntries []types.StateEntry, joinedOnly bool,
|
||||
) ([]types.Event, error) {
|
||||
|
||||
var eventNIDs types.EventNIDs
|
||||
|
@ -177,7 +177,7 @@ func GetMembershipsAtState(
|
|||
util.Unique(eventNIDs)
|
||||
|
||||
// Get all of the events in this state
|
||||
stateEvents, err := db.Events(ctx, roomNID, eventNIDs)
|
||||
stateEvents, err := db.Events(ctx, roomInfo, eventNIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -227,9 +227,9 @@ func MembershipAtEvent(ctx context.Context, db storage.RoomDatabase, info *types
|
|||
}
|
||||
|
||||
func LoadEvents(
|
||||
ctx context.Context, db storage.RoomDatabase, roomNID types.RoomNID, eventNIDs []types.EventNID,
|
||||
ctx context.Context, db storage.RoomDatabase, roomInfo *types.RoomInfo, eventNIDs []types.EventNID,
|
||||
) ([]*gomatrixserverlib.Event, error) {
|
||||
stateEvents, err := db.Events(ctx, roomNID, eventNIDs)
|
||||
stateEvents, err := db.Events(ctx, roomInfo, eventNIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -242,13 +242,13 @@ func LoadEvents(
|
|||
}
|
||||
|
||||
func LoadStateEvents(
|
||||
ctx context.Context, db storage.RoomDatabase, roomNID types.RoomNID, stateEntries []types.StateEntry,
|
||||
ctx context.Context, db storage.RoomDatabase, roomInfo *types.RoomInfo, stateEntries []types.StateEntry,
|
||||
) ([]*gomatrixserverlib.Event, error) {
|
||||
eventNIDs := make([]types.EventNID, len(stateEntries))
|
||||
for i := range stateEntries {
|
||||
eventNIDs[i] = stateEntries[i].EventNID
|
||||
}
|
||||
return LoadEvents(ctx, db, roomNID, eventNIDs)
|
||||
return LoadEvents(ctx, db, roomInfo, eventNIDs)
|
||||
}
|
||||
|
||||
func CheckServerAllowedToSeeEvent(
|
||||
|
@ -326,7 +326,7 @@ func slowGetHistoryVisibilityState(
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
return LoadStateEvents(ctx, db, info.RoomNID, filteredEntries)
|
||||
return LoadStateEvents(ctx, db, info, filteredEntries)
|
||||
}
|
||||
|
||||
// TODO: Remove this when we have tests to assert correctness of this function
|
||||
|
@ -366,7 +366,7 @@ BFSLoop:
|
|||
next = make([]string, 0)
|
||||
}
|
||||
// Retrieve the events to process from the database.
|
||||
events, err = db.EventsFromIDs(ctx, info.RoomNID, front)
|
||||
events, err = db.EventsFromIDs(ctx, info, front)
|
||||
if err != nil {
|
||||
return resultNIDs, redactEventIDs, err
|
||||
}
|
||||
|
@ -467,7 +467,7 @@ func QueryLatestEventsAndState(
|
|||
return err
|
||||
}
|
||||
|
||||
stateEvents, err := LoadStateEvents(ctx, db, roomInfo.RoomNID, stateEntries)
|
||||
stateEvents, err := LoadStateEvents(ctx, db, roomInfo, stateEntries)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -4,9 +4,10 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
|
||||
"github.com/matrix-org/dendrite/setup/base"
|
||||
|
||||
"github.com/matrix-org/dendrite/test"
|
||||
|
@ -38,9 +39,9 @@ func TestIsInvitePendingWithoutNID(t *testing.T) {
|
|||
var authNIDs []types.EventNID
|
||||
for _, x := range room.Events() {
|
||||
|
||||
roomNID, err := db.GetOrCreateRoomNID(context.Background(), x.Unwrap())
|
||||
roomInfo, err := db.GetOrCreateRoomInfo(context.Background(), x.Unwrap())
|
||||
assert.NoError(t, err)
|
||||
assert.Greater(t, roomNID, types.RoomNID(0))
|
||||
assert.NotNil(t, roomInfo)
|
||||
|
||||
eventTypeNID, err := db.GetOrCreateEventTypeNID(context.Background(), x.Type())
|
||||
assert.NoError(t, err)
|
||||
|
@ -49,7 +50,7 @@ func TestIsInvitePendingWithoutNID(t *testing.T) {
|
|||
eventStateKeyNID, err := db.GetOrCreateEventStateKeyNID(context.Background(), x.StateKey())
|
||||
assert.NoError(t, err)
|
||||
|
||||
evNID, _, _, _, err := db.StoreEvent(context.Background(), x.Event, roomNID, eventTypeNID, eventStateKeyNID, authNIDs, false)
|
||||
evNID, _, err := db.StoreEvent(context.Background(), x.Event, roomInfo, eventTypeNID, eventStateKeyNID, authNIDs, false)
|
||||
assert.NoError(t, err)
|
||||
authNIDs = append(authNIDs, evNID)
|
||||
}
|
||||
|
|
|
@ -24,9 +24,10 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
|
@ -274,8 +275,10 @@ func (r *Inputer) processRoomEvent(
|
|||
|
||||
// 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.
|
||||
redactAllowed := true
|
||||
if err = gomatrixserverlib.Allowed(event, &authEvents); err != nil {
|
||||
isRejected = true
|
||||
redactAllowed = false
|
||||
rejectionErr = err
|
||||
logger.WithError(rejectionErr).Warnf("Event %s not allowed by auth events", event.EventID())
|
||||
}
|
||||
|
@ -323,7 +326,7 @@ func (r *Inputer) processRoomEvent(
|
|||
// burning CPU time.
|
||||
historyVisibility := gomatrixserverlib.HistoryVisibilityShared // Default to shared.
|
||||
if input.Kind != api.KindOutlier && rejectionErr == nil && !isRejected && !isCreateEvent {
|
||||
historyVisibility, rejectionErr, err = r.processStateBefore(ctx, roomInfo.RoomNID, input, missingPrev)
|
||||
historyVisibility, rejectionErr, err = r.processStateBefore(ctx, roomInfo, input, missingPrev)
|
||||
if err != nil {
|
||||
return fmt.Errorf("r.processStateBefore: %w", err)
|
||||
}
|
||||
|
@ -332,9 +335,11 @@ func (r *Inputer) processRoomEvent(
|
|||
}
|
||||
}
|
||||
|
||||
roomNID, err := r.DB.GetOrCreateRoomNID(ctx, event)
|
||||
if err != nil {
|
||||
return fmt.Errorf("r.DB.GetOrCreateRoomNID: %w", err)
|
||||
if roomInfo == nil {
|
||||
roomInfo, err = r.DB.GetOrCreateRoomInfo(ctx, event)
|
||||
if err != nil {
|
||||
return fmt.Errorf("r.DB.GetOrCreateRoomInfo: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
eventTypeNID, err := r.DB.GetOrCreateEventTypeNID(ctx, event.Type())
|
||||
|
@ -348,15 +353,24 @@ func (r *Inputer) processRoomEvent(
|
|||
}
|
||||
|
||||
// Store the event.
|
||||
_, stateAtEvent, redactionEvent, redactedEventID, err := r.DB.StoreEvent(ctx, event, roomNID, eventTypeNID, eventStateKeyNID, authEventNIDs, isRejected)
|
||||
eventNID, stateAtEvent, err := r.DB.StoreEvent(ctx, event, roomInfo, eventTypeNID, eventStateKeyNID, authEventNIDs, isRejected)
|
||||
if err != nil {
|
||||
return fmt.Errorf("updater.StoreEvent: %w", err)
|
||||
}
|
||||
|
||||
// if storing this event results in it being redacted then do so.
|
||||
if !isRejected && redactedEventID == event.EventID() {
|
||||
if err = eventutil.RedactEvent(redactionEvent, event); err != nil {
|
||||
return fmt.Errorf("eventutil.RedactEvent: %w", rerr)
|
||||
var (
|
||||
redactedEventID string
|
||||
redactionEvent *gomatrixserverlib.Event
|
||||
redactedEvent *gomatrixserverlib.Event
|
||||
)
|
||||
if !isRejected && !isCreateEvent {
|
||||
redactionEvent, redactedEvent, err = r.DB.MaybeRedactEvent(ctx, roomInfo, eventNID, event, redactAllowed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if redactedEvent != nil {
|
||||
redactedEventID = redactedEvent.EventID()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,7 +503,7 @@ func (r *Inputer) handleRemoteRoomUpgrade(ctx context.Context, event *gomatrixse
|
|||
// nolint:nakedret
|
||||
func (r *Inputer) processStateBefore(
|
||||
ctx context.Context,
|
||||
roomNID types.RoomNID,
|
||||
roomInfo *types.RoomInfo,
|
||||
input *api.InputRoomEvent,
|
||||
missingPrev bool,
|
||||
) (historyVisibility gomatrixserverlib.HistoryVisibility, rejectionErr error, err error) {
|
||||
|
@ -505,7 +519,7 @@ func (r *Inputer) processStateBefore(
|
|||
case input.HasState:
|
||||
// If we're overriding the state then we need to go and retrieve
|
||||
// them from the database. It's a hard error if they are missing.
|
||||
stateEvents, err := r.DB.EventsFromIDs(ctx, roomNID, input.StateEventIDs)
|
||||
stateEvents, err := r.DB.EventsFromIDs(ctx, roomInfo, input.StateEventIDs)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("r.DB.EventsFromIDs: %w", err)
|
||||
}
|
||||
|
@ -604,7 +618,7 @@ func (r *Inputer) fetchAuthEvents(
|
|||
}
|
||||
|
||||
for _, authEventID := range authEventIDs {
|
||||
authEvents, err := r.DB.EventsFromIDs(ctx, roomInfo.RoomNID, []string{authEventID})
|
||||
authEvents, err := r.DB.EventsFromIDs(ctx, roomInfo, []string{authEventID})
|
||||
if err != nil || len(authEvents) == 0 || authEvents[0].Event == nil {
|
||||
unknown[authEventID] = struct{}{}
|
||||
continue
|
||||
|
@ -690,9 +704,11 @@ nextAuthEvent:
|
|||
logger.WithError(err).Warnf("Auth event %s rejected", authEvent.EventID())
|
||||
}
|
||||
|
||||
roomNID, err := r.DB.GetOrCreateRoomNID(ctx, authEvent)
|
||||
if err != nil {
|
||||
return fmt.Errorf("r.DB.GetOrCreateRoomNID: %w", err)
|
||||
if roomInfo == nil {
|
||||
roomInfo, err = r.DB.GetOrCreateRoomInfo(ctx, authEvent)
|
||||
if err != nil {
|
||||
return fmt.Errorf("r.DB.GetOrCreateRoomInfo: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
eventTypeNID, err := r.DB.GetOrCreateEventTypeNID(ctx, authEvent.Type())
|
||||
|
@ -706,7 +722,7 @@ nextAuthEvent:
|
|||
}
|
||||
|
||||
// Finally, store the event in the database.
|
||||
eventNID, _, _, _, err := r.DB.StoreEvent(ctx, authEvent, roomNID, eventTypeNID, eventStateKeyNID, authEventNIDs, isRejected)
|
||||
eventNID, _, err := r.DB.StoreEvent(ctx, authEvent, roomInfo, eventTypeNID, eventStateKeyNID, authEventNIDs, isRejected)
|
||||
if err != nil {
|
||||
return fmt.Errorf("updater.StoreEvent: %w", err)
|
||||
}
|
||||
|
@ -782,7 +798,7 @@ func (r *Inputer) kickGuests(ctx context.Context, event *gomatrixserverlib.Event
|
|||
return err
|
||||
}
|
||||
|
||||
memberEvents, err := r.DB.Events(ctx, roomInfo.RoomNID, membershipNIDs)
|
||||
memberEvents, err := r.DB.Events(ctx, roomInfo, membershipNIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ func (r *Inputer) updateMemberships(
|
|||
// Load the event JSON so we can look up the "membership" key.
|
||||
// TODO: Maybe add a membership key to the events table so we can load that
|
||||
// key without having to load the entire event JSON?
|
||||
events, err := updater.Events(ctx, 0, eventNIDs)
|
||||
events, err := updater.Events(ctx, nil, eventNIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -395,7 +395,7 @@ func (t *missingStateReq) lookupStateAfterEventLocally(ctx context.Context, even
|
|||
for _, entry := range stateEntries {
|
||||
stateEventNIDs = append(stateEventNIDs, entry.EventNID)
|
||||
}
|
||||
stateEvents, err := t.db.Events(ctx, t.roomInfo.RoomNID, stateEventNIDs)
|
||||
stateEvents, err := t.db.Events(ctx, t.roomInfo, stateEventNIDs)
|
||||
if err != nil {
|
||||
t.log.WithError(err).Warnf("failed to load state events locally")
|
||||
return nil
|
||||
|
@ -432,7 +432,7 @@ func (t *missingStateReq) lookupStateAfterEventLocally(ctx context.Context, even
|
|||
missingEventList = append(missingEventList, evID)
|
||||
}
|
||||
t.log.WithField("count", len(missingEventList)).Debugf("Fetching missing auth events")
|
||||
events, err := t.db.EventsFromIDs(ctx, t.roomInfo.RoomNID, missingEventList)
|
||||
events, err := t.db.EventsFromIDs(ctx, t.roomInfo, missingEventList)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -702,7 +702,7 @@ func (t *missingStateReq) lookupMissingStateViaStateIDs(ctx context.Context, roo
|
|||
}
|
||||
t.haveEventsMutex.Unlock()
|
||||
|
||||
events, err := t.db.EventsFromIDs(ctx, t.roomInfo.RoomNID, missingEventList)
|
||||
events, err := t.db.EventsFromIDs(ctx, t.roomInfo, missingEventList)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("t.db.EventsFromIDs: %w", err)
|
||||
}
|
||||
|
@ -844,7 +844,7 @@ func (t *missingStateReq) lookupEvent(ctx context.Context, roomVersion gomatrixs
|
|||
|
||||
if localFirst {
|
||||
// fetch from the roomserver
|
||||
events, err := t.db.EventsFromIDs(ctx, t.roomInfo.RoomNID, []string{missingEventID})
|
||||
events, err := t.db.EventsFromIDs(ctx, t.roomInfo, []string{missingEventID})
|
||||
if err != nil {
|
||||
t.log.Warnf("Failed to query roomserver for missing event %s: %s - falling back to remote", missingEventID, err)
|
||||
} else if len(events) == 1 {
|
||||
|
|
|
@ -70,7 +70,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
return nil
|
||||
}
|
||||
|
||||
memberEvents, err := r.DB.Events(ctx, roomInfo.RoomNID, memberNIDs)
|
||||
memberEvents, err := r.DB.Events(ctx, roomInfo, memberNIDs)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
|
||||
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
|
||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/auth"
|
||||
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
||||
|
@ -86,7 +85,7 @@ func (r *Backfiller) PerformBackfill(
|
|||
// Retrieve events from the list that was filled previously. If we fail to get
|
||||
// events from the database then attempt once to get them from federation instead.
|
||||
var loadedEvents []*gomatrixserverlib.Event
|
||||
loadedEvents, err = helpers.LoadEvents(ctx, r.DB, info.RoomNID, resultNIDs)
|
||||
loadedEvents, err = helpers.LoadEvents(ctx, r.DB, info, resultNIDs)
|
||||
if err != nil {
|
||||
if _, ok := err.(types.MissingEventError); ok {
|
||||
return r.backfillViaFederation(ctx, request, response)
|
||||
|
@ -473,7 +472,7 @@ FindSuccessor:
|
|||
// Retrieve all "m.room.member" state events of "join" membership, which
|
||||
// contains the list of users in the room before the event, therefore all
|
||||
// the servers in it at that moment.
|
||||
memberEvents, err := helpers.GetMembershipsAtState(ctx, b.db, info.RoomNID, stateEntries, true)
|
||||
memberEvents, err := helpers.GetMembershipsAtState(ctx, b.db, info, stateEntries, true)
|
||||
if err != nil {
|
||||
logrus.WithField("event_id", eventID).WithError(err).Error("ServersAtEvent: failed to get memberships before event")
|
||||
return nil
|
||||
|
@ -532,7 +531,7 @@ func (b *backfillRequester) ProvideEvents(roomVer gomatrixserverlib.RoomVersion,
|
|||
roomNID = nid.RoomNID
|
||||
}
|
||||
}
|
||||
eventsWithNids, err := b.db.Events(ctx, roomNID, eventNIDs)
|
||||
eventsWithNids, err := b.db.Events(ctx, &b.roomInfo, eventNIDs)
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithField("event_nids", eventNIDs).Error("Failed to load events")
|
||||
return nil, err
|
||||
|
@ -562,7 +561,7 @@ func joinEventsFromHistoryVisibility(
|
|||
}
|
||||
|
||||
// Get all of the events in this state
|
||||
stateEvents, err := db.Events(ctx, roomInfo.RoomNID, eventNIDs)
|
||||
stateEvents, err := db.Events(ctx, roomInfo, eventNIDs)
|
||||
if err != nil {
|
||||
// even though the default should be shared, restricting the visibility to joined
|
||||
// feels more secure here.
|
||||
|
@ -585,7 +584,7 @@ func joinEventsFromHistoryVisibility(
|
|||
if err != nil {
|
||||
return nil, visibility, err
|
||||
}
|
||||
evs, err := db.Events(ctx, roomInfo.RoomNID, joinEventNIDs)
|
||||
evs, err := db.Events(ctx, roomInfo, joinEventNIDs)
|
||||
return evs, visibility, err
|
||||
}
|
||||
|
||||
|
@ -606,7 +605,7 @@ func persistEvents(ctx context.Context, db storage.Database, events []*gomatrixs
|
|||
i++
|
||||
}
|
||||
|
||||
roomNID, err = db.GetOrCreateRoomNID(ctx, ev.Unwrap())
|
||||
roomInfo, err := db.GetOrCreateRoomInfo(ctx, ev.Unwrap())
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("failed to get or create roomNID")
|
||||
continue
|
||||
|
@ -624,23 +623,22 @@ func persistEvents(ctx context.Context, db storage.Database, events []*gomatrixs
|
|||
continue
|
||||
}
|
||||
|
||||
var redactedEventID string
|
||||
var redactionEvent *gomatrixserverlib.Event
|
||||
eventNID, _, redactionEvent, redactedEventID, err = db.StoreEvent(ctx, ev.Unwrap(), roomNID, eventTypeNID, eventStateKeyNID, authNids, false)
|
||||
eventNID, _, err = db.StoreEvent(ctx, ev.Unwrap(), roomInfo, eventTypeNID, eventStateKeyNID, authNids, false)
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithField("event_id", ev.EventID()).Error("Failed to persist event")
|
||||
continue
|
||||
}
|
||||
|
||||
_, redactedEvent, err := db.MaybeRedactEvent(ctx, roomInfo, eventNID, ev.Unwrap(), true)
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithField("event_id", ev.EventID()).Error("Failed to redact event")
|
||||
continue
|
||||
}
|
||||
// If storing this event results in it being redacted, then do so.
|
||||
// It's also possible for this event to be a redaction which results in another event being
|
||||
// redacted, which we don't care about since we aren't returning it in this backfill.
|
||||
if redactedEventID == ev.EventID() {
|
||||
eventToRedact := ev.Unwrap()
|
||||
if err := eventutil.RedactEvent(redactionEvent, eventToRedact); err != nil {
|
||||
logrus.WithError(err).WithField("event_id", ev.EventID()).Error("Failed to redact event")
|
||||
continue
|
||||
}
|
||||
ev = eventToRedact.Headered(ev.RoomVersion)
|
||||
if redactedEvent != nil && redactedEvent.EventID() == ev.EventID() {
|
||||
ev = redactedEvent.Headered(ev.RoomVersion)
|
||||
events[j] = ev
|
||||
}
|
||||
backfilledEventMap[ev.EventID()] = types.Event{
|
||||
|
|
|
@ -64,7 +64,7 @@ func (r *InboundPeeker) PerformInboundPeek(
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
latestEvents, err := r.DB.EventsFromIDs(ctx, info.RoomNID, []string{latestEventRefs[0].EventID})
|
||||
latestEvents, err := r.DB.EventsFromIDs(ctx, info, []string{latestEventRefs[0].EventID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ func (r *InboundPeeker) PerformInboundPeek(
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stateEvents, err = helpers.LoadStateEvents(ctx, r.DB, info.RoomNID, stateEntries)
|
||||
stateEvents, err = helpers.LoadStateEvents(ctx, r.DB, info, stateEntries)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ func (r *InboundPeeker) PerformInboundPeek(
|
|||
}
|
||||
authEventIDs = util.UniqueStrings(authEventIDs) // de-dupe
|
||||
|
||||
authEvents, err := query.GetAuthChain(ctx, r.DB.EventsFromIDs, authEventIDs)
|
||||
authEvents, err := query.GetAuthChain(ctx, r.DB.EventsFromIDs, info, authEventIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -194,7 +194,7 @@ func (r *Inviter) PerformInvite(
|
|||
// try and see if the user is allowed to make this invite. We can't do
|
||||
// this for invites coming in over federation - we have to take those on
|
||||
// trust.
|
||||
_, err = helpers.CheckAuthEvents(ctx, r.DB, info.RoomNID, event, event.AuthEventIDs())
|
||||
_, err = helpers.CheckAuthEvents(ctx, r.DB, info, event, event.AuthEventIDs())
|
||||
if err != nil {
|
||||
logger.WithError(err).WithField("event_id", event.EventID()).WithField("auth_event_ids", event.AuthEventIDs()).Error(
|
||||
"processInviteEvent.checkAuthEvents failed for event",
|
||||
|
@ -291,7 +291,7 @@ func buildInviteStrippedState(
|
|||
for _, stateNID := range stateEntries {
|
||||
stateNIDs = append(stateNIDs, stateNID.EventNID)
|
||||
}
|
||||
stateEvents, err := db.Events(ctx, info.RoomNID, stateNIDs)
|
||||
stateEvents, err := db.Events(ctx, info, stateNIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -21,11 +21,12 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/storage/tables"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/storage/tables"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||
"github.com/matrix-org/dendrite/internal/caching"
|
||||
"github.com/matrix-org/dendrite/roomserver/acls"
|
||||
|
@ -102,7 +103,7 @@ func (r *Queryer) QueryStateAfterEvents(
|
|||
return err
|
||||
}
|
||||
|
||||
stateEvents, err := helpers.LoadStateEvents(ctx, r.DB, info.RoomNID, stateEntries)
|
||||
stateEvents, err := helpers.LoadStateEvents(ctx, r.DB, info, stateEntries)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -114,7 +115,7 @@ func (r *Queryer) QueryStateAfterEvents(
|
|||
}
|
||||
authEventIDs = util.UniqueStrings(authEventIDs)
|
||||
|
||||
authEvents, err := GetAuthChain(ctx, r.DB.EventsFromIDs, authEventIDs)
|
||||
authEvents, err := GetAuthChain(ctx, r.DB.EventsFromIDs, info, authEventIDs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAuthChain: %w", err)
|
||||
}
|
||||
|
@ -132,24 +133,46 @@ func (r *Queryer) QueryStateAfterEvents(
|
|||
return nil
|
||||
}
|
||||
|
||||
// QueryEventsByID implements api.RoomserverInternalAPI
|
||||
// QueryEventsByID queries a list of events by event ID for one room. If no room is specified, it will try to determine
|
||||
// which room to use by querying the first events roomID.
|
||||
func (r *Queryer) QueryEventsByID(
|
||||
ctx context.Context,
|
||||
request *api.QueryEventsByIDRequest,
|
||||
response *api.QueryEventsByIDResponse,
|
||||
) error {
|
||||
events, err := r.DB.EventsFromIDs(ctx, 0, request.EventIDs)
|
||||
if len(request.EventIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
// We didn't receive a room ID, we need to fetch it first before we can continue.
|
||||
// This happens for e.g. ` /_matrix/federation/v1/event/{eventId}`
|
||||
var roomInfo *types.RoomInfo
|
||||
if request.RoomID == "" {
|
||||
var eventNIDs map[string]types.EventMetadata
|
||||
eventNIDs, err = r.DB.EventNIDs(ctx, []string{request.EventIDs[0]})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(eventNIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
roomInfo, err = r.DB.RoomInfoByNID(ctx, eventNIDs[request.EventIDs[0]].RoomNID)
|
||||
} else {
|
||||
roomInfo, err = r.DB.RoomInfo(ctx, request.RoomID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if roomInfo == nil {
|
||||
return nil
|
||||
}
|
||||
events, err := r.DB.EventsFromIDs(ctx, roomInfo, request.EventIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, event := range events {
|
||||
roomVersion, verr := r.roomVersion(event.RoomID())
|
||||
if verr != nil {
|
||||
return verr
|
||||
}
|
||||
|
||||
response.Events = append(response.Events, event.Headered(roomVersion))
|
||||
response.Events = append(response.Events, event.Headered(roomInfo.RoomVersion))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -186,7 +209,7 @@ func (r *Queryer) QueryMembershipForUser(
|
|||
response.IsInRoom = stillInRoom
|
||||
response.HasBeenInRoom = true
|
||||
|
||||
evs, err := r.DB.Events(ctx, info.RoomNID, []types.EventNID{membershipEventNID})
|
||||
evs, err := r.DB.Events(ctx, info, []types.EventNID{membershipEventNID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -268,10 +291,10 @@ func (r *Queryer) QueryMembershipAtEvent(
|
|||
// once. If we have more than one membership event, we need to get the state for each state entry.
|
||||
if canShortCircuit {
|
||||
if len(memberships) == 0 {
|
||||
memberships, err = helpers.GetMembershipsAtState(ctx, r.DB, info.RoomNID, stateEntry, false)
|
||||
memberships, err = helpers.GetMembershipsAtState(ctx, r.DB, info, stateEntry, false)
|
||||
}
|
||||
} else {
|
||||
memberships, err = helpers.GetMembershipsAtState(ctx, r.DB, info.RoomNID, stateEntry, false)
|
||||
memberships, err = helpers.GetMembershipsAtState(ctx, r.DB, info, stateEntry, false)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get memberships at state: %w", err)
|
||||
|
@ -318,7 +341,7 @@ func (r *Queryer) QueryMembershipsForRoom(
|
|||
}
|
||||
return fmt.Errorf("r.DB.GetMembershipEventNIDsForRoom: %w", err)
|
||||
}
|
||||
events, err = r.DB.Events(ctx, info.RoomNID, eventNIDs)
|
||||
events, err = r.DB.Events(ctx, info, eventNIDs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("r.DB.Events: %w", err)
|
||||
}
|
||||
|
@ -357,14 +380,14 @@ func (r *Queryer) QueryMembershipsForRoom(
|
|||
return err
|
||||
}
|
||||
|
||||
events, err = r.DB.Events(ctx, info.RoomNID, eventNIDs)
|
||||
events, err = r.DB.Events(ctx, info, eventNIDs)
|
||||
} else {
|
||||
stateEntries, err = helpers.StateBeforeEvent(ctx, r.DB, info, membershipEventNID)
|
||||
if err != nil {
|
||||
logrus.WithField("membership_event_nid", membershipEventNID).WithError(err).Error("failed to load state before event")
|
||||
return err
|
||||
}
|
||||
events, err = helpers.GetMembershipsAtState(ctx, r.DB, info.RoomNID, stateEntries, request.JoinedOnly)
|
||||
events, err = helpers.GetMembershipsAtState(ctx, r.DB, info, stateEntries, request.JoinedOnly)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -412,39 +435,39 @@ func (r *Queryer) QueryServerJoinedToRoom(
|
|||
// QueryServerAllowedToSeeEvent implements api.RoomserverInternalAPI
|
||||
func (r *Queryer) QueryServerAllowedToSeeEvent(
|
||||
ctx context.Context,
|
||||
request *api.QueryServerAllowedToSeeEventRequest,
|
||||
response *api.QueryServerAllowedToSeeEventResponse,
|
||||
) (err error) {
|
||||
events, err := r.DB.EventsFromIDs(ctx, 0, []string{request.EventID})
|
||||
serverName gomatrixserverlib.ServerName,
|
||||
eventID string,
|
||||
) (allowed bool, err error) {
|
||||
events, err := r.DB.EventNIDs(ctx, []string{eventID})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(events) == 0 {
|
||||
response.AllowedToSeeEvent = false // event doesn't exist so not allowed to see
|
||||
return
|
||||
return allowed, nil
|
||||
}
|
||||
roomID := events[0].RoomID()
|
||||
|
||||
inRoomReq := &api.QueryServerJoinedToRoomRequest{
|
||||
RoomID: roomID,
|
||||
ServerName: request.ServerName,
|
||||
}
|
||||
inRoomRes := &api.QueryServerJoinedToRoomResponse{}
|
||||
if err = r.QueryServerJoinedToRoom(ctx, inRoomReq, inRoomRes); err != nil {
|
||||
return fmt.Errorf("r.Queryer.QueryServerJoinedToRoom: %w", err)
|
||||
}
|
||||
|
||||
info, err := r.DB.RoomInfo(ctx, roomID)
|
||||
info, err := r.DB.RoomInfoByNID(ctx, events[eventID].RoomNID)
|
||||
if err != nil {
|
||||
return err
|
||||
return allowed, err
|
||||
}
|
||||
if info == nil || info.IsStub() {
|
||||
return nil
|
||||
return allowed, nil
|
||||
}
|
||||
response.AllowedToSeeEvent, err = helpers.CheckServerAllowedToSeeEvent(
|
||||
ctx, r.DB, info, request.EventID, request.ServerName, inRoomRes.IsInRoom,
|
||||
var isInRoom bool
|
||||
if r.IsLocalServerName(serverName) || serverName == "" {
|
||||
isInRoom, err = r.DB.GetLocalServerInRoom(ctx, info.RoomNID)
|
||||
if err != nil {
|
||||
return allowed, fmt.Errorf("r.DB.GetLocalServerInRoom: %w", err)
|
||||
}
|
||||
} else {
|
||||
isInRoom, err = r.DB.GetServerInRoom(ctx, info.RoomNID, serverName)
|
||||
if err != nil {
|
||||
return allowed, fmt.Errorf("r.DB.GetServerInRoom: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return helpers.CheckServerAllowedToSeeEvent(
|
||||
ctx, r.DB, info, eventID, serverName, isInRoom,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// QueryMissingEvents implements api.RoomserverInternalAPI
|
||||
|
@ -466,19 +489,22 @@ func (r *Queryer) QueryMissingEvents(
|
|||
eventsToFilter[id] = true
|
||||
}
|
||||
}
|
||||
events, err := r.DB.EventsFromIDs(ctx, 0, front)
|
||||
if len(front) == 0 {
|
||||
return nil // no events to query, give up.
|
||||
}
|
||||
events, err := r.DB.EventNIDs(ctx, []string{front[0]})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil // we are missing the events being asked to search from, give up.
|
||||
}
|
||||
info, err := r.DB.RoomInfo(ctx, events[0].RoomID())
|
||||
info, err := r.DB.RoomInfoByNID(ctx, events[front[0]].RoomNID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info == nil || info.IsStub() {
|
||||
return fmt.Errorf("missing RoomInfo for room %s", events[0].RoomID())
|
||||
return fmt.Errorf("missing RoomInfo for room %d", events[front[0]].RoomNID)
|
||||
}
|
||||
|
||||
resultNIDs, redactEventIDs, err := helpers.ScanEventTree(ctx, r.DB, info, front, visited, request.Limit, request.ServerName)
|
||||
|
@ -486,7 +512,7 @@ func (r *Queryer) QueryMissingEvents(
|
|||
return err
|
||||
}
|
||||
|
||||
loadedEvents, err := helpers.LoadEvents(ctx, r.DB, info.RoomNID, resultNIDs)
|
||||
loadedEvents, err := helpers.LoadEvents(ctx, r.DB, info, resultNIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -529,7 +555,7 @@ func (r *Queryer) QueryStateAndAuthChain(
|
|||
// TODO: this probably means it should be a different query operation...
|
||||
if request.OnlyFetchAuthChain {
|
||||
var authEvents []*gomatrixserverlib.Event
|
||||
authEvents, err = GetAuthChain(ctx, r.DB.EventsFromIDs, request.AuthEventIDs)
|
||||
authEvents, err = GetAuthChain(ctx, r.DB.EventsFromIDs, info, request.AuthEventIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -556,7 +582,7 @@ func (r *Queryer) QueryStateAndAuthChain(
|
|||
}
|
||||
authEventIDs = util.UniqueStrings(authEventIDs) // de-dupe
|
||||
|
||||
authEvents, err := GetAuthChain(ctx, r.DB.EventsFromIDs, authEventIDs)
|
||||
authEvents, err := GetAuthChain(ctx, r.DB.EventsFromIDs, info, authEventIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -611,18 +637,18 @@ func (r *Queryer) loadStateAtEventIDs(ctx context.Context, roomInfo *types.RoomI
|
|||
return nil, rejected, false, err
|
||||
}
|
||||
|
||||
events, err := helpers.LoadStateEvents(ctx, r.DB, roomInfo.RoomNID, stateEntries)
|
||||
events, err := helpers.LoadStateEvents(ctx, r.DB, roomInfo, stateEntries)
|
||||
return events, rejected, false, err
|
||||
}
|
||||
|
||||
type eventsFromIDs func(context.Context, types.RoomNID, []string) ([]types.Event, error)
|
||||
type eventsFromIDs func(context.Context, *types.RoomInfo, []string) ([]types.Event, error)
|
||||
|
||||
// GetAuthChain fetches the auth chain for the given auth events. An auth chain
|
||||
// is the list of all events that are referenced in the auth_events section, and
|
||||
// all their auth_events, recursively. The returned set of events contain the
|
||||
// given events. Will *not* error if we don't have all auth events.
|
||||
func GetAuthChain(
|
||||
ctx context.Context, fn eventsFromIDs, authEventIDs []string,
|
||||
ctx context.Context, fn eventsFromIDs, roomInfo *types.RoomInfo, authEventIDs []string,
|
||||
) ([]*gomatrixserverlib.Event, error) {
|
||||
// List of event IDs to fetch. On each pass, these events will be requested
|
||||
// from the database and the `eventsToFetch` will be updated with any new
|
||||
|
@ -633,7 +659,7 @@ func GetAuthChain(
|
|||
|
||||
for len(eventsToFetch) > 0 {
|
||||
// Try to retrieve the events from the database.
|
||||
events, err := fn(ctx, 0, eventsToFetch)
|
||||
events, err := fn(ctx, roomInfo, eventsToFetch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -852,7 +878,7 @@ func (r *Queryer) QueryServerBannedFromRoom(ctx context.Context, req *api.QueryS
|
|||
}
|
||||
|
||||
func (r *Queryer) QueryAuthChain(ctx context.Context, req *api.QueryAuthChainRequest, res *api.QueryAuthChainResponse) error {
|
||||
chain, err := GetAuthChain(ctx, r.DB.EventsFromIDs, req.EventIDs)
|
||||
chain, err := GetAuthChain(ctx, r.DB.EventsFromIDs, nil, req.EventIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -971,7 +997,7 @@ func (r *Queryer) QueryRestrictedJoinAllowed(ctx context.Context, req *api.Query
|
|||
// For each of the joined users, let's see if we can get a valid
|
||||
// membership event.
|
||||
for _, joinNID := range joinNIDs {
|
||||
events, err := r.DB.Events(ctx, roomInfo.RoomNID, []types.EventNID{joinNID})
|
||||
events, err := r.DB.Events(ctx, roomInfo, []types.EventNID{joinNID})
|
||||
if err != nil || len(events) != 1 {
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ func (db *getEventDB) addFakeEvents(graph map[string][]string) error {
|
|||
}
|
||||
|
||||
// EventsFromIDs implements RoomserverInternalAPIEventDB
|
||||
func (db *getEventDB) EventsFromIDs(ctx context.Context, roomNID types.RoomNID, eventIDs []string) (res []types.Event, err error) {
|
||||
func (db *getEventDB) EventsFromIDs(ctx context.Context, roomInfo *types.RoomInfo, eventIDs []string) (res []types.Event, err error) {
|
||||
for _, evID := range eventIDs {
|
||||
res = append(res, types.Event{
|
||||
EventNID: 0,
|
||||
|
@ -106,7 +106,7 @@ func TestGetAuthChainSingle(t *testing.T) {
|
|||
t.Fatalf("Failed to add events to db: %v", err)
|
||||
}
|
||||
|
||||
result, err := GetAuthChain(context.TODO(), db.EventsFromIDs, []string{"e"})
|
||||
result, err := GetAuthChain(context.TODO(), db.EventsFromIDs, nil, []string{"e"})
|
||||
if err != nil {
|
||||
t.Fatalf("getAuthChain failed: %v", err)
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ func TestGetAuthChainMultiple(t *testing.T) {
|
|||
t.Fatalf("Failed to add events to db: %v", err)
|
||||
}
|
||||
|
||||
result, err := GetAuthChain(context.TODO(), db.EventsFromIDs, []string{"e", "f"})
|
||||
result, err := GetAuthChain(context.TODO(), db.EventsFromIDs, nil, []string{"e", "f"})
|
||||
if err != nil {
|
||||
t.Fatalf("getAuthChain failed: %v", err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue