mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-07-29 12:42:46 +00:00
Add canonical alias support (#2236)
* Add canonical support * Add test * Check that the send event is actually an m.room.canonical_alias Check that we got an event from the database * Update to get correct required events * Add flakey test to blacklist
This commit is contained in:
parent
86d4eef9f1
commit
9fbaa1194b
7 changed files with 190 additions and 6 deletions
|
@ -14,6 +14,8 @@
|
|||
|
||||
package api
|
||||
|
||||
import "regexp"
|
||||
|
||||
// SetRoomAliasRequest is a request to SetRoomAlias
|
||||
type SetRoomAliasRequest struct {
|
||||
// ID of the user setting the alias
|
||||
|
@ -84,3 +86,20 @@ type RemoveRoomAliasResponse struct {
|
|||
// Did we remove it?
|
||||
Removed bool `json:"removed"`
|
||||
}
|
||||
|
||||
type AliasEvent struct {
|
||||
Alias string `json:"alias"`
|
||||
AltAliases []string `json:"alt_aliases"`
|
||||
}
|
||||
|
||||
var validateAliasRegex = regexp.MustCompile("^#.*:.+$")
|
||||
|
||||
func (a AliasEvent) Valid() bool {
|
||||
for _, alias := range a.AltAliases {
|
||||
if !validateAliasRegex.MatchString(alias) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return a.Alias == "" || validateAliasRegex.MatchString(a.Alias)
|
||||
}
|
||||
|
||||
|
|
62
roomserver/api/alias_test.go
Normal file
62
roomserver/api/alias_test.go
Normal file
|
@ -0,0 +1,62 @@
|
|||
package api
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestAliasEvent_Valid(t *testing.T) {
|
||||
type fields struct {
|
||||
Alias string
|
||||
AltAliases []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "empty alias",
|
||||
fields: fields{
|
||||
Alias: "",
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "empty alias, invalid alt aliases",
|
||||
fields: fields{
|
||||
Alias: "",
|
||||
AltAliases: []string{ "%not:valid.local"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "valid alias, invalid alt aliases",
|
||||
fields: fields{
|
||||
Alias: "#valid:test.local",
|
||||
AltAliases: []string{ "%not:valid.local"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty alias, invalid alt aliases",
|
||||
fields: fields{
|
||||
Alias: "",
|
||||
AltAliases: []string{ "%not:valid.local"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid alias",
|
||||
fields: fields{
|
||||
Alias: "%not:valid.local",
|
||||
AltAliases: []string{ },
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
a := AliasEvent{
|
||||
Alias: tt.fields.Alias,
|
||||
AltAliases: tt.fields.AltAliases,
|
||||
}
|
||||
if got := a.Valid(); got != tt.want {
|
||||
t.Errorf("Valid() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -16,12 +16,18 @@ package internal
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"time"
|
||||
|
||||
asAPI "github.com/matrix-org/dendrite/appservice/api"
|
||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
)
|
||||
|
||||
// RoomserverInternalAPIDatabase has the storage APIs needed to implement the alias API.
|
||||
|
@ -183,6 +189,57 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias(
|
|||
}
|
||||
}
|
||||
|
||||
ev, err := r.DB.GetStateEvent(ctx, roomID, gomatrixserverlib.MRoomCanonicalAlias, "")
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return err
|
||||
} else if ev != nil {
|
||||
stateAlias := gjson.GetBytes(ev.Content(), "alias").Str
|
||||
// the alias to remove is currently set as the canonical alias, remove it
|
||||
if stateAlias == request.Alias {
|
||||
res, err := sjson.DeleteBytes(ev.Content(), "alias")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sender := request.UserID
|
||||
if request.UserID != ev.Sender() {
|
||||
sender = ev.Sender()
|
||||
}
|
||||
|
||||
builder := &gomatrixserverlib.EventBuilder{
|
||||
Sender: sender,
|
||||
RoomID: ev.RoomID(),
|
||||
Type: ev.Type(),
|
||||
StateKey: ev.StateKey(),
|
||||
Content: res,
|
||||
}
|
||||
|
||||
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
|
||||
if err != nil {
|
||||
return fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
|
||||
}
|
||||
if len(eventsNeeded.Tuples()) == 0 {
|
||||
return errors.New("expecting state tuples for event builder, got none")
|
||||
}
|
||||
|
||||
stateRes := &api.QueryLatestEventsAndStateResponse{}
|
||||
if err := helpers.QueryLatestEventsAndState(ctx, r.DB, &api.QueryLatestEventsAndStateRequest{RoomID: roomID, StateToFetch: eventsNeeded.Tuples()}, stateRes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newEvent, err := eventutil.BuildEvent(ctx, builder, r.Cfg.Matrix, time.Now(), &eventsNeeded, stateRes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = api.SendEvents(ctx, r.RSAPI, api.KindNew, []*gomatrixserverlib.HeaderedEvent{newEvent}, r.ServerName, r.ServerName, nil, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the alias from the database
|
||||
if err := r.DB.RemoveRoomAlias(ctx, request.Alias); err != nil {
|
||||
return err
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue