aboutsummaryrefslogtreecommitdiff
path: root/clientapi
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2022-11-15 15:05:23 +0000
committerNeil Alexander <neilalexander@users.noreply.github.com>2022-11-15 15:05:23 +0000
commit6650712a1c0dec282b47b7ba14bc8c2e06a385d8 (patch)
tree12ca755c5c33d3489417f9355dda3f1b7983c779 /clientapi
parentf4ee3977340c84d321767d347795b1dcd05ac459 (diff)
Federation fixes for virtual hosting
Diffstat (limited to 'clientapi')
-rw-r--r--clientapi/routing/admin.go2
-rw-r--r--clientapi/routing/createroom.go2
-rw-r--r--clientapi/routing/directory.go2
-rw-r--r--clientapi/routing/directory_public.go2
-rw-r--r--clientapi/routing/membership.go8
-rw-r--r--clientapi/routing/profile.go14
-rw-r--r--clientapi/routing/redaction.go9
-rw-r--r--clientapi/routing/register.go39
-rw-r--r--clientapi/routing/sendevent.go9
-rw-r--r--clientapi/routing/server_notices.go1
-rw-r--r--clientapi/routing/userdirectory.go2
-rw-r--r--clientapi/threepid/invites.go8
12 files changed, 74 insertions, 24 deletions
diff --git a/clientapi/routing/admin.go b/clientapi/routing/admin.go
index 9ed1f0ca..be8073c3 100644
--- a/clientapi/routing/admin.go
+++ b/clientapi/routing/admin.go
@@ -110,7 +110,7 @@ func AdminResetPassword(req *http.Request, cfg *config.ClientAPI, device *userap
JSON: jsonerror.MissingArgument("Expecting user localpart."),
}
}
- if l, s, err := gomatrixserverlib.SplitID('@', localpart); err == nil {
+ if l, s, err := cfg.Matrix.SplitLocalID('@', localpart); err == nil {
localpart, serverName = l, s
}
request := struct {
diff --git a/clientapi/routing/createroom.go b/clientapi/routing/createroom.go
index eefe8e24..a0d80903 100644
--- a/clientapi/routing/createroom.go
+++ b/clientapi/routing/createroom.go
@@ -477,7 +477,7 @@ func createRoom(
SendAsServer: roomserverAPI.DoNotSendToOtherServers,
})
}
- if err = roomserverAPI.SendInputRoomEvents(ctx, rsAPI, inputs, false); err != nil {
+ if err = roomserverAPI.SendInputRoomEvents(ctx, rsAPI, device.UserDomain(), inputs, false); err != nil {
util.GetLogger(ctx).WithError(err).Error("roomserverAPI.SendInputRoomEvents failed")
return jsonerror.InternalServerError()
}
diff --git a/clientapi/routing/directory.go b/clientapi/routing/directory.go
index ce14745a..b3c5aae4 100644
--- a/clientapi/routing/directory.go
+++ b/clientapi/routing/directory.go
@@ -77,7 +77,7 @@ func DirectoryRoom(
// If we don't know it locally, do a federation query.
// But don't send the query to ourselves.
if !cfg.Matrix.IsLocalServerName(domain) {
- fedRes, fedErr := federation.LookupRoomAlias(req.Context(), domain, roomAlias)
+ fedRes, fedErr := federation.LookupRoomAlias(req.Context(), cfg.Matrix.ServerName, domain, roomAlias)
if fedErr != nil {
// TODO: Return 502 if the remote server errored.
// TODO: Return 504 if the remote server timed out.
diff --git a/clientapi/routing/directory_public.go b/clientapi/routing/directory_public.go
index b1043e99..60674476 100644
--- a/clientapi/routing/directory_public.go
+++ b/clientapi/routing/directory_public.go
@@ -74,7 +74,7 @@ func GetPostPublicRooms(
serverName := gomatrixserverlib.ServerName(request.Server)
if serverName != "" && !cfg.Matrix.IsLocalServerName(serverName) {
res, err := federation.GetPublicRoomsFiltered(
- req.Context(), serverName,
+ req.Context(), cfg.Matrix.ServerName, serverName,
int(request.Limit), request.Since,
request.Filter.SearchTerms, false,
"",
diff --git a/clientapi/routing/membership.go b/clientapi/routing/membership.go
index 94ba17a0..482c1f5f 100644
--- a/clientapi/routing/membership.go
+++ b/clientapi/routing/membership.go
@@ -110,6 +110,7 @@ func sendMembership(ctx context.Context, profileAPI userapi.ClientUserAPI, devic
ctx, rsAPI,
roomserverAPI.KindNew,
[]*gomatrixserverlib.HeaderedEvent{event.Event.Headered(roomVer)},
+ device.UserDomain(),
serverName,
serverName,
nil,
@@ -322,7 +323,12 @@ func buildMembershipEvent(
return nil, err
}
- return eventutil.QueryAndBuildEvent(ctx, &builder, cfg.Matrix, evTime, rsAPI, nil)
+ identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain())
+ if err != nil {
+ return nil, err
+ }
+
+ return eventutil.QueryAndBuildEvent(ctx, &builder, cfg.Matrix, identity, evTime, rsAPI, nil)
}
// loadProfile lookups the profile of a given user from the database and returns
diff --git a/clientapi/routing/profile.go b/clientapi/routing/profile.go
index 4d9e1f8a..92a75fc7 100644
--- a/clientapi/routing/profile.go
+++ b/clientapi/routing/profile.go
@@ -284,7 +284,7 @@ func updateProfile(
}
events, err := buildMembershipEvents(
- ctx, res.RoomIDs, *profile, userID, cfg, evTime, rsAPI,
+ ctx, device, res.RoomIDs, *profile, userID, cfg, evTime, rsAPI,
)
switch e := err.(type) {
case nil:
@@ -298,7 +298,7 @@ func updateProfile(
return jsonerror.InternalServerError(), e
}
- if err := api.SendEvents(ctx, rsAPI, api.KindNew, events, domain, domain, nil, true); err != nil {
+ if err := api.SendEvents(ctx, rsAPI, api.KindNew, events, device.UserDomain(), domain, domain, nil, true); err != nil {
util.GetLogger(ctx).WithError(err).Error("SendEvents failed")
return jsonerror.InternalServerError(), err
}
@@ -321,7 +321,7 @@ func getProfile(
}
if !cfg.Matrix.IsLocalServerName(domain) {
- profile, fedErr := federation.LookupProfile(ctx, domain, userID, "")
+ profile, fedErr := federation.LookupProfile(ctx, cfg.Matrix.ServerName, domain, userID, "")
if fedErr != nil {
if x, ok := fedErr.(gomatrix.HTTPError); ok {
if x.Code == http.StatusNotFound {
@@ -349,6 +349,7 @@ func getProfile(
func buildMembershipEvents(
ctx context.Context,
+ device *userapi.Device,
roomIDs []string,
newProfile authtypes.Profile, userID string, cfg *config.ClientAPI,
evTime time.Time, rsAPI api.ClientRoomserverAPI,
@@ -380,7 +381,12 @@ func buildMembershipEvents(
return nil, err
}
- event, err := eventutil.QueryAndBuildEvent(ctx, &builder, cfg.Matrix, evTime, rsAPI, nil)
+ identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain())
+ if err != nil {
+ return nil, err
+ }
+
+ event, err := eventutil.QueryAndBuildEvent(ctx, &builder, cfg.Matrix, identity, evTime, rsAPI, nil)
if err != nil {
return nil, err
}
diff --git a/clientapi/routing/redaction.go b/clientapi/routing/redaction.go
index 778a02fd..7841b3b0 100644
--- a/clientapi/routing/redaction.go
+++ b/clientapi/routing/redaction.go
@@ -123,8 +123,13 @@ func SendRedaction(
return jsonerror.InternalServerError()
}
+ identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain())
+ if err != nil {
+ return jsonerror.InternalServerError()
+ }
+
var queryRes roomserverAPI.QueryLatestEventsAndStateResponse
- e, err := eventutil.QueryAndBuildEvent(req.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
+ e, err := eventutil.QueryAndBuildEvent(req.Context(), &builder, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
return util.JSONResponse{
Code: http.StatusNotFound,
@@ -132,7 +137,7 @@ func SendRedaction(
}
}
domain := device.UserDomain()
- if err = roomserverAPI.SendEvents(context.Background(), rsAPI, roomserverAPI.KindNew, []*gomatrixserverlib.HeaderedEvent{e}, domain, domain, nil, false); err != nil {
+ if err = roomserverAPI.SendEvents(context.Background(), rsAPI, roomserverAPI.KindNew, []*gomatrixserverlib.HeaderedEvent{e}, device.UserDomain(), domain, domain, nil, false); err != nil {
util.GetLogger(req.Context()).WithError(err).Errorf("failed to SendEvents")
return jsonerror.InternalServerError()
}
diff --git a/clientapi/routing/register.go b/clientapi/routing/register.go
index 9dc63af8..a92513b8 100644
--- a/clientapi/routing/register.go
+++ b/clientapi/routing/register.go
@@ -211,9 +211,10 @@ var (
// previous parameters with the ones supplied. This mean you cannot "build up" request params.
type registerRequest struct {
// registration parameters
- Password string `json:"password"`
- Username string `json:"username"`
- Admin bool `json:"admin"`
+ Password string `json:"password"`
+ Username string `json:"username"`
+ ServerName gomatrixserverlib.ServerName `json:"-"`
+ Admin bool `json:"admin"`
// user-interactive auth params
Auth authDict `json:"auth"`
@@ -570,11 +571,14 @@ func Register(
JSON: response,
}
}
-
}
if resErr := httputil.UnmarshalJSON(reqBody, &r); resErr != nil {
return *resErr
}
+ r.ServerName = cfg.Matrix.ServerName
+ if l, d, err := cfg.Matrix.SplitLocalID('@', r.Username); err == nil {
+ r.Username, r.ServerName = l, d
+ }
if req.URL.Query().Get("kind") == "guest" {
return handleGuestRegistration(req, r, cfg, userAPI)
}
@@ -589,7 +593,7 @@ func Register(
// Auto generate a numeric username if r.Username is empty
if r.Username == "" {
nreq := &userapi.QueryNumericLocalpartRequest{
- ServerName: cfg.Matrix.ServerName, // TODO: might not be right
+ ServerName: r.ServerName,
}
nres := &userapi.QueryNumericLocalpartResponse{}
if err := userAPI.QueryNumericLocalpart(req.Context(), nreq, nres); err != nil {
@@ -609,7 +613,7 @@ func Register(
case r.Type == authtypes.LoginTypeApplicationService && accessTokenErr == nil:
// Spec-compliant case (the access_token is specified and the login type
// is correctly set, so it's an appservice registration)
- if resErr := validateApplicationServiceUsername(r.Username, cfg.Matrix.ServerName); resErr != nil {
+ if resErr := validateApplicationServiceUsername(r.Username, r.ServerName); resErr != nil {
return *resErr
}
case accessTokenErr == nil:
@@ -622,7 +626,7 @@ func Register(
default:
// Spec-compliant case (neither the access_token nor the login type are
// specified, so it's a normal user registration)
- if resErr := validateUsername(r.Username, cfg.Matrix.ServerName); resErr != nil {
+ if resErr := validateUsername(r.Username, r.ServerName); resErr != nil {
return *resErr
}
}
@@ -1023,13 +1027,27 @@ func RegisterAvailable(
// Squash username to all lowercase letters
username = strings.ToLower(username)
+ domain := cfg.Matrix.ServerName
+ if u, l, err := cfg.Matrix.SplitLocalID('@', username); err == nil {
+ username, domain = u, l
+ }
+ for _, v := range cfg.Matrix.VirtualHosts {
+ if v.ServerName == domain && !v.AllowRegistration {
+ return util.JSONResponse{
+ Code: http.StatusForbidden,
+ JSON: jsonerror.Forbidden(
+ fmt.Sprintf("Registration is not allowed on %q", string(v.ServerName)),
+ ),
+ }
+ }
+ }
- if err := validateUsername(username, cfg.Matrix.ServerName); err != nil {
+ if err := validateUsername(username, domain); err != nil {
return *err
}
// Check if this username is reserved by an application service
- userID := userutil.MakeUserID(username, cfg.Matrix.ServerName)
+ userID := userutil.MakeUserID(username, domain)
for _, appservice := range cfg.Derived.ApplicationServices {
if appservice.OwnsNamespaceCoveringUserId(userID) {
return util.JSONResponse{
@@ -1041,7 +1059,8 @@ func RegisterAvailable(
res := &userapi.QueryAccountAvailabilityResponse{}
err := registerAPI.QueryAccountAvailability(req.Context(), &userapi.QueryAccountAvailabilityRequest{
- Localpart: username,
+ Localpart: username,
+ ServerName: domain,
}, res)
if err != nil {
return util.JSONResponse{
diff --git a/clientapi/routing/sendevent.go b/clientapi/routing/sendevent.go
index bb66cf6f..90af9ac4 100644
--- a/clientapi/routing/sendevent.go
+++ b/clientapi/routing/sendevent.go
@@ -186,6 +186,7 @@ func SendEvent(
[]*gomatrixserverlib.HeaderedEvent{
e.Headered(verRes.RoomVersion),
},
+ device.UserDomain(),
domain,
domain,
txnAndSessionID,
@@ -275,8 +276,14 @@ func generateSendEvent(
return nil, &resErr
}
+ identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain())
+ if err != nil {
+ resErr := jsonerror.InternalServerError()
+ return nil, &resErr
+ }
+
var queryRes api.QueryLatestEventsAndStateResponse
- e, err := eventutil.QueryAndBuildEvent(ctx, &builder, cfg.Matrix, evTime, rsAPI, &queryRes)
+ e, err := eventutil.QueryAndBuildEvent(ctx, &builder, cfg.Matrix, identity, evTime, rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
return nil, &util.JSONResponse{
Code: http.StatusNotFound,
diff --git a/clientapi/routing/server_notices.go b/clientapi/routing/server_notices.go
index a7acee32..fb93d878 100644
--- a/clientapi/routing/server_notices.go
+++ b/clientapi/routing/server_notices.go
@@ -231,6 +231,7 @@ func SendServerNotice(
[]*gomatrixserverlib.HeaderedEvent{
e.Headered(roomVersion),
},
+ device.UserDomain(),
cfgClient.Matrix.ServerName,
cfgClient.Matrix.ServerName,
txnAndSessionID,
diff --git a/clientapi/routing/userdirectory.go b/clientapi/routing/userdirectory.go
index d3d1c22e..62af9efa 100644
--- a/clientapi/routing/userdirectory.go
+++ b/clientapi/routing/userdirectory.go
@@ -106,7 +106,7 @@ knownUsersLoop:
continue
}
// TODO: We should probably cache/store this
- fedProfile, fedErr := federation.LookupProfile(ctx, serverName, userID, "")
+ fedProfile, fedErr := federation.LookupProfile(ctx, localServerName, serverName, userID, "")
if fedErr != nil {
if x, ok := fedErr.(gomatrix.HTTPError); ok {
if x.Code == http.StatusNotFound {
diff --git a/clientapi/threepid/invites.go b/clientapi/threepid/invites.go
index 99fb8171..1f294a03 100644
--- a/clientapi/threepid/invites.go
+++ b/clientapi/threepid/invites.go
@@ -359,8 +359,13 @@ func emit3PIDInviteEvent(
return err
}
+ identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain())
+ if err != nil {
+ return err
+ }
+
queryRes := api.QueryLatestEventsAndStateResponse{}
- event, err := eventutil.QueryAndBuildEvent(ctx, builder, cfg.Matrix, evTime, rsAPI, &queryRes)
+ event, err := eventutil.QueryAndBuildEvent(ctx, builder, cfg.Matrix, identity, evTime, rsAPI, &queryRes)
if err != nil {
return err
}
@@ -371,6 +376,7 @@ func emit3PIDInviteEvent(
[]*gomatrixserverlib.HeaderedEvent{
event.Headered(queryRes.RoomVersion),
},
+ device.UserDomain(),
cfg.Matrix.ServerName,
cfg.Matrix.ServerName,
nil,