mirror of
https://github.com/matrix-org/dendrite.git
synced 2026-01-03 12:13:09 -06:00
Refactor generateInitialEvents to preserve old state events for all but the essential room setup events
This commit is contained in:
parent
e34da3a52d
commit
3613ac3f74
|
|
@ -310,7 +310,7 @@ func (r *Upgrader) userIsAuthorized(ctx context.Context, userID, roomID string,
|
||||||
return pl.UserLevel(userID) >= plToUpgrade
|
return pl.UserLevel(userID) >= plToUpgrade
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:composites,gocyclo
|
// nolint:gocyclo
|
||||||
func (r *Upgrader) generateInitialEvents(ctx context.Context, userID, roomID, newVersion string, tombstoneEvent *gomatrixserverlib.HeaderedEvent) ([]fledglingEvent, *api.PerformError) {
|
func (r *Upgrader) generateInitialEvents(ctx context.Context, userID, roomID, newVersion string, tombstoneEvent *gomatrixserverlib.HeaderedEvent) ([]fledglingEvent, *api.PerformError) {
|
||||||
req := &api.QueryLatestEventsAndStateRequest{
|
req := &api.QueryLatestEventsAndStateRequest{
|
||||||
RoomID: roomID,
|
RoomID: roomID,
|
||||||
|
|
@ -321,54 +321,45 @@ func (r *Upgrader) generateInitialEvents(ctx context.Context, userID, roomID, ne
|
||||||
Msg: fmt.Sprintf("Failed to get latest state: %s", err),
|
Msg: fmt.Sprintf("Failed to get latest state: %s", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state := make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent, len(res.StateEvents))
|
state := make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent, len(res.StateEvents))
|
||||||
for _, event := range res.StateEvents {
|
for _, event := range res.StateEvents {
|
||||||
if event.StateKey() == nil {
|
if event.StateKey() == nil {
|
||||||
continue // shouldn't ever happen, but better to be safe than sorry
|
// This shouldn't ever happen, but better to be safe than sorry.
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
tuple := gomatrixserverlib.StateKeyTuple{EventType: event.Type(), StateKey: *event.StateKey()}
|
if event.Type() == gomatrixserverlib.MRoomMember && !event.StateKeyEquals(userID) {
|
||||||
state[tuple] = event
|
// Ignore membership events that aren't our own, as event auth will
|
||||||
|
// prevent us from being able to create membership events on behalf
|
||||||
|
// of other users anyway unless they are invites or bans.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
state[gomatrixserverlib.StateKeyTuple{EventType: event.Type(), StateKey: *event.StateKey()}] = event
|
||||||
}
|
}
|
||||||
|
|
||||||
oldCreateEvent := state[gomatrixserverlib.StateKeyTuple{
|
// The following events are ones that we are going to override manually
|
||||||
EventType: gomatrixserverlib.MRoomCreate, StateKey: "",
|
// in the following section.
|
||||||
}]
|
override := map[gomatrixserverlib.StateKeyTuple]struct{}{
|
||||||
oldMembershipEvent := state[gomatrixserverlib.StateKeyTuple{
|
{EventType: gomatrixserverlib.MRoomCreate, StateKey: ""}: {},
|
||||||
EventType: gomatrixserverlib.MRoomMember, StateKey: userID,
|
{EventType: gomatrixserverlib.MRoomMember, StateKey: userID}: {},
|
||||||
}]
|
{EventType: gomatrixserverlib.MRoomPowerLevels, StateKey: ""}: {},
|
||||||
oldPowerLevelsEvent := state[gomatrixserverlib.StateKeyTuple{
|
{EventType: gomatrixserverlib.MRoomJoinRules, StateKey: ""}: {},
|
||||||
EventType: gomatrixserverlib.MRoomPowerLevels, StateKey: "",
|
}
|
||||||
}]
|
|
||||||
oldJoinRulesEvent := state[gomatrixserverlib.StateKeyTuple{
|
// The overridden events are essential events that must be present in the
|
||||||
EventType: gomatrixserverlib.MRoomJoinRules, StateKey: "",
|
// old room state. Check that they are there.
|
||||||
}]
|
for tuple := range override {
|
||||||
oldHistoryVisibilityEvent := state[gomatrixserverlib.StateKeyTuple{
|
if _, ok := state[tuple]; !ok {
|
||||||
EventType: gomatrixserverlib.MRoomHistoryVisibility, StateKey: "",
|
return nil, &api.PerformError{
|
||||||
}]
|
Msg: fmt.Sprintf("Essential event of type %q state key %q is missing", tuple.EventType, tuple.StateKey),
|
||||||
oldNameEvent := state[gomatrixserverlib.StateKeyTuple{
|
}
|
||||||
EventType: gomatrixserverlib.MRoomName, StateKey: "",
|
}
|
||||||
}]
|
}
|
||||||
oldTopicEvent := state[gomatrixserverlib.StateKeyTuple{
|
|
||||||
EventType: gomatrixserverlib.MRoomTopic, StateKey: "",
|
oldCreateEvent := state[gomatrixserverlib.StateKeyTuple{EventType: gomatrixserverlib.MRoomCreate, StateKey: ""}]
|
||||||
}]
|
oldMembershipEvent := state[gomatrixserverlib.StateKeyTuple{EventType: gomatrixserverlib.MRoomMember, StateKey: userID}]
|
||||||
oldGuestAccessEvent := state[gomatrixserverlib.StateKeyTuple{
|
oldPowerLevelsEvent := state[gomatrixserverlib.StateKeyTuple{EventType: gomatrixserverlib.MRoomPowerLevels, StateKey: ""}]
|
||||||
EventType: gomatrixserverlib.MRoomGuestAccess, StateKey: "",
|
oldJoinRulesEvent := state[gomatrixserverlib.StateKeyTuple{EventType: gomatrixserverlib.MRoomJoinRules, StateKey: ""}]
|
||||||
}]
|
|
||||||
oldAvatarEvent := state[gomatrixserverlib.StateKeyTuple{
|
|
||||||
EventType: gomatrixserverlib.MRoomAvatar, StateKey: "",
|
|
||||||
}]
|
|
||||||
oldEncryptionEvent := state[gomatrixserverlib.StateKeyTuple{
|
|
||||||
EventType: gomatrixserverlib.MRoomEncryption, StateKey: "",
|
|
||||||
}]
|
|
||||||
oldCanonicalAliasEvent := state[gomatrixserverlib.StateKeyTuple{
|
|
||||||
EventType: gomatrixserverlib.MRoomCanonicalAlias, StateKey: "",
|
|
||||||
}]
|
|
||||||
oldServerAclEvent := state[gomatrixserverlib.StateKeyTuple{
|
|
||||||
EventType: "m.room.server_acl", StateKey: "",
|
|
||||||
}]
|
|
||||||
oldRelatedGroupsEvent := state[gomatrixserverlib.StateKeyTuple{
|
|
||||||
EventType: "m.room.related_groups", StateKey: "",
|
|
||||||
}]
|
|
||||||
|
|
||||||
newCreateContent := map[string]interface{}{
|
newCreateContent := map[string]interface{}{
|
||||||
"creator": userID,
|
"creator": userID,
|
||||||
|
|
@ -433,125 +424,19 @@ func (r *Upgrader) generateInitialEvents(ctx context.Context, userID, roomID, ne
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
historyVisibilityContent, err := oldHistoryVisibilityEvent.HistoryVisibility()
|
eventsToMake := make([]fledglingEvent, 0, len(state))
|
||||||
if err != nil {
|
eventsToMake = append(eventsToMake, newCreateEvent, membershipEvent, tempPowerLevelsEvent, newJoinRulesEvent)
|
||||||
return nil, &api.PerformError{
|
|
||||||
Msg: "History visibility event had bad content",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newHistoryVisibilityEvent := fledglingEvent{
|
|
||||||
Type: gomatrixserverlib.MRoomHistoryVisibility,
|
|
||||||
Content: map[string]interface{}{
|
|
||||||
"history_visibility": historyVisibilityContent,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var newNameEvent fledglingEvent
|
if _, ok := state[gomatrixserverlib.StateKeyTuple{EventType: gomatrixserverlib.MRoomGuestAccess, StateKey: ""}]; !ok {
|
||||||
var newTopicEvent fledglingEvent
|
// Appease sytest, as it expects a guest access event for some reason.
|
||||||
var newGuestAccessEvent fledglingEvent
|
|
||||||
var newAvatarEvent fledglingEvent
|
|
||||||
var newEncryptionEvent fledglingEvent
|
|
||||||
var newServerACLEvent fledglingEvent
|
|
||||||
var newRelatedGroupsEvent fledglingEvent
|
|
||||||
var newCanonicalAliasEvent fledglingEvent
|
|
||||||
|
|
||||||
if oldNameEvent != nil {
|
|
||||||
newNameEvent = fledglingEvent{
|
|
||||||
Type: gomatrixserverlib.MRoomName,
|
|
||||||
Content: unmarshal(oldNameEvent.Content()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if oldTopicEvent != nil {
|
|
||||||
newTopicEvent = fledglingEvent{
|
|
||||||
Type: gomatrixserverlib.MRoomTopic,
|
|
||||||
Content: unmarshal(oldTopicEvent.Content()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if oldGuestAccessEvent != nil {
|
|
||||||
newGuestAccessEvent = fledglingEvent{
|
|
||||||
Type: gomatrixserverlib.MRoomGuestAccess,
|
|
||||||
Content: unmarshal(oldGuestAccessEvent.Content()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if oldAvatarEvent != nil {
|
|
||||||
newAvatarEvent = fledglingEvent{
|
|
||||||
Type: gomatrixserverlib.MRoomAvatar,
|
|
||||||
Content: unmarshal(oldAvatarEvent.Content()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if oldEncryptionEvent != nil {
|
|
||||||
newEncryptionEvent = fledglingEvent{
|
|
||||||
Type: gomatrixserverlib.MRoomEncryption,
|
|
||||||
Content: unmarshal(oldEncryptionEvent.Content()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if oldServerAclEvent != nil {
|
|
||||||
newServerACLEvent = fledglingEvent{
|
|
||||||
Type: "m.room.server_acl",
|
|
||||||
Content: unmarshal(oldServerAclEvent.Content()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if oldRelatedGroupsEvent != nil {
|
|
||||||
newRelatedGroupsEvent = fledglingEvent{
|
|
||||||
Type: "m.room.related_groups",
|
|
||||||
Content: unmarshal(oldRelatedGroupsEvent.Content()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if oldCanonicalAliasEvent != nil {
|
|
||||||
newCanonicalAliasEvent = fledglingEvent{
|
|
||||||
Type: gomatrixserverlib.MRoomCanonicalAlias,
|
|
||||||
Content: unmarshal(oldCanonicalAliasEvent.Content()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Replicate transferable state events
|
|
||||||
// send events into the room in order of:
|
|
||||||
// 1- m.room.create
|
|
||||||
// 2- m.room.power_levels (temporary, to allow the upgrading user to send everything)
|
|
||||||
// 3- m.room.join_rules
|
|
||||||
// 4- m.room.history_visibility
|
|
||||||
// 5- m.room.guest_access
|
|
||||||
// 6- m.room.name
|
|
||||||
// 7- m.room.avatar
|
|
||||||
// 8- m.room.topic
|
|
||||||
// 9- m.room.encryption
|
|
||||||
// 10-m.room.server_acl
|
|
||||||
// 11-m.room.related_groups
|
|
||||||
// 12-m.room.canonical_alias
|
|
||||||
// 13-All ban events from the old room
|
|
||||||
// 14-The original room power levels
|
|
||||||
eventsToMake := []fledglingEvent{
|
|
||||||
newCreateEvent, membershipEvent, tempPowerLevelsEvent, newJoinRulesEvent, newHistoryVisibilityEvent,
|
|
||||||
}
|
|
||||||
if oldGuestAccessEvent != nil {
|
|
||||||
eventsToMake = append(eventsToMake, newGuestAccessEvent)
|
|
||||||
} else { // Always create this with the default value to appease sytests
|
|
||||||
eventsToMake = append(eventsToMake, fledglingEvent{
|
eventsToMake = append(eventsToMake, fledglingEvent{
|
||||||
Type: gomatrixserverlib.MRoomGuestAccess,
|
Type: gomatrixserverlib.MRoomGuestAccess,
|
||||||
Content: map[string]interface{}{"guest_access": "forbidden"},
|
Content: map[string]string{
|
||||||
|
"guest_access": "forbidden",
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if oldNameEvent != nil {
|
|
||||||
eventsToMake = append(eventsToMake, newNameEvent)
|
|
||||||
}
|
|
||||||
if oldAvatarEvent != nil {
|
|
||||||
eventsToMake = append(eventsToMake, newAvatarEvent)
|
|
||||||
}
|
|
||||||
if oldTopicEvent != nil {
|
|
||||||
eventsToMake = append(eventsToMake, newTopicEvent)
|
|
||||||
}
|
|
||||||
if oldEncryptionEvent != nil {
|
|
||||||
eventsToMake = append(eventsToMake, newEncryptionEvent)
|
|
||||||
}
|
|
||||||
if oldServerAclEvent != nil {
|
|
||||||
eventsToMake = append(eventsToMake, newServerACLEvent)
|
|
||||||
}
|
|
||||||
if oldRelatedGroupsEvent != nil {
|
|
||||||
eventsToMake = append(eventsToMake, newRelatedGroupsEvent)
|
|
||||||
}
|
|
||||||
if oldCanonicalAliasEvent != nil {
|
|
||||||
eventsToMake = append(eventsToMake, newCanonicalAliasEvent)
|
|
||||||
}
|
|
||||||
banEvents, err := getBanEvents(ctx, roomID, r.URSAPI)
|
banEvents, err := getBanEvents(ctx, roomID, r.URSAPI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &api.PerformError{
|
return nil, &api.PerformError{
|
||||||
|
|
@ -560,6 +445,30 @@ func (r *Upgrader) generateInitialEvents(ctx context.Context, userID, roomID, ne
|
||||||
} else {
|
} else {
|
||||||
eventsToMake = append(eventsToMake, banEvents...)
|
eventsToMake = append(eventsToMake, banEvents...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Duplicate all of the old state events into the new room.
|
||||||
|
for tuple, event := range state {
|
||||||
|
if _, ok := override[tuple]; ok {
|
||||||
|
// Don't duplicate events we have overridden already. They
|
||||||
|
// are already in `eventsToMake`.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if event.Type() == gomatrixserverlib.MRoomMember {
|
||||||
|
// Don't duplicate membership events. Our own membership
|
||||||
|
// event has already been created above, and event auth won't
|
||||||
|
// let us create membership events for other users.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newEvent := fledglingEvent{
|
||||||
|
Type: tuple.EventType,
|
||||||
|
StateKey: tuple.StateKey,
|
||||||
|
}
|
||||||
|
if err = json.Unmarshal(event.Content(), &newEvent.Content); err != nil {
|
||||||
|
logrus.WithError(err).Error("Failed to unmarshal old event")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
eventsToMake = append(eventsToMake, newEvent)
|
||||||
|
}
|
||||||
eventsToMake = append(eventsToMake, newPowerLevelsEvent)
|
eventsToMake = append(eventsToMake, newPowerLevelsEvent)
|
||||||
return eventsToMake, nil
|
return eventsToMake, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue