diff --git a/clientapi/routing/directory.go b/clientapi/routing/directory.go index 62f295fe..13fbfe7c 100644 --- a/clientapi/routing/directory.go +++ b/clientapi/routing/directory.go @@ -273,7 +273,7 @@ func SetVisibility( req *http.Request, stateAPI currentstateAPI.CurrentStateInternalAPI, rsAPI roomserverAPI.RoomserverInternalAPI, dev *userapi.Device, roomID string, ) util.JSONResponse { - resErr := checkMemberInRoom(req.Context(), stateAPI, dev.UserID, roomID) + resErr := checkMemberInRoom(req.Context(), rsAPI, dev.UserID, roomID) if resErr != nil { return *resErr } diff --git a/clientapi/routing/membership.go b/clientapi/routing/membership.go index 202662ab..88cb2364 100644 --- a/clientapi/routing/membership.go +++ b/clientapi/routing/membership.go @@ -25,7 +25,6 @@ import ( "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/threepid" - currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/eventutil" "github.com/matrix-org/dendrite/roomserver/api" @@ -95,7 +94,6 @@ func SendKick( req *http.Request, accountDB accounts.Database, device *userapi.Device, roomID string, cfg *config.ClientAPI, rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI, - stateAPI currentstateAPI.CurrentStateInternalAPI, ) util.JSONResponse { body, evTime, roomVer, reqErr := extractRequestData(req, roomID, rsAPI) if reqErr != nil { @@ -108,7 +106,7 @@ func SendKick( } } - errRes := checkMemberInRoom(req.Context(), stateAPI, device.UserID, roomID) + errRes := checkMemberInRoom(req.Context(), rsAPI, device.UserID, roomID) if errRes != nil { return *errRes } @@ -372,13 +370,13 @@ func checkAndProcessThreepid( return } -func checkMemberInRoom(ctx context.Context, stateAPI currentstateAPI.CurrentStateInternalAPI, userID, roomID string) *util.JSONResponse { +func checkMemberInRoom(ctx context.Context, rsAPI api.RoomserverInternalAPI, userID, roomID string) *util.JSONResponse { tuple := gomatrixserverlib.StateKeyTuple{ EventType: gomatrixserverlib.MRoomMember, StateKey: userID, } - var membershipRes currentstateAPI.QueryCurrentStateResponse - err := stateAPI.QueryCurrentState(ctx, ¤tstateAPI.QueryCurrentStateRequest{ + var membershipRes api.QueryCurrentStateResponse + err := rsAPI.QueryCurrentState(ctx, &api.QueryCurrentStateRequest{ RoomID: roomID, StateTuples: []gomatrixserverlib.StateKeyTuple{tuple}, }, &membershipRes) diff --git a/clientapi/routing/redaction.go b/clientapi/routing/redaction.go index 178bfafc..9701685e 100644 --- a/clientapi/routing/redaction.go +++ b/clientapi/routing/redaction.go @@ -21,7 +21,6 @@ import ( "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" - currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/eventutil" "github.com/matrix-org/dendrite/roomserver/api" @@ -41,9 +40,9 @@ type redactionResponse struct { func SendRedaction( req *http.Request, device *userapi.Device, roomID, eventID string, cfg *config.ClientAPI, - rsAPI roomserverAPI.RoomserverInternalAPI, stateAPI currentstateAPI.CurrentStateInternalAPI, + rsAPI roomserverAPI.RoomserverInternalAPI, ) util.JSONResponse { - resErr := checkMemberInRoom(req.Context(), stateAPI, device.UserID, roomID) + resErr := checkMemberInRoom(req.Context(), rsAPI, device.UserID, roomID) if resErr != nil { return *resErr } @@ -67,7 +66,7 @@ func SendRedaction( // https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid allowedToRedact := ev.Sender() == device.UserID if !allowedToRedact { - plEvent := currentstateAPI.GetEvent(req.Context(), stateAPI, roomID, gomatrixserverlib.StateKeyTuple{ + plEvent := roomserverAPI.GetStateEvent(req.Context(), rsAPI, roomID, gomatrixserverlib.StateKeyTuple{ EventType: gomatrixserverlib.MRoomPowerLevels, StateKey: "", }) diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go index cd717e2b..d9e93b53 100644 --- a/clientapi/routing/routing.go +++ b/clientapi/routing/routing.go @@ -176,7 +176,7 @@ func Setup( if err != nil { return util.ErrorResponse(err) } - return SendKick(req, accountDB, device, vars["roomID"], cfg, rsAPI, asAPI, stateAPI) + return SendKick(req, accountDB, device, vars["roomID"], cfg, rsAPI, asAPI) }), ).Methods(http.MethodPost, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/unban", @@ -372,7 +372,7 @@ func Setup( if err != nil { return util.ErrorResponse(err) } - return SendTyping(req, device, vars["roomID"], vars["userID"], accountDB, eduAPI, stateAPI) + return SendTyping(req, device, vars["roomID"], vars["userID"], accountDB, eduAPI, rsAPI) }), ).Methods(http.MethodPut, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/redact/{eventID}", @@ -381,7 +381,7 @@ func Setup( if err != nil { return util.ErrorResponse(err) } - return SendRedaction(req, device, vars["roomID"], vars["eventID"], cfg, rsAPI, stateAPI) + return SendRedaction(req, device, vars["roomID"], vars["eventID"], cfg, rsAPI) }), ).Methods(http.MethodPost, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/redact/{eventID}/{txnId}", @@ -390,7 +390,7 @@ func Setup( if err != nil { return util.ErrorResponse(err) } - return SendRedaction(req, device, vars["roomID"], vars["eventID"], cfg, rsAPI, stateAPI) + return SendRedaction(req, device, vars["roomID"], vars["eventID"], cfg, rsAPI) }), ).Methods(http.MethodPut, http.MethodOptions) @@ -650,7 +650,7 @@ func Setup( req.Context(), device, userAPI, - stateAPI, + rsAPI, cfg.Matrix.ServerName, postContent.SearchString, postContent.Limit, diff --git a/clientapi/routing/sendtyping.go b/clientapi/routing/sendtyping.go index e4b5b7a3..3abf3db2 100644 --- a/clientapi/routing/sendtyping.go +++ b/clientapi/routing/sendtyping.go @@ -17,8 +17,8 @@ import ( "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" - currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api" "github.com/matrix-org/dendrite/eduserver/api" + roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/dendrite/userapi/storage/accounts" "github.com/matrix-org/util" @@ -35,7 +35,7 @@ func SendTyping( req *http.Request, device *userapi.Device, roomID string, userID string, accountDB accounts.Database, eduAPI api.EDUServerInputAPI, - stateAPI currentstateAPI.CurrentStateInternalAPI, + rsAPI roomserverAPI.RoomserverInternalAPI, ) util.JSONResponse { if device.UserID != userID { return util.JSONResponse{ @@ -45,7 +45,7 @@ func SendTyping( } // Verify that the user is a member of this room - resErr := checkMemberInRoom(req.Context(), stateAPI, userID, roomID) + resErr := checkMemberInRoom(req.Context(), rsAPI, userID, roomID) if resErr != nil { return *resErr } diff --git a/clientapi/routing/userdirectory.go b/clientapi/routing/userdirectory.go index db81ffea..2659bc9c 100644 --- a/clientapi/routing/userdirectory.go +++ b/clientapi/routing/userdirectory.go @@ -19,7 +19,7 @@ import ( "fmt" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" - currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api" + "github.com/matrix-org/dendrite/roomserver/api" userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" @@ -34,7 +34,7 @@ func SearchUserDirectory( ctx context.Context, device *userapi.Device, userAPI userapi.UserInternalAPI, - stateAPI currentstateAPI.CurrentStateInternalAPI, + rsAPI api.RoomserverInternalAPI, serverName gomatrixserverlib.ServerName, searchString string, limit int, @@ -81,14 +81,14 @@ func SearchUserDirectory( // start searching for known users from joined rooms. if len(results) <= limit { - stateReq := ¤tstateAPI.QueryKnownUsersRequest{ + stateReq := &api.QueryKnownUsersRequest{ UserID: device.UserID, SearchString: searchString, Limit: limit - len(results), } - stateRes := ¤tstateAPI.QueryKnownUsersResponse{} - if err := stateAPI.QueryKnownUsers(ctx, stateReq, stateRes); err != nil { - errRes := util.ErrorResponse(fmt.Errorf("stateAPI.QueryKnownUsers: %w", err)) + stateRes := &api.QueryKnownUsersResponse{} + if err := rsAPI.QueryKnownUsers(ctx, stateReq, stateRes); err != nil { + errRes := util.ErrorResponse(fmt.Errorf("rsAPI.QueryKnownUsers: %w", err)) return &errRes } diff --git a/currentstateserver/acls/acls.go b/currentstateserver/acls/acls.go deleted file mode 100644 index 775b6c73..00000000 --- a/currentstateserver/acls/acls.go +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2020 The Matrix.org Foundation C.I.C. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package acls - -import ( - "context" - "encoding/json" - "fmt" - "net" - "regexp" - "strings" - "sync" - - "github.com/matrix-org/gomatrixserverlib" - "github.com/sirupsen/logrus" -) - -type ServerACLDatabase interface { - // GetKnownRooms returns a list of all rooms we know about. - GetKnownRooms(ctx context.Context) ([]string, error) - // GetStateEvent returns the state event of a given type for a given room with a given state key - // If no event could be found, returns nil - // If there was an issue during the retrieval, returns an error - GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*gomatrixserverlib.HeaderedEvent, error) -} - -type ServerACLs struct { - acls map[string]*serverACL // room ID -> ACL - aclsMutex sync.RWMutex // protects the above -} - -func NewServerACLs(db ServerACLDatabase) *ServerACLs { - ctx := context.TODO() - acls := &ServerACLs{ - acls: make(map[string]*serverACL), - } - // Look up all of the rooms that the current state server knows about. - rooms, err := db.GetKnownRooms(ctx) - if err != nil { - logrus.WithError(err).Fatalf("Failed to get known rooms") - } - // For each room, let's see if we have a server ACL state event. If we - // do then we'll process it into memory so that we have the regexes to - // hand. - for _, room := range rooms { - state, err := db.GetStateEvent(ctx, room, "m.room.server_acl", "") - if err != nil { - logrus.WithError(err).Errorf("Failed to get server ACLs for room %q", room) - continue - } - if state != nil { - acls.OnServerACLUpdate(&state.Event) - } - } - return acls -} - -type ServerACL struct { - Allowed []string `json:"allow"` - Denied []string `json:"deny"` - AllowIPLiterals bool `json:"allow_ip_literals"` -} - -type serverACL struct { - ServerACL - allowedRegexes []*regexp.Regexp - deniedRegexes []*regexp.Regexp -} - -func compileACLRegex(orig string) (*regexp.Regexp, error) { - escaped := regexp.QuoteMeta(orig) - escaped = strings.Replace(escaped, "\\?", ".", -1) - escaped = strings.Replace(escaped, "\\*", ".*", -1) - return regexp.Compile(escaped) -} - -func (s *ServerACLs) OnServerACLUpdate(state *gomatrixserverlib.Event) { - acls := &serverACL{} - if err := json.Unmarshal(state.Content(), &acls.ServerACL); err != nil { - logrus.WithError(err).Errorf("Failed to unmarshal state content for server ACLs") - return - } - // The spec calls only for * (zero or more chars) and ? (exactly one char) - // to be supported as wildcard components, so we will escape all of the regex - // special characters and then replace * and ? with their regex counterparts. - // https://matrix.org/docs/spec/client_server/r0.6.1#m-room-server-acl - for _, orig := range acls.Allowed { - if expr, err := compileACLRegex(orig); err != nil { - logrus.WithError(err).Errorf("Failed to compile allowed regex") - } else { - acls.allowedRegexes = append(acls.allowedRegexes, expr) - } - } - for _, orig := range acls.Denied { - if expr, err := compileACLRegex(orig); err != nil { - logrus.WithError(err).Errorf("Failed to compile denied regex") - } else { - acls.deniedRegexes = append(acls.deniedRegexes, expr) - } - } - logrus.WithFields(logrus.Fields{ - "allow_ip_literals": acls.AllowIPLiterals, - "num_allowed": len(acls.allowedRegexes), - "num_denied": len(acls.deniedRegexes), - }).Debugf("Updating server ACLs for %q", state.RoomID()) - s.aclsMutex.Lock() - defer s.aclsMutex.Unlock() - s.acls[state.RoomID()] = acls -} - -func (s *ServerACLs) IsServerBannedFromRoom(serverName gomatrixserverlib.ServerName, roomID string) bool { - s.aclsMutex.RLock() - // First of all check if we have an ACL for this room. If we don't then - // no servers are banned from the room. - acls, ok := s.acls[roomID] - if !ok { - s.aclsMutex.RUnlock() - return false - } - s.aclsMutex.RUnlock() - // Split the host and port apart. This is because the spec calls on us to - // validate the hostname only in cases where the port is also present. - if serverNameOnly, _, err := net.SplitHostPort(string(serverName)); err == nil { - serverName = gomatrixserverlib.ServerName(serverNameOnly) - } - // Check if the hostname is an IPv4 or IPv6 literal. We cheat here by adding - // a /0 prefix length just to trick ParseCIDR into working. If we find that - // the server is an IP literal and we don't allow those then stop straight - // away. - if _, _, err := net.ParseCIDR(fmt.Sprintf("%s/0", serverName)); err == nil { - if !acls.AllowIPLiterals { - return true - } - } - // Check if the hostname matches one of the denied regexes. If it does then - // the server is banned from the room. - for _, expr := range acls.deniedRegexes { - if expr.MatchString(string(serverName)) { - return true - } - } - // Check if the hostname matches one of the allowed regexes. If it does then - // the server is NOT banned from the room. - for _, expr := range acls.allowedRegexes { - if expr.MatchString(string(serverName)) { - return false - } - } - // If we've got to this point then we haven't matched any regexes or an IP - // hostname if disallowed. The spec calls for default-deny here. - return true -} diff --git a/currentstateserver/acls/acls_test.go b/currentstateserver/acls/acls_test.go deleted file mode 100644 index 9fb6a558..00000000 --- a/currentstateserver/acls/acls_test.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2020 The Matrix.org Foundation C.I.C. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package acls - -import ( - "regexp" - "testing" -) - -func TestOpenACLsWithBlacklist(t *testing.T) { - roomID := "!test:test.com" - allowRegex, err := compileACLRegex("*") - if err != nil { - t.Fatalf(err.Error()) - } - denyRegex, err := compileACLRegex("foo.com") - if err != nil { - t.Fatalf(err.Error()) - } - - acls := ServerACLs{ - acls: make(map[string]*serverACL), - } - - acls.acls[roomID] = &serverACL{ - ServerACL: ServerACL{ - AllowIPLiterals: true, - }, - allowedRegexes: []*regexp.Regexp{allowRegex}, - deniedRegexes: []*regexp.Regexp{denyRegex}, - } - - if acls.IsServerBannedFromRoom("1.2.3.4", roomID) { - t.Fatal("Expected 1.2.3.4 to be allowed but wasn't") - } - if acls.IsServerBannedFromRoom("1.2.3.4:2345", roomID) { - t.Fatal("Expected 1.2.3.4:2345 to be allowed but wasn't") - } - if !acls.IsServerBannedFromRoom("foo.com", roomID) { - t.Fatal("Expected foo.com to be banned but wasn't") - } - if !acls.IsServerBannedFromRoom("foo.com:3456", roomID) { - t.Fatal("Expected foo.com:3456 to be banned but wasn't") - } - if acls.IsServerBannedFromRoom("bar.com", roomID) { - t.Fatal("Expected bar.com to be allowed but wasn't") - } - if acls.IsServerBannedFromRoom("bar.com:4567", roomID) { - t.Fatal("Expected bar.com:4567 to be allowed but wasn't") - } -} - -func TestDefaultACLsWithWhitelist(t *testing.T) { - roomID := "!test:test.com" - allowRegex, err := compileACLRegex("foo.com") - if err != nil { - t.Fatalf(err.Error()) - } - - acls := ServerACLs{ - acls: make(map[string]*serverACL), - } - - acls.acls[roomID] = &serverACL{ - ServerACL: ServerACL{ - AllowIPLiterals: false, - }, - allowedRegexes: []*regexp.Regexp{allowRegex}, - deniedRegexes: []*regexp.Regexp{}, - } - - if !acls.IsServerBannedFromRoom("1.2.3.4", roomID) { - t.Fatal("Expected 1.2.3.4 to be banned but wasn't") - } - if !acls.IsServerBannedFromRoom("1.2.3.4:2345", roomID) { - t.Fatal("Expected 1.2.3.4:2345 to be banned but wasn't") - } - if acls.IsServerBannedFromRoom("foo.com", roomID) { - t.Fatal("Expected foo.com to be allowed but wasn't") - } - if acls.IsServerBannedFromRoom("foo.com:3456", roomID) { - t.Fatal("Expected foo.com:3456 to be allowed but wasn't") - } - if !acls.IsServerBannedFromRoom("bar.com", roomID) { - t.Fatal("Expected bar.com to be allowed but wasn't") - } - if !acls.IsServerBannedFromRoom("baz.com", roomID) { - t.Fatal("Expected baz.com to be allowed but wasn't") - } - if !acls.IsServerBannedFromRoom("qux.com:4567", roomID) { - t.Fatal("Expected qux.com:4567 to be allowed but wasn't") - } -} diff --git a/currentstateserver/api/api.go b/currentstateserver/api/api.go index 5ae57bb9..a25ba48e 100644 --- a/currentstateserver/api/api.go +++ b/currentstateserver/api/api.go @@ -16,28 +16,17 @@ package api import ( "context" - "encoding/json" - "fmt" - "strings" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/gomatrixserverlib" ) type CurrentStateInternalAPI interface { - // QueryCurrentState retrieves the requested state events. If state events are not found, they will be missing from - // the response. - QueryCurrentState(ctx context.Context, req *QueryCurrentStateRequest, res *QueryCurrentStateResponse) error // QueryRoomsForUser retrieves a list of room IDs matching the given query. QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error // QueryBulkStateContent does a bulk query for state event content in the given rooms. QueryBulkStateContent(ctx context.Context, req *QueryBulkStateContentRequest, res *QueryBulkStateContentResponse) error // QuerySharedUsers returns a list of users who share at least 1 room in common with the given user. QuerySharedUsers(ctx context.Context, req *QuerySharedUsersRequest, res *QuerySharedUsersResponse) error - // QueryKnownUsers returns a list of users that we know about from our joined rooms. - QueryKnownUsers(ctx context.Context, req *QueryKnownUsersRequest, res *QueryKnownUsersResponse) error - // QueryServerBannedFromRoom returns whether a server is banned from a room by server ACLs. - QueryServerBannedFromRoom(ctx context.Context, req *QueryServerBannedFromRoomRequest, res *QueryServerBannedFromRoomResponse) error } type QuerySharedUsersRequest struct { @@ -83,58 +72,3 @@ type QueryBulkStateContentResponse struct { // map of room ID -> tuple -> content_value Rooms map[string]map[gomatrixserverlib.StateKeyTuple]string } - -type QueryCurrentStateRequest struct { - RoomID string - StateTuples []gomatrixserverlib.StateKeyTuple -} - -type QueryCurrentStateResponse struct { - StateEvents map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent -} - -type QueryKnownUsersRequest struct { - UserID string `json:"user_id"` - SearchString string `json:"search_string"` - Limit int `json:"limit"` -} - -type QueryKnownUsersResponse struct { - Users []authtypes.FullyQualifiedProfile `json:"profiles"` -} - -type QueryServerBannedFromRoomRequest struct { - ServerName gomatrixserverlib.ServerName `json:"server_name"` - RoomID string `json:"room_id"` -} - -type QueryServerBannedFromRoomResponse struct { - Banned bool `json:"banned"` -} - -// MarshalJSON stringifies the StateKeyTuple keys so they can be sent over the wire in HTTP API mode. -func (r *QueryCurrentStateResponse) MarshalJSON() ([]byte, error) { - se := make(map[string]*gomatrixserverlib.HeaderedEvent, len(r.StateEvents)) - for k, v := range r.StateEvents { - // use 0x1F (unit separator) as the delimiter between type/state key, - se[fmt.Sprintf("%s\x1F%s", k.EventType, k.StateKey)] = v - } - return json.Marshal(se) -} - -func (r *QueryCurrentStateResponse) UnmarshalJSON(data []byte) error { - res := make(map[string]*gomatrixserverlib.HeaderedEvent) - err := json.Unmarshal(data, &res) - if err != nil { - return err - } - r.StateEvents = make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent, len(res)) - for k, v := range res { - fields := strings.Split(k, "\x1F") - r.StateEvents[gomatrixserverlib.StateKeyTuple{ - EventType: fields[0], - StateKey: fields[1], - }] = v - } - return nil -} diff --git a/currentstateserver/api/wrapper.go b/currentstateserver/api/wrapper.go index 317fea43..20fae825 100644 --- a/currentstateserver/api/wrapper.go +++ b/currentstateserver/api/wrapper.go @@ -21,38 +21,6 @@ import ( "github.com/matrix-org/util" ) -// GetEvent returns the current state event in the room or nil. -func GetEvent(ctx context.Context, stateAPI CurrentStateInternalAPI, roomID string, tuple gomatrixserverlib.StateKeyTuple) *gomatrixserverlib.HeaderedEvent { - var res QueryCurrentStateResponse - err := stateAPI.QueryCurrentState(ctx, &QueryCurrentStateRequest{ - RoomID: roomID, - StateTuples: []gomatrixserverlib.StateKeyTuple{tuple}, - }, &res) - if err != nil { - util.GetLogger(ctx).WithError(err).Error("Failed to QueryCurrentState") - return nil - } - ev, ok := res.StateEvents[tuple] - if ok { - return ev - } - return nil -} - -// IsServerBannedFromRoom returns whether the server is banned from a room by server ACLs. -func IsServerBannedFromRoom(ctx context.Context, stateAPI CurrentStateInternalAPI, roomID string, serverName gomatrixserverlib.ServerName) bool { - req := &QueryServerBannedFromRoomRequest{ - ServerName: serverName, - RoomID: roomID, - } - res := &QueryServerBannedFromRoomResponse{} - if err := stateAPI.QueryServerBannedFromRoom(ctx, req, res); err != nil { - util.GetLogger(ctx).WithError(err).Error("Failed to QueryServerBannedFromRoom") - return true - } - return res.Banned -} - // PopulatePublicRooms extracts PublicRoom information for all the provided room IDs. The IDs are not checked to see if they are visible in the // published room directory. // due to lots of switches diff --git a/currentstateserver/consumers/roomserver.go b/currentstateserver/consumers/roomserver.go index cb054481..beb13305 100644 --- a/currentstateserver/consumers/roomserver.go +++ b/currentstateserver/consumers/roomserver.go @@ -19,7 +19,6 @@ import ( "encoding/json" "github.com/Shopify/sarama" - "github.com/matrix-org/dendrite/currentstateserver/acls" "github.com/matrix-org/dendrite/currentstateserver/storage" "github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/roomserver/api" @@ -31,10 +30,9 @@ import ( type OutputRoomEventConsumer struct { rsConsumer *internal.ContinualConsumer db storage.Database - acls *acls.ServerACLs } -func NewOutputRoomEventConsumer(topicName string, kafkaConsumer sarama.Consumer, store storage.Database, acls *acls.ServerACLs) *OutputRoomEventConsumer { +func NewOutputRoomEventConsumer(topicName string, kafkaConsumer sarama.Consumer, store storage.Database) *OutputRoomEventConsumer { consumer := &internal.ContinualConsumer{ ComponentName: "currentstateserver/roomserver", Topic: topicName, @@ -44,7 +42,6 @@ func NewOutputRoomEventConsumer(topicName string, kafkaConsumer sarama.Consumer, s := &OutputRoomEventConsumer{ rsConsumer: consumer, db: store, - acls: acls, } consumer.ProcessMessage = s.onMessage @@ -80,10 +77,6 @@ func (c *OutputRoomEventConsumer) onNewRoomEvent( ) error { ev := msg.Event - if ev.Type() == "m.room.server_acl" && ev.StateKeyEquals("") { - defer c.acls.OnServerACLUpdate(&ev.Event) - } - addsStateEvents := msg.AddsState() ev, err := c.updateStateEvent(ev) diff --git a/currentstateserver/currentstateserver.go b/currentstateserver/currentstateserver.go index 196434eb..f0dd4b88 100644 --- a/currentstateserver/currentstateserver.go +++ b/currentstateserver/currentstateserver.go @@ -17,7 +17,6 @@ package currentstateserver import ( "github.com/Shopify/sarama" "github.com/gorilla/mux" - "github.com/matrix-org/dendrite/currentstateserver/acls" "github.com/matrix-org/dendrite/currentstateserver/api" "github.com/matrix-org/dendrite/currentstateserver/consumers" "github.com/matrix-org/dendrite/currentstateserver/internal" @@ -40,15 +39,13 @@ func NewInternalAPI(cfg *config.CurrentStateServer, consumer sarama.Consumer) ap if err != nil { logrus.WithError(err).Panicf("failed to open database") } - serverACLs := acls.NewServerACLs(csDB) roomConsumer := consumers.NewOutputRoomEventConsumer( - cfg.Matrix.Kafka.TopicFor(config.TopicOutputRoomEvent), consumer, csDB, serverACLs, + cfg.Matrix.Kafka.TopicFor(config.TopicOutputRoomEvent), consumer, csDB, ) if err = roomConsumer.Start(); err != nil { logrus.WithError(err).Panicf("failed to start room server consumer") } return &internal.CurrentStateInternalAPI{ - DB: csDB, - ServerACLs: serverACLs, + DB: csDB, } } diff --git a/currentstateserver/currentstateserver_test.go b/currentstateserver/currentstateserver_test.go index b83103f1..4915b36c 100644 --- a/currentstateserver/currentstateserver_test.go +++ b/currentstateserver/currentstateserver_test.go @@ -15,7 +15,6 @@ package currentstateserver import ( - "bytes" "context" "crypto/ed25519" "encoding/json" @@ -139,81 +138,6 @@ func MustMakeInternalAPI(t *testing.T) (api.CurrentStateInternalAPI, storage.Dat } } -func TestQueryCurrentState(t *testing.T) { - currStateAPI, db, producer, cancel := MustMakeInternalAPI(t) - defer cancel() - plTuple := gomatrixserverlib.StateKeyTuple{ - EventType: "m.room.power_levels", - StateKey: "", - } - plEvent := testEvents[4] - offset := MustWriteOutputEvent(t, producer, &roomserverAPI.OutputNewRoomEvent{ - Event: plEvent, - AddsStateEventIDs: []string{plEvent.EventID()}, - }) - waitForOffsetProcessed(t, db, offset) - - testCases := []struct { - req api.QueryCurrentStateRequest - wantRes api.QueryCurrentStateResponse - wantErr error - }{ - { - req: api.QueryCurrentStateRequest{ - RoomID: plEvent.RoomID(), - StateTuples: []gomatrixserverlib.StateKeyTuple{ - plTuple, - }, - }, - wantRes: api.QueryCurrentStateResponse{ - StateEvents: map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent{ - plTuple: &plEvent, - }, - }, - }, - } - - runCases := func(testAPI api.CurrentStateInternalAPI) { - for _, tc := range testCases { - var gotRes api.QueryCurrentStateResponse - gotErr := testAPI.QueryCurrentState(context.TODO(), &tc.req, &gotRes) - if tc.wantErr == nil && gotErr != nil || tc.wantErr != nil && gotErr == nil { - t.Errorf("QueryCurrentState error, got %s want %s", gotErr, tc.wantErr) - continue - } - for tuple, wantEvent := range tc.wantRes.StateEvents { - gotEvent, ok := gotRes.StateEvents[tuple] - if !ok { - t.Errorf("QueryCurrentState want tuple %+v but it is missing from the response", tuple) - continue - } - gotCanon, err := gomatrixserverlib.CanonicalJSON(gotEvent.JSON()) - if err != nil { - t.Errorf("CanonicalJSON failed: %w", err) - continue - } - if !bytes.Equal(gotCanon, wantEvent.JSON()) { - t.Errorf("QueryCurrentState tuple %+v got event JSON %s want %s", tuple, string(gotCanon), string(wantEvent.JSON())) - } - } - } - } - t.Run("HTTP API", func(t *testing.T) { - router := mux.NewRouter().PathPrefix(httputil.InternalPathPrefix).Subrouter() - AddInternalRoutes(router, currStateAPI) - apiURL, cancel := test.ListenAndServe(t, router, false) - defer cancel() - httpAPI, err := inthttp.NewCurrentStateAPIClient(apiURL, &http.Client{}) - if err != nil { - t.Fatalf("failed to create HTTP client") - } - runCases(httpAPI) - }) - t.Run("Monolith", func(t *testing.T) { - runCases(currStateAPI) - }) -} - func mustMakeMembershipEvent(t *testing.T, roomID, userID, membership string) *roomserverAPI.OutputNewRoomEvent { eb := gomatrixserverlib.EventBuilder{ RoomID: roomID, diff --git a/currentstateserver/internal/api.go b/currentstateserver/internal/api.go index 0a7e025e..2c065c8e 100644 --- a/currentstateserver/internal/api.go +++ b/currentstateserver/internal/api.go @@ -16,32 +16,14 @@ package internal import ( "context" - "errors" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" - "github.com/matrix-org/dendrite/currentstateserver/acls" "github.com/matrix-org/dendrite/currentstateserver/api" "github.com/matrix-org/dendrite/currentstateserver/storage" "github.com/matrix-org/gomatrixserverlib" ) type CurrentStateInternalAPI struct { - DB storage.Database - ServerACLs *acls.ServerACLs -} - -func (a *CurrentStateInternalAPI) QueryCurrentState(ctx context.Context, req *api.QueryCurrentStateRequest, res *api.QueryCurrentStateResponse) error { - res.StateEvents = make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent) - for _, tuple := range req.StateTuples { - ev, err := a.DB.GetStateEvent(ctx, req.RoomID, tuple.EventType, tuple.StateKey) - if err != nil { - return err - } - if ev != nil { - res.StateEvents[tuple] = ev - } - } - return nil + DB storage.Database } func (a *CurrentStateInternalAPI) QueryRoomsForUser(ctx context.Context, req *api.QueryRoomsForUserRequest, res *api.QueryRoomsForUserResponse) error { @@ -53,19 +35,6 @@ func (a *CurrentStateInternalAPI) QueryRoomsForUser(ctx context.Context, req *ap return nil } -func (a *CurrentStateInternalAPI) QueryKnownUsers(ctx context.Context, req *api.QueryKnownUsersRequest, res *api.QueryKnownUsersResponse) error { - users, err := a.DB.GetKnownUsers(ctx, req.UserID, req.SearchString, req.Limit) - if err != nil { - return err - } - for _, user := range users { - res.Users = append(res.Users, authtypes.FullyQualifiedProfile{ - UserID: user, - }) - } - return nil -} - func (a *CurrentStateInternalAPI) QueryBulkStateContent(ctx context.Context, req *api.QueryBulkStateContentRequest, res *api.QueryBulkStateContentResponse) error { events, err := a.DB.GetBulkStateContent(ctx, req.RoomIDs, req.StateTuples, req.AllowWildcards) if err != nil { @@ -115,11 +84,3 @@ func (a *CurrentStateInternalAPI) QuerySharedUsers(ctx context.Context, req *api res.UserIDsToCount = users return nil } - -func (a *CurrentStateInternalAPI) QueryServerBannedFromRoom(ctx context.Context, req *api.QueryServerBannedFromRoomRequest, res *api.QueryServerBannedFromRoomResponse) error { - if a.ServerACLs == nil { - return errors.New("no server ACL tracking") - } - res.Banned = a.ServerACLs.IsServerBannedFromRoom(req.ServerName, req.RoomID) - return nil -} diff --git a/currentstateserver/inthttp/client.go b/currentstateserver/inthttp/client.go index 6d54f548..91a3359f 100644 --- a/currentstateserver/inthttp/client.go +++ b/currentstateserver/inthttp/client.go @@ -26,12 +26,9 @@ import ( // HTTP paths for the internal HTTP APIs const ( - QueryCurrentStatePath = "/currentstateserver/queryCurrentState" - QueryRoomsForUserPath = "/currentstateserver/queryRoomsForUser" - QueryBulkStateContentPath = "/currentstateserver/queryBulkStateContent" - QuerySharedUsersPath = "/currentstateserver/querySharedUsers" - QueryKnownUsersPath = "/currentstateserver/queryKnownUsers" - QueryServerBannedFromRoomPath = "/currentstateserver/queryServerBannedFromRoom" + QueryRoomsForUserPath = "/currentstateserver/queryRoomsForUser" + QueryBulkStateContentPath = "/currentstateserver/queryBulkStateContent" + QuerySharedUsersPath = "/currentstateserver/querySharedUsers" ) // NewCurrentStateAPIClient creates a CurrentStateInternalAPI implemented by talking to a HTTP POST API. @@ -54,18 +51,6 @@ type httpCurrentStateInternalAPI struct { httpClient *http.Client } -func (h *httpCurrentStateInternalAPI) QueryCurrentState( - ctx context.Context, - request *api.QueryCurrentStateRequest, - response *api.QueryCurrentStateResponse, -) error { - span, ctx := opentracing.StartSpanFromContext(ctx, "QueryCurrentState") - defer span.Finish() - - apiURL := h.apiURL + QueryCurrentStatePath - return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response) -} - func (h *httpCurrentStateInternalAPI) QueryRoomsForUser( ctx context.Context, request *api.QueryRoomsForUserRequest, @@ -99,23 +84,3 @@ func (h *httpCurrentStateInternalAPI) QuerySharedUsers( apiURL := h.apiURL + QuerySharedUsersPath return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res) } - -func (h *httpCurrentStateInternalAPI) QueryKnownUsers( - ctx context.Context, req *api.QueryKnownUsersRequest, res *api.QueryKnownUsersResponse, -) error { - span, ctx := opentracing.StartSpanFromContext(ctx, "QueryKnownUsers") - defer span.Finish() - - apiURL := h.apiURL + QueryKnownUsersPath - return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res) -} - -func (h *httpCurrentStateInternalAPI) QueryServerBannedFromRoom( - ctx context.Context, req *api.QueryServerBannedFromRoomRequest, res *api.QueryServerBannedFromRoomResponse, -) error { - span, ctx := opentracing.StartSpanFromContext(ctx, "QueryServerBannedFromRoom") - defer span.Finish() - - apiURL := h.apiURL + QueryServerBannedFromRoomPath - return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res) -} diff --git a/currentstateserver/inthttp/server.go b/currentstateserver/inthttp/server.go index 1cf8cd2a..46e78f7f 100644 --- a/currentstateserver/inthttp/server.go +++ b/currentstateserver/inthttp/server.go @@ -25,19 +25,6 @@ import ( ) func AddRoutes(internalAPIMux *mux.Router, intAPI api.CurrentStateInternalAPI) { - internalAPIMux.Handle(QueryCurrentStatePath, - httputil.MakeInternalAPI("queryCurrentState", func(req *http.Request) util.JSONResponse { - request := api.QueryCurrentStateRequest{} - response := api.QueryCurrentStateResponse{} - if err := json.NewDecoder(req.Body).Decode(&request); err != nil { - return util.MessageResponse(http.StatusBadRequest, err.Error()) - } - if err := intAPI.QueryCurrentState(req.Context(), &request, &response); err != nil { - return util.ErrorResponse(err) - } - return util.JSONResponse{Code: http.StatusOK, JSON: &response} - }), - ) internalAPIMux.Handle(QueryRoomsForUserPath, httputil.MakeInternalAPI("queryRoomsForUser", func(req *http.Request) util.JSONResponse { request := api.QueryRoomsForUserRequest{} @@ -77,30 +64,4 @@ func AddRoutes(internalAPIMux *mux.Router, intAPI api.CurrentStateInternalAPI) { return util.JSONResponse{Code: http.StatusOK, JSON: &response} }), ) - internalAPIMux.Handle(QuerySharedUsersPath, - httputil.MakeInternalAPI("queryKnownUsers", func(req *http.Request) util.JSONResponse { - request := api.QueryKnownUsersRequest{} - response := api.QueryKnownUsersResponse{} - if err := json.NewDecoder(req.Body).Decode(&request); err != nil { - return util.MessageResponse(http.StatusBadRequest, err.Error()) - } - if err := intAPI.QueryKnownUsers(req.Context(), &request, &response); err != nil { - return util.ErrorResponse(err) - } - return util.JSONResponse{Code: http.StatusOK, JSON: &response} - }), - ) - internalAPIMux.Handle(QueryServerBannedFromRoomPath, - httputil.MakeInternalAPI("queryServerBannedFromRoom", func(req *http.Request) util.JSONResponse { - request := api.QueryServerBannedFromRoomRequest{} - response := api.QueryServerBannedFromRoomResponse{} - if err := json.NewDecoder(req.Body).Decode(&request); err != nil { - return util.MessageResponse(http.StatusBadRequest, err.Error()) - } - if err := intAPI.QueryServerBannedFromRoom(req.Context(), &request, &response); err != nil { - return util.ErrorResponse(err) - } - return util.JSONResponse{Code: http.StatusOK, JSON: &response} - }), - ) } diff --git a/federationapi/routing/routing.go b/federationapi/routing/routing.go index 5ea190a1..4c43be27 100644 --- a/federationapi/routing/routing.go +++ b/federationapi/routing/routing.go @@ -76,7 +76,7 @@ func Setup( func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { return Send( httpReq, request, gomatrixserverlib.TransactionID(vars["txnID"]), - cfg, rsAPI, eduAPI, keyAPI, stateAPI, keys, federation, + cfg, rsAPI, eduAPI, keyAPI, keys, federation, ) }, )).Methods(http.MethodPut, http.MethodOptions) @@ -84,7 +84,7 @@ func Setup( v1fedmux.Handle("/invite/{roomID}/{eventID}", httputil.MakeFedAPI( "federation_invite", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -100,7 +100,7 @@ func Setup( v2fedmux.Handle("/invite/{roomID}/{eventID}", httputil.MakeFedAPI( "federation_invite", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -140,7 +140,7 @@ func Setup( v1fedmux.Handle("/state/{roomID}", httputil.MakeFedAPI( "federation_get_state", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -155,7 +155,7 @@ func Setup( v1fedmux.Handle("/state_ids/{roomID}", httputil.MakeFedAPI( "federation_get_state_ids", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -170,7 +170,7 @@ func Setup( v1fedmux.Handle("/event_auth/{roomID}/{eventID}", httputil.MakeFedAPI( "federation_get_event_auth", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -212,7 +212,7 @@ func Setup( v1fedmux.Handle("/make_join/{roomID}/{eventID}", httputil.MakeFedAPI( "federation_make_join", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -243,7 +243,7 @@ func Setup( v1fedmux.Handle("/send_join/{roomID}/{eventID}", httputil.MakeFedAPI( "federation_send_join", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -275,7 +275,7 @@ func Setup( v2fedmux.Handle("/send_join/{roomID}/{eventID}", httputil.MakeFedAPI( "federation_send_join", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -292,7 +292,7 @@ func Setup( v1fedmux.Handle("/make_leave/{roomID}/{eventID}", httputil.MakeFedAPI( "federation_make_leave", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -309,7 +309,7 @@ func Setup( v1fedmux.Handle("/send_leave/{roomID}/{eventID}", httputil.MakeFedAPI( "federation_send_leave", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -341,7 +341,7 @@ func Setup( v2fedmux.Handle("/send_leave/{roomID}/{eventID}", httputil.MakeFedAPI( "federation_send_leave", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -365,7 +365,7 @@ func Setup( v1fedmux.Handle("/get_missing_events/{roomID}", httputil.MakeFedAPI( "federation_get_missing_events", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), @@ -378,7 +378,7 @@ func Setup( v1fedmux.Handle("/backfill/{roomID}", httputil.MakeFedAPI( "federation_backfill", cfg.Matrix.ServerName, keys, wakeup, func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { - if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) { + if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) { return util.JSONResponse{ Code: http.StatusForbidden, JSON: jsonerror.Forbidden("Forbidden by server ACLs"), diff --git a/federationapi/routing/send.go b/federationapi/routing/send.go index 570062ad..beb7d461 100644 --- a/federationapi/routing/send.go +++ b/federationapi/routing/send.go @@ -21,7 +21,6 @@ import ( "net/http" "github.com/matrix-org/dendrite/clientapi/jsonerror" - currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api" eduserverAPI "github.com/matrix-org/dendrite/eduserver/api" "github.com/matrix-org/dendrite/internal/config" keyapi "github.com/matrix-org/dendrite/keyserver/api" @@ -40,7 +39,6 @@ func Send( rsAPI api.RoomserverInternalAPI, eduAPI eduserverAPI.EDUServerInputAPI, keyAPI keyapi.KeyInternalAPI, - stateAPI currentstateAPI.CurrentStateInternalAPI, keys gomatrixserverlib.JSONVerifier, federation *gomatrixserverlib.FederationClient, ) util.JSONResponse { @@ -48,7 +46,6 @@ func Send( context: httpReq.Context(), rsAPI: rsAPI, eduAPI: eduAPI, - stateAPI: stateAPI, keys: keys, federation: federation, haveEvents: make(map[string]*gomatrixserverlib.HeaderedEvent), @@ -107,7 +104,6 @@ type txnReq struct { rsAPI api.RoomserverInternalAPI eduAPI eduserverAPI.EDUServerInputAPI keyAPI keyapi.KeyInternalAPI - stateAPI currentstateAPI.CurrentStateInternalAPI keys gomatrixserverlib.JSONVerifier federation txnFederationClient // local cache of events for auth checks, etc - this may include events @@ -168,7 +164,7 @@ func (t *txnReq) processTransaction() (*gomatrixserverlib.RespSend, *util.JSONRe util.GetLogger(t.context).WithError(err).Warnf("Transaction: Failed to parse event JSON of event %s", string(pdu)) continue } - if currentstateAPI.IsServerBannedFromRoom(t.context, t.stateAPI, event.RoomID(), t.Origin) { + if api.IsServerBannedFromRoom(t.context, t.rsAPI, event.RoomID(), t.Origin) { results[event.EventID()] = gomatrixserverlib.PDUResult{ Error: "Forbidden by server ACLs", } diff --git a/federationapi/routing/send_test.go b/federationapi/routing/send_test.go index 6dc8621b..f16fde0e 100644 --- a/federationapi/routing/send_test.go +++ b/federationapi/routing/send_test.go @@ -8,7 +8,6 @@ import ( "testing" "time" - currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api" eduAPI "github.com/matrix-org/dendrite/eduserver/api" fsAPI "github.com/matrix-org/dendrite/federationsender/api" "github.com/matrix-org/dendrite/internal/test" @@ -320,33 +319,6 @@ func (t *testRoomserverAPI) QueryServerBannedFromRoom(ctx context.Context, req * return nil } -type testStateAPI struct { -} - -func (t *testStateAPI) QueryCurrentState(ctx context.Context, req *currentstateAPI.QueryCurrentStateRequest, res *currentstateAPI.QueryCurrentStateResponse) error { - return nil -} - -func (t *testStateAPI) QueryRoomsForUser(ctx context.Context, req *currentstateAPI.QueryRoomsForUserRequest, res *currentstateAPI.QueryRoomsForUserResponse) error { - return fmt.Errorf("not implemented") -} - -func (t *testStateAPI) QueryBulkStateContent(ctx context.Context, req *currentstateAPI.QueryBulkStateContentRequest, res *currentstateAPI.QueryBulkStateContentResponse) error { - return fmt.Errorf("not implemented") -} - -func (t *testStateAPI) QuerySharedUsers(ctx context.Context, req *currentstateAPI.QuerySharedUsersRequest, res *currentstateAPI.QuerySharedUsersResponse) error { - return fmt.Errorf("not implemented") -} - -func (t *testStateAPI) QueryKnownUsers(ctx context.Context, req *currentstateAPI.QueryKnownUsersRequest, res *currentstateAPI.QueryKnownUsersResponse) error { - return fmt.Errorf("not implemented") -} - -func (t *testStateAPI) QueryServerBannedFromRoom(ctx context.Context, req *currentstateAPI.QueryServerBannedFromRoomRequest, res *currentstateAPI.QueryServerBannedFromRoomResponse) error { - return nil -} - type txnFedClient struct { state map[string]gomatrixserverlib.RespState // event_id to response stateIDs map[string]gomatrixserverlib.RespStateIDs // event_id to response @@ -391,12 +363,11 @@ func (c *txnFedClient) LookupMissingEvents(ctx context.Context, s gomatrixserver return c.getMissingEvents(missing) } -func mustCreateTransaction(rsAPI api.RoomserverInternalAPI, stateAPI currentstateAPI.CurrentStateInternalAPI, fedClient txnFederationClient, pdus []json.RawMessage) *txnReq { +func mustCreateTransaction(rsAPI api.RoomserverInternalAPI, fedClient txnFederationClient, pdus []json.RawMessage) *txnReq { t := &txnReq{ context: context.Background(), rsAPI: rsAPI, eduAPI: &testEDUProducer{}, - stateAPI: stateAPI, keys: &test.NopJSONVerifier{}, federation: fedClient, haveEvents: make(map[string]*gomatrixserverlib.HeaderedEvent), @@ -476,11 +447,10 @@ func TestBasicTransaction(t *testing.T) { } }, } - stateAPI := &testStateAPI{} pdus := []json.RawMessage{ testData[len(testData)-1], // a message event } - txn := mustCreateTransaction(rsAPI, stateAPI, &txnFedClient{}, pdus) + txn := mustCreateTransaction(rsAPI, &txnFedClient{}, pdus) mustProcessTransaction(t, txn, nil) assertInputRoomEvents(t, rsAPI.inputRoomEvents, []gomatrixserverlib.HeaderedEvent{testEvents[len(testEvents)-1]}) } @@ -499,11 +469,10 @@ func TestTransactionFailAuthChecks(t *testing.T) { } }, } - stateAPI := &testStateAPI{} pdus := []json.RawMessage{ testData[len(testData)-1], // a message event } - txn := mustCreateTransaction(rsAPI, stateAPI, &txnFedClient{}, pdus) + txn := mustCreateTransaction(rsAPI, &txnFedClient{}, pdus) mustProcessTransaction(t, txn, []string{ // expect the event to have an error testEvents[len(testEvents)-1].EventID(), @@ -558,8 +527,6 @@ func TestTransactionFetchMissingPrevEvents(t *testing.T) { }, } - stateAPI := &testStateAPI{} - cli := &txnFedClient{ getMissingEvents: func(missing gomatrixserverlib.MissingEvents) (res gomatrixserverlib.RespMissingEvents, err error) { if !reflect.DeepEqual(missing.EarliestEvents, []string{haveEvent.EventID()}) { @@ -579,7 +546,7 @@ func TestTransactionFetchMissingPrevEvents(t *testing.T) { pdus := []json.RawMessage{ inputEvent.JSON(), } - txn := mustCreateTransaction(rsAPI, stateAPI, cli, pdus) + txn := mustCreateTransaction(rsAPI, cli, pdus) mustProcessTransaction(t, txn, nil) assertInputRoomEvents(t, rsAPI.inputRoomEvents, []gomatrixserverlib.HeaderedEvent{prevEvent, inputEvent}) } @@ -729,12 +696,10 @@ func TestTransactionFetchMissingStateByStateIDs(t *testing.T) { }, } - stateAPI := &testStateAPI{} - pdus := []json.RawMessage{ eventD.JSON(), } - txn := mustCreateTransaction(rsAPI, stateAPI, cli, pdus) + txn := mustCreateTransaction(rsAPI, cli, pdus) mustProcessTransaction(t, txn, nil) assertInputRoomEvents(t, rsAPI.inputRoomEvents, []gomatrixserverlib.HeaderedEvent{eventB, eventC, eventD}) } diff --git a/federationsender/federationsender.go b/federationsender/federationsender.go index 5794d40a..0e2213da 100644 --- a/federationsender/federationsender.go +++ b/federationsender/federationsender.go @@ -59,7 +59,7 @@ func NewInternalAPI( queues := queue.NewOutgoingQueues( federationSenderDB, cfg.Matrix.ServerName, federation, - rsAPI, stateAPI, stats, + rsAPI, stats, &queue.SigningInfo{ KeyID: cfg.Matrix.KeyID, PrivateKey: cfg.Matrix.PrivateKey, diff --git a/federationsender/queue/queue.go b/federationsender/queue/queue.go index b13df612..04cb57e7 100644 --- a/federationsender/queue/queue.go +++ b/federationsender/queue/queue.go @@ -22,7 +22,6 @@ import ( "sync" "time" - stateapi "github.com/matrix-org/dendrite/currentstateserver/api" "github.com/matrix-org/dendrite/federationsender/statistics" "github.com/matrix-org/dendrite/federationsender/storage" "github.com/matrix-org/dendrite/roomserver/api" @@ -36,7 +35,6 @@ import ( type OutgoingQueues struct { db storage.Database rsAPI api.RoomserverInternalAPI - stateAPI stateapi.CurrentStateInternalAPI origin gomatrixserverlib.ServerName client *gomatrixserverlib.FederationClient statistics *statistics.Statistics @@ -51,14 +49,12 @@ func NewOutgoingQueues( origin gomatrixserverlib.ServerName, client *gomatrixserverlib.FederationClient, rsAPI api.RoomserverInternalAPI, - stateAPI stateapi.CurrentStateInternalAPI, statistics *statistics.Statistics, signing *SigningInfo, ) *OutgoingQueues { queues := &OutgoingQueues{ db: db, rsAPI: rsAPI, - stateAPI: stateAPI, origin: origin, client: client, statistics: statistics, @@ -144,9 +140,9 @@ func (oqs *OutgoingQueues) SendEvent( // Check if any of the destinations are prohibited by server ACLs. for destination := range destmap { - if stateapi.IsServerBannedFromRoom( + if api.IsServerBannedFromRoom( context.TODO(), - oqs.stateAPI, + oqs.rsAPI, ev.RoomID(), destination, ) { @@ -208,9 +204,9 @@ func (oqs *OutgoingQueues) SendEDU( // ACLs. if result := gjson.GetBytes(e.Content, "room_id"); result.Exists() { for destination := range destmap { - if stateapi.IsServerBannedFromRoom( + if api.IsServerBannedFromRoom( context.TODO(), - oqs.stateAPI, + oqs.rsAPI, result.Str, destination, ) { diff --git a/go.mod b/go.mod index 3a9fef9f..4ce7318b 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4 github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3 github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd - github.com/matrix-org/gomatrixserverlib v0.0.0-20200902135805-f7a5b5e89750 + github.com/matrix-org/gomatrixserverlib v0.0.0-20200903230638-083d02f49d4d github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91 github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 github.com/mattn/go-sqlite3 v1.14.2 diff --git a/go.sum b/go.sum index 33b4f591..9e559e9b 100644 --- a/go.sum +++ b/go.sum @@ -567,8 +567,8 @@ github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bh github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0= github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd h1:xVrqJK3xHREMNjwjljkAUaadalWc0rRbmVuQatzmgwg= github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s= -github.com/matrix-org/gomatrixserverlib v0.0.0-20200902135805-f7a5b5e89750 h1:k5vsLfpylXHOXgN51N0QNbak9i+4bT33Puk/ZJgcdDw= -github.com/matrix-org/gomatrixserverlib v0.0.0-20200902135805-f7a5b5e89750/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU= +github.com/matrix-org/gomatrixserverlib v0.0.0-20200903230638-083d02f49d4d h1:nA6S6qtLsUgwfJusQJLeNjvTLjZ7F9w+eWV9RzRZrzk= +github.com/matrix-org/gomatrixserverlib v0.0.0-20200903230638-083d02f49d4d/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU= github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91 h1:HJ6U3S3ljJqNffYMcIeAncp5qT/i+ZMiJ2JC2F0aXP4= github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91/go.mod h1:sjyPyRxKM5uw1nD2cJ6O2OxI6GOqyVBfNXqKjBZTBZE= github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo= diff --git a/roomserver/internal/api.go b/roomserver/internal/api.go index b5ef5935..8dc1a170 100644 --- a/roomserver/internal/api.go +++ b/roomserver/internal/api.go @@ -41,6 +41,7 @@ func NewRoomserverAPI( outputRoomEventTopic string, caches caching.RoomServerCaches, keyRing gomatrixserverlib.JSONVerifier, ) *RoomserverInternalAPI { + serverACLs := acls.NewServerACLs(roomserverDB) a := &RoomserverInternalAPI{ DB: roomserverDB, Cfg: cfg, @@ -50,13 +51,14 @@ func NewRoomserverAPI( Queryer: &query.Queryer{ DB: roomserverDB, Cache: caches, - ServerACLs: acls.NewServerACLs(roomserverDB), + ServerACLs: serverACLs, }, Inputer: &input.Inputer{ DB: roomserverDB, OutputRoomEventTopic: outputRoomEventTopic, Producer: producer, ServerName: cfg.Matrix.ServerName, + ACLs: serverACLs, }, // perform-er structs get initialised when we have a federation sender to use } diff --git a/roomserver/internal/input/input.go b/roomserver/internal/input/input.go index 7a44ff42..51d20ad3 100644 --- a/roomserver/internal/input/input.go +++ b/roomserver/internal/input/input.go @@ -22,6 +22,7 @@ import ( "time" "github.com/Shopify/sarama" + "github.com/matrix-org/dendrite/roomserver/acls" "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/storage" "github.com/matrix-org/gomatrixserverlib" @@ -33,6 +34,7 @@ type Inputer struct { DB storage.Database Producer sarama.SyncProducer ServerName gomatrixserverlib.ServerName + ACLs *acls.ServerACLs OutputRoomEventTopic string workers sync.Map // room ID -> *inputWorker @@ -88,6 +90,10 @@ func (r *Inputer) WriteOutputEvents(roomID string, updates []api.OutputEvent) er "send_as_server": updates[i].NewRoomEvent.SendAsServer, "sender": updates[i].NewRoomEvent.Event.Sender(), }) + if updates[i].NewRoomEvent.Event.Type() == "m.room.server_acl" && updates[i].NewRoomEvent.Event.StateKeyEquals("") { + ev := updates[i].NewRoomEvent.Event.Unwrap() + defer r.ACLs.OnServerACLUpdate(&ev) + } } logger.Infof("Producing to topic '%s'", r.OutputRoomEventTopic) messages[i] = &sarama.ProducerMessage{ diff --git a/roomserver/inthttp/server.go b/roomserver/inthttp/server.go index ebfb296d..97f2a360 100644 --- a/roomserver/inthttp/server.go +++ b/roomserver/inthttp/server.go @@ -364,7 +364,7 @@ func AddRoutes(r api.RoomserverInternalAPI, internalAPIMux *mux.Router) { return util.JSONResponse{Code: http.StatusOK, JSON: &response} }), ) - internalAPIMux.Handle(RoomserverQuerySharedUsersPath, + internalAPIMux.Handle(RoomserverQueryKnownUsersPath, httputil.MakeInternalAPI("queryKnownUsers", func(req *http.Request) util.JSONResponse { request := api.QueryKnownUsersRequest{} response := api.QueryKnownUsersResponse{} diff --git a/roomserver/storage/postgres/event_types_table.go b/roomserver/storage/postgres/event_types_table.go index 037d98fe..02d6ad07 100644 --- a/roomserver/storage/postgres/event_types_table.go +++ b/roomserver/storage/postgres/event_types_table.go @@ -21,6 +21,7 @@ import ( "github.com/lib/pq" "github.com/matrix-org/dendrite/internal" + "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/roomserver/storage/shared" "github.com/matrix-org/dendrite/roomserver/storage/tables" "github.com/matrix-org/dendrite/roomserver/types" @@ -117,7 +118,8 @@ func (s *eventTypeStatements) InsertEventTypeNID( ctx context.Context, txn *sql.Tx, eventType string, ) (types.EventTypeNID, error) { var eventTypeNID int64 - err := txn.Stmt(s.insertEventTypeNIDStmt).QueryRowContext(ctx, eventType).Scan(&eventTypeNID) + stmt := sqlutil.TxStmt(txn, s.insertEventTypeNIDStmt) + err := stmt.QueryRowContext(ctx, eventType).Scan(&eventTypeNID) return types.EventTypeNID(eventTypeNID), err } @@ -125,7 +127,8 @@ func (s *eventTypeStatements) SelectEventTypeNID( ctx context.Context, txn *sql.Tx, eventType string, ) (types.EventTypeNID, error) { var eventTypeNID int64 - err := txn.Stmt(s.selectEventTypeNIDStmt).QueryRowContext(ctx, eventType).Scan(&eventTypeNID) + stmt := sqlutil.TxStmt(txn, s.selectEventTypeNIDStmt) + err := stmt.QueryRowContext(ctx, eventType).Scan(&eventTypeNID) return types.EventTypeNID(eventTypeNID), err } diff --git a/syncapi/internal/keychange_test.go b/syncapi/internal/keychange_test.go index baf60ef0..03ec4e96 100644 --- a/syncapi/internal/keychange_test.go +++ b/syncapi/internal/keychange_test.go @@ -53,14 +53,6 @@ type mockCurrentStateAPI struct { roomIDToJoinedMembers map[string][]string } -func (s *mockCurrentStateAPI) QueryCurrentState(ctx context.Context, req *api.QueryCurrentStateRequest, res *api.QueryCurrentStateResponse) error { - return nil -} - -func (s *mockCurrentStateAPI) QueryKnownUsers(ctx context.Context, req *api.QueryKnownUsersRequest, res *api.QueryKnownUsersResponse) error { - return nil -} - // QueryRoomsForUser retrieves a list of room IDs matching the given query. func (s *mockCurrentStateAPI) QueryRoomsForUser(ctx context.Context, req *api.QueryRoomsForUserRequest, res *api.QueryRoomsForUserResponse) error { return nil @@ -114,10 +106,6 @@ func (s *mockCurrentStateAPI) QuerySharedUsers(ctx context.Context, req *api.Que return nil } -func (t *mockCurrentStateAPI) QueryServerBannedFromRoom(ctx context.Context, req *api.QueryServerBannedFromRoomRequest, res *api.QueryServerBannedFromRoomResponse) error { - return nil -} - type wantCatchup struct { hasNew bool changed []string diff --git a/syncapi/storage/shared/syncserver.go b/syncapi/storage/shared/syncserver.go index f11b00b3..79d140cf 100644 --- a/syncapi/storage/shared/syncserver.go +++ b/syncapi/storage/shared/syncserver.go @@ -698,9 +698,9 @@ func (d *Database) getResponseWithPDUsForCompleteSync( return //res, toPos, joinedRoomIDs, err } -func (d* Database) getJoinResponseForCompleteSync( +func (d *Database) getJoinResponseForCompleteSync( ctx context.Context, txn *sql.Tx, - roomID string, + roomID string, r types.Range, stateFilter *gomatrixserverlib.StateFilter, numRecentEventsPerRoom int, @@ -798,8 +798,10 @@ func (d *Database) addInvitesToResponse( res.Rooms.Invite[roomID] = *ir } for roomID := range retiredInvites { - lr := types.NewLeaveResponse() - res.Rooms.Leave[roomID] = *lr + if _, ok := res.Rooms.Join[roomID]; !ok { + lr := types.NewLeaveResponse() + res.Rooms.Leave[roomID] = *lr + } } return nil } @@ -1112,37 +1114,20 @@ func (d *Database) getStateDeltas( // requests with full_state=true. // Fetches full state for all joined rooms and uses selectStateInRange to get // updates for other rooms. +// nolint:gocyclo func (d *Database) getStateDeltasForFullStateSync( ctx context.Context, device *userapi.Device, txn *sql.Tx, r types.Range, userID string, stateFilter *gomatrixserverlib.StateFilter, ) ([]stateDelta, []string, error) { - joinedRoomIDs, err := d.CurrentRoomState.SelectRoomIDsWithMembership(ctx, txn, userID, gomatrixserverlib.Join) - if err != nil { - return nil, nil, err - } + // Use a reasonable initial capacity + deltas := make(map[string]stateDelta) peeks, err := d.Peeks.SelectPeeks(ctx, txn, userID, device.ID) if err != nil { return nil, nil, err } - // Use a reasonable initial capacity - deltas := make([]stateDelta, 0, len(joinedRoomIDs) + len(peeks)) - - // Add full states for all joined rooms - for _, joinedRoomID := range joinedRoomIDs { - s, stateErr := d.currentStateStreamEventsForRoom(ctx, txn, joinedRoomID, stateFilter) - if stateErr != nil { - return nil, nil, stateErr - } - deltas = append(deltas, stateDelta{ - membership: gomatrixserverlib.Join, - stateEvents: d.StreamEventsToEvents(device, s), - roomID: joinedRoomID, - }) - } - // Add full states for all peeking rooms newPeeks := false for _, peek := range peeks { @@ -1153,16 +1138,16 @@ func (d *Database) getStateDeltasForFullStateSync( if stateErr != nil { return nil, nil, stateErr } - deltas = append(deltas, stateDelta{ + deltas[peek.RoomID] = stateDelta{ membership: gomatrixserverlib.Peek, stateEvents: d.StreamEventsToEvents(device, s), roomID: peek.RoomID, - }) + } } if newPeeks { err = d.Writer.Do(d.DB, txn, func(txn *sql.Tx) error { - return d.Peeks.MarkPeeksAsOld(ctx, txn, userID, device.ID) + return d.Peeks.MarkPeeksAsOld(ctx, txn, userID, device.ID) }) if err != nil { return nil, nil, err @@ -1183,12 +1168,12 @@ func (d *Database) getStateDeltasForFullStateSync( for _, ev := range stateStreamEvents { if membership := getMembershipFromEvent(&ev.Event, userID); membership != "" { if membership != gomatrixserverlib.Join { // We've already added full state for all joined rooms above. - deltas = append(deltas, stateDelta{ + deltas[roomID] = stateDelta{ membership: membership, membershipPos: ev.StreamPosition, stateEvents: d.StreamEventsToEvents(device, stateStreamEvents), roomID: roomID, - }) + } } break @@ -1196,7 +1181,33 @@ func (d *Database) getStateDeltasForFullStateSync( } } - return deltas, joinedRoomIDs, nil + joinedRoomIDs, err := d.CurrentRoomState.SelectRoomIDsWithMembership(ctx, txn, userID, gomatrixserverlib.Join) + if err != nil { + return nil, nil, err + } + + // Add full states for all joined rooms + for _, joinedRoomID := range joinedRoomIDs { + s, stateErr := d.currentStateStreamEventsForRoom(ctx, txn, joinedRoomID, stateFilter) + if stateErr != nil { + return nil, nil, stateErr + } + deltas[joinedRoomID] = stateDelta{ + membership: gomatrixserverlib.Join, + stateEvents: d.StreamEventsToEvents(device, s), + roomID: joinedRoomID, + } + } + + // Create a response array. + result := make([]stateDelta, len(deltas)) + i := 0 + for _, delta := range deltas { + result[i] = delta + i++ + } + + return result, joinedRoomIDs, nil } func (d *Database) currentStateStreamEventsForRoom(