business: add privacy-aware user projection

(cherry picked from commit a636192ef22ee69d792b0ca7db1c6be963be9cb2)
This commit is contained in:
A 2026-06-08 01:07:21 +08:00
parent 14d220c971
commit 8ff3343ae0
29 changed files with 2239 additions and 112 deletions

View file

@ -29,7 +29,10 @@ func TestServiceProjectsMessageUsersForViewerContacts(t *testing.T) {
{ID: strangerID, AccessHash: 33, Phone: "15550000003", FirstName: "Stranger"},
},
}}
svc := NewService(store, nil, WithContactStore(contacts))
svc := NewService(store, nil, WithContactStore(contacts), WithPhotoProvider(messageProfilePhotos{
friendID: {PhotoID: 9101, DCID: 2, Stripped: []byte{5, 6}},
strangerID: {PhotoID: 9102, DCID: 4},
}))
list, err := svc.GetHistory(ctx, ownerID, domain.MessageFilter{Limit: 10})
if err != nil {
@ -39,10 +42,16 @@ func TestServiceProjectsMessageUsersForViewerContacts(t *testing.T) {
if !friend.Contact || friend.FirstName != "Remark" || friend.LastName != "Friend" || friend.Phone != "15550000002" {
t.Fatalf("friend projection = %+v, want contact remark and phone", friend)
}
if friend.PhotoID != 9101 || friend.PhotoDCID != 2 || string(friend.PhotoStripped) != string([]byte{5, 6}) {
t.Fatalf("friend photo = id %d dc %d stripped %v, want 9101/2/[5 6]", friend.PhotoID, friend.PhotoDCID, friend.PhotoStripped)
}
stranger := findUser(t, list.Users, strangerID)
if stranger.Contact || stranger.Phone != "" || stranger.FirstName != "Stranger" {
t.Fatalf("stranger projection = %+v, want non-contact with hidden phone", stranger)
}
if stranger.PhotoID != 9102 || stranger.PhotoDCID != 4 {
t.Fatalf("stranger photo = id %d dc %d, want 9102/4", stranger.PhotoID, stranger.PhotoDCID)
}
self := findUser(t, list.Users, ownerID)
if self.Phone != "15550000001" {
t.Fatalf("self phone = %q, want preserved", self.Phone)
@ -64,6 +73,18 @@ type projectionMessageStore struct {
list domain.MessageList
}
type messageProfilePhotos map[int64]domain.ProfilePhotoRef
func (p messageProfilePhotos) CurrentProfilePhotos(_ context.Context, _ domain.PeerType, ids []int64) (map[int64]domain.ProfilePhotoRef, error) {
out := make(map[int64]domain.ProfilePhotoRef, len(ids))
for _, id := range ids {
if ref, ok := p[id]; ok {
out[id] = ref
}
}
return out, nil
}
func (s projectionMessageStore) Create(context.Context, domain.Message) (domain.Message, error) {
return domain.Message{}, nil
}