aboutsummaryrefslogtreecommitdiff
path: root/roomserver
diff options
context:
space:
mode:
authorS7evinK <2353100+S7evinK@users.noreply.github.com>2022-03-07 10:37:04 +0100
committerGitHub <noreply@github.com>2022-03-07 10:37:04 +0100
commit9fbaa1194bb3d7e9f4dfff09461528b846d26a6e (patch)
tree42b6beb39024ff9666c84c2e4ad5e3abf4bec35b /roomserver
parent86d4eef9f10abd944bf689298cc6f9e915b940c7 (diff)
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
Diffstat (limited to 'roomserver')
-rw-r--r--roomserver/api/alias.go19
-rw-r--r--roomserver/api/alias_test.go62
-rw-r--r--roomserver/internal/alias.go61
3 files changed, 140 insertions, 2 deletions
diff --git a/roomserver/api/alias.go b/roomserver/api/alias.go
index df69e5b4..be37333b 100644
--- a/roomserver/api/alias.go
+++ b/roomserver/api/alias.go
@@ -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)
+}
+
diff --git a/roomserver/api/alias_test.go b/roomserver/api/alias_test.go
new file mode 100644
index 00000000..680493b7
--- /dev/null
+++ b/roomserver/api/alias_test.go
@@ -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)
+ }
+ })
+ }
+}
diff --git a/roomserver/internal/alias.go b/roomserver/internal/alias.go
index 7995279d..5c1c04f0 100644
--- a/roomserver/internal/alias.go
+++ b/roomserver/internal/alias.go
@@ -16,12 +16,18 @@ package internal
import (
"context"
+ "database/sql"
+ "errors"
"fmt"
+ "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"
-
- asAPI "github.com/matrix-org/dendrite/appservice/api"
+ "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