Fix /createRoom and /invite containing displayname/avatarURL of inviter (#3326)

Fixes #3324
This commit is contained in:
Till 2024-02-13 19:28:52 +01:00 committed by GitHub
parent be0c27e688
commit e9deb5244e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 100 additions and 50 deletions

View file

@ -93,8 +93,8 @@ jobs:
timeout-minutes: 5 timeout-minutes: 5
name: "Sytest Coverage" name: "Sytest Coverage"
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: sytest # only run once Sytest is done needs: [ sytest, check_date ] # only run once Sytest is done and there was a commit
if: ${{ always() }} if: ${{ always() && needs.check_date.outputs.should_run != 'false' }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install Go - name: Install Go
@ -217,8 +217,8 @@ jobs:
timeout-minutes: 5 timeout-minutes: 5
name: "Complement Coverage" name: "Complement Coverage"
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: complement # only run once Complement is done needs: [ complement, check_date ] # only run once Complements is done and there was a commit
if: ${{ always() }} if: ${{ always() && needs.check_date.outputs.should_run != 'false' }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install Go - name: Install Go

View file

@ -2278,3 +2278,68 @@ func TestGetMembership(t *testing.T) {
} }
}) })
} }
func TestCreateRoomInvite(t *testing.T) {
alice := test.NewUser(t)
bob := test.NewUser(t)
test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
cfg, processCtx, close := testrig.CreateConfig(t, dbType)
routers := httputil.NewRouters()
cm := sqlutil.NewConnectionManager(processCtx, cfg.Global.DatabaseOptions)
caches := caching.NewRistrettoCache(128*1024*1024, time.Hour, caching.DisableMetrics)
defer close()
natsInstance := jetstream.NATSInstance{}
jsctx, _ := natsInstance.Prepare(processCtx, &cfg.Global.JetStream)
defer jetstream.DeleteAllStreams(jsctx, &cfg.Global.JetStream)
// Use an actual roomserver for this
rsAPI := roomserver.NewInternalAPI(processCtx, cfg, cm, &natsInstance, caches, caching.DisableMetrics)
rsAPI.SetFederationAPI(nil, nil)
userAPI := userapi.NewInternalAPI(processCtx, cfg, cm, &natsInstance, rsAPI, nil, caching.DisableMetrics, testIsBlacklistedOrBackingOff)
// We mostly need the rsAPI for this test, so nil for other APIs/caches etc.
AddPublicRoutes(processCtx, routers, cfg, &natsInstance, nil, rsAPI, nil, nil, nil, userAPI, nil, nil, caching.DisableMetrics)
accessTokens := map[*test.User]userDevice{
alice: {},
}
createAccessTokens(t, accessTokens, userAPI, processCtx.Context(), routers)
reqBody := map[string]any{
"invite": []string{bob.ID},
}
body, err := json.Marshal(reqBody)
if err != nil {
t.Fatal(err)
}
w := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodPost, "/_matrix/client/v3/createRoom", strings.NewReader(string(body)))
req.Header.Set("Authorization", "Bearer "+accessTokens[alice].accessToken)
routers.Client.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected room creation to be successful, got HTTP %d instead: %s", w.Code, w.Body.String())
}
roomID := gjson.GetBytes(w.Body.Bytes(), "room_id").Str
validRoomID, _ := spec.NewRoomID(roomID)
// Now ask the roomserver about the membership event of Bob
ev, err := rsAPI.CurrentStateEvent(context.Background(), *validRoomID, spec.MRoomMember, bob.ID)
if err != nil {
t.Fatal(err)
}
if ev == nil {
t.Fatal("Membership event for Bob does not exist")
}
// Validate that there is NO displayname in content
if gjson.GetBytes(ev.Content(), "displayname").Exists() {
t.Fatal("Found displayname in invite")
}
})
}

View file

