From ef8091d8057dee4169bc7b149ea1a550f72abb7b Mon Sep 17 00:00:00 2001 From: richjohnrambo Date: Tue, 15 Sep 2026 00:48:36 +0800 Subject: [PATCH] fix: reject friend request to missing user --- server/im_http_test.go | 34 ++++++++++++++++++++++++++++++++++ server/store/store.go | 3 +++ 2 files changed, 37 insertions(+) diff --git a/server/im_http_test.go b/server/im_http_test.go index 3f38cd5..8610feb 100644 --- a/server/im_http_test.go +++ b/server/im_http_test.go @@ -176,6 +176,7 @@ func (s *testHTTPInfrastructureStore) MarkKafkaDeadLetterReplay(_ types.TenantID type testRelationsStore struct { context *types.RelationshipContext + err error created *types.FriendRequest blocked *types.UserBlock deleted bool @@ -1348,6 +1349,9 @@ func (s *testRelationsStore) ListFriends(_ types.TenantID, _ types.Uid, _, _, _ } func (s *testRelationsStore) GetRelationshipContext(_ types.TenantID, userID, peerID types.Uid, topic string) (*types.RelationshipContext, error) { + if s.err != nil { + return nil, s.err + } if s.context != nil { return s.context, nil } @@ -8020,6 +8024,36 @@ func TestServeIMFriendRequestCreate(t *testing.T) { } } +func TestServeIMFriendRequestCreateReturnsNotFoundForMissingTarget(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + _ = expectIMBearer(t, ctrl, "token-1", 7, 1) + oldRelations := store.Relations + oldProfiles := store.Profiles + relations := &testRelationsStore{err: types.ErrNotFound} + store.Relations = relations + store.Profiles = &testProfilesStore{} + defer func() { + store.Relations = oldRelations + store.Profiles = oldProfiles + }() + + req := httptest.NewRequest(http.MethodPost, "/v1/im/friend-requests", + bytes.NewBufferString(`{"target_user_id":"`+types.Uid(2).UserId()+`","message":"你好","source":"search"}`)) + req.Header.Set("Authorization", "Bearer token-1") + req.Header.Set("Idempotency-Key", "fr-missing") + rec := httptest.NewRecorder() + + serveIMFriendRequests(rec, req) + + if rec.Code != http.StatusNotFound { + t.Fatalf("status: got %d, want %d; body=%s", rec.Code, http.StatusNotFound, rec.Body.String()) + } + if relations.created != nil { + t.Fatalf("friend request should not be created: %#v", relations.created) + } +} + func TestServeIMFriendRequestCreateIgnoresRelationEventFailure(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() diff --git a/server/store/store.go b/server/store/store.go index 8eec489..5c6b6ef 100644 --- a/server/store/store.go +++ b/server/store/store.go @@ -3436,6 +3436,9 @@ func relationshipContext(tenantAdp adapter.TenantBusinessAdapter, tenantID types if err != nil { return nil, err } + if peer == nil { + return nil, types.ErrNotFound + } ctx.Peer = peer if cachedBlock, err := cachedBlockContains(tenantID, userID, peerID); err != nil { logs.Warn.Printf("cache block[%s:%s]: read failed: %v", userID.UserId(), peerID.UserId(), err)