fix: encrypt community's Categories and ActiveMembersCount
fixes: #4943 fixes: #4944
This commit is contained in:
parent
894eb5758e
commit
0aed93ff04
|
@ -1427,6 +1427,17 @@ func (o *Community) Description() *protobuf.CommunityDescription {
|
|||
return o.config.CommunityDescription
|
||||
}
|
||||
|
||||
func (o *Community) EncryptedDescription() (*protobuf.CommunityDescription, error) {
|
||||
clone := proto.Clone(o.config.CommunityDescription).(*protobuf.CommunityDescription)
|
||||
if o.encryptor != nil {
|
||||
err := encryptDescription(o.encryptor, o, clone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return clone, nil
|
||||
}
|
||||
|
||||
func (o *Community) DescriptionProtocolMessage() []byte {
|
||||
return o.config.CommunityDescriptionProtocolMessage
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package communities
|
||||
|
||||
import (
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
|
@ -26,7 +24,7 @@ func encryptDescription(encryptor DescriptionEncryptor, community *Community, de
|
|||
|
||||
descriptionToEncrypt := &protobuf.CommunityDescription{
|
||||
Chats: map[string]*protobuf.CommunityChat{
|
||||
channelID: proto.Clone(channel).(*protobuf.CommunityChat),
|
||||
channelID: channel,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -43,7 +41,9 @@ func encryptDescription(encryptor DescriptionEncryptor, community *Community, de
|
|||
if community.Encrypted() {
|
||||
descriptionToEncrypt := &protobuf.CommunityDescription{
|
||||
Members: description.Members,
|
||||
ActiveMembersCount: description.ActiveMembersCount,
|
||||
Chats: description.Chats,
|
||||
Categories: description.Categories,
|
||||
}
|
||||
|
||||
keyIDSeqNo, encryptedDescription, err := encryptor.encryptCommunityDescription(community, descriptionToEncrypt)
|
||||
|
@ -51,10 +51,12 @@ func encryptDescription(encryptor DescriptionEncryptor, community *Community, de
|
|||
return err
|
||||
}
|
||||
|
||||
// Set private data and cleanup unencrypted members and chats
|
||||
// Set private data and cleanup unencrypted members, chats and categories
|
||||
description.PrivateData[keyIDSeqNo] = encryptedDescription
|
||||
description.Members = make(map[string]*protobuf.CommunityMember)
|
||||
description.ActiveMembersCount = 0
|
||||
description.Chats = make(map[string]*protobuf.CommunityChat)
|
||||
description.Categories = make(map[string]*protobuf.CommunityCategory)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -85,11 +87,12 @@ func decryptDescription(id types.HexBytes, encryptor DescriptionEncryptor, descr
|
|||
}
|
||||
decryptedDescription := decryptedDescriptionResponse.Description
|
||||
|
||||
for pk, member := range decryptedDescription.Members {
|
||||
if description.Members == nil {
|
||||
description.Members = make(map[string]*protobuf.CommunityMember)
|
||||
if len(decryptedDescription.Members) > 0 {
|
||||
description.Members = decryptedDescription.Members
|
||||
}
|
||||
description.Members[pk] = member
|
||||
|
||||
if decryptedDescription.ActiveMembersCount > 0 {
|
||||
description.ActiveMembersCount = decryptedDescription.ActiveMembersCount
|
||||
}
|
||||
|
||||
for id, decryptedChannel := range decryptedDescription.Chats {
|
||||
|
@ -98,13 +101,17 @@ func decryptDescription(id types.HexBytes, encryptor DescriptionEncryptor, descr
|
|||
}
|
||||
|
||||
if channel := description.Chats[id]; channel != nil {
|
||||
if len(channel.Members) == 0 {
|
||||
if len(decryptedChannel.Members) > 0 {
|
||||
channel.Members = decryptedChannel.Members
|
||||
}
|
||||
} else {
|
||||
description.Chats[id] = decryptedChannel
|
||||
}
|
||||
}
|
||||
|
||||
if len(decryptedDescription.Categories) > 0 {
|
||||
description.Categories = decryptedDescription.Categories
|
||||
}
|
||||
}
|
||||
|
||||
return failedToDecrypt, nil
|
||||
|
|
|
@ -50,13 +50,13 @@ type DescriptionEncryptorMock struct {
|
|||
|
||||
func (dem *DescriptionEncryptorMock) encryptCommunityDescription(community *Community, d *protobuf.CommunityDescription) (string, []byte, error) {
|
||||
keyIDSeqNo := uuid.New().String()
|
||||
dem.descriptions[keyIDSeqNo] = d
|
||||
dem.descriptions[keyIDSeqNo] = proto.Clone(d).(*protobuf.CommunityDescription)
|
||||
return keyIDSeqNo, []byte("encryptedDescription"), nil
|
||||
}
|
||||
|
||||
func (dem *DescriptionEncryptorMock) encryptCommunityDescriptionChannel(community *Community, channelID string, d *protobuf.CommunityDescription) (string, []byte, error) {
|
||||
keyIDSeqNo := uuid.New().String()
|
||||
dem.descriptions[keyIDSeqNo] = d
|
||||
dem.descriptions[keyIDSeqNo] = proto.Clone(d).(*protobuf.CommunityDescription)
|
||||
dem.channelIDToKeyIDSeqNo[channelID] = keyIDSeqNo
|
||||
return keyIDSeqNo, []byte("encryptedDescription"), nil
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ func (s *CommunityEncryptionDescriptionSuite) description() *protobuf.CommunityD
|
|||
"memberA": &protobuf.CommunityMember{},
|
||||
"memberB": &protobuf.CommunityMember{},
|
||||
},
|
||||
ActiveMembersCount: 1,
|
||||
Chats: map[string]*protobuf.CommunityChat{
|
||||
"channelA": &protobuf.CommunityChat{
|
||||
Members: map[string]*protobuf.CommunityMember{
|
||||
|
@ -99,6 +100,13 @@ func (s *CommunityEncryptionDescriptionSuite) description() *protobuf.CommunityD
|
|||
},
|
||||
},
|
||||
},
|
||||
Categories: map[string]*protobuf.CommunityCategory{
|
||||
"categoryA": &protobuf.CommunityCategory{
|
||||
CategoryId: "categoryA",
|
||||
Name: "categoryA",
|
||||
Position: 0,
|
||||
},
|
||||
},
|
||||
PrivateData: map[string][]byte{},
|
||||
|
||||
// ensure community and channel encryption
|
||||
|
@ -128,18 +136,23 @@ func (s *CommunityEncryptionDescriptionSuite) TestEncryptionDecryption() {
|
|||
s.Require().NoError(err)
|
||||
s.Require().Len(description.PrivateData, 2)
|
||||
|
||||
// members and chats should become empty (encrypted)
|
||||
// members, chats, categories should become empty (encrypted)
|
||||
s.Require().Empty(description.Members)
|
||||
s.Require().Empty(description.ActiveMembersCount)
|
||||
s.Require().Empty(description.Chats)
|
||||
s.Require().Empty(description.Categories)
|
||||
s.Require().Equal(description.IntroMessage, "one of not encrypted fields")
|
||||
|
||||
// members and chats should be brought back
|
||||
_, err = decryptDescription([]byte("some-id"), s.descriptionEncryptor, description, s.logger)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(description.Members, 2)
|
||||
s.Require().EqualValues(description.ActiveMembersCount, 1)
|
||||
s.Require().Len(description.Chats, 2)
|
||||
s.Require().Len(description.Chats["channelA"].Members, 2)
|
||||
s.Require().Len(description.Chats["channelB"].Members, 1)
|
||||
s.Require().Len(description.Categories, 1)
|
||||
s.Require().Equal(description.Categories["categoryA"].Name, "categoryA")
|
||||
s.Require().Equal(description.IntroMessage, "one of not encrypted fields")
|
||||
}
|
||||
|
||||
|
@ -163,19 +176,24 @@ func (s *CommunityEncryptionDescriptionSuite) TestDecryption_NoKeys() {
|
|||
_, err := decryptDescription([]byte("some-id"), s.descriptionEncryptor, description, s.logger)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(description.Members, 2)
|
||||
s.Require().EqualValues(description.ActiveMembersCount, 1)
|
||||
s.Require().Len(description.Chats, 2)
|
||||
s.Require().Len(description.Chats["channelA"].Members, 2)
|
||||
s.Require().Len(description.Chats["channelB"].Members, 0) // encrypted channel
|
||||
s.Require().Len(description.Categories, 1)
|
||||
s.Require().Equal(description.Categories["categoryA"].Name, "categoryA")
|
||||
s.Require().Equal(description.IntroMessage, "one of not encrypted fields")
|
||||
|
||||
description = proto.Clone(encryptedDescription).(*protobuf.CommunityDescription)
|
||||
// forget the keys, so chats and members can't be decrypted
|
||||
// forget the keys, so members, chats, categories can't be decrypted
|
||||
s.descriptionEncryptor.forgetAllKeys()
|
||||
|
||||
// members and chats should be empty
|
||||
// members, chats, categories should be empty
|
||||
_, err = decryptDescription([]byte("some-id"), s.descriptionEncryptor, description, s.logger)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Empty(description.Members)
|
||||
s.Require().Empty(description.ActiveMembersCount)
|
||||
s.Require().Empty(description.Chats)
|
||||
s.Require().Empty(description.Categories)
|
||||
s.Require().Equal(description.IntroMessage, "one of not encrypted fields")
|
||||
}
|
||||
|
|
|
@ -1550,11 +1550,16 @@ func (m *Messenger) acceptRequestToJoinCommunity(requestToJoin *communities.Requ
|
|||
}
|
||||
}
|
||||
|
||||
encryptedDescription, err := community.EncryptedDescription()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
requestToJoinResponseProto := &protobuf.CommunityRequestToJoinResponse{
|
||||
Clock: community.Clock(),
|
||||
Accepted: true,
|
||||
CommunityId: community.ID(),
|
||||
Community: community.Description(),
|
||||
Community: encryptedDescription,
|
||||
Grant: grant,
|
||||
ProtectedTopicPrivateKey: crypto.FromECDSA(key),
|
||||
Shard: community.Shard().Protobuffer(),
|
||||
|
|
Loading…
Reference in New Issue