aboutsummaryrefslogtreecommitdiff
path: root/clientapi
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2022-11-11 16:41:37 +0000
committerGitHub <noreply@github.com>2022-11-11 16:41:37 +0000
commit529df30b5649e67a2f98114e6640d259cba53566 (patch)
treebcb994ce79916f14c9a11cd11f32063411332585 /clientapi
parente177e0ae73d7cc34ffb9869681a6bf177f805205 (diff)
Virtual hosting schema and logic changes (#2876)
Note that virtual users cannot federate correctly yet.
Diffstat (limited to 'clientapi')
-rw-r--r--clientapi/auth/password.go21
-rw-r--r--clientapi/routing/admin.go5
-rw-r--r--clientapi/routing/login.go1
-rw-r--r--clientapi/routing/notification.go11
-rw-r--r--clientapi/routing/password.go12
-rw-r--r--clientapi/routing/pusher.go8
-rw-r--r--clientapi/routing/register.go10
-rw-r--r--clientapi/routing/routing.go2
-rw-r--r--clientapi/routing/server_notices.go8
-rw-r--r--clientapi/routing/threepid.go14
10 files changed, 62 insertions, 30 deletions
diff --git a/clientapi/auth/password.go b/clientapi/auth/password.go
index 700a72f5..4de2b443 100644
--- a/clientapi/auth/password.go
+++ b/clientapi/auth/password.go
@@ -61,7 +61,7 @@ func (t *LoginTypePassword) LoginFromJSON(ctx context.Context, reqBytes []byte)
func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login, *util.JSONResponse) {
r := req.(*PasswordRequest)
- username := strings.ToLower(r.Username())
+ username := r.Username()
if username == "" {
return nil, &util.JSONResponse{
Code: http.StatusUnauthorized,
@@ -74,32 +74,43 @@ 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)
+ localpart, domain, err := userutil.ParseUsernameParam(username, t.Config.Matrix)
if err != nil {
return nil, &util.JSONResponse{
Code: http.StatusUnauthorized,
JSON: jsonerror.InvalidUsername(err.Error()),
}
}
+ if !t.Config.Matrix.IsLocalServerName(domain) {
+ return nil, &util.JSONResponse{
+ Code: http.StatusUnauthorized,
+ JSON: jsonerror.InvalidUsername("The server name is not known."),
+ }
+ }
// Squash username to all lowercase letters
res := &api.QueryAccountByPasswordResponse{}
- err = t.GetAccountByPassword(ctx, &api.QueryAccountByPasswordRequest{Localpart: strings.ToLower(localpart), PlaintextPassword: r.Password}, res)
+ err = t.GetAccountByPassword(ctx, &api.QueryAccountByPasswordRequest{
+ Localpart: strings.ToLower(localpart),
+ ServerName: domain,
+ PlaintextPassword: r.Password,
+ }, res)
if err != nil {
return nil, &util.JSONResponse{
Code: http.StatusInternalServerError,
- JSON: jsonerror.Unknown("unable to fetch account by password"),
+ JSON: jsonerror.Unknown("Unable to fetch account by password."),
}
}
if !res.Exists {
err = t.GetAccountByPassword(ctx, &api.QueryAccountByPasswordRequest{
Localpart: localpart,
+ ServerName: domain,
PlaintextPassword: r.Password,
}, res)
if err != nil {
return nil, &util.JSONResponse{
Code: http.StatusInternalServerError,
- JSON: jsonerror.Unknown("unable to fetch account by password"),
+ JSON: jsonerror.Unknown("Unable to fetch account by password."),
}
}
// Technically we could tell them if the user does not exist by checking if err == sql.ErrNoRows
diff --git a/clientapi/routing/admin.go b/clientapi/routing/admin.go
index 9088f771..9ed1f0ca 100644
--- a/clientapi/routing/admin.go
+++ b/clientapi/routing/admin.go
@@ -102,6 +102,7 @@ func AdminResetPassword(req *http.Request, cfg *config.ClientAPI, device *userap
if err != nil {
return util.ErrorResponse(err)
}
+ serverName := cfg.Matrix.ServerName
localpart, ok := vars["localpart"]
if !ok {
return util.JSONResponse{
@@ -109,6 +110,9 @@ 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 {
+ localpart, serverName = l, s
+ }
request := struct {
Password string `json:"password"`
}{}
@@ -126,6 +130,7 @@ func AdminResetPassword(req *http.Request, cfg *config.ClientAPI, device *userap
}
updateReq := &userapi.PerformPasswordUpdateRequest{
Localpart: localpart,
+ ServerName: serverName,
Password: request.Password,
LogoutDevices: true,
}
diff --git a/clientapi/routing/login.go b/clientapi/routing/login.go
index 7f5a8c4f..0de324da 100644
--- a/clientapi/routing/login.go
+++ b/clientapi/routing/login.go
@@ -100,6 +100,7 @@ func completeAuth(
DeviceID: login.DeviceID,
AccessToken: token,
Localpart: localpart,
+ ServerName: serverName,
IPAddr: ipAddr,
UserAgent: userAgent,
}, &performRes)
diff --git a/clientapi/routing/notification.go b/clientapi/routing/notification.go
index 8a424a14..f593e27d 100644
--- a/clientapi/routing/notification.go
+++ b/clientapi/routing/notification.go
@@ -40,16 +40,17 @@ func GetNotifications(
}
var queryRes userapi.QueryNotificationsResponse
- localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
+ localpart, domain, err := gomatrixserverlib.SplitID('@', device.UserID)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("SplitID failed")
return jsonerror.InternalServerError()
}
err = userAPI.QueryNotifications(req.Context(), &userapi.QueryNotificationsRequest{
- Localpart: localpart,
- From: req.URL.Query().Get("from"),
- Limit: int(limit),
- Only: req.URL.Query().Get("only"),
+ Localpart: localpart,
+ ServerName: domain,
+ From: req.URL.Query().Get("from"),
+ Limit: int(limit),
+ Only: req.URL.Query().Get("only"),
}, &queryRes)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("QueryNotifications failed")
diff --git a/clientapi/routing/password.go b/clientapi/routing/password.go
index 6dc9af50..9772f669 100644
--- a/clientapi/routing/password.go
+++ b/clientapi/routing/password.go
@@ -86,7 +86,7 @@ func Password(
}
// Get the local part.
- localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
+ localpart, domain, err := gomatrixserverlib.SplitID('@', device.UserID)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.SplitID failed")
return jsonerror.InternalServerError()
@@ -94,8 +94,9 @@ func Password(
// Ask the user API to perform the password change.
passwordReq := &api.PerformPasswordUpdateRequest{
- Localpart: localpart,
- Password: r.NewPassword,
+ Localpart: localpart,
+ ServerName: domain,
+ Password: r.NewPassword,
}
passwordRes := &api.PerformPasswordUpdateResponse{}
if err := userAPI.PerformPasswordUpdate(req.Context(), passwordReq, passwordRes); err != nil {
@@ -122,8 +123,9 @@ func Password(
}
pushersReq := &api.PerformPusherDeletionRequest{
- Localpart: localpart,
- SessionID: device.SessionID,
+ Localpart: localpart,
+ ServerName: domain,
+ SessionID: device.SessionID,
}
if err := userAPI.PerformPusherDeletion(req.Context(), pushersReq, &struct{}{}); err != nil {
util.GetLogger(req.Context()).WithError(err).Error("PerformPusherDeletion failed")
diff --git a/clientapi/routing/pusher.go b/clientapi/routing/pusher.go
index d6a6eb93..89ec824b 100644
--- a/clientapi/routing/pusher.go
+++ b/clientapi/routing/pusher.go
@@ -31,13 +31,14 @@ func GetPushers(
userAPI userapi.ClientUserAPI,
) util.JSONResponse {
var queryRes userapi.QueryPushersResponse
- localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
+ localpart, domain, err := gomatrixserverlib.SplitID('@', device.UserID)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("SplitID failed")
return jsonerror.InternalServerError()
}
err = userAPI.QueryPushers(req.Context(), &userapi.QueryPushersRequest{
- Localpart: localpart,
+ Localpart: localpart,
+ ServerName: domain,
}, &queryRes)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("QueryPushers failed")
@@ -59,7 +60,7 @@ func SetPusher(
req *http.Request, device *userapi.Device,
userAPI userapi.ClientUserAPI,
) util.JSONResponse {
- localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
+ localpart, domain, err := gomatrixserverlib.SplitID('@', device.UserID)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("SplitID failed")
return jsonerror.InternalServerError()
@@ -93,6 +94,7 @@ func SetPusher(
}
body.Localpart = localpart
+ body.ServerName = domain
body.SessionID = device.SessionID
err = userAPI.PerformPusherSet(req.Context(), &body, &struct{}{})
if err != nil {
diff --git a/clientapi/routing/register.go b/clientapi/routing/register.go
index b9ebb051..9dc63af8 100644
--- a/clientapi/routing/register.go
+++ b/clientapi/routing/register.go
@@ -588,12 +588,15 @@ func Register(
}
// Auto generate a numeric username if r.Username is empty
if r.Username == "" {
- res := &userapi.QueryNumericLocalpartResponse{}
- if err := userAPI.QueryNumericLocalpart(req.Context(), res); err != nil {
+ nreq := &userapi.QueryNumericLocalpartRequest{
+ ServerName: cfg.Matrix.ServerName, // TODO: might not be right
+ }
+ nres := &userapi.QueryNumericLocalpartResponse{}
+ if err := userAPI.QueryNumericLocalpart(req.Context(), nreq, nres); err != nil {
util.GetLogger(req.Context()).WithError(err).Error("userAPI.QueryNumericLocalpart failed")
return jsonerror.InternalServerError()
}
- r.Username = strconv.FormatInt(res.ID, 10)
+ r.Username = strconv.FormatInt(nres.ID, 10)
}
// Is this an appservice registration? It will be if the access
@@ -676,6 +679,7 @@ func handleGuestRegistration(
var devRes userapi.PerformDeviceCreationResponse
err = userAPI.PerformDeviceCreation(req.Context(), &userapi.PerformDeviceCreationRequest{
Localpart: res.Account.Localpart,
+ ServerName: res.Account.ServerName,
DeviceDisplayName: r.InitialDisplayName,
AccessToken: token,
IPAddr: req.RemoteAddr,
diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go
index 1b3ef120..a510761e 100644
--- a/clientapi/routing/routing.go
+++ b/clientapi/routing/routing.go
@@ -157,7 +157,7 @@ func Setup(
}),
).Methods(http.MethodGet, http.MethodOptions)
- dendriteAdminRouter.Handle("/admin/resetPassword/{localpart}",
+ dendriteAdminRouter.Handle("/admin/resetPassword/{userID}",
httputil.MakeAdminAPI("admin_reset_password", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
return AdminResetPassword(req, cfg, device, userAPI)
}),
diff --git a/clientapi/routing/server_notices.go b/clientapi/routing/server_notices.go
index a6a78061..a7acee32 100644
--- a/clientapi/routing/server_notices.go
+++ b/clientapi/routing/server_notices.go
@@ -286,6 +286,7 @@ func getSenderDevice(
err := userAPI.PerformAccountCreation(ctx, &userapi.PerformAccountCreationRequest{
AccountType: userapi.AccountTypeUser,
Localpart: cfg.Matrix.ServerNotices.LocalPart,
+ ServerName: cfg.Matrix.ServerName,
OnConflict: userapi.ConflictUpdate,
}, &accRes)
if err != nil {
@@ -295,8 +296,9 @@ func getSenderDevice(
// Set the avatarurl for the user
avatarRes := &userapi.PerformSetAvatarURLResponse{}
if err = userAPI.SetAvatarURL(ctx, &userapi.PerformSetAvatarURLRequest{
- Localpart: cfg.Matrix.ServerNotices.LocalPart,
- AvatarURL: cfg.Matrix.ServerNotices.AvatarURL,
+ Localpart: cfg.Matrix.ServerNotices.LocalPart,
+ ServerName: cfg.Matrix.ServerName,
+ AvatarURL: cfg.Matrix.ServerNotices.AvatarURL,
}, avatarRes); err != nil {
util.GetLogger(ctx).WithError(err).Error("userAPI.SetAvatarURL failed")
return nil, err
@@ -308,6 +310,7 @@ func getSenderDevice(
displayNameRes := &userapi.PerformUpdateDisplayNameResponse{}
if err = userAPI.SetDisplayName(ctx, &userapi.PerformUpdateDisplayNameRequest{
Localpart: cfg.Matrix.ServerNotices.LocalPart,
+ ServerName: cfg.Matrix.ServerName,
DisplayName: cfg.Matrix.ServerNotices.DisplayName,
}, displayNameRes); err != nil {
util.GetLogger(ctx).WithError(err).Error("userAPI.SetDisplayName failed")
@@ -353,6 +356,7 @@ func getSenderDevice(
var devRes userapi.PerformDeviceCreationResponse
err = userAPI.PerformDeviceCreation(ctx, &userapi.PerformDeviceCreationRequest{
Localpart: cfg.Matrix.ServerNotices.LocalPart,
+ ServerName: cfg.Matrix.ServerName,
DeviceDisplayName: &cfg.Matrix.ServerNotices.LocalPart,
AccessToken: token,
NoDeviceListUpdate: true,
diff --git a/clientapi/routing/threepid.go b/clientapi/routing/threepid.go
index 4b7989ec..971bfcad 100644
--- a/clientapi/routing/threepid.go
+++ b/clientapi/routing/threepid.go
@@ -136,16 +136,17 @@ func CheckAndSave3PIDAssociation(
}
// Save the association in the database
- localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
+ localpart, domain, err := gomatrixserverlib.SplitID('@', device.UserID)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.SplitID failed")
return jsonerror.InternalServerError()
}
if err = threePIDAPI.PerformSaveThreePIDAssociation(req.Context(), &api.PerformSaveThreePIDAssociationRequest{
- ThreePID: address,
- Localpart: localpart,
- Medium: medium,
+ ThreePID: address,
+ Localpart: localpart,
+ ServerName: domain,
+ Medium: medium,
}, &struct{}{}); err != nil {
util.GetLogger(req.Context()).WithError(err).Error("threePIDAPI.PerformSaveThreePIDAssociation failed")
return jsonerror.InternalServerError()
@@ -161,7 +162,7 @@ func CheckAndSave3PIDAssociation(
func GetAssociated3PIDs(
req *http.Request, threepidAPI api.ClientUserAPI, device *api.Device,
) util.JSONResponse {
- localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
+ localpart, domain, err := gomatrixserverlib.SplitID('@', device.UserID)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.SplitID failed")
return jsonerror.InternalServerError()
@@ -169,7 +170,8 @@ func GetAssociated3PIDs(
res := &api.QueryThreePIDsForLocalpartResponse{}
err = threepidAPI.QueryThreePIDsForLocalpart(req.Context(), &api.QueryThreePIDsForLocalpartRequest{
- Localpart: localpart,
+ Localpart: localpart,
+ ServerName: domain,
}, res)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("threepidAPI.QueryThreePIDsForLocalpart failed")