chore: populate Community with PubsubTopicPrivateKey

part of: status-im/status-desktop#12408
This commit is contained in:
Patryk Osmaczko 2023-10-30 19:34:21 +01:00 committed by osmaczko
parent a0bd3c9a94
commit 25f25e9853
5 changed files with 84 additions and 62 deletions

View File

@ -12,6 +12,8 @@ import (
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"go.uber.org/zap" "go.uber.org/zap"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/images" "github.com/status-im/status-go/images"
@ -45,6 +47,7 @@ type Config struct {
SyncedAt uint64 SyncedAt uint64
EventsData *EventsData EventsData *EventsData
Shard *common.Shard Shard *common.Shard
PubsubTopicPrivateKey *ecdsa.PrivateKey
} }
type EventsData struct { type EventsData struct {
@ -142,15 +145,17 @@ func (o *Community) MarshalPublicAPIJSON() ([]byte, error) {
CommunityTokensMetadata []*protobuf.CommunityTokenMetadata `json:"communityTokensMetadata"` CommunityTokensMetadata []*protobuf.CommunityTokenMetadata `json:"communityTokensMetadata"`
ActiveMembersCount uint64 `json:"activeMembersCount"` ActiveMembersCount uint64 `json:"activeMembersCount"`
PubsubTopic string `json:"pubsubTopic"` PubsubTopic string `json:"pubsubTopic"`
PubsubTopicKey string `json:"pubsubTopicKey"`
Shard *common.Shard `json:"shard"` Shard *common.Shard `json:"shard"`
}{ }{
ID: o.ID(), ID: o.ID(),
Verified: o.config.Verified, Verified: o.config.Verified,
Chats: make(map[string]CommunityChat), Chats: make(map[string]CommunityChat),
Categories: make(map[string]CommunityCategory), Categories: make(map[string]CommunityCategory),
Tags: o.Tags(), Tags: o.Tags(),
PubsubTopic: o.PubsubTopic(), PubsubTopic: o.PubsubTopic(),
Shard: o.Shard(), PubsubTopicKey: o.PubsubTopicKey(),
Shard: o.Shard(),
} }
if o.config.CommunityDescription != nil { if o.config.CommunityDescription != nil {
@ -258,6 +263,7 @@ func (o *Community) MarshalJSON() ([]byte, error) {
CommunityTokensMetadata []*protobuf.CommunityTokenMetadata `json:"communityTokensMetadata"` CommunityTokensMetadata []*protobuf.CommunityTokenMetadata `json:"communityTokensMetadata"`
ActiveMembersCount uint64 `json:"activeMembersCount"` ActiveMembersCount uint64 `json:"activeMembersCount"`
PubsubTopic string `json:"pubsubTopic"` PubsubTopic string `json:"pubsubTopic"`
PubsubTopicKey string `json:"pubsubTopicKey"`
Shard *common.Shard `json:"shard"` Shard *common.Shard `json:"shard"`
}{ }{
ID: o.ID(), ID: o.ID(),
@ -279,6 +285,7 @@ func (o *Community) MarshalJSON() ([]byte, error) {
Tags: o.Tags(), Tags: o.Tags(),
Encrypted: o.Encrypted(), Encrypted: o.Encrypted(),
PubsubTopic: o.PubsubTopic(), PubsubTopic: o.PubsubTopic(),
PubsubTopicKey: o.PubsubTopicKey(),
Shard: o.Shard(), Shard: o.Shard(),
} }
if o.config.CommunityDescription != nil { if o.config.CommunityDescription != nil {
@ -1308,6 +1315,21 @@ func (o *Community) PubsubTopic() string {
return transport.GetPubsubTopic(o.Shard().TransportShard()) return transport.GetPubsubTopic(o.Shard().TransportShard())
} }
func (o *Community) PubsubTopicPrivateKey() *ecdsa.PrivateKey {
return o.config.PubsubTopicPrivateKey
}
func (o *Community) SetPubsubTopicPrivateKey(privKey *ecdsa.PrivateKey) {
o.config.PubsubTopicPrivateKey = privKey
}
func (o *Community) PubsubTopicKey() string {
if o.config.PubsubTopicPrivateKey == nil {
return ""
}
return hexutil.Encode(crypto.FromECDSAPub(&o.config.PubsubTopicPrivateKey.PublicKey))
}
func (o *Community) DefaultFilters() []transport.FiltersToInitialize { func (o *Community) DefaultFilters() []transport.FiltersToInitialize {
cID := o.IDString() cID := o.IDString()
uncompressedPubKey := common.PubkeyToHex(o.config.ID)[2:] uncompressedPubKey := common.PubkeyToHex(o.config.ID)[2:]

View File

@ -625,7 +625,7 @@ func (m *Manager) All() ([]*Community, error) {
} }
for _, c := range communities { for _, c := range communities {
err = initializeCommunity(c) err = m.initializeCommunity(c)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -687,7 +687,7 @@ func (m *Manager) Joined() ([]*Community, error) {
} }
for _, c := range communities { for _, c := range communities {
err = initializeCommunity(c) err = m.initializeCommunity(c)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -703,7 +703,7 @@ func (m *Manager) Spectated() ([]*Community, error) {
} }
for _, c := range communities { for _, c := range communities {
err = initializeCommunity(c) err = m.initializeCommunity(c)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -719,7 +719,7 @@ func (m *Manager) JoinedAndPendingCommunitiesWithRequests() ([]*Community, error
} }
for _, c := range communities { for _, c := range communities {
err = initializeCommunity(c) err = m.initializeCommunity(c)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -735,7 +735,7 @@ func (m *Manager) DeletedCommunities() ([]*Community, error) {
} }
for _, c := range communities { for _, c := range communities {
err = initializeCommunity(c) err = m.initializeCommunity(c)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -754,7 +754,7 @@ func (m *Manager) Controlled() ([]*Community, error) {
for _, c := range communities { for _, c := range communities {
if c.IsControlNode() { if c.IsControlNode() {
err = initializeCommunity(c) err = m.initializeCommunity(c)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1116,6 +1116,18 @@ func (m *Manager) SetShard(communityID types.HexBytes, shard *common.Shard) (*Co
return community, nil return community, nil
} }
func (m *Manager) UpdatePubsubTopicPrivateKey(community *Community, privKey *ecdsa.PrivateKey) error {
community.SetPubsubTopicPrivateKey(privKey)
if privKey != nil {
if err := m.transport.StorePubsubTopicKey(community.PubsubTopic(), privKey); err != nil {
return err
}
}
return nil
}
// EditCommunity takes a description, updates the community with the description, // EditCommunity takes a description, updates the community with the description,
// saves it and returns it // saves it and returns it
func (m *Manager) EditCommunity(request *requests.EditCommunity) (*Community, error) { func (m *Manager) EditCommunity(request *requests.EditCommunity) (*Community, error) {
@ -3188,12 +3200,20 @@ func (m *Manager) BanUserFromCommunity(request *requests.BanUserFromCommunity) (
} }
// Apply events to raw community // Apply events to raw community
func initializeCommunity(community *Community) error { func (m *Manager) initializeCommunity(community *Community) error {
err := community.updateCommunityDescriptionByEvents() err := community.updateCommunityDescriptionByEvents()
if err != nil { if err != nil {
return err return err
} }
if m.transport != nil && m.transport.WakuVersion() == 2 {
privKey, err := m.transport.RetrievePubsubTopicKey(community.PubsubTopic())
if err != nil {
return err
}
community.config.PubsubTopicPrivateKey = privKey
}
// Workaround for https://github.com/status-im/status-desktop/issues/12188 // Workaround for https://github.com/status-im/status-desktop/issues/12188
HydrateChannelsMembers(community.IDString(), community.config.CommunityDescription) HydrateChannelsMembers(community.IDString(), community.config.CommunityDescription)
@ -3209,7 +3229,7 @@ func (m *Manager) GetByID(id []byte) (*Community, error) {
return nil, nil return nil, nil
} }
err = initializeCommunity(community) err = m.initializeCommunity(community)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -2084,7 +2084,12 @@ func (m *Messenger) SetCommunityShard(request *requests.SetCommunityShard) (*Mes
return nil, err return nil, err
} }
err = m.UpdateCommunityFilters(community, topicPrivKey) err = m.communitiesManager.UpdatePubsubTopicPrivateKey(community, topicPrivKey)
if err != nil {
return nil, err
}
err = m.UpdateCommunityFilters(community)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -2095,22 +2100,12 @@ func (m *Messenger) SetCommunityShard(request *requests.SetCommunityShard) (*Mes
} }
response := &MessengerResponse{} response := &MessengerResponse{}
response.AddProtectedTopic(&ProtectedTopic{ response.AddCommunity(community)
CommunityID: community.IDString(),
PubsubTopic: community.PubsubTopic(),
PublicKey: hexutil.Encode(crypto.FromECDSAPub(&topicPrivKey.PublicKey)),
})
return response, nil return response, nil
} }
func (m *Messenger) UpdateCommunityFilters(community *communities.Community, privKey *ecdsa.PrivateKey) error { func (m *Messenger) UpdateCommunityFilters(community *communities.Community) error {
if m.transport.WakuVersion() == 2 && privKey != nil {
if err := m.transport.StorePubsubTopicKey(community.PubsubTopic(), privKey); err != nil {
return err
}
}
publicFiltersToInit := make([]transport.FiltersToInitialize, 0, len(community.DefaultFilters())+len(community.Chats())) publicFiltersToInit := make([]transport.FiltersToInitialize, 0, len(community.DefaultFilters())+len(community.Chats()))
publicFiltersToInit = append(publicFiltersToInit, community.DefaultFilters()...) publicFiltersToInit = append(publicFiltersToInit, community.DefaultFilters()...)
@ -2499,11 +2494,7 @@ func (m *Messenger) SendCommunityShardKey(community *communities.Community, pubk
return nil return nil
} }
key, err := m.transport.RetrievePubsubTopicKey(community.PubsubTopic()) key := community.PubsubTopicPrivateKey()
if err != nil {
return err
}
if key == nil { if key == nil {
return nil // No community shard key available return nil // No community shard key available
} }
@ -3073,11 +3064,14 @@ func (m *Messenger) HandleCommunityShardKey(state *ReceivedMessageState, message
return errors.New("signer can't be nil") return errors.New("signer can't be nil")
} }
if !community.IsMemberOwner(signer) { err = m.handleCommunityShardAndFiltersFromProto(community, common.ShardFromProtobuff(message.Shard), message.PrivateKey)
return communities.ErrNotAuthorized if err != nil {
return err
} }
return m.handleCommunityShardAndFiltersFromProto(community, common.ShardFromProtobuff(message.Shard), message.PrivateKey) state.Response.AddCommunity(community)
return nil
} }
func (m *Messenger) handleCommunityShardAndFiltersFromProto(community *communities.Community, shard *common.Shard, privateKeyBytes []byte) error { func (m *Messenger) handleCommunityShardAndFiltersFromProto(community *communities.Community, shard *common.Shard, privateKeyBytes []byte) error {
@ -3094,7 +3088,12 @@ func (m *Messenger) handleCommunityShardAndFiltersFromProto(community *communiti
} }
} }
err = m.UpdateCommunityFilters(community, privKey) err = m.communitiesManager.UpdatePubsubTopicPrivateKey(community, privKey)
if err != nil {
return err
}
err = m.UpdateCommunityFilters(community)
if err != nil { if err != nil {
return err return err
} }

View File

@ -34,12 +34,6 @@ type ClearedHistory struct {
ClearedAt uint64 `json:"clearedAt"` ClearedAt uint64 `json:"clearedAt"`
} }
type ProtectedTopic struct {
CommunityID string `json:"communityID"`
PubsubTopic string `json:"pubsubTopic"`
PublicKey string `json:"publicKey"`
}
type MessengerResponse struct { type MessengerResponse struct {
Contacts []*Contact Contacts []*Contact
Installations []*multidevice.Installation Installations []*multidevice.Installation
@ -68,7 +62,6 @@ type MessengerResponse struct {
removedMessages map[string]*RemovedMessage removedMessages map[string]*RemovedMessage
communities map[string]*communities.Community communities map[string]*communities.Community
communitiesSettings map[string]*communities.CommunitySettings communitiesSettings map[string]*communities.CommunitySettings
protectedTopics map[string]*ProtectedTopic
activityCenterNotifications map[string]*ActivityCenterNotification activityCenterNotifications map[string]*ActivityCenterNotification
activityCenterState *ActivityCenterState activityCenterState *ActivityCenterState
messages map[string]*common.Message messages map[string]*common.Message
@ -110,7 +103,6 @@ func (r *MessengerResponse) MarshalJSON() ([]byte, error) {
Notifications []*localnotifications.Notification `json:"notifications"` Notifications []*localnotifications.Notification `json:"notifications"`
Communities []*communities.Community `json:"communities,omitempty"` Communities []*communities.Community `json:"communities,omitempty"`
CommunitiesSettings []*communities.CommunitySettings `json:"communitiesSettings,omitempty"` CommunitiesSettings []*communities.CommunitySettings `json:"communitiesSettings,omitempty"`
ProtectedTopics []ProtectedTopic `json:"protectedTopics,omitempty"`
ActivityCenterNotifications []*ActivityCenterNotification `json:"activityCenterNotifications,omitempty"` ActivityCenterNotifications []*ActivityCenterNotification `json:"activityCenterNotifications,omitempty"`
ActivityCenterState *ActivityCenterState `json:"activityCenterState,omitempty"` ActivityCenterState *ActivityCenterState `json:"activityCenterState,omitempty"`
CurrentStatus *UserStatus `json:"currentStatus,omitempty"` CurrentStatus *UserStatus `json:"currentStatus,omitempty"`
@ -152,7 +144,6 @@ func (r *MessengerResponse) MarshalJSON() ([]byte, error) {
Chats: r.Chats(), Chats: r.Chats(),
Communities: r.Communities(), Communities: r.Communities(),
CommunitiesSettings: r.CommunitiesSettings(), CommunitiesSettings: r.CommunitiesSettings(),
ProtectedTopics: r.ProtectedTopics(),
RemovedChats: r.RemovedChats(), RemovedChats: r.RemovedChats(),
RemovedMessages: r.RemovedMessages(), RemovedMessages: r.RemovedMessages(),
ClearedHistories: r.ClearedHistories(), ClearedHistories: r.ClearedHistories(),
@ -220,14 +211,6 @@ func (r *MessengerResponse) CommunitiesSettings() []*communities.CommunitySettin
return settings return settings
} }
func (r *MessengerResponse) ProtectedTopics() []ProtectedTopic {
protectedTopics := make([]ProtectedTopic, 0, len(r.protectedTopics))
for _, pt := range r.protectedTopics {
protectedTopics = append(protectedTopics, *pt)
}
return protectedTopics
}
func (r *MessengerResponse) Notifications() []*localnotifications.Notification { func (r *MessengerResponse) Notifications() []*localnotifications.Notification {
var notifications []*localnotifications.Notification var notifications []*localnotifications.Notification
for _, n := range r.notifications { for _, n := range r.notifications {
@ -372,14 +355,6 @@ func (r *MessengerResponse) AddRequestsToJoinCommunity(requestsToJoin []*communi
r.RequestsToJoinCommunity = append(r.RequestsToJoinCommunity, requestsToJoin...) r.RequestsToJoinCommunity = append(r.RequestsToJoinCommunity, requestsToJoin...)
} }
func (r *MessengerResponse) AddProtectedTopic(pt *ProtectedTopic) {
if r.protectedTopics == nil {
r.protectedTopics = make(map[string]*ProtectedTopic)
}
r.protectedTopics[pt.CommunityID] = pt
}
func (r *MessengerResponse) AddRequestToJoinCommunity(requestToJoin *communities.RequestToJoin) { func (r *MessengerResponse) AddRequestToJoinCommunity(requestToJoin *communities.RequestToJoin) {
r.RequestsToJoinCommunity = append(r.RequestsToJoinCommunity, requestToJoin) r.RequestsToJoinCommunity = append(r.RequestsToJoinCommunity, requestToJoin)
} }

View File

@ -104,6 +104,9 @@ type ChannelGroup struct {
UnviewedMessagesCount int `json:"unviewedMessagesCount"` UnviewedMessagesCount int `json:"unviewedMessagesCount"`
UnviewedMentionsCount int `json:"unviewedMentionsCount"` UnviewedMentionsCount int `json:"unviewedMentionsCount"`
CheckChannelPermissionResponses map[string]*communities.CheckChannelPermissionsResponse `json:"checkChannelPermissionResponses"` CheckChannelPermissionResponses map[string]*communities.CheckChannelPermissionsResponse `json:"checkChannelPermissionResponses"`
PubsubTopic string `json:"pubsubTopic"`
PubsubTopicKey string `json:"pubsubTopicKey"`
Shard *common.Shard `json:"shard"`
} }
func NewAPI(service *Service) *API { func NewAPI(service *Service) *API {
@ -234,6 +237,9 @@ func (api *API) getChannelGroups(ctx context.Context, channelGroupID string) (ma
UnviewedMessagesCount: totalUnviewedMessageCount, UnviewedMessagesCount: totalUnviewedMessageCount,
UnviewedMentionsCount: totalUnviewedMentionsCount, UnviewedMentionsCount: totalUnviewedMentionsCount,
CheckChannelPermissionResponses: make(map[string]*communities.CheckChannelPermissionsResponse), CheckChannelPermissionResponses: make(map[string]*communities.CheckChannelPermissionsResponse),
PubsubTopic: community.PubsubTopic(),
PubsubTopicKey: community.PubsubTopicKey(),
Shard: community.Shard(),
} }
for t, i := range community.Images() { for t, i := range community.Images() {