Federation for v3/v4 rooms (#954)
* Update gomatrixserverlib * Default to room version 4 * Update gomatrixserverlib * Limit prev_events and auth_events * Fix auth_events, prev_events * Fix linter issues * Update gomatrixserverlib * Fix getState * Update sytest-whitelist * Squashed commit of the following: commit067b875063
Author: Neil Alexander <neilalexander@users.noreply.github.com> Date: Fri Apr 3 14:29:06 2020 +0100 Invites v2 endpoint (#952) * Start converting v1 invite endpoint to v2 * Update gomatrixserverlib * Early federationsender code for sending invites * Sending invites sorta happens now * Populate invite request with stripped state * Remodel a bit, don't reflect received invites * Handle invite_room_state * Handle room versions a bit better * Update gomatrixserverlib * Tweak order in destinationQueue.next * Revert check in processMessage * Tweak federation sender destination queue code a bit * Add comments commit955244c092
Author: Ben B <benne@klimlive.de> Date: Fri Apr 3 12:40:50 2020 +0200 use custom http client instead of the http DefaultClient (#823) This commit replaces the default client from the http lib with a custom one. The previously used default client doesn't come with a timeout. This could cause unwanted locks. That solution chosen here creates a http client in the base component dendrite with a constant timeout of 30 seconds. If it should be necessary to overwrite this, we could include the timeout in the dendrite configuration. Here it would be a good idea to extend the type "Address" by a timeout and create an http client for each service. Closes #820 Signed-off-by: Benedikt Bongartz <benne@klimlive.de> Co-authored-by: Kegsay <kegan@matrix.org> * Update sytest-whitelist, sytest-blacklist * Update go.mod/go.sum * Add some error wrapping for debug * Add a NOTSPEC to common/events.go * Perform state resolution at send_join * Set default room version to v2 again * Tweak GetCapabilities * Add comments to ResolveConflictsAdhoc * Update sytest-blacklist * go mod tidy * Update sytest-whitelist, sytest-blacklist * Update versions * Updates from review comments * Update sytest-blacklist, sytest-whitelist * Check room versions compatible at make_join, add some comments, update gomatrixserverlib, other tweaks * Set default room version back to v2 * Update gomatrixserverlib, sytest-whitelist
This commit is contained in:
parent
067b875063
commit
dacee648f7
|
@ -29,7 +29,7 @@ func GetCapabilities(
|
||||||
req *http.Request, queryAPI roomserverAPI.RoomserverQueryAPI,
|
req *http.Request, queryAPI roomserverAPI.RoomserverQueryAPI,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
roomVersionsQueryReq := roomserverAPI.QueryRoomVersionCapabilitiesRequest{}
|
roomVersionsQueryReq := roomserverAPI.QueryRoomVersionCapabilitiesRequest{}
|
||||||
var roomVersionsQueryRes roomserverAPI.QueryRoomVersionCapabilitiesResponse
|
roomVersionsQueryRes := roomserverAPI.QueryRoomVersionCapabilitiesResponse{}
|
||||||
if err := queryAPI.QueryRoomVersionCapabilities(
|
if err := queryAPI.QueryRoomVersionCapabilities(
|
||||||
req.Context(),
|
req.Context(),
|
||||||
&roomVersionsQueryReq,
|
&roomVersionsQueryReq,
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -323,14 +330,14 @@ func (r joinRoomReq) joinRoomUsingServer(roomID string, server gomatrixserverlib
|
||||||
respMakeJoin, err := r.federation.MakeJoin(r.req.Context(), server, roomID, r.userID, supportedVersions)
|
respMakeJoin, err := r.federation.MakeJoin(r.req.Context(), server, roomID, r.userID, supportedVersions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: Check if the user was not allowed to join the room.
|
// TODO: Check if the user was not allowed to join the room.
|
||||||
return nil, err
|
return nil, fmt.Errorf("r.federation.MakeJoin: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set all the fields to be what they should be, this should be a no-op
|
// Set all the fields to be what they should be, this should be a no-op
|
||||||
// but it's possible that the remote server returned us something "odd"
|
// but it's possible that the remote server returned us something "odd"
|
||||||
err = r.writeToBuilder(&respMakeJoin.JoinEvent, roomID)
|
err = r.writeToBuilder(&respMakeJoin.JoinEvent, roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("r.writeToBuilder: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if respMakeJoin.RoomVersion == "" {
|
if respMakeJoin.RoomVersion == "" {
|
||||||
|
@ -350,18 +357,16 @@ func (r joinRoomReq) joinRoomUsingServer(roomID string, server gomatrixserverlib
|
||||||
r.cfg.Matrix.PrivateKey, respMakeJoin.RoomVersion,
|
r.cfg.Matrix.PrivateKey, respMakeJoin.RoomVersion,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.GetLogger(r.req.Context()).WithError(err).Error("respMakeJoin.JoinEvent.Build failed")
|
return nil, fmt.Errorf("respMakeJoin.JoinEvent.Build: %w", err)
|
||||||
res := jsonerror.InternalServerError()
|
|
||||||
return &res, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
respSendJoin, err := r.federation.SendJoin(r.req.Context(), server, event, respMakeJoin.RoomVersion)
|
respSendJoin, err := r.federation.SendJoin(r.req.Context(), server, event, respMakeJoin.RoomVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("r.federation.SendJoin: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = respSendJoin.Check(r.req.Context(), r.keyRing, event); err != nil {
|
if err = respSendJoin.Check(r.req.Context(), r.keyRing, event); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("respSendJoin: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = r.producer.SendEventWithState(
|
if err = r.producer.SendEventWithState(
|
||||||
|
@ -369,9 +374,7 @@ func (r joinRoomReq) joinRoomUsingServer(roomID string, server gomatrixserverlib
|
||||||
gomatrixserverlib.RespState(respSendJoin.RespState),
|
gomatrixserverlib.RespState(respSendJoin.RespState),
|
||||||
event.Headered(respMakeJoin.RoomVersion),
|
event.Headered(respMakeJoin.RoomVersion),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
util.GetLogger(r.req.Context()).WithError(err).Error("gomatrixserverlib.RespState failed")
|
return nil, fmt.Errorf("r.producer.SendEventWithState: %w", err)
|
||||||
res := jsonerror.InternalServerError()
|
|
||||||
return &res, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &util.JSONResponse{
|
return &util.JSONResponse{
|
||||||
|
|
|
@ -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,26 +98,26 @@ 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)
|
||||||
switch eventFormat {
|
switch eventFormat {
|
||||||
case gomatrixserverlib.EventFormatV1:
|
case gomatrixserverlib.EventFormatV1:
|
||||||
builder.AuthEvents = refs
|
builder.AuthEvents = truncAuth
|
||||||
builder.PrevEvents = queryRes.LatestEvents
|
builder.PrevEvents = truncPrev
|
||||||
case gomatrixserverlib.EventFormatV2:
|
case gomatrixserverlib.EventFormatV2:
|
||||||
v2AuthRefs := []string{}
|
v2AuthRefs, v2PrevRefs := []string{}, []string{}
|
||||||
v2PrevRefs := []string{}
|
for _, ref := range truncAuth {
|
||||||
for _, ref := range refs {
|
|
||||||
v2AuthRefs = append(v2AuthRefs, ref.EventID)
|
v2AuthRefs = append(v2AuthRefs, ref.EventID)
|
||||||
}
|
}
|
||||||
for _, ref := range queryRes.LatestEvents {
|
for _, ref := range truncPrev {
|
||||||
v2PrevRefs = append(v2PrevRefs, ref.EventID)
|
v2PrevRefs = append(v2PrevRefs, ref.EventID)
|
||||||
}
|
}
|
||||||
builder.AuthEvents = v2AuthRefs
|
builder.AuthEvents = v2AuthRefs
|
||||||
|
@ -124,3 +126,21 @@ func AddPrevEventsToEvent(
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// truncateAuthAndPrevEvents limits the number of events we add into
|
||||||
|
// an event as prev_events or auth_events.
|
||||||
|
// NOTSPEC: The limits here feel a bit arbitrary but they are currently
|
||||||
|
// here because of https://github.com/matrix-org/matrix-doc/issues/2307
|
||||||
|
// and because Synapse will just drop events that don't comply.
|
||||||
|
func truncateAuthAndPrevEvents(auth, prev []gomatrixserverlib.EventReference) (
|
||||||
|
truncAuth, truncPrev []gomatrixserverlib.EventReference,
|
||||||
|
) {
|
||||||
|
truncAuth, truncPrev = auth, prev
|
||||||
|
if len(truncAuth) > 10 {
|
||||||
|
truncAuth = truncAuth[:10]
|
||||||
|
}
|
||||||
|
if len(truncPrev) > 20 {
|
||||||
|
truncPrev = truncPrev[:20]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
|
),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +219,7 @@ func SendJoin(
|
||||||
PrevEventIDs: event.PrevEventIDs(),
|
PrevEventIDs: event.PrevEventIDs(),
|
||||||
AuthEventIDs: event.AuthEventIDs(),
|
AuthEventIDs: event.AuthEventIDs(),
|
||||||
RoomID: roomID,
|
RoomID: roomID,
|
||||||
|
ResolveState: true,
|
||||||
}, &stateAndAuthChainResponse)
|
}, &stateAndAuthChainResponse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.GetLogger(httpReq.Context()).WithError(err).Error("query.QueryStateAndAuthChain failed")
|
util.GetLogger(httpReq.Context()).WithError(err).Error("query.QueryStateAndAuthChain failed")
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -107,7 +107,6 @@ func getState(
|
||||||
return nil, &util.JSONResponse{Code: http.StatusNotFound, JSON: nil}
|
return nil, &util.JSONResponse{Code: http.StatusNotFound, JSON: nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
prevEventIDs := getIDsFromEventRef(event.PrevEvents())
|
|
||||||
authEventIDs := getIDsFromEventRef(event.AuthEvents())
|
authEventIDs := getIDsFromEventRef(event.AuthEvents())
|
||||||
|
|
||||||
var response api.QueryStateAndAuthChainResponse
|
var response api.QueryStateAndAuthChainResponse
|
||||||
|
@ -115,7 +114,7 @@ func getState(
|
||||||
ctx,
|
ctx,
|
||||||
&api.QueryStateAndAuthChainRequest{
|
&api.QueryStateAndAuthChainRequest{
|
||||||
RoomID: roomID,
|
RoomID: roomID,
|
||||||
PrevEventIDs: prevEventIDs,
|
PrevEventIDs: []string{eventID},
|
||||||
AuthEventIDs: authEventIDs,
|
AuthEventIDs: authEventIDs,
|
||||||
},
|
},
|
||||||
&response,
|
&response,
|
||||||
|
|
6
go.mod
6
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-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-20200409140603-8b9a51fe9b89
|
||||||
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
|
||||||
|
@ -23,9 +23,9 @@ require (
|
||||||
github.com/tidwall/pretty v1.0.1 // indirect
|
github.com/tidwall/pretty v1.0.1 // indirect
|
||||||
github.com/uber/jaeger-client-go v2.22.1+incompatible
|
github.com/uber/jaeger-client-go v2.22.1+incompatible
|
||||||
github.com/uber/jaeger-lib v2.2.0+incompatible
|
github.com/uber/jaeger-lib v2.2.0+incompatible
|
||||||
go.uber.org/atomic v1.6.0 // indirect
|
go.uber.org/atomic v1.6.0
|
||||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d
|
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d
|
||||||
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b // indirect
|
golang.org/x/tools v0.0.0-20200402223321-bcf690261a44 // indirect
|
||||||
gopkg.in/Shopify/sarama.v1 v1.20.1
|
gopkg.in/Shopify/sarama.v1 v1.20.1
|
||||||
gopkg.in/h2non/bimg.v1 v1.0.18
|
gopkg.in/h2non/bimg.v1 v1.0.18
|
||||||
gopkg.in/yaml.v2 v2.2.5
|
gopkg.in/yaml.v2 v2.2.5
|
||||||
|
|
15
go.sum
15
go.sum
|
@ -130,8 +130,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-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200124100636-0c2ec91d1df5 h1:kmRjpmFOenVpOaV/DRlo9p6z/IbOKlUC+hhKsAAh8Qg=
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20200124100636-0c2ec91d1df5 h1:kmRjpmFOenVpOaV/DRlo9p6z/IbOKlUC+hhKsAAh8Qg=
|
||||||
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-20200409140603-8b9a51fe9b89 h1:YAlUJK/Ty2ZrP/DL41CiR0Cp3pteshnyIS420KVs220=
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200402141635-4a6e1ade46f8/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI=
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20200409140603-8b9a51fe9b89/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=
|
||||||
|
@ -253,6 +253,7 @@ github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/Aaua
|
||||||
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
|
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
|
||||||
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
|
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
|
||||||
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.uber.org/atomic v1.3.0 h1:vs7fgriifsPbGdK3bNuMWapNn3qnZhCRXc19NRdq010=
|
go.uber.org/atomic v1.3.0 h1:vs7fgriifsPbGdK3bNuMWapNn3qnZhCRXc19NRdq010=
|
||||||
go.uber.org/atomic v1.3.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.3.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
@ -276,6 +277,8 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||||
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -288,8 +291,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
|
||||||
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
@ -324,7 +327,11 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c h1:IGkKhmfzcztjm6gYkykvu/NiS8kaqbCWAEWWAyf8J5U=
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c h1:IGkKhmfzcztjm6gYkykvu/NiS8kaqbCWAEWWAyf8J5U=
|
||||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20200402223321-bcf690261a44 h1:bMm0eoDiGkM5VfIyKjxDvoflW5GLp7+VCo+60n8F+TE=
|
||||||
|
golang.org/x/tools v0.0.0-20200402223321-bcf690261a44/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
|
|
@ -203,6 +203,9 @@ type QueryStateAndAuthChainRequest struct {
|
||||||
PrevEventIDs []string `json:"prev_event_ids"`
|
PrevEventIDs []string `json:"prev_event_ids"`
|
||||||
// The list of auth events for the event. Used to calculate the auth chain
|
// The list of auth events for the event. Used to calculate the auth chain
|
||||||
AuthEventIDs []string `json:"auth_event_ids"`
|
AuthEventIDs []string `json:"auth_event_ids"`
|
||||||
|
// Should state resolution be ran on the result events?
|
||||||
|
// TODO: check call sites and remove if we always want to do state res
|
||||||
|
ResolveState bool `json:"resolve_state"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryStateAndAuthChainResponse is a response to QueryStateAndAuthChain
|
// QueryStateAndAuthChainResponse is a response to QueryStateAndAuthChain
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
|
@ -736,6 +736,14 @@ func (r *RoomserverQueryAPI) QueryStateAndAuthChain(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if request.ResolveState {
|
||||||
|
if stateEvents, err = state.ResolveConflictsAdhoc(
|
||||||
|
roomVersion, stateEvents, authEvents,
|
||||||
|
); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, event := range stateEvents {
|
for _, event := range stateEvents {
|
||||||
response.StateEvents = append(response.StateEvents, event.Headered(roomVersion))
|
response.StateEvents = append(response.StateEvents, event.Headered(roomVersion))
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
@ -681,6 +680,83 @@ func (v StateResolution) calculateStateAfterManyEvents(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResolveConflictsAdhoc is a helper function to assist the query API in
|
||||||
|
// performing state resolution when requested. This is a different code
|
||||||
|
// path to the rest of state.go because this assumes you already have
|
||||||
|
// gomatrixserverlib.Event objects and not just a bunch of NIDs like
|
||||||
|
// elsewhere in the state resolution.
|
||||||
|
// TODO: Some of this can possibly be deduplicated
|
||||||
|
func ResolveConflictsAdhoc(
|
||||||
|
version gomatrixserverlib.RoomVersion,
|
||||||
|
events []gomatrixserverlib.Event,
|
||||||
|
authEvents []gomatrixserverlib.Event,
|
||||||
|
) ([]gomatrixserverlib.Event, error) {
|
||||||
|
type stateKeyTuple struct {
|
||||||
|
Type string
|
||||||
|
StateKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare our data structures.
|
||||||
|
eventMap := make(map[stateKeyTuple][]gomatrixserverlib.Event)
|
||||||
|
var conflicted, notConflicted, resolved []gomatrixserverlib.Event
|
||||||
|
|
||||||
|
// Run through all of the events that we were given and sort them
|
||||||
|
// into a map, sorted by (event_type, state_key) tuple. This means
|
||||||
|
// that we can easily spot events that are "conflicted", e.g.
|
||||||
|
// there are duplicate values for the same tuple key.
|
||||||
|
for _, event := range events {
|
||||||
|
if event.StateKey() == nil {
|
||||||
|
// Ignore events that are not state events.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Append the events if there is already a conflicted list for
|
||||||
|
// this tuple key, create it if not.
|
||||||
|
tuple := stateKeyTuple{event.Type(), *event.StateKey()}
|
||||||
|
if _, ok := eventMap[tuple]; ok {
|
||||||
|
eventMap[tuple] = append(eventMap[tuple], event)
|
||||||
|
} else {
|
||||||
|
eventMap[tuple] = []gomatrixserverlib.Event{event}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split out the events in the map into conflicted and unconflicted
|
||||||
|
// buckets. The conflicted events will be ran through state res,
|
||||||
|
// whereas unconfliced events will always going to appear in the
|
||||||
|
// final resolved state.
|
||||||
|
for _, list := range eventMap {
|
||||||
|
if len(list) > 1 {
|
||||||
|
conflicted = append(conflicted, list...)
|
||||||
|
} else {
|
||||||
|
notConflicted = append(notConflicted, list...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Work out which state resolution algorithm we want to run for
|
||||||
|
// the room version.
|
||||||
|
stateResAlgo, err := version.StateResAlgorithm()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch stateResAlgo {
|
||||||
|
case gomatrixserverlib.StateResV1:
|
||||||
|
// Currently state res v1 doesn't handle unconflicted events
|
||||||
|
// for us, like state res v2 does, so we will need to add the
|
||||||
|
// unconflicted events into the state ourselves.
|
||||||
|
// TODO: Fix state res v1 so this is handled for the caller.
|
||||||
|
resolved = gomatrixserverlib.ResolveStateConflicts(conflicted, authEvents)
|
||||||
|
resolved = append(resolved, notConflicted...)
|
||||||
|
case gomatrixserverlib.StateResV2:
|
||||||
|
// TODO: auth difference here?
|
||||||
|
resolved = gomatrixserverlib.ResolveStateConflictsV2(conflicted, notConflicted, authEvents, authEvents)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported state resolution algorithm %v", stateResAlgo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the final resolved state events, including both the
|
||||||
|
// resolved set of conflicted events, and the unconflicted events.
|
||||||
|
return resolved, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (v StateResolution) resolveConflicts(
|
func (v StateResolution) resolveConflicts(
|
||||||
ctx context.Context, version gomatrixserverlib.RoomVersion,
|
ctx context.Context, version gomatrixserverlib.RoomVersion,
|
||||||
notConflicted, conflicted []types.StateEntry,
|
notConflicted, conflicted []types.StateEntry,
|
||||||
|
@ -695,7 +771,7 @@ func (v StateResolution) resolveConflicts(
|
||||||
case gomatrixserverlib.StateResV2:
|
case gomatrixserverlib.StateResV2:
|
||||||
return v.resolveConflictsV2(ctx, notConflicted, conflicted)
|
return v.resolveConflictsV2(ctx, notConflicted, conflicted)
|
||||||
}
|
}
|
||||||
return nil, errors.New("unsupported state resolution algorithm")
|
return nil, fmt.Errorf("unsupported state resolution algorithm %v", stateResAlgo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolveConflicts resolves a list of conflicted state entries. It takes two lists.
|
// resolveConflicts resolves a list of conflicted state entries. It takes two lists.
|
||||||
|
|
|
@ -43,12 +43,12 @@ var roomVersions = map[gomatrixserverlib.RoomVersion]RoomVersionDescription{
|
||||||
Stable: true,
|
Stable: true,
|
||||||
},
|
},
|
||||||
gomatrixserverlib.RoomVersionV3: RoomVersionDescription{
|
gomatrixserverlib.RoomVersionV3: RoomVersionDescription{
|
||||||
Supported: false,
|
Supported: true,
|
||||||
Stable: false,
|
Stable: true,
|
||||||
},
|
},
|
||||||
gomatrixserverlib.RoomVersionV4: RoomVersionDescription{
|
gomatrixserverlib.RoomVersionV4: RoomVersionDescription{
|
||||||
Supported: false,
|
Supported: true,
|
||||||
Stable: false,
|
Stable: true,
|
||||||
},
|
},
|
||||||
gomatrixserverlib.RoomVersionV5: RoomVersionDescription{
|
gomatrixserverlib.RoomVersionV5: RoomVersionDescription{
|
||||||
Supported: false,
|
Supported: false,
|
||||||
|
|
|
@ -32,3 +32,6 @@ Alias creators can delete canonical alias with no ops
|
||||||
# Blacklisted because we need to implement v2 invite endpoints for room versions
|
# Blacklisted because we need to implement v2 invite endpoints for room versions
|
||||||
# to be supported (currently fails with M_UNSUPPORTED_ROOM_VERSION)
|
# to be supported (currently fails with M_UNSUPPORTED_ROOM_VERSION)
|
||||||
Inbound federation rejects invites which are not signed by the sender
|
Inbound federation rejects invites which are not signed by the sender
|
||||||
|
|
||||||
|
# Blacklisted because we don't support ignores yet
|
||||||
|
Ignore invite in incremental sync
|
||||||
|
|
|
@ -215,7 +215,6 @@ Guest users can sync from default guest_access rooms if joined
|
||||||
Real non-joined users cannot room initalSync for non-world_readable rooms
|
Real non-joined users cannot room initalSync for non-world_readable rooms
|
||||||
Push rules come down in an initial /sync
|
Push rules come down in an initial /sync
|
||||||
Regular users can add and delete aliases in the default room configuration
|
Regular users can add and delete aliases in the default room configuration
|
||||||
Regular users can add and delete aliases when m.room.aliases is restricted
|
|
||||||
GET /r0/capabilities is not public
|
GET /r0/capabilities is not public
|
||||||
GET /joined_rooms lists newly-created room
|
GET /joined_rooms lists newly-created room
|
||||||
/joined_rooms returns only joined rooms
|
/joined_rooms returns only joined rooms
|
||||||
|
@ -225,6 +224,7 @@ Remote user can backfill in a room with version 1
|
||||||
POST /createRoom creates a room with the given version
|
POST /createRoom creates a room with the given version
|
||||||
POST /createRoom rejects attempts to create rooms with numeric versions
|
POST /createRoom rejects attempts to create rooms with numeric versions
|
||||||
POST /createRoom rejects attempts to create rooms with unknown versions
|
POST /createRoom rejects attempts to create rooms with unknown versions
|
||||||
|
Regular users can add and delete aliases when m.room.aliases is restricted
|
||||||
User can create and send/receive messages in a room with version 2
|
User can create and send/receive messages in a room with version 2
|
||||||
local user can join room with version 2
|
local user can join room with version 2
|
||||||
remote user can join room with version 2
|
remote user can join room with version 2
|
||||||
|
@ -232,3 +232,16 @@ User can invite local user to room with version 2
|
||||||
Remote user can backfill in a room with version 2
|
Remote user can backfill in a room with version 2
|
||||||
Inbound federation accepts attempts to join v2 rooms from servers with support
|
Inbound federation accepts attempts to join v2 rooms from servers with support
|
||||||
Outbound federation can send invites via v2 API
|
Outbound federation can send invites via v2 API
|
||||||
|
User can create and send/receive messages in a room with version 3
|
||||||
|
local user can join room with version 3
|
||||||
|
Remote user can backfill in a room with version 3
|
||||||
|
User can create and send/receive messages in a room with version 4
|
||||||
|
local user can join room with version 4
|
||||||
|
remote user can join room with version 3
|
||||||
|
remote user can join room with version 4
|
||||||
|
Remote user can backfill in a room with version 4
|
||||||
|
# We don't support ignores yet, so ignore this for now - ha ha.
|
||||||
|
# Ignore invite in incremental sync
|
||||||
|
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
|
||||||
|
|
Loading…
Reference in a new issue