@ -324,19 +324,18 @@ func SendInvite(
} }
// We already received the return value, so no need to check for an error here. // We already received the return value, so no need to check for an error here.
response, _ := sendInvite(req.Context(), profileAPI, device, roomID, body.UserID, body.Reason, cfg, rsAPI, asAPI, evTime) response, _ := sendInvite(req.Context(), device, roomID, body.UserID, body.Reason, cfg, rsAPI, evTime)
return response return response
} }
// sendInvite sends an invitation to a user. Returns a JSONResponse and an error // sendInvite sends an invitation to a user. Returns a JSONResponse and an error
func sendInvite( func sendInvite(
ctx context.Context, ctx context.Context,
profileAPI userapi.ClientUserAPI,
device *userapi.Device, device *userapi.Device,
roomID, userID, reason string, roomID, userID, reason string,
cfg *config.ClientAPI, cfg *config.ClientAPI,
rsAPI roomserverAPI.ClientRoomserverAPI, rsAPI roomserverAPI.ClientRoomserverAPI,
asAPI appserviceAPI.AppServiceInternalAPI, evTime time.Time, evTime time.Time,
) (util.JSONResponse, error) { ) (util.JSONResponse, error) {
validRoomID, err := spec.NewRoomID(roomID) validRoomID, err := spec.NewRoomID(roomID)
if err != nil { if err != nil {
@ -359,13 +358,7 @@ func sendInvite(
JSON: spec.InvalidParam("UserID is invalid"), JSON: spec.InvalidParam("UserID is invalid"),
}, err }, err
} }
profile, err := loadProfile(ctx, userID, cfg, profileAPI, asAPI)
if err != nil {
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}, err
}
identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain()) identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain())
if err != nil { if err != nil {
return util.JSONResponse{ return util.JSONResponse{
@ -375,16 +368,14 @@ func sendInvite(
} }
err = rsAPI.PerformInvite(ctx, &api.PerformInviteRequest{ err = rsAPI.PerformInvite(ctx, &api.PerformInviteRequest{
InviteInput: roomserverAPI.InviteInput{ InviteInput: roomserverAPI.InviteInput{
RoomID: *validRoomID, RoomID: *validRoomID,
Inviter: *inviter, Inviter: *inviter,
Invitee: *invitee, Invitee: *invitee,
DisplayName: profile.DisplayName, Reason: reason,
AvatarURL: profile.AvatarURL, IsDirect: false,
Reason: reason, KeyID: identity.KeyID,
IsDirect: false, PrivateKey: identity.PrivateKey,
KeyID: identity.KeyID, EventTime: evTime,
PrivateKey: identity.PrivateKey,
EventTime: evTime,
}, },
InviteRoomState: nil, // ask the roomserver to draw up invite room state for us InviteRoomState: nil, // ask the roomserver to draw up invite room state for us
SendAsServer: string(device.UserDomain()), SendAsServer: string(device.UserDomain()),

View file

@ -215,7 +215,7 @@ func SendServerNotice(
} }
if !membershipRes.IsInRoom { if !membershipRes.IsInRoom {
// re-invite the user // re-invite the user
res, err := sendInvite(ctx, userAPI, senderDevice, roomID, r.UserID, "Server notice room", cfgClient, rsAPI, asAPI, time.Now()) res, err := sendInvite(ctx, senderDevice, roomID, r.UserID, "Server notice room", cfgClient, rsAPI, time.Now())
if err != nil { if err != nil {
return res return res
} }

View file

@ -50,16 +50,14 @@ type PerformLeaveResponse struct {
} }
type InviteInput struct { type InviteInput struct {
RoomID spec.RoomID RoomID spec.RoomID
Inviter spec.UserID Inviter spec.UserID
Invitee spec.UserID Invitee spec.UserID
DisplayName string Reason string
AvatarURL string IsDirect bool
Reason string KeyID gomatrixserverlib.KeyID
IsDirect bool PrivateKey ed25519.PrivateKey
KeyID gomatrixserverlib.KeyID EventTime time.Time
PrivateKey ed25519.PrivateKey
EventTime time.Time
} }
type PerformInviteRequest struct { type PerformInviteRequest struct {

View file

@ -503,16 +503,14 @@ func (c *Creator) PerformCreateRoom(ctx context.Context, userID spec.UserID, roo
err = c.RSAPI.PerformInvite(ctx, &api.PerformInviteRequest{ err = c.RSAPI.PerformInvite(ctx, &api.PerformInviteRequest{
InviteInput: api.InviteInput{ InviteInput: api.InviteInput{
RoomID: roomID, RoomID: roomID,
Inviter: userID, Inviter: userID,
Invitee: *inviteeUserID, Invitee: *inviteeUserID,
DisplayName: createRequest.UserDisplayName, Reason: "",
AvatarURL: createRequest.UserAvatarURL, IsDirect: createRequest.IsDirect,
Reason: "", KeyID: createRequest.KeyID,
IsDirect: createRequest.IsDirect, PrivateKey: createRequest.PrivateKey,
KeyID: createRequest.KeyID, EventTime: createRequest.EventTime,
PrivateKey: createRequest.PrivateKey,
EventTime: createRequest.EventTime,
}, },
InviteRoomState: globalStrippedState, InviteRoomState: globalStrippedState,
SendAsServer: string(userID.Domain()), SendAsServer: string(userID.Domain()),

View file

@ -144,11 +144,9 @@ func (r *Inviter) PerformInvite(
} }
content := gomatrixserverlib.MemberContent{ content := gomatrixserverlib.MemberContent{
Membership: spec.Invite, Membership: spec.Invite,
DisplayName: req.InviteInput.DisplayName, Reason: req.InviteInput.Reason,
AvatarURL: req.InviteInput.AvatarURL, IsDirect: req.InviteInput.IsDirect,
Reason: req.InviteInput.Reason,
IsDirect: req.InviteInput.IsDirect,
} }
if err = proto.SetContent(content); err != nil { if err = proto.SetContent(content); err != nil {