diff --git a/clientapi/clientapi.go b/clientapi/clientapi.go index bb44e016a..e608b69f3 100644 --- a/clientapi/clientapi.go +++ b/clientapi/clientapi.go @@ -46,7 +46,7 @@ func SetupClientAPIComponent( transactionsCache *transactions.Cache, fedSenderAPI federationSenderAPI.FederationSenderQueryAPI, ) { - roomserverProducer := producers.NewRoomserverProducer(inputAPI) + roomserverProducer := producers.NewRoomserverProducer(inputAPI, queryAPI) typingProducer := producers.NewTypingServerProducer(typingInputAPI) userUpdateProducer := &producers.UserUpdateProducer{ diff --git a/clientapi/producers/roomserver.go b/clientapi/producers/roomserver.go index 0fe2d556b..553b590eb 100644 --- a/clientapi/producers/roomserver.go +++ b/clientapi/producers/roomserver.go @@ -24,12 +24,14 @@ import ( // RoomserverProducer produces events for the roomserver to consume. type RoomserverProducer struct { InputAPI api.RoomserverInputAPI + QueryAPI api.RoomserverQueryAPI } // NewRoomserverProducer creates a new RoomserverProducer -func NewRoomserverProducer(inputAPI api.RoomserverInputAPI) *RoomserverProducer { +func NewRoomserverProducer(inputAPI api.RoomserverInputAPI, queryAPI api.RoomserverQueryAPI) *RoomserverProducer { return &RoomserverProducer{ InputAPI: inputAPI, + QueryAPI: queryAPI, } } @@ -38,9 +40,24 @@ func (c *RoomserverProducer) SendEvents( ctx context.Context, events []gomatrixserverlib.Event, sendAsServer gomatrixserverlib.ServerName, txnID *api.TransactionID, ) (string, error) { + roomVersions := make(map[string]gomatrixserverlib.RoomVersion) + ires := make([]api.InputRoomEvent, len(events)) for i, event := range events { - roomVersion := gomatrixserverlib.RoomVersionV1 + var roomVersion gomatrixserverlib.RoomVersion + roomID := event.RoomID() + if v, ok := roomVersions[roomID]; ok { + roomVersion = v + } else { + verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID} + verRes := api.QueryRoomVersionForRoomResponse{} + err := c.QueryAPI.QueryRoomVersionForRoom(ctx, &verReq, &verRes) + if err != nil { + return "", err + } + roomVersion = verRes.RoomVersion + roomVersions[roomID] = roomVersion + } ires[i] = api.InputRoomEvent{ Kind: api.KindNew, @@ -63,14 +80,18 @@ func (c *RoomserverProducer) SendEventWithState( return err } - // TODO: Room version here - roomVersion := gomatrixserverlib.RoomVersionV1 + verReq := api.QueryRoomVersionForRoomRequest{RoomID: event.RoomID()} + verRes := api.QueryRoomVersionForRoomResponse{} + err = c.QueryAPI.QueryRoomVersionForRoom(ctx, &verReq, &verRes) + if err != nil { + return err + } ires := make([]api.InputRoomEvent, len(outliers)+1) for i, outlier := range outliers { ires[i] = api.InputRoomEvent{ Kind: api.KindOutlier, - Event: outlier.Headered(roomVersion), + Event: outlier.Headered(verRes.RoomVersion), AuthEventIDs: outlier.AuthEventIDs(), } } @@ -82,7 +103,7 @@ func (c *RoomserverProducer) SendEventWithState( ires[len(outliers)] = api.InputRoomEvent{ Kind: api.KindNew, - Event: event.Headered(roomVersion), + Event: event.Headered(verRes.RoomVersion), AuthEventIDs: event.AuthEventIDs(), HasState: true, StateEventIDs: stateEventIDs, @@ -109,12 +130,16 @@ func (c *RoomserverProducer) SendInputRoomEvents( func (c *RoomserverProducer) SendInvite( ctx context.Context, inviteEvent gomatrixserverlib.Event, ) error { - // TODO: Room version here - roomVersion := gomatrixserverlib.RoomVersionV1 + verReq := api.QueryRoomVersionForRoomRequest{RoomID: inviteEvent.RoomID()} + verRes := api.QueryRoomVersionForRoomResponse{} + err := c.QueryAPI.QueryRoomVersionForRoom(ctx, &verReq, &verRes) + if err != nil { + return err + } request := api.InputRoomEventsRequest{ InputInviteEvents: []api.InputInviteEvent{{ - Event: inviteEvent.Headered(roomVersion), + Event: inviteEvent.Headered(verRes.RoomVersion), }}, } var response api.InputRoomEventsResponse diff --git a/federationapi/federationapi.go b/federationapi/federationapi.go index ef57da881..90db95b3a 100644 --- a/federationapi/federationapi.go +++ b/federationapi/federationapi.go @@ -42,7 +42,7 @@ func SetupFederationAPIComponent( asAPI appserviceAPI.AppServiceQueryAPI, federationSenderAPI federationSenderAPI.FederationSenderQueryAPI, ) { - roomserverProducer := producers.NewRoomserverProducer(inputAPI) + roomserverProducer := producers.NewRoomserverProducer(inputAPI, queryAPI) routing.Setup( base.APIMux, base.Cfg, queryAPI, aliasAPI, asAPI, diff --git a/federationapi/routing/join.go b/federationapi/routing/join.go index aebd695a0..ac7773d7c 100644 --- a/federationapi/routing/join.go +++ b/federationapi/routing/join.go @@ -15,7 +15,6 @@ package routing import ( - "encoding/json" "net/http" "time" @@ -80,6 +79,7 @@ func MakeJoin( for i := range queryRes.StateEvents { stateEvents[i] = &queryRes.StateEvents[i].Event } + provider := gomatrixserverlib.NewAuthEvents(stateEvents) if err = gomatrixserverlib.Allowed(*event, &provider); err != nil { return util.JSONResponse{ @@ -88,9 +88,11 @@ func MakeJoin( } } + resultMap := map[string]interface{}{"event": builder} + return util.JSONResponse{ Code: http.StatusOK, - JSON: map[string]interface{}{"event": builder}, + JSON: resultMap, } } @@ -104,8 +106,17 @@ func SendJoin( keys gomatrixserverlib.KeyRing, roomID, eventID string, ) util.JSONResponse { - var event gomatrixserverlib.Event - if err := json.Unmarshal(request.Content(), &event); err != nil { + verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID} + verRes := api.QueryRoomVersionForRoomResponse{} + if err := query.QueryRoomVersionForRoom(httpReq.Context(), &verReq, &verRes); err != nil { + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: jsonerror.InternalServerError(), + } + } + + event, err := gomatrixserverlib.NewEventFromUntrustedJSON(request.Content(), verRes.RoomVersion) + if err != nil { return util.JSONResponse{ Code: http.StatusBadRequest, JSON: jsonerror.NotJSON("The request body could not be decoded into valid JSON. " + err.Error()), diff --git a/federationapi/routing/send.go b/federationapi/routing/send.go index d3e060ac2..b903a2d09 100644 --- a/federationapi/routing/send.go +++ b/federationapi/routing/send.go @@ -39,7 +39,6 @@ func Send( keys gomatrixserverlib.KeyRing, federation *gomatrixserverlib.FederationClient, ) util.JSONResponse { - t := txnReq{ context: httpReq.Context(), query: query, @@ -47,7 +46,12 @@ func Send( keys: keys, federation: federation, } - if err := json.Unmarshal(request.Content(), &t); err != nil { + + var txnEvents struct { + events []json.RawMessage `json:"events"` + } + + if err := json.Unmarshal(request.Content(), &txnEvents); err != nil { return util.JSONResponse{ Code: http.StatusBadRequest, JSON: jsonerror.NotJSON("The request body could not be decoded into valid JSON. " + err.Error()), diff --git a/go.mod b/go.mod index 29598d936..5e9646c46 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/matrix-org/go-http-js-libp2p v0.0.0-20200318135427-31631a9ef51f github.com/matrix-org/go-sqlite3-js v0.0.0-20200304164012-aa524245b658 github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 - github.com/matrix-org/gomatrixserverlib v0.0.0-20200323100819-422881c3d06b + github.com/matrix-org/gomatrixserverlib v0.0.0-20200323160828-b738416a2b5e github.com/matrix-org/naffka v0.0.0-20200127221512-0716baaabaf1 github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 github.com/mattn/go-sqlite3 v2.0.2+incompatible diff --git a/go.sum b/go.sum index 793e35547..9ffad4889 100644 --- a/go.sum +++ b/go.sum @@ -136,6 +136,10 @@ github.com/matrix-org/gomatrixserverlib v0.0.0-20200323095935-e6d3df15dbfe h1:Zt github.com/matrix-org/gomatrixserverlib v0.0.0-20200323095935-e6d3df15dbfe/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI= github.com/matrix-org/gomatrixserverlib v0.0.0-20200323100819-422881c3d06b h1:QrO9XkmoR+kbPwRmjcNl2crTt6XGXKcpsCyV/nZJDd0= github.com/matrix-org/gomatrixserverlib v0.0.0-20200323100819-422881c3d06b/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI= +github.com/matrix-org/gomatrixserverlib v0.0.0-20200323155135-fd2e0821d1e0 h1:wVR4nLO/R7kvwnRnno50DW5ZDhvUL506UBG4lOtEytU= +github.com/matrix-org/gomatrixserverlib v0.0.0-20200323155135-fd2e0821d1e0/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI= +github.com/matrix-org/gomatrixserverlib v0.0.0-20200323160828-b738416a2b5e h1:ftQ7/kwP5SQDmL2P4heKaxKwlI/S0++WqPClAHuPwdI= +github.com/matrix-org/gomatrixserverlib v0.0.0-20200323160828-b738416a2b5e/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI= github.com/matrix-org/naffka v0.0.0-20200127221512-0716baaabaf1 h1:osLoFdOy+ChQqVUn2PeTDETFftVkl4w9t/OW18g3lnk= github.com/matrix-org/naffka v0.0.0-20200127221512-0716baaabaf1/go.mod h1:cXoYQIENbdWIQHt1SyCo6Bl3C3raHwJ0wgVrXHSqf+A= github.com/matrix-org/util v0.0.0-20171127121716-2e2df66af2f5 h1:W7l5CP4V7wPyPb4tYE11dbmeAOwtFQBTW0rf4OonOS8= diff --git a/roomserver/storage/postgres/state_block_table.go b/roomserver/storage/postgres/state_block_table.go index b9246b763..741d1800e 100644 --- a/roomserver/storage/postgres/state_block_table.go +++ b/roomserver/storage/postgres/state_block_table.go @@ -51,7 +51,8 @@ CREATE TABLE IF NOT EXISTS roomserver_state_block ( const insertStateDataSQL = "" + "INSERT INTO roomserver_state_block (state_block_nid, event_type_nid, event_state_key_nid, event_nid)" + - " VALUES ($1, $2, $3, $4)" + " VALUES ($1, $2, $3, $4)" + + " ON CONFLICT DO NOTHING" const selectNextStateBlockNIDSQL = "" + "SELECT nextval('roomserver_state_block_nid_seq')" diff --git a/roomserver/storage/postgres/storage.go b/roomserver/storage/postgres/storage.go index 9098b482f..40d392a64 100644 --- a/roomserver/storage/postgres/storage.go +++ b/roomserver/storage/postgres/storage.go @@ -258,7 +258,6 @@ func (d *Database) Events( var roomVersion gomatrixserverlib.RoomVersion result := &results[i] result.EventNID = eventJSON.EventNID - // TODO: Use NewEventFromTrustedJSON for efficiency roomNID, err = d.statements.selectRoomNIDForEventNID(ctx, nil, eventJSON.EventNID) if err != nil { return nil, err @@ -267,6 +266,7 @@ func (d *Database) Events( if err != nil { return nil, err } + // TODO: Use NewEventFromTrustedJSON for efficiency result.Event, err = gomatrixserverlib.NewEventFromUntrustedJSON( eventJSON.EventJSON, roomVersion, ) diff --git a/roomserver/storage/sqlite3/state_block_table.go b/roomserver/storage/sqlite3/state_block_table.go index cc7c75733..bcfd7c546 100644 --- a/roomserver/storage/sqlite3/state_block_table.go +++ b/roomserver/storage/sqlite3/state_block_table.go @@ -39,7 +39,8 @@ const stateDataSchema = ` const insertStateDataSQL = "" + "INSERT INTO roomserver_state_block (state_block_nid, event_type_nid, event_state_key_nid, event_nid)" + - " VALUES ($1, $2, $3, $4)" + " VALUES ($1, $2, $3, $4)" + + " ON CONFLICT DO NOTHING" const selectNextStateBlockNIDSQL = ` SELECT IFNULL(MAX(state_block_nid), 0) + 1 FROM roomserver_state_block diff --git a/roomserver/version/version.go b/roomserver/version/version.go index ed16ecca0..1ad502f23 100644 --- a/roomserver/version/version.go +++ b/roomserver/version/version.go @@ -43,11 +43,11 @@ var roomVersions = map[gomatrixserverlib.RoomVersion]RoomVersionDescription{ Stable: true, }, gomatrixserverlib.RoomVersionV3: RoomVersionDescription{ - Supported: false, + Supported: true, Stable: false, }, gomatrixserverlib.RoomVersionV4: RoomVersionDescription{ - Supported: false, + Supported: true, Stable: false, }, gomatrixserverlib.RoomVersionV5: RoomVersionDescription{ @@ -59,7 +59,7 @@ var roomVersions = map[gomatrixserverlib.RoomVersion]RoomVersionDescription{ // DefaultRoomVersion contains the room version that will, by // default, be used to create new rooms on this server. func DefaultRoomVersion() gomatrixserverlib.RoomVersion { - return gomatrixserverlib.RoomVersionV2 + return gomatrixserverlib.RoomVersionV4 } // RoomVersions returns a map of all known room versions to this