aboutsummaryrefslogtreecommitdiff
path: root/roomserver
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2022-10-26 12:59:19 +0100
committerGitHub <noreply@github.com>2022-10-26 12:59:19 +0100
commitf6dea712d2e9c71f6ebe61f90e45a142852432e8 (patch)
tree981b818ec9ece4e67f1b27ed52f82510aecc465d /roomserver
parent2a4c7f45b37a9bcd1a37d42b0668e0c3dfb29762 (diff)
Initial support for multiple server names (#2829)
This PR is the first step towards virtual hosting by laying the groundwork for multiple server names being configured.
Diffstat (limited to 'roomserver')
-rw-r--r--roomserver/internal/perform/perform_admin.go11
-rw-r--r--roomserver/internal/perform/perform_invite.go4
-rw-r--r--roomserver/internal/perform/perform_join.go23
-rw-r--r--roomserver/internal/perform/perform_leave.go6
-rw-r--r--roomserver/internal/perform/perform_peek.go6
-rw-r--r--roomserver/internal/perform/perform_unpeek.go2
-rw-r--r--roomserver/internal/perform/perform_upgrade.go37
7 files changed, 55 insertions, 34 deletions
diff --git a/roomserver/internal/perform/perform_admin.go b/roomserver/internal/perform/perform_admin.go
index cb6b22d3..6a6d51b0 100644
--- a/roomserver/internal/perform/perform_admin.go
+++ b/roomserver/internal/perform/perform_admin.go
@@ -117,6 +117,11 @@ func (r *Admin) PerformAdminEvacuateRoom(
PrevEvents: prevEvents,
}
+ _, senderDomain, err := gomatrixserverlib.SplitID('@', fledglingEvent.Sender)
+ if err != nil {
+ continue
+ }
+
if fledglingEvent.Content, err = json.Marshal(memberContent); err != nil {
res.Error = &api.PerformError{
Code: api.PerformErrorBadRequest,
@@ -146,8 +151,8 @@ func (r *Admin) PerformAdminEvacuateRoom(
inputEvents = append(inputEvents, api.InputRoomEvent{
Kind: api.KindNew,
Event: event,
- Origin: r.Cfg.Matrix.ServerName,
- SendAsServer: string(r.Cfg.Matrix.ServerName),
+ Origin: senderDomain,
+ SendAsServer: string(senderDomain),
})
res.Affected = append(res.Affected, stateKey)
prevEvents = []gomatrixserverlib.EventReference{
@@ -176,7 +181,7 @@ func (r *Admin) PerformAdminEvacuateUser(
}
return nil
}
- if domain != r.Cfg.Matrix.ServerName {
+ if !r.Cfg.Matrix.IsLocalServerName(domain) {
res.Error = &api.PerformError{
Code: api.PerformErrorBadRequest,
Msg: "Can only evacuate local users using this endpoint",
diff --git a/roomserver/internal/perform/perform_invite.go b/roomserver/internal/perform/perform_invite.go
index 3fbdf332..f60247cd 100644
--- a/roomserver/internal/perform/perform_invite.go
+++ b/roomserver/internal/perform/perform_invite.go
@@ -70,8 +70,8 @@ func (r *Inviter) PerformInvite(
}
return nil, nil
}
- isTargetLocal := domain == r.Cfg.Matrix.ServerName
- isOriginLocal := senderDomain == r.Cfg.Matrix.ServerName
+ isTargetLocal := r.Cfg.Matrix.IsLocalServerName(domain)
+ isOriginLocal := r.Cfg.Matrix.IsLocalServerName(senderDomain)
if !isOriginLocal && !isTargetLocal {
res.Error = &api.PerformError{
Code: api.PerformErrorBadRequest,
diff --git a/roomserver/internal/perform/perform_join.go b/roomserver/internal/perform/perform_join.go
index 262273ff..9d596ab3 100644
--- a/roomserver/internal/perform/perform_join.go
+++ b/roomserver/internal/perform/perform_join.go
@@ -92,7 +92,7 @@ func (r *Joiner) performJoin(
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
}
}
- if domain != r.Cfg.Matrix.ServerName {
+ if !r.Cfg.Matrix.IsLocalServerName(domain) {
return "", "", &rsAPI.PerformError{
Code: rsAPI.PerformErrorBadRequest,
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
@@ -124,7 +124,7 @@ func (r *Joiner) performJoinRoomByAlias(
// Check if this alias matches our own server configuration. If it
// doesn't then we'll need to try a federated join.
var roomID string
- if domain != r.Cfg.Matrix.ServerName {
+ if !r.Cfg.Matrix.IsLocalServerName(domain) {
// The alias isn't owned by us, so we will need to try joining using
// a remote server.
dirReq := fsAPI.PerformDirectoryLookupRequest{
@@ -172,7 +172,7 @@ func (r *Joiner) performJoinRoomByID(
// The original client request ?server_name=... may include this HS so filter that out so we
// don't attempt to make_join with ourselves
for i := 0; i < len(req.ServerNames); i++ {
- if req.ServerNames[i] == r.Cfg.Matrix.ServerName {
+ if r.Cfg.Matrix.IsLocalServerName(req.ServerNames[i]) {
// delete this entry
req.ServerNames = append(req.ServerNames[:i], req.ServerNames[i+1:]...)
i--
@@ -191,12 +191,19 @@ func (r *Joiner) performJoinRoomByID(
// If the server name in the room ID isn't ours then it's a
// possible candidate for finding the room via federation. Add
// it to the list of servers to try.
- if domain != r.Cfg.Matrix.ServerName {
+ if !r.Cfg.Matrix.IsLocalServerName(domain) {
req.ServerNames = append(req.ServerNames, domain)
}
// Prepare the template for the join event.
userID := req.UserID
+ _, userDomain, err := gomatrixserverlib.SplitID('@', userID)
+ if err != nil {
+ return "", "", &rsAPI.PerformError{
+ Code: rsAPI.PerformErrorBadRequest,
+ Msg: fmt.Sprintf("User ID %q is invalid: %s", userID, err),
+ }
+ }
eb := gomatrixserverlib.EventBuilder{
Type: gomatrixserverlib.MRoomMember,
Sender: userID,
@@ -247,7 +254,7 @@ func (r *Joiner) performJoinRoomByID(
// If we were invited by someone from another server then we can
// assume they are in the room so we can join via them.
- if inviterDomain != r.Cfg.Matrix.ServerName {
+ if !r.Cfg.Matrix.IsLocalServerName(inviterDomain) {
req.ServerNames = append(req.ServerNames, inviterDomain)
forceFederatedJoin = true
memberEvent := gjson.Parse(string(inviteEvent.JSON()))
@@ -300,7 +307,7 @@ func (r *Joiner) performJoinRoomByID(
{
Kind: rsAPI.KindNew,
Event: event.Headered(buildRes.RoomVersion),
- SendAsServer: string(r.Cfg.Matrix.ServerName),
+ SendAsServer: string(userDomain),
},
},
}
@@ -323,7 +330,7 @@ func (r *Joiner) performJoinRoomByID(
// The room doesn't exist locally. If the room ID looks like it should
// be ours then this probably means that we've nuked our database at
// some point.
- if domain == r.Cfg.Matrix.ServerName {
+ if r.Cfg.Matrix.IsLocalServerName(domain) {
// If there are no more server names to try then give up here.
// Otherwise we'll try a federated join as normal, since it's quite
// possible that the room still exists on other servers.
@@ -348,7 +355,7 @@ func (r *Joiner) performJoinRoomByID(
// it will have been overwritten with a room ID by performJoinRoomByAlias.
// We should now include this in the response so that the CS API can
// return the right room ID.
- return req.RoomIDOrAlias, r.Cfg.Matrix.ServerName, nil
+ return req.RoomIDOrAlias, userDomain, nil
}
func (r *Joiner) performFederatedJoinRoomByID(
diff --git a/roomserver/internal/perform/perform_leave.go b/roomserver/internal/perform/perform_leave.go
index 85b65981..49e4b479 100644
--- a/roomserver/internal/perform/perform_leave.go
+++ b/roomserver/internal/perform/perform_leave.go
@@ -52,7 +52,7 @@ func (r *Leaver) PerformLeave(
if err != nil {
return nil, fmt.Errorf("supplied user ID %q in incorrect format", req.UserID)
}
- if domain != r.Cfg.Matrix.ServerName {
+ if !r.Cfg.Matrix.IsLocalServerName(domain) {
return nil, fmt.Errorf("user %q does not belong to this homeserver", req.UserID)
}
logger := logrus.WithContext(ctx).WithFields(logrus.Fields{
@@ -85,7 +85,7 @@ func (r *Leaver) performLeaveRoomByID(
if serr != nil {
return nil, fmt.Errorf("sender %q is invalid", senderUser)
}
- if senderDomain != r.Cfg.Matrix.ServerName {
+ if !r.Cfg.Matrix.IsLocalServerName(senderDomain) {
return r.performFederatedRejectInvite(ctx, req, res, senderUser, eventID)
}
// check that this is not a "server notice room"
@@ -186,7 +186,7 @@ func (r *Leaver) performLeaveRoomByID(
Kind: api.KindNew,
Event: event.Headered(buildRes.RoomVersion),
Origin: senderDomain,
- SendAsServer: string(r.Cfg.Matrix.ServerName),
+ SendAsServer: string(senderDomain),
},
},
}
diff --git a/roomserver/internal/perform/perform_peek.go b/roomserver/internal/perform/perform_peek.go
index 74d87a5b..436d137f 100644
--- a/roomserver/internal/perform/perform_peek.go
+++ b/roomserver/internal/perform/perform_peek.go
@@ -72,7 +72,7 @@ func (r *Peeker) performPeek(
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
}
}
- if domain != r.Cfg.Matrix.ServerName {
+ if !r.Cfg.Matrix.IsLocalServerName(domain) {
return "", &api.PerformError{
Code: api.PerformErrorBadRequest,
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
@@ -104,7 +104,7 @@ func (r *Peeker) performPeekRoomByAlias(
// Check if this alias matches our own server configuration. If it
// doesn't then we'll need to try a federated peek.
var roomID string
- if domain != r.Cfg.Matrix.ServerName {
+ if !r.Cfg.Matrix.IsLocalServerName(domain) {
// The alias isn't owned by us, so we will need to try peeking using
// a remote server.
dirReq := fsAPI.PerformDirectoryLookupRequest{
@@ -154,7 +154,7 @@ func (r *Peeker) performPeekRoomByID(
// handle federated peeks
// FIXME: don't create an outbound peek if we already have one going.
- if domain != r.Cfg.Matrix.ServerName {
+ if !r.Cfg.Matrix.IsLocalServerName(domain) {
// If the server name in the room ID isn't ours then it's a
// possible candidate for finding the room via federation. Add
// it to the list of servers to try.
diff --git a/roomserver/internal/perform/perform_unpeek.go b/roomserver/internal/perform/perform_unpeek.go
index 49e9067c..0d97da4d 100644
--- a/roomserver/internal/perform/perform_unpeek.go
+++ b/roomserver/internal/perform/perform_unpeek.go
@@ -67,7 +67,7 @@ func (r *Unpeeker) performUnpeek(
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
}
}
- if domain != r.Cfg.Matrix.ServerName {
+ if !r.Cfg.Matrix.IsLocalServerName(domain) {
return &api.PerformError{
Code: api.PerformErrorBadRequest,
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
diff --git a/roomserver/internal/perform/perform_upgrade.go b/roomserver/internal/perform/perform_upgrade.go
index d6dc9708..38abe323 100644
--- a/roomserver/internal/perform/perform_upgrade.go
+++ b/roomserver/internal/perform/perform_upgrade.go
@@ -60,6 +60,13 @@ func (r *Upgrader) performRoomUpgrade(
) (string, *api.PerformError) {
roomID := req.RoomID
userID := req.UserID
+ _, userDomain, err := gomatrixserverlib.SplitID('@', userID)
+ if err != nil {
+ return "", &api.PerformError{
+ Code: api.PerformErrorNotAllowed,
+ Msg: "Error validating the user ID",
+ }
+ }
evTime := time.Now()
// Return an immediate error if the room does not exist
@@ -80,7 +87,7 @@ func (r *Upgrader) performRoomUpgrade(
// TODO (#267): Check room ID doesn't clash with an existing one, and we
// probably shouldn't be using pseudo-random strings, maybe GUIDs?
- newRoomID := fmt.Sprintf("!%s:%s", util.RandomString(16), r.Cfg.Matrix.ServerName)
+ newRoomID := fmt.Sprintf("!%s:%s", util.RandomString(16), userDomain)
// Get the existing room state for the old room.
oldRoomReq := &api.QueryLatestEventsAndStateRequest{
@@ -107,12 +114,12 @@ func (r *Upgrader) performRoomUpgrade(
}
// Send the setup events to the new room
- if pErr = r.sendInitialEvents(ctx, evTime, userID, newRoomID, string(req.RoomVersion), eventsToMake); pErr != nil {
+ if pErr = r.sendInitialEvents(ctx, evTime, userID, userDomain, newRoomID, string(req.RoomVersion), eventsToMake); pErr != nil {
return "", pErr
}
// 5. Send the tombstone event to the old room
- if pErr = r.sendHeaderedEvent(ctx, tombstoneEvent, string(r.Cfg.Matrix.ServerName)); pErr != nil {
+ if pErr = r.sendHeaderedEvent(ctx, userDomain, tombstoneEvent, string(userDomain)); pErr != nil {
return "", pErr
}
@@ -122,7 +129,7 @@ func (r *Upgrader) performRoomUpgrade(
}
// If the old room had a canonical alias event, it should be deleted in the old room
- if pErr = r.clearOldCanonicalAliasEvent(ctx, oldRoomRes, evTime, userID, roomID); pErr != nil {
+ if pErr = r.clearOldCanonicalAliasEvent(ctx, oldRoomRes, evTime, userID, userDomain, roomID); pErr != nil {
return "", pErr
}
@@ -132,7 +139,7 @@ func (r *Upgrader) performRoomUpgrade(
}
// 6. Restrict power levels in the old room
- if pErr = r.restrictOldRoomPowerLevels(ctx, evTime, userID, roomID); pErr != nil {
+ if pErr = r.restrictOldRoomPowerLevels(ctx, evTime, userID, userDomain, roomID); pErr != nil {
return "", pErr
}
@@ -154,7 +161,7 @@ func (r *Upgrader) getRoomPowerLevels(ctx context.Context, roomID string) (*goma
return powerLevelContent, nil
}
-func (r *Upgrader) restrictOldRoomPowerLevels(ctx context.Context, evTime time.Time, userID, roomID string) *api.PerformError {
+func (r *Upgrader) restrictOldRoomPowerLevels(ctx context.Context, evTime time.Time, userID string, userDomain gomatrixserverlib.ServerName, roomID string) *api.PerformError {
restrictedPowerLevelContent, pErr := r.getRoomPowerLevels(ctx, roomID)
if pErr != nil {
return pErr
@@ -183,7 +190,7 @@ func (r *Upgrader) restrictOldRoomPowerLevels(ctx context.Context, evTime time.T
return resErr
}
} else {
- if resErr = r.sendHeaderedEvent(ctx, restrictedPowerLevelsHeadered, api.DoNotSendToOtherServers); resErr != nil {
+ if resErr = r.sendHeaderedEvent(ctx, userDomain, restrictedPowerLevelsHeadered, api.DoNotSendToOtherServers); resErr != nil {
return resErr
}
}
@@ -223,7 +230,7 @@ func moveLocalAliases(ctx context.Context,
return nil
}
-func (r *Upgrader) clearOldCanonicalAliasEvent(ctx context.Context, oldRoom *api.QueryLatestEventsAndStateResponse, evTime time.Time, userID, roomID string) *api.PerformError {
+func (r *Upgrader) clearOldCanonicalAliasEvent(ctx context.Context, oldRoom *api.QueryLatestEventsAndStateResponse, evTime time.Time, userID string, userDomain gomatrixserverlib.ServerName, roomID string) *api.PerformError {
for _, event := range oldRoom.StateEvents {
if event.Type() != gomatrixserverlib.MRoomCanonicalAlias || !event.StateKeyEquals("") {
continue
@@ -254,7 +261,7 @@ func (r *Upgrader) clearOldCanonicalAliasEvent(ctx context.Context, oldRoom *api
return resErr
}
} else {
- if resErr = r.sendHeaderedEvent(ctx, emptyCanonicalAliasEvent, api.DoNotSendToOtherServers); resErr != nil {
+ if resErr = r.sendHeaderedEvent(ctx, userDomain, emptyCanonicalAliasEvent, api.DoNotSendToOtherServers); resErr != nil {
return resErr
}
}
@@ -495,7 +502,7 @@ func (r *Upgrader) generateInitialEvents(ctx context.Context, oldRoom *api.Query
return eventsToMake, nil
}
-func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, userID, newRoomID, newVersion string, eventsToMake []fledglingEvent) *api.PerformError {
+func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, userID string, userDomain gomatrixserverlib.ServerName, newRoomID, newVersion string, eventsToMake []fledglingEvent) *api.PerformError {
var err error
var builtEvents []*gomatrixserverlib.HeaderedEvent
authEvents := gomatrixserverlib.NewAuthEvents(nil)
@@ -519,7 +526,7 @@ func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, user
builder.PrevEvents = []gomatrixserverlib.EventReference{builtEvents[i-1].EventReference()}
}
var event *gomatrixserverlib.Event
- event, err = r.buildEvent(&builder, &authEvents, evTime, gomatrixserverlib.RoomVersion(newVersion))
+ event, err = r.buildEvent(&builder, userDomain, &authEvents, evTime, gomatrixserverlib.RoomVersion(newVersion))
if err != nil {
return &api.PerformError{
Msg: fmt.Sprintf("Failed to build new %q event: %s", builder.Type, err),
@@ -547,7 +554,7 @@ func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, user
inputs = append(inputs, api.InputRoomEvent{
Kind: api.KindNew,
Event: event,
- Origin: r.Cfg.Matrix.ServerName,
+ Origin: userDomain,
SendAsServer: api.DoNotSendToOtherServers,
})
}
@@ -668,6 +675,7 @@ func createTemporaryPowerLevels(powerLevelContent *gomatrixserverlib.PowerLevelC
func (r *Upgrader) sendHeaderedEvent(
ctx context.Context,
+ serverName gomatrixserverlib.ServerName,
headeredEvent *gomatrixserverlib.HeaderedEvent,
sendAsServer string,
) *api.PerformError {
@@ -675,7 +683,7 @@ func (r *Upgrader) sendHeaderedEvent(
inputs = append(inputs, api.InputRoomEvent{
Kind: api.KindNew,
Event: headeredEvent,
- Origin: r.Cfg.Matrix.ServerName,
+ Origin: serverName,
SendAsServer: sendAsServer,
})
if err := api.SendInputRoomEvents(ctx, r.URSAPI, inputs, false); err != nil {
@@ -689,6 +697,7 @@ func (r *Upgrader) sendHeaderedEvent(
func (r *Upgrader) buildEvent(
builder *gomatrixserverlib.EventBuilder,
+ serverName gomatrixserverlib.ServerName,
provider gomatrixserverlib.AuthEventProvider,
evTime time.Time,
roomVersion gomatrixserverlib.RoomVersion,
@@ -703,7 +712,7 @@ func (r *Upgrader) buildEvent(
}
builder.AuthEvents = refs
event, err := builder.Build(
- evTime, r.Cfg.Matrix.ServerName, r.Cfg.Matrix.KeyID,
+ evTime, serverName, r.Cfg.Matrix.KeyID,
r.Cfg.Matrix.PrivateKey, roomVersion,
)
if err != nil {