feature(messenger): RequestContactInfoFromMailserver (#3376)

This commit is contained in:
Igor Sirotin 2023-04-05 23:25:44 +03:00 committed by GitHub
parent 5577679733
commit fb36298e37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 134 additions and 14 deletions

View File

@ -144,6 +144,9 @@ type Messenger struct {
requestedCommunitiesLock sync.RWMutex requestedCommunitiesLock sync.RWMutex
requestedCommunities map[string]*transport.Filter requestedCommunities map[string]*transport.Filter
requestedContactsLock sync.RWMutex
requestedContacts map[string]*transport.Filter
connectionState connection.State connectionState connection.State
telemetryClient *telemetry.Client telemetryClient *telemetry.Client
contractMaker *contracts.ContractMaker contractMaker *contracts.ContractMaker
@ -478,6 +481,8 @@ func NewMessenger(
cancel: cancel, cancel: cancel,
requestedCommunitiesLock: sync.RWMutex{}, requestedCommunitiesLock: sync.RWMutex{},
requestedCommunities: make(map[string]*transport.Filter), requestedCommunities: make(map[string]*transport.Filter),
requestedContactsLock: sync.RWMutex{},
requestedContacts: make(map[string]*transport.Filter),
importingCommunities: make(map[string]bool), importingCommunities: make(map[string]bool),
browserDatabase: c.browserDatabase, browserDatabase: c.browserDatabase,
httpServer: c.httpServer, httpServer: c.httpServer,
@ -3351,10 +3356,12 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte
senderID := contactIDFromPublicKey(publicKey) senderID := contactIDFromPublicKey(publicKey)
if _, ok := m.requestedContacts[senderID]; !ok {
// Check for messages from blocked users // Check for messages from blocked users
if contact, ok := messageState.AllContacts.Load(senderID); ok && contact.Blocked { if contact, ok := messageState.AllContacts.Load(senderID); ok && contact.Blocked {
continue continue
} }
}
// Don't process duplicates // Don't process duplicates
messageID := types.EncodeHex(msg.ID) messageID := types.EncodeHex(msg.ID)
@ -3379,6 +3386,7 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte
} }
contact = c contact = c
messageState.AllContacts.Store(senderID, contact) messageState.AllContacts.Store(senderID, contact)
m.forgetContactInfoRequest(senderID)
} }
messageState.CurrentMessageState = &CurrentMessageState{ messageState.CurrentMessageState = &CurrentMessageState{
MessageID: messageID, MessageID: messageID,
@ -3846,6 +3854,8 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte
} }
case protobuf.ContactUpdate: case protobuf.ContactUpdate:
logger.Info("<<< ContactUpdate", zap.String("publicKey", senderID))
if common.IsPubKeyEqual(messageState.CurrentMessageState.PublicKey, &m.identity.PublicKey) { if common.IsPubKeyEqual(messageState.CurrentMessageState.PublicKey, &m.identity.PublicKey) {
logger.Warn("coming from us, ignoring") logger.Warn("coming from us, ignoring")
continue continue
@ -3859,6 +3869,8 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte
allMessagesProcessed = false allMessagesProcessed = false
continue continue
} }
m.forgetContactInfoRequest(senderID)
case protobuf.AcceptContactRequest: case protobuf.AcceptContactRequest:
logger.Debug("Handling AcceptContactRequest") logger.Debug("Handling AcceptContactRequest")
message := msg.ParsedMessage.Interface().(protobuf.AcceptContactRequest) message := msg.ParsedMessage.Interface().(protobuf.AcceptContactRequest)

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"errors" "errors"
"time"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"go.uber.org/zap" "go.uber.org/zap"
@ -326,16 +327,13 @@ func (m *Messenger) addContact(pubKey, ensName, nickname, displayName, contactRe
return nil, err return nil, err
} }
// Fetch contact code
publicKey, err := contact.PublicKey() publicKey, err := contact.PublicKey()
if err != nil { if err != nil {
return nil, err return nil, err
} }
filter, err := m.transport.JoinPrivate(publicKey)
if err != nil { // Fetch contact code
return nil, err _, err = m.scheduleSyncFiltersForContact(publicKey)
}
_, err = m.scheduleSyncFilters([]*transport.Filter{filter})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -989,18 +987,124 @@ func (m *Messenger) BuildContact(request *requests.BuildContact) (*Contact, erro
} }
// Schedule sync filter to fetch information about the contact // Schedule sync filter to fetch information about the contact
publicKey, err := contact.PublicKey() publicKey, err := contact.PublicKey()
if err != nil { if err != nil {
return nil, err return nil, err
} }
filter, err := m.transport.JoinPrivate(publicKey)
if err != nil { _, err = m.scheduleSyncFiltersForContact(publicKey)
return nil, err
}
_, err = m.scheduleSyncFilters([]*transport.Filter{filter})
if err != nil { if err != nil {
return nil, err return nil, err
} }
return contact, nil return contact, nil
} }
func (m *Messenger) scheduleSyncFiltersForContact(publicKey *ecdsa.PublicKey) (*transport.Filter, error) {
filter, err := m.transport.JoinPrivate(publicKey)
if err != nil {
return nil, err
}
_, err = m.scheduleSyncFilters([]*transport.Filter{filter})
if err != nil {
return filter, err
}
return filter, nil
}
func (m *Messenger) RequestContactInfoFromMailserver(pubkey string, waitForResponse bool) (*Contact, error) {
err := m.requestContactInfoFromMailserver(pubkey)
if err != nil {
return nil, err
}
if !waitForResponse {
return nil, nil
}
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 15*time.Second)
defer cancel()
var contact *Contact
fetching := true
for fetching {
select {
case <-time.After(200 * time.Millisecond):
var ok bool
contact, ok = m.allContacts.Load(pubkey)
if ok && contact != nil && contact.DisplayName != "" {
fetching = false
m.logger.Info("contact info received", zap.String("pubkey", contact.ID))
}
case <-ctx.Done():
fetching = false
}
}
m.forgetContactInfoRequest(pubkey)
return contact, nil
}
func (m *Messenger) requestContactInfoFromMailserver(pubkey string) error {
m.requestedContactsLock.Lock()
defer m.requestedContactsLock.Unlock()
if _, ok := m.requestedContacts[pubkey]; ok {
return nil
}
m.logger.Debug("requesting contact info from mailserver", zap.String("publicKey", pubkey))
c, err := buildContactFromPkString(pubkey)
if err != nil {
return err
}
publicKey, err := c.PublicKey()
if err != nil {
return err
}
var filter *transport.Filter
filter, err = m.scheduleSyncFiltersForContact(publicKey)
if err != nil {
return err
}
m.requestedContacts[pubkey] = filter
return nil
}
func (m *Messenger) forgetContactInfoRequest(publicKey string) {
m.requestedContactsLock.Lock()
defer m.requestedContactsLock.Unlock()
filter, ok := m.requestedContacts[publicKey]
if !ok {
return
}
m.logger.Debug("forgetting contact info request", zap.String("publicKey", publicKey))
err := m.transport.RemoveFilters([]*transport.Filter{filter})
if err != nil {
m.logger.Warn("failed to remove filter", zap.Error(err))
}
delete(m.requestedContacts, publicKey)
}

View File

@ -334,6 +334,10 @@ func (api *PublicAPI) GetContactByID(parent context.Context, id string) *protoco
return api.service.messenger.GetContactByID(id) return api.service.messenger.GetContactByID(id)
} }
func (api *PublicAPI) RequestContactInfoFromMailserver(pubkey string) (*protocol.Contact, error) {
return api.service.messenger.RequestContactInfoFromMailserver(pubkey, true)
}
func (api *PublicAPI) RemoveFilters(parent context.Context, chats []*transport.Filter) error { func (api *PublicAPI) RemoveFilters(parent context.Context, chats []*transport.Filter) error {
return api.service.messenger.RemoveFilters(chats) return api.service.messenger.RemoveFilters(chats)
} }