chore: don't expose `RevealedAccount`s on community description

Prior to this commit a control node would add the revealed addresses to
the member struct on the community description, which exposes all those
addresses to the public.

We don't want that. Revealed addresses are exclusively shared with
control nodes and should stay there (although, they might be privately
shared among token masters, see
https://github.com/status-im/status-desktop/issues/11610).

In this commit, we no longer add the revealed addresses to the community
description. The addresses are already stored in the requestToJoin
database table so we can take them from there if we need them.

Closes: https://github.com/status-im/status-desktop/issues/11573
This commit is contained in:
Pascal Precht 2023-08-04 11:49:11 +02:00 committed by r4bbit
parent e30cba4303
commit 688fb333a0
4 changed files with 67 additions and 49 deletions

View File

@ -628,7 +628,7 @@ func (m *Manager) ReevaluateMembers(community *Community) error {
hasMemberPermissions := len(becomeMemberPermissions) > 0 hasMemberPermissions := len(becomeMemberPermissions) > 0
for memberKey, member := range community.Members() { for memberKey := range community.Members() {
memberPubKey, err := common.HexToPubkey(memberKey) memberPubKey, err := common.HexToPubkey(memberKey)
if err != nil { if err != nil {
return err return err
@ -640,7 +640,13 @@ func (m *Manager) ReevaluateMembers(community *Community) error {
isTokenMaster := community.IsMemberTokenMaster(memberPubKey) isTokenMaster := community.IsMemberTokenMaster(memberPubKey)
isAdmin := community.IsMemberAdmin(memberPubKey) isAdmin := community.IsMemberAdmin(memberPubKey)
memberHasWallet := len(member.RevealedAccounts) > 0 requestID := CalculateRequestID(memberKey, community.ID())
revealedAccounts, err := m.persistence.GetRequestToJoinRevealedAddresses(requestID)
if err != nil {
return err
}
memberHasWallet := len(revealedAccounts) > 0
// Check if user has privilege role without sharing the account to controlNode // Check if user has privilege role without sharing the account to controlNode
// or user treated as a member without wallet in closed community // or user treated as a member without wallet in closed community
@ -652,7 +658,7 @@ func (m *Manager) ReevaluateMembers(community *Community) error {
continue continue
} }
accountsAndChainIDs := revealedAccountsToAccountsAndChainIDsCombination(member.RevealedAccounts) accountsAndChainIDs := revealedAccountsToAccountsAndChainIDsCombination(revealedAccounts)
isTokenMaster, err = m.ReevaluatePrivelegedMember(community, becomeTokenMasterPermissions, accountsAndChainIDs, memberPubKey, isTokenMaster, err = m.ReevaluatePrivelegedMember(community, becomeTokenMasterPermissions, accountsAndChainIDs, memberPubKey,
protobuf.CommunityMember_ROLE_TOKEN_MASTER, isTokenMaster) protobuf.CommunityMember_ROLE_TOKEN_MASTER, isTokenMaster)
@ -1727,7 +1733,7 @@ func (m *Manager) AcceptRequestToJoin(request *requests.AcceptRequestToJoinCommu
memberRoles = []protobuf.CommunityMember_Roles{role} memberRoles = []protobuf.CommunityMember_Roles{role}
} }
_, err = community.AddMemberWithRevealedAccounts(dbRequest, memberRoles, revealedAccounts) _, err = community.AddMember(pk, memberRoles)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -2012,7 +2018,18 @@ func (m *Manager) HandleCommunityEditSharedAddresses(signer *ecdsa.PublicKey, re
} }
} }
_, err = community.AddMemberRevealedAccounts(common.PubkeyToHex(signer), request.RevealedAccounts, request.Clock) requestToJoin := &RequestToJoin{
PublicKey: common.PubkeyToHex(signer),
CommunityID: community.ID(),
RevealedAccounts: request.RevealedAccounts,
}
requestToJoin.CalculateID()
err = m.persistence.RemoveRequestToJoinRevealedAddresses(requestToJoin.ID)
if err != nil {
return err
}
err = m.persistence.SaveRequestToJoinRevealedAddresses(requestToJoin)
if err != nil { if err != nil {
return err return err
} }
@ -4237,6 +4254,11 @@ func (m *Manager) fixupChannelMembers() error {
return nil return nil
} }
func (m *Manager) GetRevealedAddresses(communityID types.HexBytes, memberPk string) ([]*protobuf.RevealedAccount, error) {
requestID := CalculateRequestID(memberPk, communityID)
return m.persistence.GetRequestToJoinRevealedAddresses(requestID)
}
func (m *Manager) ReevaluatePrivelegedMember(community *Community, tokenPermissions []*protobuf.CommunityTokenPermission, func (m *Manager) ReevaluatePrivelegedMember(community *Community, tokenPermissions []*protobuf.CommunityTokenPermission,
accountsAndChainIDs []*AccountChainIDsCombination, memberPubKey *ecdsa.PublicKey, accountsAndChainIDs []*AccountChainIDsCombination, memberPubKey *ecdsa.PublicKey,
privilegedRole protobuf.CommunityMember_Roles, alreadyHasPrivilegedRole bool) (bool, error) { privilegedRole protobuf.CommunityMember_Roles, alreadyHasPrivilegedRole bool) (bool, error) {

View File

@ -576,6 +576,11 @@ func (p *Persistence) GetPermissionTokenCriteriaResult(permissionID string, comm
return &PermissionTokenCriteriaResult{Criteria: criteria}, nil return &PermissionTokenCriteriaResult{Criteria: criteria}, nil
} }
func (p *Persistence) RemoveRequestToJoinRevealedAddresses(requestID []byte) error {
_, err := p.db.Exec(`DELETE FROM communities_requests_to_join_revealed_addresses WHERE request_id = ?`, requestID)
return err
}
func (p *Persistence) GetRequestToJoinRevealedAddresses(requestID []byte) ([]*protobuf.RevealedAccount, error) { func (p *Persistence) GetRequestToJoinRevealedAddresses(requestID []byte) ([]*protobuf.RevealedAccount, error) {
revealedAccounts := make([]*protobuf.RevealedAccount, 0) revealedAccounts := make([]*protobuf.RevealedAccount, 0)
rows, err := p.db.Query(`SELECT address, chain_ids, is_airdrop_address FROM communities_requests_to_join_revealed_addresses WHERE request_id = ?`, requestID) rows, err := p.db.Query(`SELECT address, chain_ids, is_airdrop_address FROM communities_requests_to_join_revealed_addresses WHERE request_id = ?`, requestID)

View File

@ -412,19 +412,21 @@ func (s *MessengerCommunitiesTokenPermissionsSuite) TestJoinedCommunityMembersSh
s.Require().Equal(3, community.MembersCount()) s.Require().Equal(3, community.MembersCount())
for pubKey, member := range community.Members() { for pubKey := range community.Members() {
if pubKey != common.PubkeyToHex(&s.owner.identity.PublicKey) { if pubKey != common.PubkeyToHex(&s.owner.identity.PublicKey) {
revealedAccounts, err := s.owner.communitiesManager.GetRevealedAddresses(community.ID(), pubKey)
s.Require().NoError(err)
switch pubKey { switch pubKey {
case common.PubkeyToHex(&s.alice.identity.PublicKey): case common.PubkeyToHex(&s.alice.identity.PublicKey):
s.Require().Len(member.RevealedAccounts, 2) s.Require().Len(revealedAccounts, 2)
s.Require().Equal(member.RevealedAccounts[0].Address, aliceAddress1) s.Require().Equal(revealedAccounts[0].Address, aliceAddress1)
s.Require().Equal(member.RevealedAccounts[1].Address, aliceAddress2) s.Require().Equal(revealedAccounts[1].Address, aliceAddress2)
s.Require().Equal(true, member.RevealedAccounts[0].IsAirdropAddress) s.Require().Equal(true, revealedAccounts[0].IsAirdropAddress)
case common.PubkeyToHex(&s.bob.identity.PublicKey): case common.PubkeyToHex(&s.bob.identity.PublicKey):
s.Require().Len(member.RevealedAccounts, 1) s.Require().Len(revealedAccounts, 1)
s.Require().Equal(member.RevealedAccounts[0].Address, bobAddress) s.Require().Equal(revealedAccounts[0].Address, bobAddress)
s.Require().Equal(true, member.RevealedAccounts[0].IsAirdropAddress) s.Require().Equal(true, revealedAccounts[0].IsAirdropAddress)
default: default:
s.Require().Fail("pubKey does not match expected keys") s.Require().Fail("pubKey does not match expected keys")
} }
@ -443,14 +445,16 @@ func (s *MessengerCommunitiesTokenPermissionsSuite) TestJoinedCommunityMembersSe
s.Require().Equal(2, community.MembersCount()) s.Require().Equal(2, community.MembersCount())
for pubKey, member := range community.Members() { for pubKey := range community.Members() {
if pubKey != common.PubkeyToHex(&s.owner.identity.PublicKey) { if pubKey != common.PubkeyToHex(&s.owner.identity.PublicKey) {
s.Require().Len(member.RevealedAccounts, 1) revealedAccounts, err := s.owner.communitiesManager.GetRevealedAddresses(community.ID(), pubKey)
s.Require().NoError(err)
s.Require().Len(revealedAccounts, 1)
switch pubKey { switch pubKey {
case common.PubkeyToHex(&s.alice.identity.PublicKey): case common.PubkeyToHex(&s.alice.identity.PublicKey):
s.Require().Equal(member.RevealedAccounts[0].Address, aliceAddress2) s.Require().Equal(revealedAccounts[0].Address, aliceAddress2)
s.Require().Equal(true, member.RevealedAccounts[0].IsAirdropAddress) s.Require().Equal(true, revealedAccounts[0].IsAirdropAddress)
default: default:
s.Require().Fail("pubKey does not match expected keys") s.Require().Fail("pubKey does not match expected keys")
} }
@ -469,15 +473,17 @@ func (s *MessengerCommunitiesTokenPermissionsSuite) TestJoinedCommunityMembersMu
s.Require().Equal(2, community.MembersCount()) s.Require().Equal(2, community.MembersCount())
for pubKey, member := range community.Members() { for pubKey := range community.Members() {
if pubKey != common.PubkeyToHex(&s.owner.identity.PublicKey) { if pubKey != common.PubkeyToHex(&s.owner.identity.PublicKey) {
s.Require().Len(member.RevealedAccounts, 2) revealedAccounts, err := s.owner.communitiesManager.GetRevealedAddresses(community.ID(), pubKey)
s.Require().NoError(err)
s.Require().Len(revealedAccounts, 2)
switch pubKey { switch pubKey {
case common.PubkeyToHex(&s.alice.identity.PublicKey): case common.PubkeyToHex(&s.alice.identity.PublicKey):
s.Require().Equal(member.RevealedAccounts[0].Address, aliceAddress1) s.Require().Equal(revealedAccounts[0].Address, aliceAddress1)
s.Require().Equal(member.RevealedAccounts[1].Address, aliceAddress2) s.Require().Equal(revealedAccounts[1].Address, aliceAddress2)
s.Require().Equal(true, member.RevealedAccounts[1].IsAirdropAddress) s.Require().Equal(true, revealedAccounts[1].IsAirdropAddress)
default: default:
s.Require().Fail("pubKey does not match expected keys") s.Require().Fail("pubKey does not match expected keys")
} }
@ -485,19 +491,11 @@ func (s *MessengerCommunitiesTokenPermissionsSuite) TestJoinedCommunityMembersMu
} }
} }
func (s *MessengerCommunitiesTokenPermissionsSuite) validateAliceAddress(community *communities.Community, wantedAddress string) error { func (s *MessengerCommunitiesTokenPermissionsSuite) validateAddress(accounts []*protobuf.RevealedAccount, wantedAddress string) error {
for pubKey, member := range community.Members() {
if pubKey != common.PubkeyToHex(&s.owner.identity.PublicKey) {
s.Require().Len(member.RevealedAccounts, 1)
switch pubKey { for _, account := range accounts {
case common.PubkeyToHex(&s.alice.identity.PublicKey): if account.Address != wantedAddress {
if member.RevealedAccounts[0].Address != wantedAddress { return errors.New("revealed address does not match the wanted address. Wanted " + wantedAddress + ", Found: " + account.Address)
return errors.New("Alice's address does not match the wanted address. Wanted " + wantedAddress + ", Found: " + member.RevealedAccounts[0].Address)
}
default:
return errors.New("pubKey does not match expected keys")
}
} }
} }
return nil return nil
@ -511,10 +509,12 @@ func (s *MessengerCommunitiesTokenPermissionsSuite) TestEditSharedAddresses() {
community, err := s.owner.GetCommunityByID(community.ID()) community, err := s.owner.GetCommunityByID(community.ID())
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(2, community.MembersCount()) s.Require().Equal(2, community.MembersCount())
err = s.validateAliceAddress(community, aliceAddress2) revealedAccounts, err := s.owner.communitiesManager.GetRevealedAddresses(community.ID(), common.PubkeyToHex(&s.alice.identity.PublicKey))
s.Require().NoError(err)
err = s.validateAddress(revealedAccounts, aliceAddress2)
s.Require().NoError(err) s.Require().NoError(err)
passwdHash := types.EncodeHex(crypto.Keccak256([]byte(alicePassword))) passwdHash := types.EncodeHex(crypto.Keccak256([]byte(alicePassword)))
@ -532,16 +532,13 @@ func (s *MessengerCommunitiesTokenPermissionsSuite) TestEditSharedAddresses() {
if len(response.Communities()) == 0 { if len(response.Communities()) == 0 {
return errors.New("no communities in response (address change reception)") return errors.New("no communities in response (address change reception)")
} }
community := response.Communities()[0] return nil
return s.validateAliceAddress(community, aliceAddress1)
}) })
s.Require().NoError(err) s.Require().NoError(err)
revealedAccounts, err = s.owner.communitiesManager.GetRevealedAddresses(community.ID(), common.PubkeyToHex(&s.alice.identity.PublicKey))
// Also check that the owner has the new address in their DB
community, err = s.owner.GetCommunityByID(community.ID())
s.Require().NoError(err) s.Require().NoError(err)
err = s.validateAliceAddress(community, aliceAddress1) err = s.validateAddress(revealedAccounts, aliceAddress1)
s.Require().NoError(err) s.Require().NoError(err)
// Retrieve community description change // Retrieve community description change
@ -556,13 +553,6 @@ func (s *MessengerCommunitiesTokenPermissionsSuite) TestEditSharedAddresses() {
return nil return nil
}) })
s.Require().NoError(err) s.Require().NoError(err)
// Check that Alice's community is updated with the new addresses
community, err = s.alice.GetCommunityByID(community.ID())
s.Require().NoError(err)
err = s.validateAliceAddress(community, aliceAddress1)
s.Require().NoError(err)
} }
func (s *MessengerCommunitiesTokenPermissionsSuite) TestBecomeMemberPermissions() { func (s *MessengerCommunitiesTokenPermissionsSuite) TestBecomeMemberPermissions() {

View File

@ -23,6 +23,7 @@ message CommunityMember {
ROLE_TOKEN_MASTER = 5; ROLE_TOKEN_MASTER = 5;
} }
repeated Roles roles = 1; repeated Roles roles = 1;
// deprecated, do not put accounts here
repeated RevealedAccount revealed_accounts = 2; repeated RevealedAccount revealed_accounts = 2;
uint64 last_update_clock = 3; uint64 last_update_clock = 3;
} }