Roomserver input endpoint for handling invite room state for us (not sure if I like this)

This commit is contained in:
Neil Alexander 2020-04-23 17:43:16 +01:00
parent 3b289ff248
commit d3e5b09cde
6 changed files with 136 additions and 57 deletions

View file

@ -99,3 +99,16 @@ func (c *RoomserverProducer) SendInputRoomEvents(
eventID = response.EventID
return
}
// SendInputNewInviteEvents writes the given input new events to the roomserver input API.
// The roomserver will automatically populate the invite room state for us before sending
// the invite onward.
func (c *RoomserverProducer) SendInputNewInviteEvents(
ctx context.Context, ires []api.InputRoomEvent,
) (eventID string, err error) {
request := api.InputRoomEventsRequest{InputRoomEvents: ires}
var response api.InputRoomEventsResponse
err = c.InputAPI.InputNewInviteEvents(ctx, &request, &response)
eventID = response.EventID
return
}

View file

@ -104,6 +104,22 @@ func SendMembership(
return jsonerror.InternalServerError()
}
if membership == gomatrixserverlib.Invite {
if _, err := producer.SendInputNewInviteEvents(
req.Context(),
[]api.InputRoomEvent{
api.InputRoomEvent{
Kind: api.KindNew,
Event: event.Headered(verRes.RoomVersion),
AuthEventIDs: event.AuthEventIDs(),
SendAsServer: string(cfg.Matrix.ServerName),
},
},
); err != nil {
util.GetLogger(req.Context()).WithError(err).Error("producer.SendEvents failed")
return jsonerror.InternalServerError()
}
} else {
if _, err := producer.SendEvents(
req.Context(),
[]gomatrixserverlib.HeaderedEvent{(*event).Headered(verRes.RoomVersion)},
@ -113,6 +129,7 @@ func SendMembership(
util.GetLogger(req.Context()).WithError(err).Error("producer.SendEvents failed")
return jsonerror.InternalServerError()
}
}
var returnData interface{} = struct{}{}

View file

@ -99,10 +99,17 @@ type RoomserverInputAPI interface {
request *InputRoomEventsRequest,
response *InputRoomEventsResponse,
) error
InputNewInviteEvents(
ctx context.Context,
request *InputRoomEventsRequest,
response *InputRoomEventsResponse,
) error
}
// RoomserverInputRoomEventsPath is the HTTP path for the InputRoomEvents API.
const RoomserverInputRoomEventsPath = "/api/roomserver/inputRoomEvents"
const RoomserverInputNewInviteEventsPath = "/api/roomserver/inputRoomEvents"
// NewRoomserverInputAPIHTTP creates a RoomserverInputAPI implemented by talking to a HTTP POST API.
// If httpClient is nil an error is returned
@ -130,3 +137,16 @@ func (h *httpRoomserverInputAPI) InputRoomEvents(
apiURL := h.roomserverURL + RoomserverInputRoomEventsPath
return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
}
// InputRoomEvents implements RoomserverInputAPI
func (h *httpRoomserverInputAPI) InputNewInviteEvents(
ctx context.Context,
request *InputRoomEventsRequest,
response *InputRoomEventsResponse,
) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "InputNewInviteEvents")
defer span.Finish()
apiURL := h.roomserverURL + RoomserverInputNewInviteEventsPath
return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
}

View file

