diff --git a/server/im_http.go b/server/im_http.go index 72662a0..7d28c49 100644 --- a/server/im_http.go +++ b/server/im_http.go @@ -8704,6 +8704,7 @@ func authenticateTopicReader(wrt http.ResponseWriter, req *http.Request, topic s writeIMError(wrt, req, http.StatusBadRequest, 30000, imReasonMalformedRequest, "malformed request", map[string]any{"field": "topic"}) return nil, "", false } + topic = normalizeConversationSettingsTopic(topic, principal.Uid) sub, err := store.Subs.Get(principal.TenantID, topic, principal.Uid, false) if err != nil { writeIMRelationError(wrt, req, err) diff --git a/server/im_http_test.go b/server/im_http_test.go index 7a6143d..4f14cc6 100644 --- a/server/im_http_test.go +++ b/server/im_http_test.go @@ -5186,6 +5186,61 @@ func TestServeIMMessageSearchContextAndMedia(t *testing.T) { } } +func TestServeIMTopicReadActionsNormalizeP2PUserTopic(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + actor := types.Uid(42) + peer := types.Uid(43) + normalizedTopic := actor.P2PName(peer) + oldStore := store.Store + mockStore := mock_store.NewMockPersistentStorageInterface(ctrl) + tokenAuth := mock_auth.NewMockAuthHandler(ctrl) + mockStore.EXPECT().GetLogicalAuthHandler("token").Return(tokenAuth).Times(2) + tokenAuth.EXPECT().IsInitialized().Return(true).Times(2) + tokenAuth.EXPECT().Authenticate(auth.AuthContext{}, []byte("token-1")). + Return(&auth.Rec{TenantID: 7, Uid: actor, AuthLevel: auth.LevelAuth}, nil, nil).Times(2) + store.Store = mockStore + oldSubs := store.Subs + oldMessages := store.Messages + subs := mock_store.NewMockSubsPersistenceInterface(ctrl) + messages := mock_store.NewMockMessagesPersistenceInterface(ctrl) + store.Subs = subs + store.Messages = messages + defer func() { + store.Store = oldStore + store.Subs = oldSubs + store.Messages = oldMessages + }() + + subs.EXPECT().Get(types.TenantID(7), normalizedTopic, actor, false).Return(&types.Subscription{ + TenantID: 7, + User: actor.String(), + Topic: normalizedTopic, + ModeWant: types.ModeCPublic, + ModeGiven: types.ModeCPublic, + }, nil).Times(2) + textMsg := types.Message{TenantID: 7, SeqId: 9, Topic: normalizedTopic, From: actor.String(), Head: types.KVMap{"type": "text"}, Content: map[string]any{"text": "好的"}} + imageMsg := types.Message{TenantID: 7, SeqId: 10, Topic: normalizedTopic, From: actor.String(), Head: types.KVMap{"type": "image"}, Content: map[string]any{"file_id": "file-1", "mime": "image/png"}} + messages.EXPECT().Search(types.TenantID(7), normalizedTopic, actor, "好的", "text", "", 50).Return([]types.Message{textMsg}, "", nil) + messages.EXPECT().Search(types.TenantID(7), normalizedTopic, actor, "", "image", "", 50).Return([]types.Message{imageMsg}, "", nil) + + searchReq := httptest.NewRequest(http.MethodGet, "/v1/im/topics/"+peer.UserId()+"/messages/search?q=%E5%A5%BD%E7%9A%84&type=text", nil) + searchReq.Header.Set("Authorization", "Bearer token-1") + searchRec := httptest.NewRecorder() + serveIMTopicMessageAction(searchRec, searchReq) + if searchRec.Code != http.StatusOK { + t.Fatalf("search status: got %d body=%s", searchRec.Code, searchRec.Body.String()) + } + + mediaReq := httptest.NewRequest(http.MethodGet, "/v1/im/topics/"+peer.UserId()+"/media?type=image", nil) + mediaReq.Header.Set("Authorization", "Bearer token-1") + mediaRec := httptest.NewRecorder() + serveIMTopicMessageAction(mediaRec, mediaReq) + if mediaRec.Code != http.StatusOK { + t.Fatalf("media status: got %d body=%s", mediaRec.Code, mediaRec.Body.String()) + } +} + func TestServeIMTopicCalls(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish()