From 2611a42ab68e25516a20444985f2a8910df39749 Mon Sep 17 00:00:00 2001 From: Till Faelligen <2353100+S7evinK@users.noreply.github.com> Date: Mon, 7 Nov 2022 09:56:30 +0100 Subject: [PATCH] Handle remote room upgrades --- roomserver/internal/input/input_events.go | 38 +++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/roomserver/internal/input/input_events.go b/roomserver/internal/input/input_events.go index 60160e8e5..788c880eb 100644 --- a/roomserver/internal/input/input_events.go +++ b/roomserver/internal/input/input_events.go @@ -23,6 +23,8 @@ import ( "fmt" "time" + "github.com/tidwall/gjson" + "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" "github.com/opentracing/opentracing-go" @@ -409,6 +411,13 @@ func (r *Inputer) processRoomEvent( } } + // Handle remote room upgrades, e.g. remove published room + if event.Type() == "m.room.tombstone" && event.StateKeyEquals("") && !r.Cfg.Matrix.IsLocalServerName(senderDomain) { + if err = r.handleRemoteRoomUpgrade(ctx, event); err != nil { + return fmt.Errorf("failed to handle remote room upgrade: %w") + } + } + // processing this event resulted in an event (which may not be the one we're processing) // being redacted. We are guaranteed to have both sides (the redaction/redacted event), // so notify downstream components to redact this event - they should have it if they've @@ -434,6 +443,35 @@ func (r *Inputer) processRoomEvent( return nil } +// handleRemoteRoomUpgrade updates published rooms and room aliases +func (r *Inputer) handleRemoteRoomUpgrade(ctx context.Context, event *gomatrixserverlib.Event) error { + oldRoomID := event.RoomID() + newRoomID := gjson.GetBytes(event.Content(), "replacement_room").Str + // un-publish old room + if err := r.DB.PublishRoom(ctx, oldRoomID, "", "", false); err != nil { + return fmt.Errorf("failed to unpublish room: %w", err) + } + // publish new room + if err := r.DB.PublishRoom(ctx, newRoomID, "", "", true); err != nil { + return fmt.Errorf("failed to publish room: %w", err) + } + + aliases, err := r.DB.GetAliasesForRoomID(ctx, oldRoomID) + if err != nil { + return fmt.Errorf("failed to get room aliases: %w", err) + } + + for _, alias := range aliases { + if err = r.DB.RemoveRoomAlias(ctx, alias); err != nil { + fmt.Errorf("failed to remove room alias: %w", err) + } + if err = r.DB.SetRoomAlias(ctx, alias, newRoomID, event.Sender()); err != nil { + return fmt.Errorf("failed to set room alias: %w", err) + } + } + return nil +} + // processStateBefore works out what the state is before the event and // then checks the event auths against the state at the time. It also // tries to determine what the history visibility was of the event at