@ -280,53 +280,4 @@ func processInviteEvent(
succeeded = true
return nil
}
func buildInviteStrippedState(
ctx context.Context,
db RoomEventDatabase,
input api.InputInviteEvent,
) (json.RawMessage, error) {
roomNID, err := db.RoomNID(ctx, input.Event.RoomID())
if err != nil || roomNID == 0 {
return nil, nil
}
stateWanted := []gomatrixserverlib.StateKeyTuple{}
for _, t := range []string{
gomatrixserverlib.MRoomName, gomatrixserverlib.MRoomCanonicalAlias,
gomatrixserverlib.MRoomAliases, gomatrixserverlib.MRoomJoinRules,
} {
stateWanted = append(stateWanted, gomatrixserverlib.StateKeyTuple{
EventType: t,
StateKey: "",
})
}
_, currentStateSnapshotNID, _, err := db.LatestEventIDs(ctx, roomNID)
if err != nil {
return nil, err
}
roomState := state.NewStateResolution(db)
stateEntries, err := roomState.LoadStateAtSnapshotForStringTuples(
ctx, currentStateSnapshotNID, stateWanted,
)
if err != nil {
return nil, err
}
stateNIDs := []types.EventNID{}
for _, stateNID := range stateEntries {
stateNIDs = append(stateNIDs, stateNID.EventNID)
}
stateEvents, err := db.Events(ctx, stateNIDs)
if err != nil {
return nil, err
}
inviteState := []gomatrixserverlib.InviteV2StrippedState{}
for _, event := range stateEvents {
inviteState = append(inviteState, gomatrixserverlib.NewInviteV2StrippedState(&event.Event))
}
inviteStrippedState, err := json.Marshal(inviteState)
if err != nil {
return nil, err
}
return inviteStrippedState, nil
}
*/

View file

@ -72,6 +72,24 @@ func (r *RoomserverInputAPI) InputRoomEvents(
return nil
}
// InputNewInviteEvents implements api.RoomserverInputAPI
func (r *RoomserverInputAPI) InputNewInviteEvents(
ctx context.Context,
request *api.InputRoomEventsRequest,
response *api.InputRoomEventsResponse,
) (err error) {
for i := range request.InputRoomEvents {
inviteRoomState, err := buildInviteStrippedState(ctx, r.DB, request.InputRoomEvents[i])
if err != nil {
return err
}
if err := request.InputRoomEvents[i].Event.SetUnsignedField("invite_room_state", inviteRoomState); err != nil {
return err
}
}
return r.InputRoomEvents(ctx, request, response)
}
// SetupHTTP adds the RoomserverInputAPI handlers to the http.ServeMux.
func (r *RoomserverInputAPI) SetupHTTP(servMux *http.ServeMux) {
servMux.Handle(api.RoomserverInputRoomEventsPath,

View file

@ -0,0 +1,60 @@
package input
import (
"context"
"encoding/json"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/roomserver/state"
"github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/gomatrixserverlib"
)
func buildInviteStrippedState(
ctx context.Context,
db RoomEventDatabase,
input api.InputRoomEvent,
) (json.RawMessage, error) {
roomNID, err := db.RoomNID(ctx, input.Event.RoomID())
if err != nil || roomNID == 0 {
return nil, nil
}
stateWanted := []gomatrixserverlib.StateKeyTuple{}
for _, t := range []string{
gomatrixserverlib.MRoomName, gomatrixserverlib.MRoomCanonicalAlias,
gomatrixserverlib.MRoomAliases, gomatrixserverlib.MRoomJoinRules,
} {
stateWanted = append(stateWanted, gomatrixserverlib.StateKeyTuple{
EventType: t,
StateKey: "",
})
}
_, currentStateSnapshotNID, _, err := db.LatestEventIDs(ctx, roomNID)
if err != nil {
return nil, err
}
roomState := state.NewStateResolution(db)
stateEntries, err := roomState.LoadStateAtSnapshotForStringTuples(
ctx, currentStateSnapshotNID, stateWanted,
)
if err != nil {
return nil, err
}
stateNIDs := []types.EventNID{}
for _, stateNID := range stateEntries {
stateNIDs = append(stateNIDs, stateNID.EventNID)
}
stateEvents, err := db.Events(ctx, stateNIDs)
if err != nil {
return nil, err
}
inviteState := []gomatrixserverlib.InviteV2StrippedState{}
for _, event := range stateEvents {
inviteState = append(inviteState, gomatrixserverlib.NewInviteV2StrippedState(&event.Event))
}
inviteStrippedState, err := json.Marshal(inviteState)
if err != nil {
return nil, err
}
return inviteStrippedState, nil
}