Use ProtoEvent where needed instead of EventBuilder (#3075)

They are fundamentally different concepts, so should be represented as
such. Proto events are exchanged in /make_xxx calls over federation, and
made as "fledgling" events in /createRoom and general event sending.
*Building* events is a reasonably complex VERSION SPECIFIC process which
needs amongst other things, auth event providers, prev events, signing
keys, etc.

Requires https://github.com/matrix-org/gomatrixserverlib/pull/379
This commit is contained in:
kegsay 2023-05-04 11:17:42 +01:00 committed by GitHub
parent d5c11a3c86
commit 2b34f88fde
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 152 additions and 119 deletions

View file

@ -113,7 +113,7 @@ func (f *fedClient) MakeJoin(ctx context.Context, origin, s spec.ServerName, roo
for _, r := range f.allowJoins {
if r.ID == roomID {
res.RoomVersion = r.Version
res.JoinEvent = gomatrixserverlib.EventBuilder{
res.JoinEvent = gomatrixserverlib.ProtoEvent{
Sender: userID,
RoomID: roomID,
Type: "m.room.member",
@ -122,7 +122,7 @@ func (f *fedClient) MakeJoin(ctx context.Context, origin, s spec.ServerName, roo
PrevEvents: r.ForwardExtremities(),
}
var needed gomatrixserverlib.StateNeeded
needed, err = gomatrixserverlib.StateNeededForEventBuilder(&res.JoinEvent)
needed, err = gomatrixserverlib.StateNeededForProtoEvent(&res.JoinEvent)
if err != nil {
f.t.Errorf("StateNeededForEventBuilder: %v", err)
return

View file

@ -439,7 +439,7 @@ func (r *FederationInternalAPI) PerformLeave(
// Work out if we support the room version that has been supplied in
// the make_leave response.
_, err = gomatrixserverlib.GetRoomVersion(respMakeLeave.RoomVersion)
verImpl, err := gomatrixserverlib.GetRoomVersion(respMakeLeave.RoomVersion)
if err != nil {
return err
}
@ -451,27 +451,28 @@ func (r *FederationInternalAPI) PerformLeave(
respMakeLeave.LeaveEvent.StateKey = &request.UserID
respMakeLeave.LeaveEvent.RoomID = request.RoomID
respMakeLeave.LeaveEvent.Redacts = ""
leaveEB := verImpl.NewEventBuilderFromProtoEvent(&respMakeLeave.LeaveEvent)
if respMakeLeave.LeaveEvent.Content == nil {
content := map[string]interface{}{
"membership": "leave",
}
if err = respMakeLeave.LeaveEvent.SetContent(content); err != nil {
if err = leaveEB.SetContent(content); err != nil {
logrus.WithError(err).Warnf("respMakeLeave.LeaveEvent.SetContent failed")
continue
}
}
if err = respMakeLeave.LeaveEvent.SetUnsigned(struct{}{}); err != nil {
if err = leaveEB.SetUnsigned(struct{}{}); err != nil {
logrus.WithError(err).Warnf("respMakeLeave.LeaveEvent.SetUnsigned failed")
continue
}
// Build the leave event.
event, err := respMakeLeave.LeaveEvent.Build(
event, err := leaveEB.Build(
time.Now(),
origin,
r.cfg.Matrix.KeyID,
r.cfg.Matrix.PrivateKey,
respMakeLeave.RoomVersion,
)
if err != nil {
logrus.WithError(err).Warnf("respMakeLeave.LeaveEvent.Build failed")

View file

@ -118,7 +118,7 @@ func MakeJoin(
}
// Try building an event for the server
builder := gomatrixserverlib.EventBuilder{
proto := gomatrixserverlib.ProtoEvent{
Sender: userID,
RoomID: roomID,
Type: "m.room.member",
@ -128,7 +128,7 @@ func MakeJoin(
Membership: spec.Join,
AuthorisedVia: authorisedVia,
}
if err = builder.SetContent(content); err != nil {
if err = proto.SetContent(content); err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("builder.SetContent failed")
return jsonerror.InternalServerError()
}
@ -146,7 +146,7 @@ func MakeJoin(
queryRes := api.QueryLatestEventsAndStateResponse{
RoomVersion: roomVersion,
}
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &builder, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &proto, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
return util.JSONResponse{
Code: http.StatusNotFound,
@ -179,7 +179,7 @@ func MakeJoin(
return util.JSONResponse{
Code: http.StatusOK,
JSON: map[string]interface{}{
"event": builder,
"event": proto,
"room_version": roomVersion,
},
}

View file

@ -52,15 +52,15 @@ func MakeLeave(
}
// Try building an event for the server
builder := gomatrixserverlib.EventBuilder{
proto := gomatrixserverlib.ProtoEvent{
Sender: userID,
RoomID: roomID,
Type: "m.room.member",
StateKey: &userID,
}
err = builder.SetContent(map[string]interface{}{"membership": spec.Leave})
err = proto.SetContent(map[string]interface{}{"membership": spec.Leave})
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("builder.SetContent failed")
util.GetLogger(httpReq.Context()).WithError(err).Error("proto.SetContent failed")
return jsonerror.InternalServerError()
}
@ -75,7 +75,7 @@ func MakeLeave(
}
var queryRes api.QueryLatestEventsAndStateResponse
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &builder, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &proto, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
return util.JSONResponse{
Code: http.StatusNotFound,
@ -126,7 +126,7 @@ func MakeLeave(
Code: http.StatusOK,
JSON: map[string]interface{}{
"room_version": event.Version(),
"event": builder,
"event": proto,
},
}
}

View file

@ -121,8 +121,8 @@ func ExchangeThirdPartyInvite(
cfg *config.FederationAPI,
federation fclient.FederationClient,
) util.JSONResponse {
var builder gomatrixserverlib.EventBuilder
if err := json.Unmarshal(request.Content(), &builder); err != nil {
var proto gomatrixserverlib.ProtoEvent
if err := json.Unmarshal(request.Content(), &proto); err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.NotJSON("The request body could not be decoded into valid JSON. " + err.Error()),
@ -130,14 +130,14 @@ func ExchangeThirdPartyInvite(
}
// Check that the room ID is correct.
if builder.RoomID != roomID {
if proto.RoomID != roomID {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.BadJSON("The room ID in the request path must match the room ID in the invite event JSON"),
}
}
_, senderDomain, err := cfg.Matrix.SplitLocalID('@', builder.Sender)
_, senderDomain, err := cfg.Matrix.SplitLocalID('@', proto.Sender)
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
@ -146,7 +146,7 @@ func ExchangeThirdPartyInvite(
}
// Check that the state key is correct.
_, targetDomain, err := gomatrixserverlib.SplitID('@', *builder.StateKey)
_, targetDomain, err := gomatrixserverlib.SplitID('@', *proto.StateKey)
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
@ -171,7 +171,7 @@ func ExchangeThirdPartyInvite(
}
// Auth and build the event from what the remote server sent us
event, err := buildMembershipEvent(httpReq.Context(), &builder, rsAPI, cfg)
event, err := buildMembershipEvent(httpReq.Context(), &proto, rsAPI, cfg)
if err == errNotInRoom {
return util.JSONResponse{
Code: http.StatusNotFound,
@ -248,7 +248,7 @@ func createInviteFrom3PIDInvite(
}
// Build the event
builder := &gomatrixserverlib.EventBuilder{
proto := &gomatrixserverlib.ProtoEvent{
Type: "m.room.member",
Sender: inv.Sender,
RoomID: inv.RoomID,
@ -269,13 +269,13 @@ func createInviteFrom3PIDInvite(
},
}
if err = builder.SetContent(content); err != nil {
if err = proto.SetContent(content); err != nil {
return nil, err
}
event, err := buildMembershipEvent(ctx, builder, rsAPI, cfg)
event, err := buildMembershipEvent(ctx, proto, rsAPI, cfg)
if err == errNotInRoom {
return nil, sendToRemoteServer(ctx, inv, federation, cfg, *builder)
return nil, sendToRemoteServer(ctx, inv, federation, cfg, *proto)
}
if err != nil {
return nil, err
@ -291,10 +291,10 @@ func createInviteFrom3PIDInvite(
// Returns an error if something failed during the process.
func buildMembershipEvent(
ctx context.Context,
builder *gomatrixserverlib.EventBuilder, rsAPI api.FederationRoomserverAPI,
protoEvent *gomatrixserverlib.ProtoEvent, rsAPI api.FederationRoomserverAPI,
cfg *config.FederationAPI,
) (gomatrixserverlib.PDU, error) {
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
eventsNeeded, err := gomatrixserverlib.StateNeededForProtoEvent(protoEvent)
if err != nil {
return nil, err
}
@ -305,7 +305,7 @@ func buildMembershipEvent(
// Ask the roomserver for information about this room
queryReq := api.QueryLatestEventsAndStateRequest{
RoomID: builder.RoomID,
RoomID: protoEvent.RoomID,
StateToFetch: eventsNeeded.Tuples(),
}
var queryRes api.QueryLatestEventsAndStateResponse
@ -319,8 +319,8 @@ func buildMembershipEvent(
}
// Auth the event locally
builder.Depth = queryRes.Depth
builder.PrevEvents = queryRes.LatestEvents
protoEvent.Depth = queryRes.Depth
protoEvent.PrevEvents = queryRes.LatestEvents
authEvents := gomatrixserverlib.NewAuthEvents(nil)
@ -331,7 +331,7 @@ func buildMembershipEvent(
}
}
if err = fillDisplayName(builder, authEvents); err != nil {
if err = fillDisplayName(protoEvent, authEvents); err != nil {
return nil, err
}
@ -339,11 +339,17 @@ func buildMembershipEvent(
if err != nil {
return nil, err
}
builder.AuthEvents = refs
protoEvent.AuthEvents = refs
verImpl, err := gomatrixserverlib.GetRoomVersion(queryRes.RoomVersion)
if err != nil {
return nil, err
}
builder := verImpl.NewEventBuilderFromProtoEvent(protoEvent)
event, err := builder.Build(
time.Now(), cfg.Matrix.ServerName, cfg.Matrix.KeyID,
cfg.Matrix.PrivateKey, queryRes.RoomVersion,
cfg.Matrix.PrivateKey,
)
return event, err
@ -357,7 +363,7 @@ func buildMembershipEvent(
func sendToRemoteServer(
ctx context.Context, inv invite,
federation fclient.FederationClient, cfg *config.FederationAPI,
builder gomatrixserverlib.EventBuilder,
proto gomatrixserverlib.ProtoEvent,
) (err error) {
remoteServers := make([]spec.ServerName, 2)
_, remoteServers[0], err = gomatrixserverlib.SplitID('@', inv.Sender)
@ -372,7 +378,7 @@ func sendToRemoteServer(
}
for _, server := range remoteServers {
err = federation.ExchangeThirdPartyInvite(ctx, cfg.Matrix.ServerName, server, builder)
err = federation.ExchangeThirdPartyInvite(ctx, cfg.Matrix.ServerName, server, proto)
if err == nil {
return
}
@ -393,7 +399,7 @@ func sendToRemoteServer(
// found. Returning an error isn't necessary in this case as the event will be
// rejected by gomatrixserverlib.
func fillDisplayName(
builder *gomatrixserverlib.EventBuilder, authEvents gomatrixserverlib.AuthEvents,
builder *gomatrixserverlib.ProtoEvent, authEvents gomatrixserverlib.AuthEvents,
) error {
var content gomatrixserverlib.MemberContent
if err := json.Unmarshal(builder.Content, &content); err != nil {