feat(communities): enable selecting addresses to pass when joining (#3656)
Improve `RequestToJoinCommunity` to accept `Addresses` in the request. If `Addresses` is not empty, we then only pass to the owner the selected addresses. The others are ignored. Does not validate that the addresses in the slice are part of the user's wallet. Those not part of the wallet are just ignored.
This commit is contained in:
parent
3e7d1a5f34
commit
9c596343be
|
@ -48,7 +48,8 @@ const alicePassword = "qwerty"
|
|||
const bobPassword = "bob123"
|
||||
|
||||
const adminAddress = "0x0100000000000000000000000000000000000000"
|
||||
const aliceAddress = "0x0200000000000000000000000000000000000000"
|
||||
const aliceAddress1 = "0x0200000000000000000000000000000000000000"
|
||||
const aliceAddress2 = "0x0210000000000000000000000000000000000000"
|
||||
const bobAddress = "0x0300000000000000000000000000000000000000"
|
||||
|
||||
type AccountManagerMock struct {
|
||||
|
@ -110,9 +111,9 @@ func (s *MessengerCommunitiesSuite) SetupTest() {
|
|||
s.shh = gethbridge.NewGethWakuWrapper(shh)
|
||||
s.Require().NoError(shh.Start())
|
||||
|
||||
s.admin = s.newMessengerWithWallet(adminPassword, adminAddress)
|
||||
s.bob = s.newMessengerWithWallet(bobPassword, bobAddress)
|
||||
s.alice = s.newMessengerWithWallet(alicePassword, aliceAddress)
|
||||
s.admin = s.newMessengerWithWallet(adminPassword, []string{adminAddress})
|
||||
s.bob = s.newMessengerWithWallet(bobPassword, []string{bobAddress})
|
||||
s.alice = s.newMessengerWithWallet(alicePassword, []string{aliceAddress1, aliceAddress2})
|
||||
_, err := s.admin.Start()
|
||||
s.Require().NoError(err)
|
||||
_, err = s.bob.Start()
|
||||
|
@ -204,29 +205,35 @@ func (s *MessengerCommunitiesSuite) newMessenger(accountsManager account.Manager
|
|||
return s.newMessengerWithKey(s.shh, privateKey, accountsManager)
|
||||
}
|
||||
|
||||
func (s *MessengerCommunitiesSuite) newMessengerWithWallet(password string, walletAddress string) *Messenger {
|
||||
func (s *MessengerCommunitiesSuite) newMessengerWithWallet(password string, walletAddresses []string) *Messenger {
|
||||
accountsManager := &AccountManagerMock{}
|
||||
accountsManager.AccountsMap = make(map[string]string)
|
||||
accountsManager.AccountsMap[walletAddress] = types.EncodeHex(crypto.Keccak256([]byte(password)))
|
||||
for _, walletAddress := range walletAddresses {
|
||||
accountsManager.AccountsMap[walletAddress] = types.EncodeHex(crypto.Keccak256([]byte(password)))
|
||||
}
|
||||
|
||||
messenger := s.newMessenger(accountsManager)
|
||||
|
||||
// add wallet account with keypair
|
||||
kp := accounts.GetProfileKeypairForTest(false, true, false)
|
||||
kp.Accounts[0].Address = types.HexToAddress(walletAddress)
|
||||
err := messenger.settings.SaveOrUpdateKeypair(kp)
|
||||
s.Require().NoError(err)
|
||||
for _, walletAddress := range walletAddresses {
|
||||
kp := accounts.GetProfileKeypairForTest(false, true, false)
|
||||
kp.Accounts[0].Address = types.HexToAddress(walletAddress)
|
||||
err := messenger.settings.SaveOrUpdateKeypair(kp)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
walletAccounts, err := messenger.settings.GetAccounts()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(walletAccounts, 1)
|
||||
s.Require().Equal(walletAccounts[0].Type, accounts.AccountTypeGenerated)
|
||||
s.Require().Len(walletAccounts, len(walletAddresses))
|
||||
for i := range walletAddresses {
|
||||
s.Require().Equal(walletAccounts[i].Type, accounts.AccountTypeGenerated)
|
||||
}
|
||||
return messenger
|
||||
}
|
||||
|
||||
func (s *MessengerCommunitiesSuite) requestToJoinCommunity(user *Messenger, communityID types.HexBytes, password string) (*MessengerResponse, error) {
|
||||
func (s *MessengerCommunitiesSuite) requestToJoinCommunity(user *Messenger, communityID types.HexBytes, password string, addresses []string) (*MessengerResponse, error) {
|
||||
passwdHash := types.EncodeHex(crypto.Keccak256([]byte(password)))
|
||||
request := &requests.RequestToJoinCommunity{CommunityID: communityID, Password: passwdHash}
|
||||
request := &requests.RequestToJoinCommunity{CommunityID: communityID, Password: passwdHash, AddressesToReveal: addresses}
|
||||
return user.RequestToJoinCommunity(request)
|
||||
}
|
||||
|
||||
|
@ -262,7 +269,7 @@ func (s *MessengerCommunitiesSuite) TestCreateCommunity_WithoutDefaultChannel()
|
|||
}
|
||||
|
||||
func (s *MessengerCommunitiesSuite) TestRetrieveCommunity() {
|
||||
alice := s.newMessengerWithWallet(alicePassword, aliceAddress)
|
||||
alice := s.newMessengerWithWallet(alicePassword, []string{aliceAddress1})
|
||||
|
||||
description := &requests.CreateCommunity{
|
||||
Membership: protobuf.CommunityPermissions_NO_MEMBERSHIP,
|
||||
|
@ -577,9 +584,9 @@ func (s *MessengerCommunitiesSuite) advertiseCommunityTo(community *communities.
|
|||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *MessengerCommunitiesSuite) joinCommunity(community *communities.Community, user *Messenger, password string) {
|
||||
func (s *MessengerCommunitiesSuite) joinCommunityWithAddresses(community *communities.Community, user *Messenger, password string, addresses []string) {
|
||||
// Request to join the community
|
||||
response, err := s.requestToJoinCommunity(user, community.ID(), password)
|
||||
response, err := s.requestToJoinCommunity(user, community.ID(), password, addresses)
|
||||
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(response)
|
||||
|
@ -625,6 +632,10 @@ func (s *MessengerCommunitiesSuite) joinCommunity(community *communities.Communi
|
|||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *MessengerCommunitiesSuite) joinCommunity(community *communities.Community, user *Messenger, password string) {
|
||||
s.joinCommunityWithAddresses(community, user, password, []string{})
|
||||
}
|
||||
|
||||
func (s *MessengerCommunitiesSuite) TestCommunityContactCodeAdvertisement() {
|
||||
// add bob's profile keypair
|
||||
bobProfileKp := accounts.GetProfileKeypairForTest(true, false, false)
|
||||
|
@ -3709,12 +3720,14 @@ func (s *MessengerCommunitiesSuite) TestJoinedCommunityMembersSharedAddress() {
|
|||
|
||||
for pubKey, member := range community.Members() {
|
||||
if pubKey != common.PubkeyToHex(&s.admin.identity.PublicKey) {
|
||||
s.Require().Len(member.RevealedAccounts, 1)
|
||||
|
||||
switch pubKey {
|
||||
case common.PubkeyToHex(&s.alice.identity.PublicKey):
|
||||
s.Require().Equal(member.RevealedAccounts[0].Address, aliceAddress)
|
||||
s.Require().Len(member.RevealedAccounts, 2)
|
||||
s.Require().Equal(member.RevealedAccounts[0].Address, aliceAddress1)
|
||||
s.Require().Equal(member.RevealedAccounts[1].Address, aliceAddress2)
|
||||
case common.PubkeyToHex(&s.bob.identity.PublicKey):
|
||||
s.Require().Len(member.RevealedAccounts, 1)
|
||||
s.Require().Equal(member.RevealedAccounts[0].Address, bobAddress)
|
||||
default:
|
||||
s.Require().Fail("pubKey does not match expected keys")
|
||||
|
@ -3722,3 +3735,28 @@ func (s *MessengerCommunitiesSuite) TestJoinedCommunityMembersSharedAddress() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *MessengerCommunitiesSuite) TestJoinedCommunityMembersSelectedSharedAddress() {
|
||||
community := s.createCommunity()
|
||||
s.advertiseCommunityTo(community, s.alice)
|
||||
|
||||
s.joinCommunityWithAddresses(community, s.alice, alicePassword, []string{aliceAddress2})
|
||||
|
||||
community, err := s.admin.GetCommunityByID(community.ID())
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().Equal(2, community.MembersCount())
|
||||
|
||||
for pubKey, member := range community.Members() {
|
||||
if pubKey != common.PubkeyToHex(&s.admin.identity.PublicKey) {
|
||||
s.Require().Len(member.RevealedAccounts, 1)
|
||||
|
||||
switch pubKey {
|
||||
case common.PubkeyToHex(&s.alice.identity.PublicKey):
|
||||
s.Require().Equal(member.RevealedAccounts[0].Address, aliceAddress2)
|
||||
default:
|
||||
s.Require().Fail("pubKey does not match expected keys")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -704,8 +704,22 @@ func (m *Messenger) RequestToJoinCommunity(request *requests.RequestToJoinCommun
|
|||
revealedAccounts := make(map[gethcommon.Address]*protobuf.RevealedAccount)
|
||||
revealedAddresses := make([]gethcommon.Address, 0)
|
||||
|
||||
containsAddress := func(addresses []string, targetAddress string) bool {
|
||||
for _, address := range addresses {
|
||||
if address == targetAddress {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for _, walletAccount := range walletAccounts {
|
||||
if !walletAccount.Chat && walletAccount.Type != accounts.AccountTypeWatch {
|
||||
|
||||
if len(request.AddressesToReveal) > 0 && !containsAddress(request.AddressesToReveal, walletAccount.Address.Hex()) {
|
||||
continue
|
||||
}
|
||||
|
||||
verifiedAccount, err := m.accountsManager.GetVerifiedWalletAccount(m.settings, walletAccount.Address.Hex(), request.Password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -7,17 +7,22 @@ import (
|
|||
)
|
||||
|
||||
var ErrRequestToJoinCommunityInvalidCommunityID = errors.New("request-to-join-community: invalid community id")
|
||||
var ErrRequestToJoinCommunityMissingPassword = errors.New("request-to-join-community: password is necessary when sending a list of addresses")
|
||||
|
||||
type RequestToJoinCommunity struct {
|
||||
CommunityID types.HexBytes `json:"communityId"`
|
||||
ENSName string `json:"ensName"`
|
||||
Password string `json:"password"`
|
||||
CommunityID types.HexBytes `json:"communityId"`
|
||||
ENSName string `json:"ensName"`
|
||||
Password string `json:"password"`
|
||||
AddressesToReveal []string `json:"addressesToReveal"`
|
||||
}
|
||||
|
||||
func (j *RequestToJoinCommunity) Validate() error {
|
||||
if len(j.CommunityID) == 0 {
|
||||
return ErrRequestToJoinCommunityInvalidCommunityID
|
||||
}
|
||||
if len(j.AddressesToReveal) > 0 && j.Password == "" {
|
||||
return ErrRequestToJoinCommunityMissingPassword
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue