feat: allow group admin to delete others message (#3259)
This commit is contained in:
parent
3f3e8f8894
commit
475b5f855f
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
userimage "github.com/status-im/status-go/images"
|
userimage "github.com/status-im/status-go/images"
|
||||||
"github.com/status-im/status-go/protocol/common"
|
"github.com/status-im/status-go/protocol/common"
|
||||||
|
"github.com/status-im/status-go/protocol/protobuf"
|
||||||
"github.com/status-im/status-go/protocol/tt"
|
"github.com/status-im/status-go/protocol/tt"
|
||||||
"github.com/status-im/status-go/waku"
|
"github.com/status-im/status-go/waku"
|
||||||
)
|
)
|
||||||
|
@ -356,3 +357,89 @@ func (s *MessengerGroupChatSuite) TestGroupChatEdit() {
|
||||||
defer s.NoError(admin.Shutdown())
|
defer s.NoError(admin.Shutdown())
|
||||||
defer s.NoError(member.Shutdown())
|
defer s.NoError(member.Shutdown())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) TestGroupChatDeleteMemberMessage() {
|
||||||
|
admin := s.startNewMessenger()
|
||||||
|
member := s.startNewMessenger()
|
||||||
|
s.makeMutualContacts(admin, member)
|
||||||
|
|
||||||
|
groupChat := s.createGroupChat(admin, "test_group_chat", []string{common.PubkeyToHex(&member.identity.PublicKey)})
|
||||||
|
s.verifyGroupChatCreated(member, true)
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
inputMessage := buildTestMessage(*groupChat)
|
||||||
|
_, err := member.SendChatMessage(ctx, inputMessage)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
response, err := WaitOnMessengerResponse(
|
||||||
|
admin,
|
||||||
|
func(r *MessengerResponse) bool { return len(r.Messages()) > 0 },
|
||||||
|
"messages not received",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(response.Messages(), 1)
|
||||||
|
s.Require().Equal(inputMessage.Text, response.Messages()[0].Text)
|
||||||
|
|
||||||
|
message := response.Messages()[0]
|
||||||
|
deleteMessageResponse, err := admin.DeleteMessageAndSend(ctx, message.ID)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
_, err = WaitOnMessengerResponse(member, func(response *MessengerResponse) bool {
|
||||||
|
return len(response.RemovedMessages()) > 0
|
||||||
|
}, "removed messages not received")
|
||||||
|
s.Require().Equal(deleteMessageResponse.RemovedMessages()[0].DeletedBy, contactIDFromPublicKey(admin.IdentityPublicKey()))
|
||||||
|
s.Require().NoError(err)
|
||||||
|
message, err = member.MessageByID(message.ID)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().True(message.Deleted)
|
||||||
|
|
||||||
|
defer s.NoError(admin.Shutdown())
|
||||||
|
defer s.NoError(member.Shutdown())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) TestGroupChatHandleDeleteMemberMessage() {
|
||||||
|
admin := s.startNewMessenger()
|
||||||
|
member := s.startNewMessenger()
|
||||||
|
s.makeMutualContacts(admin, member)
|
||||||
|
|
||||||
|
groupChat := s.createGroupChat(admin, "test_group_chat", []string{common.PubkeyToHex(&member.identity.PublicKey)})
|
||||||
|
s.verifyGroupChatCreated(member, true)
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
inputMessage := buildTestMessage(*groupChat)
|
||||||
|
_, err := member.SendChatMessage(ctx, inputMessage)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
response, err := WaitOnMessengerResponse(
|
||||||
|
admin,
|
||||||
|
func(r *MessengerResponse) bool { return len(r.Messages()) > 0 },
|
||||||
|
"messages not received",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(response.Messages(), 1)
|
||||||
|
s.Require().Equal(inputMessage.Text, response.Messages()[0].Text)
|
||||||
|
|
||||||
|
deleteMessage := DeleteMessage{
|
||||||
|
DeleteMessage: protobuf.DeleteMessage{
|
||||||
|
Clock: 2,
|
||||||
|
MessageType: protobuf.MessageType_PRIVATE_GROUP,
|
||||||
|
MessageId: inputMessage.ID,
|
||||||
|
ChatId: groupChat.ID,
|
||||||
|
},
|
||||||
|
From: common.PubkeyToHex(&admin.identity.PublicKey),
|
||||||
|
}
|
||||||
|
|
||||||
|
state := &ReceivedMessageState{
|
||||||
|
Response: &MessengerResponse{},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = member.HandleDeleteMessage(state, deleteMessage)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
removedMessages := state.Response.RemovedMessages()
|
||||||
|
s.Require().Len(removedMessages, 1)
|
||||||
|
s.Require().Equal(removedMessages[0].MessageID, inputMessage.ID)
|
||||||
|
|
||||||
|
defer s.NoError(admin.Shutdown())
|
||||||
|
defer s.NoError(member.Shutdown())
|
||||||
|
}
|
||||||
|
|
|
@ -1531,16 +1531,22 @@ func (m *Messenger) HandleDeleteMessage(state *ReceivedMessageState, deleteMessa
|
||||||
|
|
||||||
var canDeleteMessageForEveryone = false
|
var canDeleteMessageForEveryone = false
|
||||||
if originalMessage.From != deleteMessage.From {
|
if originalMessage.From != deleteMessage.From {
|
||||||
|
fromPublicKey, err := common.HexToPubkey(deleteMessage.From)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if chat.ChatType == ChatTypeCommunityChat {
|
if chat.ChatType == ChatTypeCommunityChat {
|
||||||
fromPublicKey, err := common.HexToPubkey(deleteMessage.From)
|
canDeleteMessageForEveryone = m.CanDeleteMessageForEveryoneInCommunity(chat.CommunityID, fromPublicKey)
|
||||||
if err != nil {
|
if !canDeleteMessageForEveryone {
|
||||||
return err
|
return ErrInvalidDeletePermission
|
||||||
}
|
}
|
||||||
canDeleteMessageForEveryone = m.CanDeleteMessageForEveryone(chat.CommunityID, fromPublicKey)
|
} else if chat.ChatType == ChatTypePrivateGroupChat {
|
||||||
|
canDeleteMessageForEveryone = m.CanDeleteMessageForEveryoneInPrivateGroupChat(chat, fromPublicKey)
|
||||||
if !canDeleteMessageForEveryone {
|
if !canDeleteMessageForEveryone {
|
||||||
return ErrInvalidDeletePermission
|
return ErrInvalidDeletePermission
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check edit is valid
|
// Check edit is valid
|
||||||
if !canDeleteMessageForEveryone {
|
if !canDeleteMessageForEveryone {
|
||||||
return errors.New("invalid delete, not the right author")
|
return errors.New("invalid delete, not the right author")
|
||||||
|
|
|
@ -90,7 +90,7 @@ func (m *Messenger) EditMessage(ctx context.Context, request *requests.EditMessa
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Messenger) CanDeleteMessageForEveryone(communityID string, publicKey *ecdsa.PublicKey) bool {
|
func (m *Messenger) CanDeleteMessageForEveryoneInCommunity(communityID string, publicKey *ecdsa.PublicKey) bool {
|
||||||
if communityID != "" {
|
if communityID != "" {
|
||||||
community, err := m.communitiesManager.GetByIDString(communityID)
|
community, err := m.communitiesManager.GetByIDString(communityID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -102,6 +102,16 @@ func (m *Messenger) CanDeleteMessageForEveryone(communityID string, publicKey *e
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) CanDeleteMessageForEveryoneInPrivateGroupChat(chat *Chat, publicKey *ecdsa.PublicKey) bool {
|
||||||
|
group, err := newProtocolGroupFromChat(chat)
|
||||||
|
if err != nil {
|
||||||
|
m.logger.Error("failed to find group", zap.String("chatID", chat.ID), zap.Error(err))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
admins := group.Admins()
|
||||||
|
return stringSliceContains(admins, common.PubkeyToHex(publicKey))
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Messenger) DeleteMessageAndSend(ctx context.Context, messageID string) (*MessengerResponse, error) {
|
func (m *Messenger) DeleteMessageAndSend(ctx context.Context, messageID string) (*MessengerResponse, error) {
|
||||||
message, err := m.persistence.MessageByID(messageID)
|
message, err := m.persistence.MessageByID(messageID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -119,7 +129,12 @@ func (m *Messenger) DeleteMessageAndSend(ctx context.Context, messageID string)
|
||||||
if message.From != common.PubkeyToHex(&m.identity.PublicKey) {
|
if message.From != common.PubkeyToHex(&m.identity.PublicKey) {
|
||||||
if message.MessageType == protobuf.MessageType_COMMUNITY_CHAT {
|
if message.MessageType == protobuf.MessageType_COMMUNITY_CHAT {
|
||||||
communityID := chat.CommunityID
|
communityID := chat.CommunityID
|
||||||
canDeleteMessageForEveryone = m.CanDeleteMessageForEveryone(communityID, &m.identity.PublicKey)
|
canDeleteMessageForEveryone = m.CanDeleteMessageForEveryoneInCommunity(communityID, &m.identity.PublicKey)
|
||||||
|
if !canDeleteMessageForEveryone {
|
||||||
|
return nil, ErrInvalidDeletePermission
|
||||||
|
}
|
||||||
|
} else if message.MessageType == protobuf.MessageType_PRIVATE_GROUP {
|
||||||
|
canDeleteMessageForEveryone = m.CanDeleteMessageForEveryoneInPrivateGroupChat(chat, &m.identity.PublicKey)
|
||||||
if !canDeleteMessageForEveryone {
|
if !canDeleteMessageForEveryone {
|
||||||
return nil, ErrInvalidDeletePermission
|
return nil, ErrInvalidDeletePermission
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue