mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-07-29 12:42:46 +00:00
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.
This commit is contained in:
parent
2a4c7f45b3
commit
f6dea712d2
46 changed files with 291 additions and 155 deletions
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue