aboutsummaryrefslogtreecommitdiff
path: root/clientapi/routing/profile.go
diff options
context:
space:
mode:
authorTill <2353100+S7evinK@users.noreply.github.com>2022-10-21 10:48:25 +0200
committerGitHub <noreply@github.com>2022-10-21 10:48:25 +0200
commite57b30172227c4a0b7de15ba635b20921dedda5e (patch)
treefa73a898b6a58d2250e2e7c6fd7b7f5df8b0f7f2 /clientapi/routing/profile.go
parent40cfb9a4ea23f1c9214553255feb296c2578b213 (diff)
Set `display_name` and/or `avatar_url` for server notices (#2820)
This should fix #2815 by making sure we actually set the `display_name` and/or `avatar_url` and create the needed membership event. To avoid creating a new membership event when starting Dendrite, `SetAvatarURL` and `SetDisplayName` now return a `Changed` value, which also makes the regular endpoints idempotent.
Diffstat (limited to 'clientapi/routing/profile.go')
-rw-r--r--clientapi/routing/profile.go127
1 files changed, 45 insertions, 82 deletions
diff --git a/clientapi/routing/profile.go b/clientapi/routing/profile.go
index 0685c735..c9647eb1 100644
--- a/clientapi/routing/profile.go
+++ b/clientapi/routing/profile.go
@@ -19,6 +19,8 @@ import (
"net/http"
"time"
+ "github.com/matrix-org/gomatrixserverlib"
+
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/httputil"
@@ -27,7 +29,6 @@ import (
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/setup/config"
userapi "github.com/matrix-org/dendrite/userapi/api"
- "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrix"
"github.com/matrix-org/util"
@@ -126,20 +127,6 @@ func SetAvatarURL(
}
}
- res := &userapi.QueryProfileResponse{}
- err = profileAPI.QueryProfile(req.Context(), &userapi.QueryProfileRequest{
- UserID: userID,
- }, res)
- if err != nil {
- util.GetLogger(req.Context()).WithError(err).Error("profileAPI.QueryProfile failed")
- return jsonerror.InternalServerError()
- }
- oldProfile := &authtypes.Profile{
- Localpart: localpart,
- DisplayName: res.DisplayName,
- AvatarURL: res.AvatarURL,
- }
-
setRes := &userapi.PerformSetAvatarURLResponse{}
if err = profileAPI.SetAvatarURL(req.Context(), &userapi.PerformSetAvatarURLRequest{
Localpart: localpart,
@@ -148,41 +135,17 @@ func SetAvatarURL(
util.GetLogger(req.Context()).WithError(err).Error("profileAPI.SetAvatarURL failed")
return jsonerror.InternalServerError()
}
-
- var roomsRes api.QueryRoomsForUserResponse
- err = rsAPI.QueryRoomsForUser(req.Context(), &api.QueryRoomsForUserRequest{
- UserID: device.UserID,
- WantMembership: "join",
- }, &roomsRes)
- if err != nil {
- util.GetLogger(req.Context()).WithError(err).Error("QueryRoomsForUser failed")
- return jsonerror.InternalServerError()
- }
-
- newProfile := authtypes.Profile{
- Localpart: localpart,
- DisplayName: oldProfile.DisplayName,
- AvatarURL: r.AvatarURL,
- }
-
- events, err := buildMembershipEvents(
- req.Context(), roomsRes.RoomIDs, newProfile, userID, cfg, evTime, rsAPI,
- )
- switch e := err.(type) {
- case nil:
- case gomatrixserverlib.BadJSONError:
+ // No need to build new membership events, since nothing changed
+ if !setRes.Changed {
return util.JSONResponse{
- Code: http.StatusBadRequest,
- JSON: jsonerror.BadJSON(e.Error()),
+ Code: http.StatusOK,
+ JSON: struct{}{},
}
- default:
- util.GetLogger(req.Context()).WithError(err).Error("buildMembershipEvents failed")
- return jsonerror.InternalServerError()
}
- if err := api.SendEvents(req.Context(), rsAPI, api.KindNew, events, cfg.Matrix.ServerName, cfg.Matrix.ServerName, nil, true); err != nil {
- util.GetLogger(req.Context()).WithError(err).Error("SendEvents failed")
- return jsonerror.InternalServerError()
+ response, err := updateProfile(req.Context(), rsAPI, device, setRes.Profile, userID, cfg, evTime)
+ if err != nil {
+ return response
}
return util.JSONResponse{
@@ -255,47 +218,51 @@ func SetDisplayName(
}
}
- pRes := &userapi.QueryProfileResponse{}
- err = profileAPI.QueryProfile(req.Context(), &userapi.QueryProfileRequest{
- UserID: userID,
- }, pRes)
- if err != nil {
- util.GetLogger(req.Context()).WithError(err).Error("profileAPI.QueryProfile failed")
- return jsonerror.InternalServerError()
- }
- oldProfile := &authtypes.Profile{
- Localpart: localpart,
- DisplayName: pRes.DisplayName,
- AvatarURL: pRes.AvatarURL,
- }
-
+ profileRes := &userapi.PerformUpdateDisplayNameResponse{}
err = profileAPI.SetDisplayName(req.Context(), &userapi.PerformUpdateDisplayNameRequest{
Localpart: localpart,
DisplayName: r.DisplayName,
- }, &struct{}{})
+ }, profileRes)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("profileAPI.SetDisplayName failed")
return jsonerror.InternalServerError()
}
+ // No need to build new membership events, since nothing changed
+ if !profileRes.Changed {
+ return util.JSONResponse{
+ Code: http.StatusOK,
+ JSON: struct{}{},
+ }
+ }
+
+ response, err := updateProfile(req.Context(), rsAPI, device, profileRes.Profile, userID, cfg, evTime)
+ if err != nil {
+ return response
+ }
+
+ return util.JSONResponse{
+ Code: http.StatusOK,
+ JSON: struct{}{},
+ }
+}
+func updateProfile(
+ ctx context.Context, rsAPI api.ClientRoomserverAPI, device *userapi.Device,
+ profile *authtypes.Profile,
+ userID string, cfg *config.ClientAPI, evTime time.Time,
+) (util.JSONResponse, error) {
var res api.QueryRoomsForUserResponse
- err = rsAPI.QueryRoomsForUser(req.Context(), &api.QueryRoomsForUserRequest{
+ err := rsAPI.QueryRoomsForUser(ctx, &api.QueryRoomsForUserRequest{
UserID: device.UserID,
WantMembership: "join",
}, &res)
if err != nil {
- util.GetLogger(req.Context()).WithError(err).Error("QueryRoomsForUser failed")
- return jsonerror.InternalServerError()
- }
-
- newProfile := authtypes.Profile{
- Localpart: localpart,
- DisplayName: r.DisplayName,
- AvatarURL: oldProfile.AvatarURL,
+ util.GetLogger(ctx).WithError(err).Error("QueryRoomsForUser failed")
+ return jsonerror.InternalServerError(), err
}
events, err := buildMembershipEvents(
- req.Context(), res.RoomIDs, newProfile, userID, cfg, evTime, rsAPI,
+ ctx, res.RoomIDs, *profile, userID, cfg, evTime, rsAPI,
)
switch e := err.(type) {
case nil:
@@ -303,21 +270,17 @@ func SetDisplayName(
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.BadJSON(e.Error()),
- }
+ }, e
default:
- util.GetLogger(req.Context()).WithError(err).Error("buildMembershipEvents failed")
- return jsonerror.InternalServerError()
- }
-
- if err := api.SendEvents(req.Context(), rsAPI, api.KindNew, events, cfg.Matrix.ServerName, cfg.Matrix.ServerName, nil, true); err != nil {
- util.GetLogger(req.Context()).WithError(err).Error("SendEvents failed")
- return jsonerror.InternalServerError()
+ util.GetLogger(ctx).WithError(err).Error("buildMembershipEvents failed")
+ return jsonerror.InternalServerError(), e
}
- return util.JSONResponse{
- Code: http.StatusOK,
- JSON: struct{}{},
+ if err := api.SendEvents(ctx, rsAPI, api.KindNew, events, cfg.Matrix.ServerName, cfg.Matrix.ServerName, nil, true); err != nil {
+ util.GetLogger(ctx).WithError(err).Error("SendEvents failed")
+ return jsonerror.InternalServerError(), err
}
+ return util.JSONResponse{}, nil
}
// getProfile gets the full profile of a user by querying the database or a