Add change group chat name endpoint

This commit is contained in:
Andrea Maria Piana 2020-04-14 13:48:32 +02:00
parent 79be6eaf3a
commit f3fc6812cd
5 changed files with 141 additions and 6 deletions

View File

@ -1 +1 @@
0.51.1
0.52.0

View File

@ -200,6 +200,8 @@ func (p *messageProcessor) SendPairInstallation(
return messageID, nil
}
// EncodeMembershipUpdate takes a group and an optional chat message and returns the protobuf representation to be sent on the wire.
// All the events in a group are encoded and added to the payload
func (p *messageProcessor) EncodeMembershipUpdate(
group *v1protocol.Group,
chatMessage *protobuf.ChatMessage,

View File

@ -35,6 +35,7 @@ const transactionSentTxt = "Transaction sent"
var (
ErrChatIDEmpty = errors.New("chat ID is empty")
ErrChatNotFound = errors.New("can't find chat")
ErrNotImplemented = errors.New("not implemented")
)
@ -702,7 +703,7 @@ func (m *Messenger) RemoveMemberFromGroupChat(ctx context.Context, chatID string
logger.Info("Removing member form group chat", zap.String("chatID", chatID), zap.String("member", member))
chat, ok := m.allChats[chatID]
if !ok {
return nil, errors.New("can't find chat")
return nil, ErrChatNotFound
}
group, err := newProtocolGroupFromChat(chat)
@ -766,7 +767,7 @@ func (m *Messenger) AddMembersToGroupChat(ctx context.Context, chatID string, me
logger.Info("Adding members form group chat", zap.String("chatID", chatID), zap.Any("members", members))
chat, ok := m.allChats[chatID]
if !ok {
return nil, errors.New("can't find chat")
return nil, ErrChatNotFound
}
group, err := newProtocolGroupFromChat(chat)
@ -821,6 +822,72 @@ func (m *Messenger) AddMembersToGroupChat(ctx context.Context, chatID string, me
return &response, m.saveChat(chat)
}
func (m *Messenger) ChangeGroupChatName(ctx context.Context, chatID string, name string) (*MessengerResponse, error) {
logger := m.logger.With(zap.String("site", "ChangeGroupChatName"))
logger.Info("Changing group chat name", zap.String("chatID", chatID), zap.String("name", name))
m.mutex.Lock()
defer m.mutex.Unlock()
chat, ok := m.allChats[chatID]
if !ok {
return nil, ErrChatNotFound
}
group, err := newProtocolGroupFromChat(chat)
if err != nil {
return nil, err
}
clock, _ := chat.NextClockAndTimestamp(m.getTimesource())
// Add members
event := v1protocol.NewNameChangedEvent(name, clock)
event.ChatID = chat.ID
err = event.Sign(m.identity)
if err != nil {
return nil, err
}
// Update in-memory group
err = group.ProcessEvent(event)
if err != nil {
return nil, err
}
recipients, err := stringSliceToPublicKeys(group.Members(), true)
if err != nil {
return nil, err
}
encodedMessage, err := m.processor.EncodeMembershipUpdate(group, nil)
if err != nil {
return nil, err
}
_, err = m.dispatchMessage(ctx, &RawMessage{
LocalChatID: chat.ID,
Payload: encodedMessage,
MessageType: protobuf.ApplicationMetadataMessage_MEMBERSHIP_UPDATE_MESSAGE,
Recipients: recipients,
ResendAutomatically: true,
})
if err != nil {
return nil, err
}
chat.updateChatFromProtocolGroup(group)
var response MessengerResponse
response.Chats = []*Chat{chat}
response.Messages = buildSystemMessages([]v1protocol.MembershipUpdateEvent{event}, m.systemMessagesTranslations)
err = m.persistence.SaveMessagesLegacy(response.Messages)
if err != nil {
return nil, err
}
return &response, m.saveChat(chat)
}
func (m *Messenger) AddAdminsToGroupChat(ctx context.Context, chatID string, members []string) (*MessengerResponse, error) {
m.mutex.Lock()
defer m.mutex.Unlock()
@ -831,7 +898,7 @@ func (m *Messenger) AddAdminsToGroupChat(ctx context.Context, chatID string, mem
chat, ok := m.allChats[chatID]
if !ok {
return nil, errors.New("can't find chat")
return nil, ErrChatNotFound
}
group, err := newProtocolGroupFromChat(chat)
@ -894,7 +961,7 @@ func (m *Messenger) ConfirmJoiningGroup(ctx context.Context, chatID string) (*Me
chat, ok := m.allChats[chatID]
if !ok {
return nil, errors.New("can't find chat")
return nil, ErrChatNotFound
}
err := m.Join(*chat)
@ -961,7 +1028,7 @@ func (m *Messenger) LeaveGroupChat(ctx context.Context, chatID string) (*Messeng
chat, ok := m.allChats[chatID]
if !ok {
return nil, errors.New("can't find chat")
return nil, ErrChatNotFound
}
err := m.Leave(*chat)

View File

@ -874,6 +874,68 @@ func (s *MessengerSuite) TestRetrieveTheirPrivateGroupChat() {
s.Require().NotNil(actualChat.LastMessage)
}
// Test receiving a message on an existing private group chat
func (s *MessengerSuite) TestChangeNameGroupChat() {
var response *MessengerResponse
theirMessenger := s.newMessenger(s.shh)
response, err := s.m.CreateGroupChatWithMembers(context.Background(), "old-name", []string{})
s.NoError(err)
s.Require().Len(response.Chats, 1)
ourChat := response.Chats[0]
err = s.m.SaveChat(ourChat)
s.NoError(err)
members := []string{"0x" + hex.EncodeToString(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))}
_, err = s.m.AddMembersToGroupChat(context.Background(), ourChat.ID, members)
s.NoError(err)
// Retrieve their messages so that the chat is created
err = tt.RetryWithBackOff(func() error {
var err error
response, err = theirMessenger.RetrieveAll()
if err == nil && len(response.Chats) == 0 {
err = errors.New("chat invitation not received")
}
return err
})
s.Require().NoError(err)
_, err = theirMessenger.ConfirmJoiningGroup(context.Background(), ourChat.ID)
s.NoError(err)
// Wait for join group event
err = tt.RetryWithBackOff(func() error {
var err error
response, err = s.m.RetrieveAll()
if err == nil && len(response.Chats) == 0 {
err = errors.New("no joining group event received")
}
return err
})
s.Require().NoError(err)
newName := "new-name"
_, err = s.m.ChangeGroupChatName(context.Background(), ourChat.ID, newName)
s.NoError(err)
// Retrieve their messages so that the chat is created
err = tt.RetryWithBackOff(func() error {
var err error
response, err = theirMessenger.RetrieveAll()
if err == nil && len(response.Chats) == 0 {
err = errors.New("chat invitation not received")
}
return err
})
s.Require().NoError(err)
s.Require().Len(response.Chats, 1)
actualChat := response.Chats[0]
s.Require().Equal(newName, actualChat.Name)
}
// Test receiving a message on an existing private group chat, if messages
// are not wrapped this will fail as they'll likely come out of order
// NOTE: Disabling this as too flaky

View File

@ -226,6 +226,10 @@ func (api *PublicAPI) ConfirmJoiningGroup(ctx context.Context, chatID string) (*
return api.service.messenger.ConfirmJoiningGroup(ctx, chatID)
}
func (api *PublicAPI) ChangeGroupChatName(ctx Context, chatID string, name string) (*protocol.MessengerResponse, error) {
return api.service.messenger.ChangeGroupChatName(ctx, chatID, name)
}
func (api *PublicAPI) LoadFilters(parent context.Context, chats []*transport.Filter) ([]*transport.Filter, error) {
return api.service.messenger.LoadFilters(chats)
}