diff options
author | Neil Alexander <neilalexander@users.noreply.github.com> | 2021-07-21 16:53:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-21 16:53:50 +0100 |
commit | c1447a58e5de5408d80e0de84c0424342121b06c (patch) | |
tree | 860e76d35790c547df26cb554632e9d1cbc76287 /roomserver | |
parent | f0f8c7f0553b55c2e83400ca812b9d64bac00511 (diff) |
Various alias fixes (#1934)
* Generate m.room.canonical_alias instead of legacy m.room.aliases
* Add omitempty tags
* Add aliases endpoint to client API
* Check power levels when setting aliases
* Don't return null on /aliases
* Don't return error if the state event fails
* Update sytest-whitelist
* Don't send updated m.room.canonical_alias events
* Don't check PLs after all because for local aliases they are apparently irrelevant
* Fix some bugs
* Allow deleting a local alias with enough PL
* Fix some more bugs
* Update sytest-whitelist
* Fix copyright notices
* Review comments
Diffstat (limited to 'roomserver')
-rw-r--r-- | roomserver/api/alias.go | 7 | ||||
-rw-r--r-- | roomserver/internal/alias.go | 133 | ||||
-rw-r--r-- | roomserver/internal/perform/perform_invite.go | 4 | ||||
-rw-r--r-- | roomserver/storage/shared/storage.go | 3 |
4 files changed, 35 insertions, 112 deletions
diff --git a/roomserver/api/alias.go b/roomserver/api/alias.go index 2eb91129..df69e5b4 100644 --- a/roomserver/api/alias.go +++ b/roomserver/api/alias.go @@ -78,4 +78,9 @@ type RemoveRoomAliasRequest struct { } // RemoveRoomAliasResponse is a response to RemoveRoomAlias -type RemoveRoomAliasResponse struct{} +type RemoveRoomAliasResponse struct { + // Did the alias exist before? + Found bool `json:"found"` + // Did we remove it? + Removed bool `json:"removed"` +} diff --git a/roomserver/internal/alias.go b/roomserver/internal/alias.go index f15881d7..7995279d 100644 --- a/roomserver/internal/alias.go +++ b/roomserver/internal/alias.go @@ -16,10 +16,7 @@ package internal import ( "context" - "encoding/json" - "errors" "fmt" - "time" "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrixserverlib" @@ -73,11 +70,7 @@ func (r *RoomserverInternalAPI) SetRoomAlias( return err } - // Send a m.room.aliases event with the updated list of aliases for this room - // At this point we've already committed the alias to the database so we - // shouldn't cancel this request. - // TODO: Ensure that we send unsent events when if server restarts. - return r.sendUpdatedAliasesEvent(context.TODO(), request.UserID, request.RoomID) + return nil } // GetRoomIDForAlias implements alias.RoomserverInternalAPI @@ -157,122 +150,44 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias( request *api.RemoveRoomAliasRequest, response *api.RemoveRoomAliasResponse, ) error { - // Look up the room ID in the database roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias) if err != nil { - return err - } - - // Remove the dalias from the database - if err := r.DB.RemoveRoomAlias(ctx, request.Alias); err != nil { - return err + return fmt.Errorf("r.DB.GetRoomIDForAlias: %w", err) } - - // Send an updated m.room.aliases event - // At this point we've already committed the alias to the database so we - // shouldn't cancel this request. - // TODO: Ensure that we send unsent events when if server restarts. - return r.sendUpdatedAliasesEvent(context.TODO(), request.UserID, roomID) -} - -type roomAliasesContent struct { - Aliases []string `json:"aliases"` -} - -// Build the updated m.room.aliases event to send to the room after addition or -// removal of an alias -func (r *RoomserverInternalAPI) sendUpdatedAliasesEvent( - ctx context.Context, userID string, roomID string, -) error { - serverName := string(r.Cfg.Matrix.ServerName) - - builder := gomatrixserverlib.EventBuilder{ - Sender: userID, - RoomID: roomID, - Type: "m.room.aliases", - StateKey: &serverName, + if roomID == "" { + response.Found = false + response.Removed = false + return nil } - // Retrieve the updated list of aliases, marhal it and set it as the - // event's content - aliases, err := r.DB.GetAliasesForRoomID(ctx, roomID) - if err != nil { - return err - } - content := roomAliasesContent{Aliases: aliases} - rawContent, err := json.Marshal(content) - if err != nil { - return err - } - err = builder.SetContent(json.RawMessage(rawContent)) + response.Found = true + creatorID, err := r.DB.GetCreatorIDForAlias(ctx, request.Alias) if err != nil { - return err + return fmt.Errorf("r.DB.GetCreatorIDForAlias: %w", err) } - // Get needed state events and depth - eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(&builder) - if err != nil { - return err - } - if len(eventsNeeded.Tuples()) == 0 { - return errors.New("expecting state tuples for event builder, got none") - } - req := api.QueryLatestEventsAndStateRequest{ - RoomID: roomID, - StateToFetch: eventsNeeded.Tuples(), - } - var res api.QueryLatestEventsAndStateResponse - if err = r.QueryLatestEventsAndState(ctx, &req, &res); err != nil { - return err - } - builder.Depth = res.Depth - builder.PrevEvents = res.LatestEvents + if creatorID != request.UserID { + plEvent, err := r.DB.GetStateEvent(ctx, roomID, gomatrixserverlib.MRoomPowerLevels, "") + if err != nil { + return fmt.Errorf("r.DB.GetStateEvent: %w", err) + } - // Add auth events - authEvents := gomatrixserverlib.NewAuthEvents(nil) - for i := range res.StateEvents { - err = authEvents.AddEvent(res.StateEvents[i].Event) + pls, err := plEvent.PowerLevels() if err != nil { - return err + return fmt.Errorf("plEvent.PowerLevels: %w", err) } - } - refs, err := eventsNeeded.AuthEventReferences(&authEvents) - if err != nil { - return err - } - builder.AuthEvents = refs - roomInfo, err := r.DB.RoomInfo(ctx, roomID) - if err != nil { - return err - } - if roomInfo == nil { - return fmt.Errorf("room %s does not exist", roomID) + if pls.UserLevel(request.UserID) < pls.EventLevel(gomatrixserverlib.MRoomCanonicalAlias, true) { + response.Removed = false + return nil + } } - // Build the event - now := time.Now() - event, err := builder.Build( - now, r.Cfg.Matrix.ServerName, r.Cfg.Matrix.KeyID, - r.Cfg.Matrix.PrivateKey, roomInfo.RoomVersion, - ) - if err != nil { + // Remove the alias from the database + if err := r.DB.RemoveRoomAlias(ctx, request.Alias); err != nil { return err } - // Create the request - ire := api.InputRoomEvent{ - Kind: api.KindNew, - Event: event.Headered(roomInfo.RoomVersion), - AuthEventIDs: event.AuthEventIDs(), - SendAsServer: serverName, - } - inputReq := api.InputRoomEventsRequest{ - InputRoomEvents: []api.InputRoomEvent{ire}, - } - var inputRes api.InputRoomEventsResponse - - // Send the request - r.InputRoomEvents(ctx, &inputReq, &inputRes) - return inputRes.Err() + response.Removed = true + return nil } diff --git a/roomserver/internal/perform/perform_invite.go b/roomserver/internal/perform/perform_invite.go index fa65ce9b..c6ad79d9 100644 --- a/roomserver/internal/perform/perform_invite.go +++ b/roomserver/internal/perform/perform_invite.go @@ -223,8 +223,8 @@ func buildInviteStrippedState( // https://matrix.org/docs/spec/client_server/r0.6.0#m-room-member for _, t := range []string{ gomatrixserverlib.MRoomName, gomatrixserverlib.MRoomCanonicalAlias, - gomatrixserverlib.MRoomAliases, gomatrixserverlib.MRoomJoinRules, - "m.room.avatar", "m.room.encryption", gomatrixserverlib.MRoomCreate, + gomatrixserverlib.MRoomJoinRules, gomatrixserverlib.MRoomAvatar, + gomatrixserverlib.MRoomEncryption, gomatrixserverlib.MRoomCreate, } { stateWanted = append(stateWanted, gomatrixserverlib.StateKeyTuple{ EventType: t, diff --git a/roomserver/storage/shared/storage.go b/roomserver/storage/shared/storage.go index 4c1aae42..e1851679 100644 --- a/roomserver/storage/shared/storage.go +++ b/roomserver/storage/shared/storage.go @@ -857,6 +857,9 @@ func (d *Database) GetStateEvent(ctx context.Context, roomID, evType, stateKey s if err != nil { return nil, err } + if roomInfo == nil || roomInfo.IsStub { + return nil, fmt.Errorf("room %s doesn't exist", roomID) + } eventTypeNID, err := d.EventTypesTable.SelectEventTypeNID(ctx, nil, evType) if err == sql.ErrNoRows { // No rooms have an event of this type, otherwise we'd have an event type NID |