aboutsummaryrefslogtreecommitdiff
path: root/clientapi
diff options
context:
space:
mode:
Diffstat (limited to 'clientapi')
-rw-r--r--clientapi/auth/password.go2
-rw-r--r--clientapi/routing/admin.go4
-rw-r--r--clientapi/routing/createroom.go25
-rw-r--r--clientapi/routing/directory.go4
-rw-r--r--clientapi/routing/directory_public.go3
-rw-r--r--clientapi/routing/login.go6
-rw-r--r--clientapi/routing/membership.go9
-rw-r--r--clientapi/routing/openid.go2
-rw-r--r--clientapi/routing/profile.go34
-rw-r--r--clientapi/routing/redaction.go3
-rw-r--r--clientapi/routing/register.go2
-rw-r--r--clientapi/routing/sendevent.go5
-rw-r--r--clientapi/threepid/invites.go2
-rw-r--r--clientapi/userutil/userutil.go13
-rw-r--r--clientapi/userutil/userutil_test.go25
15 files changed, 97 insertions, 42 deletions
diff --git a/clientapi/auth/password.go b/clientapi/auth/password.go
index 890b1818..700a72f5 100644
--- a/clientapi/auth/password.go
+++ b/clientapi/auth/password.go
@@ -74,7 +74,7 @@ func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login,
JSON: jsonerror.BadJSON("A password must be supplied."),
}
}
- localpart, err := userutil.ParseUsernameParam(username, &t.Config.Matrix.ServerName)
+ localpart, _, err := userutil.ParseUsernameParam(username, t.Config.Matrix)
if err != nil {
return nil, &util.JSONResponse{
Code: http.StatusUnauthorized,
diff --git a/clientapi/routing/admin.go b/clientapi/routing/admin.go
index 89c269f1..69bca13b 100644
--- a/clientapi/routing/admin.go
+++ b/clientapi/routing/admin.go
@@ -70,7 +70,7 @@ func AdminEvacuateUser(req *http.Request, cfg *config.ClientAPI, device *userapi
if err != nil {
return util.MessageResponse(http.StatusBadRequest, err.Error())
}
- if domain != cfg.Matrix.ServerName {
+ if !cfg.Matrix.IsLocalServerName(domain) {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.MissingArgument("User ID must belong to this server."),
@@ -169,7 +169,7 @@ func AdminMarkAsStale(req *http.Request, cfg *config.ClientAPI, keyAPI api.Clien
if err != nil {
return util.MessageResponse(http.StatusBadRequest, err.Error())
}
- if domain == cfg.Matrix.ServerName {
+ if cfg.Matrix.IsLocalServerName(domain) {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.InvalidParam("Can not mark local device list as stale"),
diff --git a/clientapi/routing/createroom.go b/clientapi/routing/createroom.go
index 3e837c86..eefe8e24 100644
--- a/clientapi/routing/createroom.go
+++ b/clientapi/routing/createroom.go
@@ -169,9 +169,21 @@ func createRoom(
asAPI appserviceAPI.AppServiceInternalAPI,
evTime time.Time,
) util.JSONResponse {
+ _, userDomain, err := gomatrixserverlib.SplitID('@', device.UserID)
+ if err != nil {
+ util.GetLogger(ctx).WithError(err).Error("gomatrixserverlib.SplitID failed")
+ return jsonerror.InternalServerError()
+ }
+ if !cfg.Matrix.IsLocalServerName(userDomain) {
+ return util.JSONResponse{
+ Code: http.StatusForbidden,
+ JSON: jsonerror.Forbidden(fmt.Sprintf("User domain %q not configured locally", userDomain)),
+ }
+ }
+
// TODO (#267): Check room ID doesn't clash with an existing one, and we
// probably shouldn't be using pseudo-random strings, maybe GUIDs?
- roomID := fmt.Sprintf("!%s:%s", util.RandomString(16), cfg.Matrix.ServerName)
+ roomID := fmt.Sprintf("!%s:%s", util.RandomString(16), userDomain)
logger := util.GetLogger(ctx)
userID := device.UserID
@@ -314,7 +326,7 @@ func createRoom(
var roomAlias string
if r.RoomAliasName != "" {
- roomAlias = fmt.Sprintf("#%s:%s", r.RoomAliasName, cfg.Matrix.ServerName)
+ roomAlias = fmt.Sprintf("#%s:%s", r.RoomAliasName, userDomain)
// check it's free TODO: This races but is better than nothing
hasAliasReq := roomserverAPI.GetRoomIDForAliasRequest{
Alias: roomAlias,
@@ -436,7 +448,7 @@ func createRoom(
builder.PrevEvents = []gomatrixserverlib.EventReference{builtEvents[i-1].EventReference()}
}
var ev *gomatrixserverlib.Event
- ev, err = buildEvent(&builder, &authEvents, cfg, evTime, roomVersion)
+ ev, err = buildEvent(&builder, userDomain, &authEvents, cfg, evTime, roomVersion)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("buildEvent failed")
return jsonerror.InternalServerError()
@@ -461,7 +473,7 @@ func createRoom(
inputs = append(inputs, roomserverAPI.InputRoomEvent{
Kind: roomserverAPI.KindNew,
Event: event,
- Origin: cfg.Matrix.ServerName,
+ Origin: userDomain,
SendAsServer: roomserverAPI.DoNotSendToOtherServers,
})
}
@@ -548,7 +560,7 @@ func createRoom(
Event: event,
InviteRoomState: inviteStrippedState,
RoomVersion: event.RoomVersion,
- SendAsServer: string(cfg.Matrix.ServerName),
+ SendAsServer: string(userDomain),
}, &inviteRes); err != nil {
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
return util.JSONResponse{
@@ -591,6 +603,7 @@ func createRoom(
// buildEvent fills out auth_events for the builder then builds the event
func buildEvent(
builder *gomatrixserverlib.EventBuilder,
+ serverName gomatrixserverlib.ServerName,
provider gomatrixserverlib.AuthEventProvider,
cfg *config.ClientAPI,
evTime time.Time,
@@ -606,7 +619,7 @@ func buildEvent(
}
builder.AuthEvents = refs
event, err := builder.Build(
- evTime, cfg.Matrix.ServerName, cfg.Matrix.KeyID,
+ evTime, serverName, cfg.Matrix.KeyID,
cfg.Matrix.PrivateKey, roomVersion,
)
if err != nil {
diff --git a/clientapi/routing/directory.go b/clientapi/routing/directory.go
index 836d9e15..33bc63d1 100644
--- a/clientapi/routing/directory.go
+++ b/clientapi/routing/directory.go
@@ -75,7 +75,7 @@ func DirectoryRoom(
if res.RoomID == "" {
// If we don't know it locally, do a federation query.
// But don't send the query to ourselves.
- if domain != cfg.Matrix.ServerName {
+ if !cfg.Matrix.IsLocalServerName(domain) {
fedRes, fedErr := federation.LookupRoomAlias(req.Context(), domain, roomAlias)
if fedErr != nil {
// TODO: Return 502 if the remote server errored.
@@ -127,7 +127,7 @@ func SetLocalAlias(
}
}
- if domain != cfg.Matrix.ServerName {
+ if !cfg.Matrix.IsLocalServerName(domain) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Alias must be on local homeserver"),
diff --git a/clientapi/routing/directory_public.go b/clientapi/routing/directory_public.go
index 8ddb3267..4ebf2295 100644
--- a/clientapi/routing/directory_public.go
+++ b/clientapi/routing/directory_public.go
@@ -62,8 +62,7 @@ func GetPostPublicRooms(
}
serverName := gomatrixserverlib.ServerName(request.Server)
-
- if serverName != "" && serverName != cfg.Matrix.ServerName {
+ if serverName != "" && !cfg.Matrix.IsLocalServerName(serverName) {
res, err := federation.GetPublicRoomsFiltered(
req.Context(), serverName,
int(request.Limit), request.Since,
diff --git a/clientapi/routing/login.go b/clientapi/routing/login.go
index 6017b584..7f5a8c4f 100644
--- a/clientapi/routing/login.go
+++ b/clientapi/routing/login.go
@@ -68,7 +68,7 @@ func Login(
return *authErr
}
// make a device/access token
- authErr2 := completeAuth(req.Context(), cfg.Matrix.ServerName, userAPI, login, req.RemoteAddr, req.UserAgent())
+ authErr2 := completeAuth(req.Context(), cfg.Matrix, userAPI, login, req.RemoteAddr, req.UserAgent())
cleanup(req.Context(), &authErr2)
return authErr2
}
@@ -79,7 +79,7 @@ func Login(
}
func completeAuth(
- ctx context.Context, serverName gomatrixserverlib.ServerName, userAPI userapi.ClientUserAPI, login *auth.Login,
+ ctx context.Context, cfg *config.Global, userAPI userapi.ClientUserAPI, login *auth.Login,
ipAddr, userAgent string,
) util.JSONResponse {
token, err := auth.GenerateAccessToken()
@@ -88,7 +88,7 @@ func completeAuth(
return jsonerror.InternalServerError()
}
- localpart, err := userutil.ParseUsernameParam(login.Username(), &serverName)
+ localpart, serverName, err := userutil.ParseUsernameParam(login.Username(), cfg)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("auth.ParseUsernameParam failed")
return jsonerror.InternalServerError()
diff --git a/clientapi/routing/membership.go b/clientapi/routing/membership.go
index 77f627eb..94ba17a0 100644
--- a/clientapi/routing/membership.go
+++ b/clientapi/routing/membership.go
@@ -105,12 +105,13 @@ func sendMembership(ctx context.Context, profileAPI userapi.ClientUserAPI, devic
return jsonerror.InternalServerError()
}
+ serverName := device.UserDomain()
if err = roomserverAPI.SendEvents(
ctx, rsAPI,
roomserverAPI.KindNew,
[]*gomatrixserverlib.HeaderedEvent{event.Event.Headered(roomVer)},
- cfg.Matrix.ServerName,
- cfg.Matrix.ServerName,
+ serverName,
+ serverName,
nil,
false,
); err != nil {
@@ -271,7 +272,7 @@ func sendInvite(
Event: event,
InviteRoomState: nil, // ask the roomserver to draw up invite room state for us
RoomVersion: event.RoomVersion,
- SendAsServer: string(cfg.Matrix.ServerName),
+ SendAsServer: string(device.UserDomain()),
}, &inviteRes); err != nil {
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
return util.JSONResponse{
@@ -341,7 +342,7 @@ func loadProfile(
}
var profile *authtypes.Profile
- if serverName == cfg.Matrix.ServerName {
+ if cfg.Matrix.IsLocalServerName(serverName) {
profile, err = appserviceAPI.RetrieveUserProfile(ctx, userID, asAPI, profileAPI)
} else {
profile = &authtypes.Profile{}
diff --git a/clientapi/routing/openid.go b/clientapi/routing/openid.go
index cfb440be..8e9be788 100644
--- a/clientapi/routing/openid.go
+++ b/clientapi/routing/openid.go
@@ -63,7 +63,7 @@ func CreateOpenIDToken(
JSON: openIDTokenResponse{
AccessToken: response.Token.Token,
TokenType: "Bearer",
- MatrixServerName: string(cfg.Matrix.ServerName),
+ MatrixServerName: string(device.UserDomain()),
ExpiresIn: response.Token.ExpiresAtMS / 1000, // convert ms to s
},
}
diff --git a/clientapi/routing/profile.go b/clientapi/routing/profile.go
index c9647eb1..4d9e1f8a 100644
--- a/clientapi/routing/profile.go
+++ b/clientapi/routing/profile.go
@@ -113,12 +113,19 @@ func SetAvatarURL(
}
}
- localpart, _, err := gomatrixserverlib.SplitID('@', userID)
+ localpart, domain, err := gomatrixserverlib.SplitID('@', userID)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.SplitID failed")
return jsonerror.InternalServerError()
}
+ if !cfg.Matrix.IsLocalServerName(domain) {
+ return util.JSONResponse{
+ Code: http.StatusForbidden,
+ JSON: jsonerror.Forbidden("userID does not belong to a locally configured domain"),
+ }
+ }
+
evTime, err := httputil.ParseTSParam(req)
if err != nil {
return util.JSONResponse{
@@ -129,8 +136,9 @@ func SetAvatarURL(
setRes := &userapi.PerformSetAvatarURLResponse{}
if err = profileAPI.SetAvatarURL(req.Context(), &userapi.PerformSetAvatarURLRequest{
- Localpart: localpart,
- AvatarURL: r.AvatarURL,
+ Localpart: localpart,
+ ServerName: domain,
+ AvatarURL: r.AvatarURL,
}, setRes); err != nil {
util.GetLogger(req.Context()).WithError(err).Error("profileAPI.SetAvatarURL failed")
return jsonerror.InternalServerError()
@@ -204,12 +212,19 @@ func SetDisplayName(
}
}
- localpart, _, err := gomatrixserverlib.SplitID('@', userID)
+ localpart, domain, err := gomatrixserverlib.SplitID('@', userID)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.SplitID failed")
return jsonerror.InternalServerError()
}
+ if !cfg.Matrix.IsLocalServerName(domain) {
+ return util.JSONResponse{
+ Code: http.StatusForbidden,
+ JSON: jsonerror.Forbidden("userID does not belong to a locally configured domain"),
+ }
+ }
+
evTime, err := httputil.ParseTSParam(req)
if err != nil {
return util.JSONResponse{
@@ -221,6 +236,7 @@ func SetDisplayName(
profileRes := &userapi.PerformUpdateDisplayNameResponse{}
err = profileAPI.SetDisplayName(req.Context(), &userapi.PerformUpdateDisplayNameRequest{
Localpart: localpart,
+ ServerName: domain,
DisplayName: r.DisplayName,
}, profileRes)
if err != nil {
@@ -261,6 +277,12 @@ func updateProfile(
return jsonerror.InternalServerError(), err
}
+ _, domain, err := gomatrixserverlib.SplitID('@', userID)
+ if err != nil {
+ util.GetLogger(ctx).WithError(err).Error("gomatrixserverlib.SplitID failed")
+ return jsonerror.InternalServerError(), err
+ }
+
events, err := buildMembershipEvents(
ctx, res.RoomIDs, *profile, userID, cfg, evTime, rsAPI,
)
@@ -276,7 +298,7 @@ func updateProfile(
return jsonerror.InternalServerError(), e
}
- if err := api.SendEvents(ctx, rsAPI, api.KindNew, events, cfg.Matrix.ServerName, cfg.Matrix.ServerName, nil, true); err != nil {
+ if err := api.SendEvents(ctx, rsAPI, api.KindNew, events, domain, domain, nil, true); err != nil {
util.GetLogger(ctx).WithError(err).Error("SendEvents failed")
return jsonerror.InternalServerError(), err
}
@@ -298,7 +320,7 @@ func getProfile(
return nil, err
}
- if domain != cfg.Matrix.ServerName {
+ if !cfg.Matrix.IsLocalServerName(domain) {
profile, fedErr := federation.LookupProfile(ctx, domain, userID, "")
if fedErr != nil {
if x, ok := fedErr.(gomatrix.HTTPError); ok {
diff --git a/clientapi/routing/redaction.go b/clientapi/routing/redaction.go
index a0f3b115..778a02fd 100644
--- a/clientapi/routing/redaction.go
+++ b/clientapi/routing/redaction.go
@@ -131,7 +131,8 @@ func SendRedaction(
JSON: jsonerror.NotFound("Room does not exist"),
}
}
- if err = roomserverAPI.SendEvents(context.Background(), rsAPI, roomserverAPI.KindNew, []*gomatrixserverlib.HeaderedEvent{e}, cfg.Matrix.ServerName, cfg.Matrix.ServerName, nil, false); err != nil {
+ domain := device.UserDomain()
+ if err = roomserverAPI.SendEvents(context.Background(), rsAPI, roomserverAPI.KindNew, []*gomatrixserverlib.HeaderedEvent{e}, 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 0bda1e48..698d185b 100644
--- a/clientapi/routing/register.go
+++ b/clientapi/routing/register.go
@@ -412,7 +412,7 @@ func UserIDIsWithinApplicationServiceNamespace(
return false
}
- if domain != cfg.Matrix.ServerName {
+ if !cfg.Matrix.IsLocalServerName(domain) {
return false
}
diff --git a/clientapi/routing/sendevent.go b/clientapi/routing/sendevent.go
index 114e9088..bb66cf6f 100644
--- a/clientapi/routing/sendevent.go
+++ b/clientapi/routing/sendevent.go
@@ -94,6 +94,7 @@ func SendEvent(
// create a mutex for the specific user in the specific room
// this avoids a situation where events that are received in quick succession are sent to the roomserver in a jumbled order
userID := device.UserID
+ domain := device.UserDomain()
mutex, _ := userRoomSendMutexes.LoadOrStore(roomID+userID, &sync.Mutex{})
mutex.(*sync.Mutex).Lock()
defer mutex.(*sync.Mutex).Unlock()
@@ -185,8 +186,8 @@ func SendEvent(
[]*gomatrixserverlib.HeaderedEvent{
e.Headered(verRes.RoomVersion),
},
- cfg.Matrix.ServerName,
- cfg.Matrix.ServerName,
+ domain,
+ domain,
txnAndSessionID,
false,
); err != nil {
diff --git a/clientapi/threepid/invites.go b/clientapi/threepid/invites.go
index 9670feca..99fb8171 100644
--- a/clientapi/threepid/invites.go
+++ b/clientapi/threepid/invites.go
@@ -215,7 +215,7 @@ func queryIDServerStoreInvite(
}
var profile *authtypes.Profile
- if serverName == cfg.Matrix.ServerName {
+ if cfg.Matrix.IsLocalServerName(serverName) {
res := &userapi.QueryProfileResponse{}
err = userAPI.QueryProfile(ctx, &userapi.QueryProfileRequest{UserID: device.UserID}, res)
if err != nil {
diff --git a/clientapi/userutil/userutil.go b/clientapi/userutil/userutil.go
index 7e909ffa..9be1e9b3 100644
--- a/clientapi/userutil/userutil.go
+++ b/clientapi/userutil/userutil.go
@@ -17,6 +17,7 @@ import (
"fmt"
"strings"
+ "github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/gomatrixserverlib"
)
@@ -24,23 +25,23 @@ import (
// usernameParam can either be a user ID or just the localpart/username.
// If serverName is passed, it is verified against the domain obtained from usernameParam (if present)
// Returns error in case of invalid usernameParam.
-func ParseUsernameParam(usernameParam string, expectedServerName *gomatrixserverlib.ServerName) (string, error) {
+func ParseUsernameParam(usernameParam string, cfg *config.Global) (string, gomatrixserverlib.ServerName, error) {
localpart := usernameParam
if strings.HasPrefix(usernameParam, "@") {
lp, domain, err := gomatrixserverlib.SplitID('@', usernameParam)
if err != nil {
- return "", errors.New("invalid username")
+ return "", "", errors.New("invalid username")
}
- if expectedServerName != nil && domain != *expectedServerName {
- return "", errors.New("user ID does not belong to this server")
+ if !cfg.IsLocalServerName(domain) {
+ return "", "", errors.New("user ID does not belong to this server")
}
- localpart = lp
+ return lp, domain, nil
}
- return localpart, nil
+ return localpart, cfg.ServerName, nil
}
// MakeUserID generates user ID from localpart & server name
diff --git a/clientapi/userutil/userutil_test.go b/clientapi/userutil/userutil_test.go
index 2628642f..ccd6647b 100644
--- a/clientapi/userutil/userutil_test.go
+++ b/clientapi/userutil/userutil_test.go
@@ -15,6 +15,7 @@ package userutil
import (
"testing"
+ "github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/gomatrixserverlib"
)
@@ -28,7 +29,11 @@ var (
// TestGoodUserID checks that correct localpart is returned for a valid user ID.
func TestGoodUserID(t *testing.T) {
- lp, err := ParseUsernameParam(goodUserID, &serverName)
+ cfg := &config.Global{
+ ServerName: serverName,
+ }
+
+ lp, _, err := ParseUsernameParam(goodUserID, cfg)
if err != nil {
t.Error("User ID Parsing failed for ", goodUserID, " with error: ", err.Error())
@@ -41,7 +46,11 @@ func TestGoodUserID(t *testing.T) {
// TestWithLocalpartOnly checks that localpart is returned when usernameParam contains only localpart.
func TestWithLocalpartOnly(t *testing.T) {
- lp, err := ParseUsernameParam(localpart, &serverName)
+ cfg := &config.Global{
+ ServerName: serverName,
+ }
+
+ lp, _, err := ParseUsernameParam(localpart, cfg)
if err != nil {
t.Error("User ID Parsing failed for ", localpart, " with error: ", err.Error())
@@ -54,7 +63,11 @@ func TestWithLocalpartOnly(t *testing.T) {
// TestIncorrectDomain checks for error when there's server name mismatch.
func TestIncorrectDomain(t *testing.T) {
- _, err := ParseUsernameParam(goodUserID, &invalidServerName)
+ cfg := &config.Global{
+ ServerName: invalidServerName,
+ }
+
+ _, _, err := ParseUsernameParam(goodUserID, cfg)
if err == nil {
t.Error("Invalid Domain should return an error")
@@ -63,7 +76,11 @@ func TestIncorrectDomain(t *testing.T) {
// TestBadUserID checks that ParseUsernameParam fails for invalid user ID
func TestBadUserID(t *testing.T) {
- _, err := ParseUsernameParam(badUserID, &serverName)
+ cfg := &config.Global{
+ ServerName: serverName,
+ }
+
+ _, _, err := ParseUsernameParam(badUserID, cfg)
if err == nil {
t.Error("Illegal User ID should return an error")