Check room versions compatible at make_join, add some comments, update gomatrixserverlib, other tweaks

This commit is contained in:
Neil Alexander 2020-04-06 15:03:37 +01:00
parent 5ee393d691
commit e7215c954a
9 changed files with 82 additions and 22 deletions

View file

@ -242,6 +242,9 @@ func (r joinRoomReq) joinRoomUsingServers(
queryRes := roomserverAPI.QueryLatestEventsAndStateResponse{} queryRes := roomserverAPI.QueryLatestEventsAndStateResponse{}
event, err := common.BuildEvent(r.req.Context(), &eb, r.cfg, r.evTime, r.queryAPI, &queryRes) event, err := common.BuildEvent(r.req.Context(), &eb, r.cfg, r.evTime, r.queryAPI, &queryRes)
if err == nil { if err == nil {
// If we have successfully built an event at this point then we can
// assert that the room is a local room, as BuildEvent was able to
// add prev_events etc successfully.
if _, err = r.producer.SendEvents( if _, err = r.producer.SendEvents(
r.req.Context(), r.req.Context(),
[]gomatrixserverlib.HeaderedEvent{ []gomatrixserverlib.HeaderedEvent{
@ -260,6 +263,10 @@ func (r joinRoomReq) joinRoomUsingServers(
}{roomID}, }{roomID},
} }
} }
// Otherwise, if we've reached here, then we haven't been able to populate
// prev_events etc for the room, therefore the room is probably federated.
// TODO: This needs to be re-thought, as in the case of an invite, the room // TODO: This needs to be re-thought, as in the case of an invite, the room
// will exist in the database in roomserver_rooms but won't have any state // will exist in the database in roomserver_rooms but won't have any state
// events, therefore this below check fails. // events, therefore this below check fails.

View file

@ -17,6 +17,7 @@ package common
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"time" "time"
"github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/common/config"
@ -46,6 +47,7 @@ func BuildEvent(
err := AddPrevEventsToEvent(ctx, builder, queryAPI, queryRes) err := AddPrevEventsToEvent(ctx, builder, queryAPI, queryRes)
if err != nil { if err != nil {
// This can pass through a ErrRoomNoExists to the caller
return nil, err return nil, err
} }
@ -68,7 +70,7 @@ func AddPrevEventsToEvent(
) error { ) error {
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder) eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
if err != nil { if err != nil {
return err return fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
} }
// Ask the roomserver for information about this room // Ask the roomserver for information about this room
@ -77,7 +79,7 @@ func AddPrevEventsToEvent(
StateToFetch: eventsNeeded.Tuples(), StateToFetch: eventsNeeded.Tuples(),
} }
if err = queryAPI.QueryLatestEventsAndState(ctx, &queryReq, queryRes); err != nil { if err = queryAPI.QueryLatestEventsAndState(ctx, &queryReq, queryRes); err != nil {
return err return fmt.Errorf("queryAPI.QueryLatestEventsAndState: %w", err)
} }
if !queryRes.RoomExists { if !queryRes.RoomExists {
@ -86,7 +88,7 @@ func AddPrevEventsToEvent(
eventFormat, err := queryRes.RoomVersion.EventFormat() eventFormat, err := queryRes.RoomVersion.EventFormat()
if err != nil { if err != nil {
return err return fmt.Errorf("queryRes.RoomVersion.EventFormat: %w", err)
} }
builder.Depth = queryRes.Depth builder.Depth = queryRes.Depth
@ -96,13 +98,13 @@ func AddPrevEventsToEvent(
for i := range queryRes.StateEvents { for i := range queryRes.StateEvents {
err = authEvents.AddEvent(&queryRes.StateEvents[i].Event) err = authEvents.AddEvent(&queryRes.StateEvents[i].Event)
if err != nil { if err != nil {
return err return fmt.Errorf("authEvents.AddEvent: %w", err)
} }
} }
refs, err := eventsNeeded.AuthEventReferences(&authEvents) refs, err := eventsNeeded.AuthEventReferences(&authEvents)
if err != nil { if err != nil {
return err return fmt.Errorf("eventsNeeded.AuthEventReferences: %w", err)
} }
truncAuth, truncPrev := truncateAuthAndPrevEvents(refs, queryRes.LatestEvents) truncAuth, truncPrev := truncateAuthAndPrevEvents(refs, queryRes.LatestEvents)

View file

@ -15,6 +15,7 @@
package routing package routing
import ( import (
"fmt"
"net/http" "net/http"
"time" "time"
@ -34,6 +35,7 @@ func MakeJoin(
cfg *config.Dendrite, cfg *config.Dendrite,
query api.RoomserverQueryAPI, query api.RoomserverQueryAPI,
roomID, userID string, roomID, userID string,
remoteVersions []gomatrixserverlib.RoomVersion,
) util.JSONResponse { ) util.JSONResponse {
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID} verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
verRes := api.QueryRoomVersionForRoomResponse{} verRes := api.QueryRoomVersionForRoomResponse{}
@ -44,6 +46,27 @@ func MakeJoin(
} }
} }
// Check that the room that the remote side is trying to join is actually
// one of the room versions that they listed in their supported ?ver= in
// the make_join URL.
// https://matrix.org/docs/spec/server_server/r0.1.3#get-matrix-federation-v1-make-join-roomid-userid
remoteSupportsVersion := false
for _, v := range remoteVersions {
if v == verRes.RoomVersion {
remoteSupportsVersion = true
break
}
}
// If it isn't, stop trying to join the room.
if !remoteSupportsVersion {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.UnsupportedRoomVersion(
fmt.Sprintf("Joining server does not support room version %s", verRes.RoomVersion),
),
}
}
_, domain, err := gomatrixserverlib.SplitID('@', userID) _, domain, err := gomatrixserverlib.SplitID('@', userID)
if err != nil { if err != nil {
return util.JSONResponse{ return util.JSONResponse{
@ -140,7 +163,12 @@ func SendJoin(
if event.RoomID() != roomID { if event.RoomID() != roomID {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusBadRequest, Code: http.StatusBadRequest,
JSON: jsonerror.BadJSON("The room ID in the request path must match the room ID in the join event JSON"), JSON: jsonerror.BadJSON(
fmt.Sprintf(
"The room ID in the request path (%q) must match the room ID in the join event JSON (%q)",
roomID, event.RoomID(),
),
),
} }
} }
@ -148,7 +176,12 @@ func SendJoin(
if event.EventID() != eventID { if event.EventID() != eventID {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusBadRequest, Code: http.StatusBadRequest,
JSON: jsonerror.BadJSON("The event ID in the request path must match the event ID in the join event JSON"), JSON: jsonerror.BadJSON(
fmt.Sprintf(
"The event ID in the request path (%q) must match the event ID in the join event JSON (%q)",
eventID, event.EventID(),
),
),
} }
} }

View file

@ -198,7 +198,7 @@ func Setup(
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v1fedmux.Handle("/make_join/{roomID}/{userID}", common.MakeFedAPI( v1fedmux.Handle("/make_join/{roomID}/{eventID}", common.MakeFedAPI(
"federation_make_join", cfg.Matrix.ServerName, keys, "federation_make_join", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
vars, err := common.URLDecodeMapValues(mux.Vars(httpReq)) vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
@ -206,14 +206,28 @@ func Setup(
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
roomID := vars["roomID"] roomID := vars["roomID"]
userID := vars["userID"] eventID := vars["eventID"]
queryVars := httpReq.URL.Query()
remoteVersions := []gomatrixserverlib.RoomVersion{}
if vers, ok := queryVars["ver"]; ok {
// The remote side supplied a ?=ver so use that to build up the list
// of supported room versions
for _, v := range vers {
remoteVersions = append(remoteVersions, gomatrixserverlib.RoomVersion(v))
}
} else {
// The remote side didn't supply a ?ver= so just assume that they only
// support room version 1, as per the spec
// https://matrix.org/docs/spec/server_server/r0.1.3#get-matrix-federation-v1-make-join-roomid-userid
remoteVersions = append(remoteVersions, gomatrixserverlib.RoomVersionV1)
}
return MakeJoin( return MakeJoin(
httpReq, request, cfg, query, roomID, userID, httpReq, request, cfg, query, roomID, eventID, remoteVersions,
) )
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v2fedmux.Handle("/send_join/{roomID}/{userID}", common.MakeFedAPI( v2fedmux.Handle("/send_join/{roomID}/{eventID}", common.MakeFedAPI(
"federation_send_join", cfg.Matrix.ServerName, keys, "federation_send_join", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
vars, err := common.URLDecodeMapValues(mux.Vars(httpReq)) vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
@ -221,14 +235,14 @@ func Setup(
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
roomID := vars["roomID"] roomID := vars["roomID"]
userID := vars["userID"] eventID := vars["eventID"]
return SendJoin( return SendJoin(
httpReq, request, cfg, query, producer, keys, roomID, userID, httpReq, request, cfg, query, producer, keys, roomID, eventID,
) )
}, },
)).Methods(http.MethodPut) )).Methods(http.MethodPut)
v1fedmux.Handle("/make_leave/{roomID}/{userID}", common.MakeFedAPI( v1fedmux.Handle("/make_leave/{roomID}/{eventID}", common.MakeFedAPI(
"federation_make_leave", cfg.Matrix.ServerName, keys, "federation_make_leave", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
vars, err := common.URLDecodeMapValues(mux.Vars(httpReq)) vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
@ -236,14 +250,14 @@ func Setup(
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
roomID := vars["roomID"] roomID := vars["roomID"]
userID := vars["userID"] eventID := vars["eventID"]
return MakeLeave( return MakeLeave(
httpReq, request, cfg, query, roomID, userID, httpReq, request, cfg, query, roomID, eventID,
) )
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v2fedmux.Handle("/send_leave/{roomID}/{userID}", common.MakeFedAPI( v2fedmux.Handle("/send_leave/{roomID}/{eventID}", common.MakeFedAPI(
"federation_send_leave", cfg.Matrix.ServerName, keys, "federation_send_leave", cfg.Matrix.ServerName, keys,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest) util.JSONResponse {
vars, err := common.URLDecodeMapValues(mux.Vars(httpReq)) vars, err := common.URLDecodeMapValues(mux.Vars(httpReq))
@ -251,9 +265,9 @@ func Setup(
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
roomID := vars["roomID"] roomID := vars["roomID"]
userID := vars["userID"] eventID := vars["eventID"]
return SendLeave( return SendLeave(
httpReq, request, cfg, producer, keys, roomID, userID, httpReq, request, cfg, producer, keys, roomID, eventID,
) )
}, },
)).Methods(http.MethodPut) )).Methods(http.MethodPut)

2
go.mod
View file

@ -9,7 +9,7 @@ require (
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200318135427-31631a9ef51f github.com/matrix-org/go-http-js-libp2p v0.0.0-20200318135427-31631a9ef51f
github.com/matrix-org/go-sqlite3-js v0.0.0-20200325174927-327088cdef10 github.com/matrix-org/go-sqlite3-js v0.0.0-20200325174927-327088cdef10
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26
github.com/matrix-org/gomatrixserverlib v0.0.0-20200402141635-4a6e1ade46f8 github.com/matrix-org/gomatrixserverlib v0.0.0-20200406135443-bfe03fcbf050
github.com/matrix-org/naffka v0.0.0-20200127221512-0716baaabaf1 github.com/matrix-org/naffka v0.0.0-20200127221512-0716baaabaf1
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7
github.com/mattn/go-sqlite3 v2.0.2+incompatible github.com/mattn/go-sqlite3 v2.0.2+incompatible

2
go.sum
View file

@ -132,6 +132,8 @@ github.com/matrix-org/gomatrixserverlib v0.0.0-20200124100636-0c2ec91d1df5 h1:km
github.com/matrix-org/gomatrixserverlib v0.0.0-20200124100636-0c2ec91d1df5/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI= github.com/matrix-org/gomatrixserverlib v0.0.0-20200124100636-0c2ec91d1df5/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200402141635-4a6e1ade46f8 h1:VZ7xGklSuzU9geMekuxKO4FvUBUaPjP+8IkcwzQtqOI= github.com/matrix-org/gomatrixserverlib v0.0.0-20200402141635-4a6e1ade46f8 h1:VZ7xGklSuzU9geMekuxKO4FvUBUaPjP+8IkcwzQtqOI=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200402141635-4a6e1ade46f8/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI= github.com/matrix-org/gomatrixserverlib v0.0.0-20200402141635-4a6e1ade46f8/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200406135443-bfe03fcbf050 h1:SzSf5GN1ikjGSTEYdhpEUQubqIyH28vZIjYorzdU4Gc=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200406135443-bfe03fcbf050/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 h1:osLoFdOy+ChQqVUn2PeTDETFftVkl4w9t/OW18g3lnk=
github.com/matrix-org/naffka v0.0.0-20200127221512-0716baaabaf1/go.mod h1:cXoYQIENbdWIQHt1SyCo6Bl3C3raHwJ0wgVrXHSqf+A= 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= github.com/matrix-org/util v0.0.0-20171127121716-2e2df66af2f5 h1:W7l5CP4V7wPyPb4tYE11dbmeAOwtFQBTW0rf4OonOS8=

View file

@ -132,7 +132,7 @@ func (r *RoomserverQueryAPI) QueryLatestEventsAndState(
return err return err
} }
// Look up the currrent state for the requested tuples. // Look up the current state for the requested tuples.
stateEntries, err := roomState.LoadStateAtSnapshotForStringTuples( stateEntries, err := roomState.LoadStateAtSnapshotForStringTuples(
ctx, currentStateSnapshotNID, request.StateToFetch, ctx, currentStateSnapshotNID, request.StateToFetch,
) )

View file

@ -59,7 +59,7 @@ var roomVersions = map[gomatrixserverlib.RoomVersion]RoomVersionDescription{
// DefaultRoomVersion contains the room version that will, by // DefaultRoomVersion contains the room version that will, by
// default, be used to create new rooms on this server. // default, be used to create new rooms on this server.
func DefaultRoomVersion() gomatrixserverlib.RoomVersion { func DefaultRoomVersion() gomatrixserverlib.RoomVersion {
return gomatrixserverlib.RoomVersionV2 return gomatrixserverlib.RoomVersionV4
} }
// RoomVersions returns a map of all known room versions to this // RoomVersions returns a map of all known room versions to this

View file

@ -242,3 +242,5 @@ Remote user can backfill in a room with version 4
# We don't support ignores yet, so ignore this for now - ha ha. # We don't support ignores yet, so ignore this for now - ha ha.
# Ignore invite in incremental sync # Ignore invite in incremental sync
Outbound federation can send invites via v2 API Outbound federation can send invites via v2 API
User can invite local user to room with version 3
User can invite local user to room with version 4