From 1da0a21923e9e526773c65d18c1b51eb950580de Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Fri, 26 Feb 2021 16:18:02 +0000 Subject: [PATCH 01/14] Changes that I made a long time ago --- clientapi/routing/getevent.go | 27 ++++++++++++++++++++++----- userapi/api/api.go | 3 +++ userapi/internal/api.go | 3 ++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/clientapi/routing/getevent.go b/clientapi/routing/getevent.go index 29340cc04..76e06dfd4 100644 --- a/clientapi/routing/getevent.go +++ b/clientapi/routing/getevent.go @@ -23,6 +23,7 @@ import ( userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" + log "github.com/sirupsen/logrus" ) type getEventRequest struct { @@ -79,10 +80,11 @@ func GetEvent( stateReq := api.QueryStateAfterEventsRequest{ RoomID: r.requestedEvent.RoomID(), PrevEventIDs: r.requestedEvent.PrevEventIDs(), - StateToFetch: []gomatrixserverlib.StateKeyTuple{{ - EventType: gomatrixserverlib.MRoomMember, - StateKey: device.UserID, - }}, + // XXX: Appservices require you to fetch the lot + // StateToFetch: []gomatrixserverlib.StateKeyTuple{{ + // EventType: gomatrixserverlib.MRoomMember, + // StateKey: device.UserID, + // }}, } var stateResp api.QueryStateAfterEventsResponse if err := rsAPI.QueryStateAfterEvents(req.Context(), &stateReq, &stateResp); err != nil { @@ -102,9 +104,24 @@ func GetEvent( JSON: jsonerror.NotFound("The event was not found or you do not have permission to read this event"), } } + var appService *config.ApplicationService + if device.AppserviceID != "" { + for _, as := range cfg.Derived.ApplicationServices { + if as.ID == device.AppserviceID { + appService = &as + break + } + } + } for _, stateEvent := range stateResp.StateEvents { - if !stateEvent.StateKeyEquals(device.UserID) { + if stateEvent.Type() != gomatrixserverlib.MRoomMember { + continue + } + // Allow appservices to fetch events + if appService != nil && !appService.IsInterestedInUserID(*stateEvent.StateKey()) { + continue + } else if stateEvent.StateKeyEquals(device.UserID) { continue } membership, err := stateEvent.Membership() diff --git a/userapi/api/api.go b/userapi/api/api.go index 809ba0476..45e4e834e 100644 --- a/userapi/api/api.go +++ b/userapi/api/api.go @@ -241,6 +241,9 @@ type Device struct { LastSeenTS int64 LastSeenIP string UserAgent string + // If the device is for an appservice user, + // this is the appservice ID. + AppserviceID string } // Account represents a Matrix account on this home server. diff --git a/userapi/internal/api.go b/userapi/internal/api.go index cf588a40c..a6a2f685e 100644 --- a/userapi/internal/api.go +++ b/userapi/internal/api.go @@ -379,7 +379,8 @@ func (a *UserInternalAPI) queryAppServiceToken(ctx context.Context, token, appSe // Use AS dummy device ID ID: types.AppServiceDeviceID, // AS dummy device has AS's token. - AccessToken: token, + AccessToken: token, + AppserviceID: appService.ID, } localpart, err := userutil.ParseUsernameParam(appServiceUserID, &a.ServerName) From ea0eae20f5ea1e777bd57584f33820c5c4a75c1f Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Fri, 26 Feb 2021 16:21:46 +0000 Subject: [PATCH 02/14] Rename to appserviceJoinedAtEvent --- appservice/consumers/roomserver.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appservice/consumers/roomserver.go b/appservice/consumers/roomserver.go index 7b3e6dd5e..04a5a2f94 100644 --- a/appservice/consumers/roomserver.go +++ b/appservice/consumers/roomserver.go @@ -126,9 +126,9 @@ func (s *OutputRoomEventConsumer) filterRoomserverEvents( return nil } -// appserviceHasMembershipInRoom returns a boolean depending on whether a given +// appserviceJoinedAtEvent returns a boolean depending on whether a given // appservice has membership at the time a given event was created. -func (s *OutputRoomEventConsumer) appserviceHasMembershipForEvent(ctx context.Context, event *gomatrixserverlib.HeaderedEvent, appservice config.ApplicationService) bool { +func (s *OutputRoomEventConsumer) appserviceJoinedAtEvent(ctx context.Context, event *gomatrixserverlib.HeaderedEvent, appservice config.ApplicationService) bool { // Check if any of the members in the room match the appservice membershipReq := api.QueryStateAfterEventsRequest{ PrevEventIDs: []string{event.EventID()}, @@ -194,5 +194,5 @@ func (s *OutputRoomEventConsumer) appserviceIsInterestedInEvent(ctx context.Cont } // Check if any of the members in the room match the appservice - return s.appserviceHasMembershipForEvent(ctx, event, appservice) + return s.appserviceJoinedAtEvent(ctx, event, appservice) } From 5058157cfaa89526cf70997551f32378d5d25a2b Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Fri, 26 Feb 2021 16:43:40 +0000 Subject: [PATCH 03/14] Check membership in GetMemberships --- clientapi/routing/memberships.go | 5 +++++ roomserver/api/query.go | 2 -- roomserver/internal/query/query.go | 5 ----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/clientapi/routing/memberships.go b/clientapi/routing/memberships.go index 6ddcf1be3..a4086832f 100644 --- a/clientapi/routing/memberships.go +++ b/clientapi/routing/memberships.go @@ -57,6 +57,11 @@ func GetMemberships( _ *config.ClientAPI, rsAPI api.RoomserverInternalAPI, ) util.JSONResponse { + resErr := checkMemberInRoom(req.Context(), rsAPI, device.UserID, roomID) + if resErr != nil { + return *resErr + } + queryReq := api.QueryMembershipsForRoomRequest{ JoinedOnly: joinedOnly, RoomID: roomID, diff --git a/roomserver/api/query.go b/roomserver/api/query.go index 43bbfd16d..657f1a6dd 100644 --- a/roomserver/api/query.go +++ b/roomserver/api/query.go @@ -151,8 +151,6 @@ type QueryMembershipsForRoomRequest struct { JoinedOnly bool `json:"joined_only"` // ID of the room to fetch memberships from RoomID string `json:"room_id"` - // ID of the user sending the request - Sender string `json:"sender"` } // QueryMembershipsForRoomResponse is a response to QueryMembershipsForRoom diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go index 3aa51726e..7ff8d84e4 100644 --- a/roomserver/internal/query/query.go +++ b/roomserver/internal/query/query.go @@ -243,11 +243,6 @@ func (r *Queryer) QueryMembershipsForRoom( return err } - membershipEventNID, stillInRoom, isRoomforgotten, err := r.DB.GetMembership(ctx, info.RoomNID, request.Sender) - if err != nil { - return err - } - response.IsRoomForgotten = isRoomforgotten if membershipEventNID == 0 { From 078aa09a5c297a354cacf0bb6b8d6354cb4bc3d1 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Mar 2021 11:47:58 +0000 Subject: [PATCH 04/14] Update QueryMembershipsForRoom --- roomserver/api/query.go | 4 ++++ roomserver/internal/query/query.go | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/roomserver/api/query.go b/roomserver/api/query.go index 657f1a6dd..af35f7e72 100644 --- a/roomserver/api/query.go +++ b/roomserver/api/query.go @@ -151,6 +151,10 @@ type QueryMembershipsForRoomRequest struct { JoinedOnly bool `json:"joined_only"` // ID of the room to fetch memberships from RoomID string `json:"room_id"` + // Optional - ID of the user sending the request, for checking if the + // user is allowed to see the memberships. If not specified then all + // room memberships will be returned. + Sender string `json:"sender"` } // QueryMembershipsForRoomResponse is a response to QueryMembershipsForRoom diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go index 7ff8d84e4..ec8f7e1b5 100644 --- a/roomserver/internal/query/query.go +++ b/roomserver/internal/query/query.go @@ -243,6 +243,29 @@ func (r *Queryer) QueryMembershipsForRoom( return err } + if request.Sender == "" { + var events []types.Event + var eventNIDs []types.EventNID + eventNIDs, err = r.DB.GetMembershipEventNIDsForRoom(ctx, info.RoomNID, request.JoinedOnly, false) + if err != nil { + return fmt.Errorf("r.DB.GetMembershipEventNIDsForRoom: %w", err) + } + events, err = r.DB.Events(ctx, eventNIDs) + if err != nil { + return fmt.Errorf("r.DB.Events: %w", err) + } + for _, event := range events { + clientEvent := gomatrixserverlib.ToClientEvent(event.Event, gomatrixserverlib.FormatAll) + response.JoinEvents = append(response.JoinEvents, clientEvent) + } + return nil + } + + membershipEventNID, stillInRoom, isRoomforgotten, err := r.DB.GetMembership(ctx, info.RoomNID, request.Sender) + if err != nil { + return err + } + response.IsRoomForgotten = isRoomforgotten if membershipEventNID == 0 { From 1b580b30b27ca31c9151f7cb66ef04aa378b39d6 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Mar 2021 11:48:41 +0000 Subject: [PATCH 05/14] Tweaks in client API --- clientapi/routing/getevent.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clientapi/routing/getevent.go b/clientapi/routing/getevent.go index 76e06dfd4..ed66c74f0 100644 --- a/clientapi/routing/getevent.go +++ b/clientapi/routing/getevent.go @@ -23,7 +23,6 @@ import ( userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" - log "github.com/sirupsen/logrus" ) type getEventRequest struct { @@ -38,6 +37,7 @@ type getEventRequest struct { // GetEvent implements GET /_matrix/client/r0/rooms/{roomId}/event/{eventId} // https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-rooms-roomid-event-eventid +// nolint:gocyclo func GetEvent( req *http.Request, device *userapi.Device, From f241ec581a2ccafdfa2fe818e382267e5511d411 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Mar 2021 11:55:29 +0000 Subject: [PATCH 06/14] Update appserviceJoinedAtEvent --- appservice/consumers/roomserver.go | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/appservice/consumers/roomserver.go b/appservice/consumers/roomserver.go index 04a5a2f94..778f44f98 100644 --- a/appservice/consumers/roomserver.go +++ b/appservice/consumers/roomserver.go @@ -130,19 +130,22 @@ func (s *OutputRoomEventConsumer) filterRoomserverEvents( // appservice has membership at the time a given event was created. func (s *OutputRoomEventConsumer) appserviceJoinedAtEvent(ctx context.Context, event *gomatrixserverlib.HeaderedEvent, appservice config.ApplicationService) bool { // Check if any of the members in the room match the appservice - membershipReq := api.QueryStateAfterEventsRequest{ - PrevEventIDs: []string{event.EventID()}, - RoomID: event.RoomID(), + membershipReq := &api.QueryMembershipsForRoomRequest{ + JoinedOnly: false, + RoomID: event.RoomID(), } - var membershipRes api.QueryStateAfterEventsResponse + membershipRes := &api.QueryMembershipsForRoomResponse{} // XXX: This could potentially race if the state for the event is not known yet // e.g. the event came over federation but we do not have the full state persisted. - if err := s.rsAPI.QueryStateAfterEvents(ctx, &membershipReq, &membershipRes); err == nil { - for _, ev := range membershipRes.StateEvents { - if ev.Type() == gomatrixserverlib.MRoomMember { - var membership, _ = ev.Membership() - if membership == gomatrixserverlib.Join && appservice.IsInterestedInUserID(*ev.StateKey()) { + if err := s.rsAPI.QueryMembershipsForRoom(ctx, membershipReq, membershipRes); err == nil { + for _, ev := range membershipRes.JoinEvents { + if ev.Type == gomatrixserverlib.MRoomMember { + var membership gomatrixserverlib.MemberContent + if err = json.Unmarshal(ev.Content, &membership); err != nil || ev.StateKey == nil { + continue + } + if membership.Membership == gomatrixserverlib.Join && appservice.IsInterestedInUserID(*ev.StateKey) { return true } } From 1c5de026151127e2ff4795b93612261161f60ed8 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Mar 2021 11:56:37 +0000 Subject: [PATCH 07/14] Comments --- appservice/consumers/roomserver.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/appservice/consumers/roomserver.go b/appservice/consumers/roomserver.go index 778f44f98..6a089b8ea 100644 --- a/appservice/consumers/roomserver.go +++ b/appservice/consumers/roomserver.go @@ -129,9 +129,12 @@ func (s *OutputRoomEventConsumer) filterRoomserverEvents( // appserviceJoinedAtEvent returns a boolean depending on whether a given // appservice has membership at the time a given event was created. func (s *OutputRoomEventConsumer) appserviceJoinedAtEvent(ctx context.Context, event *gomatrixserverlib.HeaderedEvent, appservice config.ApplicationService) bool { - // Check if any of the members in the room match the appservice + // TODO: This is only checking the current room state, not the state at + // the event in question. Pretty sure this is what Synapse does too, but + // until we have a lighter way of checking the state before the event that + // doesn't involve state res, then this is probably OK. membershipReq := &api.QueryMembershipsForRoomRequest{ - JoinedOnly: false, + JoinedOnly: true, RoomID: event.RoomID(), } membershipRes := &api.QueryMembershipsForRoomResponse{} From 74cfc371164b2424596b02a13a66d72d641f6c43 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Mar 2021 12:21:47 +0000 Subject: [PATCH 08/14] Try QueryMembershipForUser instead --- appservice/consumers/roomserver.go | 23 +++++++---------------- roomserver/internal/query/query.go | 18 ------------------ 2 files changed, 7 insertions(+), 34 deletions(-) diff --git a/appservice/consumers/roomserver.go b/appservice/consumers/roomserver.go index 6a089b8ea..eb4b8aeb2 100644 --- a/appservice/consumers/roomserver.go +++ b/appservice/consumers/roomserver.go @@ -17,6 +17,7 @@ package consumers import ( "context" "encoding/json" + "fmt" "github.com/matrix-org/dendrite/appservice/storage" "github.com/matrix-org/dendrite/appservice/types" @@ -133,26 +134,16 @@ func (s *OutputRoomEventConsumer) appserviceJoinedAtEvent(ctx context.Context, e // the event in question. Pretty sure this is what Synapse does too, but // until we have a lighter way of checking the state before the event that // doesn't involve state res, then this is probably OK. - membershipReq := &api.QueryMembershipsForRoomRequest{ - JoinedOnly: true, - RoomID: event.RoomID(), + membershipReq := &api.QueryMembershipForUserRequest{ + RoomID: event.RoomID(), + UserID: fmt.Sprintf("@%s:%s", appservice.SenderLocalpart, s.serverName), } - membershipRes := &api.QueryMembershipsForRoomResponse{} + membershipRes := &api.QueryMembershipForUserResponse{} // XXX: This could potentially race if the state for the event is not known yet // e.g. the event came over federation but we do not have the full state persisted. - if err := s.rsAPI.QueryMembershipsForRoom(ctx, membershipReq, membershipRes); err == nil { - for _, ev := range membershipRes.JoinEvents { - if ev.Type == gomatrixserverlib.MRoomMember { - var membership gomatrixserverlib.MemberContent - if err = json.Unmarshal(ev.Content, &membership); err != nil || ev.StateKey == nil { - continue - } - if membership.Membership == gomatrixserverlib.Join && appservice.IsInterestedInUserID(*ev.StateKey) { - return true - } - } - } + if err := s.rsAPI.QueryMembershipForUser(ctx, membershipReq, membershipRes); err == nil { + return membershipRes.IsInRoom } else { log.WithFields(log.Fields{ "room_id": event.RoomID(), diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go index ec8f7e1b5..3aa51726e 100644 --- a/roomserver/internal/query/query.go +++ b/roomserver/internal/query/query.go @@ -243,24 +243,6 @@ func (r *Queryer) QueryMembershipsForRoom( return err } - if request.Sender == "" { - var events []types.Event - var eventNIDs []types.EventNID - eventNIDs, err = r.DB.GetMembershipEventNIDsForRoom(ctx, info.RoomNID, request.JoinedOnly, false) - if err != nil { - return fmt.Errorf("r.DB.GetMembershipEventNIDsForRoom: %w", err) - } - events, err = r.DB.Events(ctx, eventNIDs) - if err != nil { - return fmt.Errorf("r.DB.Events: %w", err) - } - for _, event := range events { - clientEvent := gomatrixserverlib.ToClientEvent(event.Event, gomatrixserverlib.FormatAll) - response.JoinEvents = append(response.JoinEvents, clientEvent) - } - return nil - } - membershipEventNID, stillInRoom, isRoomforgotten, err := r.DB.GetMembership(ctx, info.RoomNID, request.Sender) if err != nil { return err From 441ccf04d18e8d2f848fde685430fd5ad7e2fef0 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Mar 2021 12:49:17 +0000 Subject: [PATCH 09/14] Undo some changes to client API that shouldn't be needed --- clientapi/routing/getevent.go | 26 +++++--------------------- clientapi/routing/memberships.go | 5 ----- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/clientapi/routing/getevent.go b/clientapi/routing/getevent.go index ed66c74f0..1162cde36 100644 --- a/clientapi/routing/getevent.go +++ b/clientapi/routing/getevent.go @@ -80,11 +80,10 @@ func GetEvent( stateReq := api.QueryStateAfterEventsRequest{ RoomID: r.requestedEvent.RoomID(), PrevEventIDs: r.requestedEvent.PrevEventIDs(), - // XXX: Appservices require you to fetch the lot - // StateToFetch: []gomatrixserverlib.StateKeyTuple{{ - // EventType: gomatrixserverlib.MRoomMember, - // StateKey: device.UserID, - // }}, + StateToFetch: []gomatrixserverlib.StateKeyTuple{{ + EventType: gomatrixserverlib.MRoomMember, + StateKey: device.UserID, + }}, } var stateResp api.QueryStateAfterEventsResponse if err := rsAPI.QueryStateAfterEvents(req.Context(), &stateReq, &stateResp); err != nil { @@ -104,24 +103,9 @@ func GetEvent( JSON: jsonerror.NotFound("The event was not found or you do not have permission to read this event"), } } - var appService *config.ApplicationService - if device.AppserviceID != "" { - for _, as := range cfg.Derived.ApplicationServices { - if as.ID == device.AppserviceID { - appService = &as - break - } - } - } for _, stateEvent := range stateResp.StateEvents { - if stateEvent.Type() != gomatrixserverlib.MRoomMember { - continue - } - // Allow appservices to fetch events - if appService != nil && !appService.IsInterestedInUserID(*stateEvent.StateKey()) { - continue - } else if stateEvent.StateKeyEquals(device.UserID) { + if stateEvent.StateKeyEquals(device.UserID) { continue } membership, err := stateEvent.Membership() diff --git a/clientapi/routing/memberships.go b/clientapi/routing/memberships.go index a4086832f..6ddcf1be3 100644 --- a/clientapi/routing/memberships.go +++ b/clientapi/routing/memberships.go @@ -57,11 +57,6 @@ func GetMemberships( _ *config.ClientAPI, rsAPI api.RoomserverInternalAPI, ) util.JSONResponse { - resErr := checkMemberInRoom(req.Context(), rsAPI, device.UserID, roomID) - if resErr != nil { - return *resErr - } - queryReq := api.QueryMembershipsForRoomRequest{ JoinedOnly: joinedOnly, RoomID: roomID, From f6bac264a8d224a4b7be4834750483a17bafa357 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Mar 2021 12:50:41 +0000 Subject: [PATCH 10/14] More /event tweaks --- clientapi/routing/getevent.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clientapi/routing/getevent.go b/clientapi/routing/getevent.go index 1162cde36..29340cc04 100644 --- a/clientapi/routing/getevent.go +++ b/clientapi/routing/getevent.go @@ -37,7 +37,6 @@ type getEventRequest struct { // GetEvent implements GET /_matrix/client/r0/rooms/{roomId}/event/{eventId} // https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-rooms-roomid-event-eventid -// nolint:gocyclo func GetEvent( req *http.Request, device *userapi.Device, @@ -105,7 +104,7 @@ func GetEvent( } for _, stateEvent := range stateResp.StateEvents { - if stateEvent.StateKeyEquals(device.UserID) { + if !stateEvent.StateKeyEquals(device.UserID) { continue } membership, err := stateEvent.Membership() From 3391e4c8275cbd1298b789f8b5c4611066a120b4 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Mar 2021 12:56:10 +0000 Subject: [PATCH 11/14] Refactor /event bit --- clientapi/routing/getevent.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/clientapi/routing/getevent.go b/clientapi/routing/getevent.go index 29340cc04..36f3ee9e3 100644 --- a/clientapi/routing/getevent.go +++ b/clientapi/routing/getevent.go @@ -103,8 +103,22 @@ func GetEvent( } } + var appService *config.ApplicationService + if device.AppserviceID != "" { + for _, as := range cfg.Derived.ApplicationServices { + if as.ID == device.AppserviceID { + appService = &as + break + } + } + } + for _, stateEvent := range stateResp.StateEvents { - if !stateEvent.StateKeyEquals(device.UserID) { + if appService != nil { + if !appService.IsInterestedInUserID(*stateEvent.StateKey()) { + continue + } + } else if !stateEvent.StateKeyEquals(device.UserID) { continue } membership, err := stateEvent.Membership() From e3791552cc41beca12ef6cb86f6058a4c1e403cb Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Mar 2021 13:51:33 +0000 Subject: [PATCH 12/14] Go back to QueryMembershipsForRoom because appservices are hard --- appservice/consumers/roomserver.go | 23 ++++++++++++++++------- roomserver/internal/query/query.go | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/appservice/consumers/roomserver.go b/appservice/consumers/roomserver.go index eb4b8aeb2..cc2714c16 100644 --- a/appservice/consumers/roomserver.go +++ b/appservice/consumers/roomserver.go @@ -17,7 +17,6 @@ package consumers import ( "context" "encoding/json" - "fmt" "github.com/matrix-org/dendrite/appservice/storage" "github.com/matrix-org/dendrite/appservice/types" @@ -134,16 +133,26 @@ func (s *OutputRoomEventConsumer) appserviceJoinedAtEvent(ctx context.Context, e // the event in question. Pretty sure this is what Synapse does too, but // until we have a lighter way of checking the state before the event that // doesn't involve state res, then this is probably OK. - membershipReq := &api.QueryMembershipForUserRequest{ - RoomID: event.RoomID(), - UserID: fmt.Sprintf("@%s:%s", appservice.SenderLocalpart, s.serverName), + membershipReq := &api.QueryMembershipsForRoomRequest{ + RoomID: event.RoomID(), + JoinedOnly: true, } - membershipRes := &api.QueryMembershipForUserResponse{} + membershipRes := &api.QueryMembershipsForRoomResponse{} // XXX: This could potentially race if the state for the event is not known yet // e.g. the event came over federation but we do not have the full state persisted. - if err := s.rsAPI.QueryMembershipForUser(ctx, membershipReq, membershipRes); err == nil { - return membershipRes.IsInRoom + if err := s.rsAPI.QueryMembershipsForRoom(ctx, membershipReq, membershipRes); err == nil { + for _, ev := range membershipRes.JoinEvents { + if ev.Type == gomatrixserverlib.MRoomMember { + var membership gomatrixserverlib.MemberContent + if err = json.Unmarshal(ev.Content, &membership); err != nil || ev.StateKey == nil { + continue + } + if membership.Membership == gomatrixserverlib.Join && appservice.IsInterestedInUserID(*ev.StateKey) { + return true + } + } + } } else { log.WithFields(log.Fields{ "room_id": event.RoomID(), diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go index 3aa51726e..ec8f7e1b5 100644 --- a/roomserver/internal/query/query.go +++ b/roomserver/internal/query/query.go @@ -243,6 +243,24 @@ func (r *Queryer) QueryMembershipsForRoom( return err } + if request.Sender == "" { + var events []types.Event + var eventNIDs []types.EventNID + eventNIDs, err = r.DB.GetMembershipEventNIDsForRoom(ctx, info.RoomNID, request.JoinedOnly, false) + if err != nil { + return fmt.Errorf("r.DB.GetMembershipEventNIDsForRoom: %w", err) + } + events, err = r.DB.Events(ctx, eventNIDs) + if err != nil { + return fmt.Errorf("r.DB.Events: %w", err) + } + for _, event := range events { + clientEvent := gomatrixserverlib.ToClientEvent(event.Event, gomatrixserverlib.FormatAll) + response.JoinEvents = append(response.JoinEvents, clientEvent) + } + return nil + } + membershipEventNID, stillInRoom, isRoomforgotten, err := r.DB.GetMembership(ctx, info.RoomNID, request.Sender) if err != nil { return err From 09bbedd7db72b528fdb77fb3d21c213a989fca86 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Mar 2021 15:30:07 +0000 Subject: [PATCH 13/14] Fix bugs in onMessage --- appservice/consumers/roomserver.go | 18 +++++++----------- appservice/workers/transaction_scheduler.go | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/appservice/consumers/roomserver.go b/appservice/consumers/roomserver.go index cc2714c16..2ad7f68fe 100644 --- a/appservice/consumers/roomserver.go +++ b/appservice/consumers/roomserver.go @@ -85,9 +85,6 @@ func (s *OutputRoomEventConsumer) onMessage(msg *sarama.ConsumerMessage) error { } if output.Type != api.OutputTypeNewRoomEvent { - log.WithField("type", output.Type).Debug( - "roomserver output log: ignoring unknown output type", - ) return nil } @@ -114,6 +111,7 @@ func (s *OutputRoomEventConsumer) filterRoomserverEvents( // Queue this event to be sent off to the application service if err := s.asDB.StoreEvent(ctx, ws.AppService.ID, event); err != nil { log.WithError(err).Warn("failed to insert incoming event into appservices database") + return err } else { // Tell our worker to send out new messages by updating remaining message // count and waking them up with a broadcast @@ -143,14 +141,12 @@ func (s *OutputRoomEventConsumer) appserviceJoinedAtEvent(ctx context.Context, e // e.g. the event came over federation but we do not have the full state persisted. if err := s.rsAPI.QueryMembershipsForRoom(ctx, membershipReq, membershipRes); err == nil { for _, ev := range membershipRes.JoinEvents { - if ev.Type == gomatrixserverlib.MRoomMember { - var membership gomatrixserverlib.MemberContent - if err = json.Unmarshal(ev.Content, &membership); err != nil || ev.StateKey == nil { - continue - } - if membership.Membership == gomatrixserverlib.Join && appservice.IsInterestedInUserID(*ev.StateKey) { - return true - } + var membership gomatrixserverlib.MemberContent + if err = json.Unmarshal(ev.Content, &membership); err != nil || ev.StateKey == nil { + continue + } + if appservice.IsInterestedInUserID(*ev.StateKey) { + return true } } } else { diff --git a/appservice/workers/transaction_scheduler.go b/appservice/workers/transaction_scheduler.go index 6528fc1b6..45748c214 100644 --- a/appservice/workers/transaction_scheduler.go +++ b/appservice/workers/transaction_scheduler.go @@ -62,7 +62,7 @@ func SetupTransactionWorkers( func worker(db storage.Database, ws types.ApplicationServiceWorkerState) { log.WithFields(log.Fields{ "appservice": ws.AppService.ID, - }).Info("starting application service") + }).Info("Starting application service") ctx := context.Background() // Create a HTTP client for sending requests to app services From d37f1601e9163f5359c773418131ab586a796f39 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Mar 2021 16:09:54 +0000 Subject: [PATCH 14/14] Add comments --- roomserver/internal/query/query.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go index a9f354cbf..f69f67f7c 100644 --- a/roomserver/internal/query/query.go +++ b/roomserver/internal/query/query.go @@ -242,6 +242,9 @@ func (r *Queryer) QueryMembershipsForRoom( return err } + // If no sender is specified then we will just return the entire + // set of memberships for the room, regardless of whether a specific + // user is allowed to see them or not. if request.Sender == "" { var events []types.Event var eventNIDs []types.EventNID