diff --git a/go.mod b/go.mod index 377a156fe..0786f1b25 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 - github.com/matrix-org/gomatrixserverlib v0.0.0-20220725104114-b6003e522771 + github.com/matrix-org/gomatrixserverlib v0.0.0-20220801083850-5ff38e2c2839 github.com/matrix-org/pinecone v0.0.0-20220708135211-1ce778fcde6a github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 github.com/mattn/go-sqlite3 v1.14.13 @@ -38,7 +38,7 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.12.2 - github.com/sirupsen/logrus v1.8.1 + github.com/sirupsen/logrus v1.9.0 github.com/stretchr/testify v1.7.1 github.com/tidwall/gjson v1.14.1 github.com/tidwall/sjson v1.2.4 @@ -46,7 +46,7 @@ require ( github.com/uber/jaeger-lib v2.4.1+incompatible github.com/yggdrasil-network/yggdrasil-go v0.4.3 go.uber.org/atomic v1.9.0 - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 golang.org/x/mobile v0.0.0-20220518205345-8578da9835fd golang.org/x/net v0.0.0-20220524220425-1d687d428aca @@ -102,7 +102,7 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect + golang.org/x/sys v0.0.0-20220731174439-a90be440212d // indirect golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b // indirect golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect golang.org/x/tools v0.1.10 // indirect diff --git a/go.sum b/go.sum index 10b1638a5..470f7634d 100644 --- a/go.sum +++ b/go.sum @@ -343,6 +343,8 @@ github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 h1:ZtO5uywdd5d github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s= github.com/matrix-org/gomatrixserverlib v0.0.0-20220725104114-b6003e522771 h1:ZIPHFIPNDS9dmEbPEiJbNmyCGJtn9exfpLC7JOcn/bE= github.com/matrix-org/gomatrixserverlib v0.0.0-20220725104114-b6003e522771/go.mod h1:jX38yp3SSLJNftBg3PXU1ayd0PCLIiDHQ4xAc9DIixk= +github.com/matrix-org/gomatrixserverlib v0.0.0-20220801083850-5ff38e2c2839 h1:QEFxKWH8PlEt3ZQKl31yJNAm8lvpNUwT51IMNTl9v1k= +github.com/matrix-org/gomatrixserverlib v0.0.0-20220801083850-5ff38e2c2839/go.mod h1:jX38yp3SSLJNftBg3PXU1ayd0PCLIiDHQ4xAc9DIixk= github.com/matrix-org/pinecone v0.0.0-20220708135211-1ce778fcde6a h1:DdG8vXMlZ65EAtc4V+3t7zHZ2Gqs24pSnyXS+4BRHUs= github.com/matrix-org/pinecone v0.0.0-20220708135211-1ce778fcde6a/go.mod h1:ulJzsVOTssIVp1j/m5eI//4VpAGDkMt5NrRuAVX7wpc= github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U= @@ -493,6 +495,8 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= @@ -570,6 +574,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -749,6 +755,9 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220731174439-a90be440212d h1:Sv5ogFZatcgIMMtBSTTAgMYsicp25MXBubjXNDKwm80= +golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 h1:CBpWXWQpIRjzmkkA+M7q9Fqnwd2mZr3AFqexg8YTfoM= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/roomserver/api/api.go b/roomserver/api/api.go index 3ca2c565f..e35014730 100644 --- a/roomserver/api/api.go +++ b/roomserver/api/api.go @@ -98,10 +98,12 @@ type SyncRoomserverAPI interface { res *PerformBackfillResponse, ) error + // QueryMembershipAtEvent queries the memberships at the given events. + // Returns a map from eventID to a slice of gomatrixserverlib.HeaderedEvent. QueryMembershipAtEvent( ctx context.Context, - request *QueryMembersipAtEventRequest, - response *QueryMembersipAtEventResponse, + request *QueryMembershipAtEventRequest, + response *QueryMembershipAtEventResponse, ) error } diff --git a/roomserver/api/api_trace.go b/roomserver/api/api_trace.go index 81532e91a..3e0184db5 100644 --- a/roomserver/api/api_trace.go +++ b/roomserver/api/api_trace.go @@ -375,8 +375,8 @@ func (t *RoomserverInternalAPITrace) QueryRestrictedJoinAllowed( func (t *RoomserverInternalAPITrace) QueryMembershipAtEvent( ctx context.Context, - request *QueryMembersipAtEventRequest, - response *QueryMembersipAtEventResponse, + request *QueryMembershipAtEventRequest, + response *QueryMembershipAtEventResponse, ) error { err := t.Impl.QueryMembershipAtEvent(ctx, request, response) util.GetLogger(ctx).WithError(err).Infof("QueryMembershipAtEvent req=%+v res=%+v", js(request), js(response)) diff --git a/roomserver/api/query.go b/roomserver/api/query.go index 8c91592e7..c8e6f9dc6 100644 --- a/roomserver/api/query.go +++ b/roomserver/api/query.go @@ -428,12 +428,16 @@ func (r *QueryCurrentStateResponse) UnmarshalJSON(data []byte) error { return nil } -type QueryMembersipAtEventRequest struct { +// QueryMembershipAtEventRequest requests the membership events for a user +// for a list of eventIDs. +type QueryMembershipAtEventRequest struct { RoomID string EventIDs []string UserID string } -type QueryMembersipAtEventResponse struct { +// QueryMembershipAtEventResponse is the response to QueryMembershipAtEventRequest. +type QueryMembershipAtEventResponse struct { + // Memberships is a map from eventID to a list of events (if any). Memberships map[string][]*gomatrixserverlib.HeaderedEvent `json:"memberships"` } diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go index 8da9ce78e..a5b6c4653 100644 --- a/roomserver/internal/query/query.go +++ b/roomserver/internal/query/query.go @@ -206,8 +206,8 @@ func (r *Queryer) QueryMembershipForUser( func (r *Queryer) QueryMembershipAtEvent( ctx context.Context, - request *api.QueryMembersipAtEventRequest, - response *api.QueryMembersipAtEventResponse, + request *api.QueryMembershipAtEventRequest, + response *api.QueryMembershipAtEventResponse, ) error { response.Memberships = make(map[string][]*gomatrixserverlib.HeaderedEvent) info, err := r.DB.RoomInfo(ctx, request.RoomID) diff --git a/roomserver/inthttp/client.go b/roomserver/inthttp/client.go index 465d00f47..b7c45717e 100644 --- a/roomserver/inthttp/client.go +++ b/roomserver/inthttp/client.go @@ -595,7 +595,7 @@ func (h *httpRoomserverInternalAPI) PerformForget(ctx context.Context, req *api. } -func (h *httpRoomserverInternalAPI) QueryMembershipAtEvent(ctx context.Context, req *api.QueryMembersipAtEventRequest, res *api.QueryMembersipAtEventResponse) error { +func (h *httpRoomserverInternalAPI) QueryMembershipAtEvent(ctx context.Context, req *api.QueryMembershipAtEventRequest, res *api.QueryMembershipAtEventResponse) error { span, ctx := opentracing.StartSpanFromContext(ctx, "QueryMembershiptAtEvent") defer span.Finish() diff --git a/roomserver/inthttp/server.go b/roomserver/inthttp/server.go index f9b9a0bd8..0ccd67cbb 100644 --- a/roomserver/inthttp/server.go +++ b/roomserver/inthttp/server.go @@ -498,8 +498,8 @@ func AddRoutes(r api.RoomserverInternalAPI, internalAPIMux *mux.Router) { ) internalAPIMux.Handle(RoomserverQueryMembershipAtEventPath, httputil.MakeInternalAPI("queryMembershipAtEventPath", func(req *http.Request) util.JSONResponse { - request := api.QueryMembersipAtEventRequest{} - response := api.QueryMembersipAtEventResponse{} + request := api.QueryMembershipAtEventRequest{} + response := api.QueryMembershipAtEventResponse{} if err := json.NewDecoder(req.Body).Decode(&request); err != nil { return util.MessageResponse(http.StatusBadRequest, err.Error()) } diff --git a/syncapi/internal/history_visibility.go b/syncapi/internal/history_visibility.go index a37484dbf..e73c004e5 100644 --- a/syncapi/internal/history_visibility.go +++ b/syncapi/internal/history_visibility.go @@ -17,7 +17,6 @@ package internal import ( "context" "math" - "sync" "time" "github.com/matrix-org/dendrite/roomserver/api" @@ -27,7 +26,9 @@ import ( "github.com/tidwall/gjson" ) -var registerOnce = &sync.Once{} +func init() { + prometheus.MustRegister(calculateHistoryVisibilityDuration) +} // calculateHistoryVisibilityDuration stores the time it takes to // calculate the history visibility. In polylith mode the roundtrip @@ -62,6 +63,7 @@ type eventVisibility struct { } // allowed checks the eventVisibility if the user is allowed to see the event. +// Rules as defined by https://spec.matrix.org/v1.3/client-server-api/#server-behaviour-5 func (ev eventVisibility) allowed() (allowed bool) { switch ev.visibility { case gomatrixserverlib.HistoryVisibilityWorldReadable: @@ -104,9 +106,6 @@ func ApplyHistoryVisibilityFilter( alwaysIncludeEventIDs map[string]struct{}, userID, endpoint string, ) ([]*gomatrixserverlib.HeaderedEvent, error) { - registerOnce.Do(func() { - prometheus.MustRegister(calculateHistoryVisibilityDuration) - }) if len(events) == 0 { return events, nil } @@ -118,21 +117,15 @@ func ApplyHistoryVisibilityFilter( return nil, err } - eventIDs := make([]string, len(events)) - for i := range events { - eventIDs[i] = events[i].EventID() - } - // Get the mapping from eventID -> eventVisibility eventsFiltered := make([]*gomatrixserverlib.HeaderedEvent, 0, len(events)) - event, err := visibilityForEvents(ctx, rsAPI, eventIDs, userID, events[0].RoomID()) + visibilities, err := visibilityForEvents(ctx, rsAPI, events, userID, events[0].RoomID()) if err != nil { return eventsFiltered, err } for _, ev := range events { - d := event[ev.EventID()] - d.membershipCurrent = membershipCurrent - d.visibility = ev.Visibility + evVis := visibilities[ev.EventID()] + evVis.membershipCurrent = membershipCurrent // Always include specific state events for /sync responses if alwaysIncludeEventIDs != nil { if _, ok := alwaysIncludeEventIDs[ev.EventID()]; ok { @@ -141,23 +134,29 @@ func ApplyHistoryVisibilityFilter( } } // NOTSPEC: Always allow user to see their own membership events (spec contains more "rules") - if ev.Type() == gomatrixserverlib.MRoomMember && ev.StateKey() != nil && *ev.StateKey() == userID { + if ev.Type() == gomatrixserverlib.MRoomMember && ev.StateKeyEquals(userID) { eventsFiltered = append(eventsFiltered, ev) continue } - // Handle history visibility changes + // Always allow history evVis events on boundaries. This is done + // by setting the effective evVis to the least restrictive + // of the old vs new. + // https://spec.matrix.org/v1.3/client-server-api/#server-behaviour-5 if hisVis, err := ev.HistoryVisibility(); err == nil { prevHisVis := gjson.GetBytes(ev.Unsigned(), "prev_content.history_visibility").String() - if oldPrio, ok := historyVisibilityPriority[gomatrixserverlib.HistoryVisibility(prevHisVis)]; ok { - // no OK check, since this should have been validated when setting the value - newPrio := historyVisibilityPriority[hisVis] - if oldPrio < newPrio { - d.visibility = gomatrixserverlib.HistoryVisibility(prevHisVis) - } + oldPrio, ok := historyVisibilityPriority[gomatrixserverlib.HistoryVisibility(prevHisVis)] + // if we can't get the previous history visibility, default to shared. + if !ok { + oldPrio = historyVisibilityPriority[gomatrixserverlib.HistoryVisibilityShared] + } + // no OK check, since this should have been validated when setting the value + newPrio := historyVisibilityPriority[hisVis] + if oldPrio < newPrio { + evVis.visibility = gomatrixserverlib.HistoryVisibility(prevHisVis) } } // do the actual check - allowed := d.allowed() + allowed := evVis.allowed() if allowed { eventsFiltered = append(eventsFiltered, ev) } @@ -166,39 +165,53 @@ func ApplyHistoryVisibilityFilter( return eventsFiltered, nil } -// visibilityForEvents returns a map from eventID to eventVisibility containing the visibility and the membership at the given event. +// visibilityForEvents returns a map from eventID to eventVisibility containing the visibility and the membership +// of `userID` at the given event. // Returns an error if the roomserver can't calculate the memberships. -func visibilityForEvents(ctx context.Context, rsAPI api.SyncRoomserverAPI, eventIDs []string, userID, roomID string) (map[string]eventVisibility, error) { - res := make(map[string]eventVisibility, len(eventIDs)) +func visibilityForEvents( + ctx context.Context, + rsAPI api.SyncRoomserverAPI, + events []*gomatrixserverlib.HeaderedEvent, + userID, roomID string, +) (map[string]eventVisibility, error) { + eventIDs := make([]string, len(events)) + for i := range events { + eventIDs[i] = events[i].EventID() + } + + result := make(map[string]eventVisibility, len(eventIDs)) // get the membership events for all eventIDs - resp := &api.QueryMembersipAtEventResponse{} - err := rsAPI.QueryMembershipAtEvent(ctx, &api.QueryMembersipAtEventRequest{ + membershipResp := &api.QueryMembershipAtEventResponse{} + err := rsAPI.QueryMembershipAtEvent(ctx, &api.QueryMembershipAtEventRequest{ RoomID: roomID, EventIDs: eventIDs, UserID: userID, - }, resp) + }, membershipResp) if err != nil { - return res, err + return result, err } // Create a map from eventID -> eventVisibility - for _, eventID := range eventIDs { - vis := eventVisibility{membershipAtEvent: gomatrixserverlib.Leave} - events, ok := resp.Memberships[eventID] + for _, event := range events { + eventID := event.EventID() + vis := eventVisibility{ + membershipAtEvent: gomatrixserverlib.Leave, // default to leave, to not expose events by accident + visibility: event.Visibility, + } + membershipEvs, ok := membershipResp.Memberships[eventID] if !ok { - res[eventID] = vis + result[eventID] = vis continue } - for _, ev := range events { + for _, ev := range membershipEvs { membership, err := ev.Membership() if err != nil { - return res, err + return result, err } vis.membershipAtEvent = membership } - res[eventID] = vis + result[eventID] = vis } - - return res, nil + return result, nil } diff --git a/syncapi/routing/context.go b/syncapi/routing/context.go index 769eb4f79..13c4e9d89 100644 --- a/syncapi/routing/context.go +++ b/syncapi/routing/context.go @@ -111,7 +111,7 @@ func Context( // verify the user is allowed to see the context for this room/event startTime := time.Now() - filteredEvent, err := internal.ApplyHistoryVisibilityFilter(ctx, syncDB, rsAPI, []*gomatrixserverlib.HeaderedEvent{&requestedEvent}, nil, device.UserID, "context") + filteredEvents, err := internal.ApplyHistoryVisibilityFilter(ctx, syncDB, rsAPI, []*gomatrixserverlib.HeaderedEvent{&requestedEvent}, nil, device.UserID, "context") if err != nil { logrus.WithError(err).Error("unable to apply history visibility filter") return jsonerror.InternalServerError() @@ -120,7 +120,7 @@ func Context( "duration": time.Since(startTime), "room_id": roomID, }).Debug("applied history visibility (context)") - if len(filteredEvent) == 0 { + if len(filteredEvents) == 0 { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("User is not allowed to query context"), diff --git a/syncapi/streams/stream_pdu.go b/syncapi/streams/stream_pdu.go index a58238fc6..68523fe43 100644 --- a/syncapi/streams/stream_pdu.go +++ b/syncapi/streams/stream_pdu.go @@ -300,7 +300,7 @@ func (p *PDUStreamProvider) addRoomDeltaToResponse( switch delta.Membership { case gomatrixserverlib.Join: // We need to make sure we always include the latest states events, if they are in the timeline - events, err := applyHistoryVisibilityFilter(ctx, p.DB, p.rsAPI, delta.RoomID, device.UserID, recentEvents) + events, err := applyHistoryVisibilityFilter(ctx, p.DB, p.rsAPI, delta.RoomID, device.UserID, eventFilter.Limit, recentEvents) if err != nil { logrus.WithError(err).Error("unable to apply history visibility filter") } @@ -310,6 +310,8 @@ func (p *PDUStreamProvider) addRoomDeltaToResponse( } jr.Timeline.PrevBatch = &prevBatch jr.Timeline.Events = gomatrixserverlib.HeaderedToClientEvents(events, gomatrixserverlib.FormatSync) + // If we are limited by the filter AND the history visibility filter + // didn't "remove" events, return that the response is limited. jr.Timeline.Limited = limited && len(events) == len(recentEvents) jr.State.Events = gomatrixserverlib.HeaderedToClientEvents(delta.StateEvents, gomatrixserverlib.FormatSync) res.Rooms.Join[delta.RoomID] = *jr @@ -346,12 +348,16 @@ func applyHistoryVisibilityFilter( db storage.Database, rsAPI roomserverAPI.SyncRoomserverAPI, roomID, userID string, + limit int, recentEvents []*gomatrixserverlib.HeaderedEvent, ) ([]*gomatrixserverlib.HeaderedEvent, error) { - // We need to make sure we always include the latest states events, if they are in the timeline - stateEvents, err := db.CurrentState(ctx, roomID, &gomatrixserverlib.StateFilter{Limit: 1000}, nil) + // We need to make sure we always include the latest states events, if they are in the timeline. + // We grep at least limit * 2 events, to ensure we really get the needed events. + stateEvents, err := db.CurrentState(ctx, roomID, &gomatrixserverlib.StateFilter{Limit: limit * 2}, nil) if err != nil { - logrus.WithError(err).Warnf("failed to get current state") + // Not a fatal error, we can continue without the stateEvents, + // they are only needed if there are state events in the timeline. + logrus.WithError(err).Warnf("failed to get current room state") } alwaysIncludeIDs := make(map[string]struct{}, len(stateEvents)) for _, ev := range stateEvents { @@ -478,12 +484,14 @@ func (p *PDUStreamProvider) getJoinResponseForCompleteSync( events := recentEvents // Only apply history visibility checks if the response is for joined rooms if !isPeek { - events, err = applyHistoryVisibilityFilter(ctx, p.DB, p.rsAPI, roomID, device.UserID, recentEvents) + events, err = applyHistoryVisibilityFilter(ctx, p.DB, p.rsAPI, roomID, device.UserID, eventFilter.Limit, recentEvents) if err != nil { logrus.WithError(err).Error("unable to apply history visibility filter") } } + // If we are limited by the filter AND the history visibility filter + // didn't "remove" events, return that the response is limited. limited = limited && len(events) == len(recentEvents) if stateFilter.LazyLoadMembers { diff --git a/syncapi/syncapi_test.go b/syncapi/syncapi_test.go index 17b9eaac4..1278cea30 100644 --- a/syncapi/syncapi_test.go +++ b/syncapi/syncapi_test.go @@ -59,7 +59,7 @@ func (s *syncRoomserverAPI) QueryMembershipForUser(ctx context.Context, req *rsa return nil } -func (s *syncRoomserverAPI) QueryMembershipAtEvent(ctx context.Context, req *rsapi.QueryMembersipAtEventRequest, res *rsapi.QueryMembersipAtEventResponse) error { +func (s *syncRoomserverAPI) QueryMembershipAtEvent(ctx context.Context, req *rsapi.QueryMembershipAtEventRequest, res *rsapi.QueryMembershipAtEventResponse) error { return nil } @@ -397,7 +397,6 @@ func testHistoryVisibility(t *testing.T, dbType test.DBType) { base, close := testrig.CreateBaseDendrite(t, dbType) defer close() - _ = close jsctx, _ := base.NATS.Prepare(base.ProcessContext, &base.Cfg.Global.JetStream) defer jetstream.DeleteAllStreams(jsctx, &base.Cfg.Global.JetStream) @@ -477,16 +476,12 @@ func testHistoryVisibility(t *testing.T, dbType test.DBType) { func verifyEventVisible(t *testing.T, wantVisible bool, wantVisibleEvent *gomatrixserverlib.HeaderedEvent, chunk []gomatrixserverlib.ClientEvent) { t.Helper() if wantVisible { - found := false for _, ev := range chunk { if ev.EventID == wantVisibleEvent.EventID() { - found = true - break + return } } - if !found { - t.Fatalf("expected to see event %s but didn't: %+v", wantVisibleEvent.EventID(), chunk) - } + t.Fatalf("expected to see event %s but didn't: %+v", wantVisibleEvent.EventID(), chunk) } else { for _, ev := range chunk { if ev.EventID == wantVisibleEvent.EventID() {