fix: tokenMaster does not have members revealed addresses (#4425)
This commit is contained in:
parent
e0bbb7e2ec
commit
fe604b2806
|
@ -4,6 +4,7 @@ import (
|
|||
"crypto/ecdsa"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/protocol/common"
|
||||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
)
|
||||
|
||||
|
@ -33,22 +34,6 @@ func (m *Manager) HandleRequestToJoinPrivilegedUserSyncMessage(message *protobuf
|
|||
}
|
||||
requestToJoin.CalculateID()
|
||||
|
||||
_, err := m.saveOrUpdateRequestToJoin(communityID, requestToJoin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
requestsToJoin = append(requestsToJoin, requestToJoin)
|
||||
}
|
||||
|
||||
return requestsToJoin, nil
|
||||
}
|
||||
|
||||
func (m *Manager) HandleSyncAllRequestToJoinForNewPrivilegedMember(message *protobuf.CommunityPrivilegedUserSyncMessage, communityID types.HexBytes) ([]*RequestToJoin, error) {
|
||||
requestsToJoin := []*RequestToJoin{}
|
||||
for _, syncRequestToJoin := range message.SyncRequestsToJoin {
|
||||
requestToJoin := new(RequestToJoin)
|
||||
requestToJoin.InitFromSyncProtobuf(syncRequestToJoin)
|
||||
|
||||
if _, err := m.saveOrUpdateRequestToJoin(communityID, requestToJoin); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -62,7 +47,41 @@ func (m *Manager) HandleSyncAllRequestToJoinForNewPrivilegedMember(message *prot
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
requestsToJoin = append(requestsToJoin, requestToJoin)
|
||||
}
|
||||
|
||||
return requestsToJoin, nil
|
||||
}
|
||||
|
||||
func (m *Manager) HandleSyncAllRequestToJoinForNewPrivilegedMember(message *protobuf.CommunityPrivilegedUserSyncMessage, communityID types.HexBytes) ([]*RequestToJoin, error) {
|
||||
nonAcceptedRequestsToJoin := []*RequestToJoin{}
|
||||
|
||||
myPk := common.PubkeyToHex(&m.identity.PublicKey)
|
||||
|
||||
// We received all requests to join from the control node. Remove all requests to join except our own
|
||||
err := m.persistence.RemoveAllCommunityRequestsToJoinWithRevealedAddressesExceptPublicKey(myPk, communityID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, syncRequestToJoin := range message.SyncRequestsToJoin {
|
||||
requestToJoin := new(RequestToJoin)
|
||||
requestToJoin.InitFromSyncProtobuf(syncRequestToJoin)
|
||||
|
||||
if _, err := m.saveOrUpdateRequestToJoin(communityID, requestToJoin); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if requestToJoin.RevealedAccounts != nil && len(requestToJoin.RevealedAccounts) > 0 {
|
||||
if err := m.persistence.SaveRequestToJoinRevealedAddresses(requestToJoin.ID, requestToJoin.RevealedAccounts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if requestToJoin.State != RequestToJoinStateAccepted {
|
||||
nonAcceptedRequestsToJoin = append(nonAcceptedRequestsToJoin, requestToJoin)
|
||||
}
|
||||
}
|
||||
return nonAcceptedRequestsToJoin, nil
|
||||
}
|
||||
|
|
|
@ -1580,24 +1580,20 @@ func (m *Manager) HandleCommunityDescriptionMessage(signer *ecdsa.PublicKey, des
|
|||
}
|
||||
}
|
||||
|
||||
if hasTokenOwnership {
|
||||
if hasTokenOwnership && verifiedOwner != nil {
|
||||
// Override verified owner
|
||||
if verifiedOwner != nil {
|
||||
m.logger.Info("updating verified owner", zap.String("communityID", community.IDString()), zap.String("owner", common.PubkeyToHex(verifiedOwner)))
|
||||
m.logger.Info("updating verified owner", zap.String("communityID", community.IDString()), zap.String("owner", common.PubkeyToHex(verifiedOwner)))
|
||||
|
||||
// If we are not the verified owner anymore, drop the private key
|
||||
if !common.IsPubKeyEqual(verifiedOwner, &m.identity.PublicKey) {
|
||||
community.config.PrivateKey = nil
|
||||
}
|
||||
// If we are not the verified owner anymore, drop the private key
|
||||
if !common.IsPubKeyEqual(verifiedOwner, &m.identity.PublicKey) {
|
||||
community.config.PrivateKey = nil
|
||||
}
|
||||
|
||||
// new control node will be set in the 'UpdateCommunityDescription'
|
||||
if !common.IsPubKeyEqual(verifiedOwner, signer) {
|
||||
return nil, ErrNotAuthorized
|
||||
}
|
||||
} else if !common.IsPubKeyEqual(community.ControlNode(), signer) {
|
||||
// new control node will be set in the 'UpdateCommunityDescription'
|
||||
if !common.IsPubKeyEqual(verifiedOwner, signer) {
|
||||
return nil, ErrNotAuthorized
|
||||
}
|
||||
} else if !common.IsPubKeyEqual(community.PublicKey(), signer) {
|
||||
} else if !common.IsPubKeyEqual(community.ControlNode(), signer) {
|
||||
return nil, ErrNotAuthorized
|
||||
}
|
||||
|
||||
|
@ -2227,6 +2223,7 @@ func (m *Manager) AcceptRequestToJoin(dbRequest *RequestToJoin) (*Community, err
|
|||
return nil, err
|
||||
}
|
||||
|
||||
dbRequest.RevealedAccounts = revealedAccounts
|
||||
if err = m.shareAcceptedRequestToJoinWithPrivilegedMembers(community, dbRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -4925,7 +4922,7 @@ func (m *Manager) shareRequestsToJoinWithNewPrivilegedMembers(community *Communi
|
|||
case protobuf.CommunityMember_ROLE_ADMIN:
|
||||
subscriptionMsg.CommunityPrivilegedUserSyncMessage = syncMsgWithoutRevealedAccounts
|
||||
case protobuf.CommunityMember_ROLE_OWNER:
|
||||
fallthrough
|
||||
continue
|
||||
case protobuf.CommunityMember_ROLE_TOKEN_MASTER:
|
||||
subscriptionMsg.CommunityPrivilegedUserSyncMessage = syncMsgWitRevealedAccounts
|
||||
}
|
||||
|
|
|
@ -1669,3 +1669,12 @@ func (p *Persistence) AllNonApprovedCommunitiesRequestsToJoin() ([]*RequestToJoi
|
|||
}
|
||||
return nonApprovedRequestsToJoin, nil
|
||||
}
|
||||
|
||||
func (p *Persistence) RemoveAllCommunityRequestsToJoinWithRevealedAddressesExceptPublicKey(pk string, communityID []byte) error {
|
||||
_, err := p.db.Exec(`
|
||||
DELETE FROM communities_requests_to_join_revealed_addresses
|
||||
WHERE request_id IN (SELECT id FROM communities_requests_to_join WHERE community_id = ? AND public_key != ?);
|
||||
DELETE FROM communities_requests_to_join
|
||||
WHERE community_id = ? AND public_key != ?;`, communityID, pk, communityID, pk)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -757,3 +757,108 @@ func (s *PersistenceSuite) TestAllNonApprovedCommunitiesRequestsToJoin() {
|
|||
s.Require().NoError(err)
|
||||
s.Require().Len(result, 6) // all except RequestToJoinStateAccepted
|
||||
}
|
||||
|
||||
func (s *PersistenceSuite) TestRemoveAllCommunityRequestsToJoinWithRevealedAddressesExceptPublicKey() {
|
||||
myIdentity, err := crypto.GenerateKey()
|
||||
s.Require().NoError(err, "crypto.GenerateKey shouldn't give any error")
|
||||
|
||||
myPk := common.PubkeyToHex(&myIdentity.PublicKey)
|
||||
|
||||
clock := uint64(time.Now().Unix())
|
||||
|
||||
// add a new community
|
||||
community := s.makeNewCommunity(myIdentity)
|
||||
err = s.db.SaveCommunity(community)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// check on empty db
|
||||
err = s.db.RemoveAllCommunityRequestsToJoinWithRevealedAddressesExceptPublicKey(myPk, community.ID())
|
||||
s.Require().NoError(err)
|
||||
|
||||
// add requests to join to the community
|
||||
allStates := []RequestToJoinState{
|
||||
RequestToJoinStatePending,
|
||||
RequestToJoinStateDeclined,
|
||||
RequestToJoinStateAccepted,
|
||||
RequestToJoinStateCanceled,
|
||||
RequestToJoinStateAcceptedPending,
|
||||
RequestToJoinStateDeclinedPending,
|
||||
RequestToJoinStateAwaitingAddresses,
|
||||
}
|
||||
|
||||
allRequestsToJoinIDs := [][]byte{}
|
||||
|
||||
for i := range allStates {
|
||||
identity, err := crypto.GenerateKey()
|
||||
s.Require().NoError(err)
|
||||
|
||||
revealedAccounts := []*protobuf.RevealedAccount{}
|
||||
for j := 0; j < i; j++ {
|
||||
acc := &protobuf.RevealedAccount{
|
||||
Address: "testAddr",
|
||||
ChainIds: []uint64{123},
|
||||
IsAirdropAddress: true,
|
||||
Signature: []byte{},
|
||||
}
|
||||
revealedAccounts = append(revealedAccounts, acc)
|
||||
}
|
||||
|
||||
rtj := &RequestToJoin{
|
||||
ID: types.HexBytes{1, 2, 3, 4, 5, 6, 7, byte(i)},
|
||||
PublicKey: common.PubkeyToHex(&identity.PublicKey),
|
||||
Clock: clock,
|
||||
CommunityID: community.ID(),
|
||||
State: allStates[i],
|
||||
RevealedAccounts: revealedAccounts,
|
||||
}
|
||||
|
||||
allRequestsToJoinIDs = append(allRequestsToJoinIDs, rtj.ID)
|
||||
|
||||
err = s.db.SaveRequestToJoin(rtj)
|
||||
s.Require().NoError(err, "SaveRequestToJoin shouldn't give any error")
|
||||
err = s.db.SaveRequestToJoinRevealedAddresses(rtj.ID, rtj.RevealedAccounts)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
err = s.db.RemoveAllCommunityRequestsToJoinWithRevealedAddressesExceptPublicKey(myPk, community.ID())
|
||||
s.Require().NoError(err)
|
||||
|
||||
requests, err := s.db.GetCommunityRequestsToJoinWithRevealedAddresses(community.ID())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(requests, 0)
|
||||
|
||||
for _, rtjID := range allRequestsToJoinIDs {
|
||||
accounts, err := s.db.GetRequestToJoinRevealedAddresses(rtjID)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(accounts, 0)
|
||||
}
|
||||
|
||||
myRtj := &RequestToJoin{
|
||||
ID: types.HexBytes{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PublicKey: myPk,
|
||||
Clock: clock,
|
||||
CommunityID: community.ID(),
|
||||
State: RequestToJoinStateAccepted,
|
||||
RevealedAccounts: []*protobuf.RevealedAccount{
|
||||
{
|
||||
Address: "testAddr",
|
||||
ChainIds: []uint64{123},
|
||||
IsAirdropAddress: true,
|
||||
Signature: []byte{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err = s.db.SaveRequestToJoin(myRtj)
|
||||
s.Require().NoError(err, "SaveRequestToJoin shouldn't give any error")
|
||||
err = s.db.SaveRequestToJoinRevealedAddresses(myRtj.ID, myRtj.RevealedAccounts)
|
||||
s.Require().NoError(err)
|
||||
|
||||
err = s.db.RemoveAllCommunityRequestsToJoinWithRevealedAddressesExceptPublicKey(myPk, community.ID())
|
||||
s.Require().NoError(err)
|
||||
|
||||
requests, err = s.db.GetCommunityRequestsToJoinWithRevealedAddresses(community.ID())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(requests, 1)
|
||||
s.Require().Len(requests[0].RevealedAccounts, 1)
|
||||
}
|
||||
|
|
|
@ -1459,7 +1459,7 @@ func testControlNodeHandlesMultipleEventSenderRequestToJoinDecisions(base Commun
|
|||
// control node receives event sender 1's and 2's decision
|
||||
_, err = WaitOnMessengerResponse(
|
||||
base.GetControlNode(),
|
||||
func(r *MessengerResponse) bool { return len(r.Communities()) > 0 },
|
||||
func(r *MessengerResponse) bool { return len(r.RequestsToJoinCommunity) > 0 },
|
||||
"control node did not receive event senders decision",
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
@ -2032,15 +2032,6 @@ func testJoinedPrivilegedMemberReceiveRequestsToJoin(base CommunityEventsTestsIn
|
|||
advertiseCommunityTo(s, community, base.GetControlNode(), bob)
|
||||
advertiseCommunityTo(s, community, base.GetControlNode(), newPrivilegedUser)
|
||||
|
||||
requestMember := &requests.RequestToJoinCommunity{
|
||||
CommunityID: community.ID(),
|
||||
AddressesToReveal: []string{bobAccountAddress},
|
||||
ENSName: "bob",
|
||||
AirdropAddress: bobAccountAddress,
|
||||
}
|
||||
|
||||
requestToJoinCommunity(s, base.GetControlNode(), bob, requestMember)
|
||||
|
||||
requestNewPrivilegedUser := &requests.RequestToJoinCommunity{
|
||||
CommunityID: community.ID(),
|
||||
AddressesToReveal: []string{eventsSenderAccountAddress},
|
||||
|
@ -2060,38 +2051,39 @@ func testJoinedPrivilegedMemberReceiveRequestsToJoin(base CommunityEventsTestsIn
|
|||
s.Require().NotNil(updatedCommunity)
|
||||
s.Require().True(updatedCommunity.HasMember(&newPrivilegedUser.identity.PublicKey))
|
||||
|
||||
// privileged user should receive request to join from user and its shared addresses from control node
|
||||
_, err = WaitOnMessengerResponse(
|
||||
newPrivilegedUser,
|
||||
base.GetEventSender(),
|
||||
func(r *MessengerResponse) bool {
|
||||
requestsToJoin, err := newPrivilegedUser.communitiesManager.GetCommunityRequestsToJoinWithRevealedAddresses(community.ID())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if len(requestsToJoin) != 4 {
|
||||
s.T().Log("invalid requests to join count:", len(requestsToJoin))
|
||||
return false
|
||||
}
|
||||
|
||||
for _, request := range requestsToJoin {
|
||||
if tokenPermissionType == protobuf.CommunityTokenPermission_BECOME_TOKEN_MASTER {
|
||||
if len(request.RevealedAccounts) != 1 {
|
||||
s.T().Log("no accounts revealed")
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if len(request.RevealedAccounts) != 0 {
|
||||
s.T().Log("unexpected accounts revealed")
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
return len(r.Communities()) > 0 &&
|
||||
len(r.Communities()[0].TokenPermissionsByType(tokenPermissionType)) > 0 &&
|
||||
r.Communities()[0].HasPermissionToSendCommunityEvents()
|
||||
},
|
||||
"newPrivilegedUser did not receive all requests to join from the control node",
|
||||
"newPrivilegedUser did not receive privileged role",
|
||||
)
|
||||
|
||||
s.Require().NoError(err)
|
||||
|
||||
expectedLength := 3
|
||||
// newPrivilegedUser user should receive all requests to join with shared addresses from the control node
|
||||
waitAndCheckRequestsToJoin(s, newPrivilegedUser, expectedLength, community.ID(), tokenPermissionType == protobuf.CommunityTokenPermission_BECOME_TOKEN_MASTER)
|
||||
|
||||
// bob joins the community
|
||||
requestMember := &requests.RequestToJoinCommunity{
|
||||
CommunityID: community.ID(),
|
||||
AddressesToReveal: []string{bobAccountAddress},
|
||||
ENSName: "bob",
|
||||
AirdropAddress: bobAccountAddress,
|
||||
}
|
||||
|
||||
bobRequestToJoinID := requestToJoinCommunity(s, base.GetControlNode(), bob, requestMember)
|
||||
|
||||
// accept join request
|
||||
acceptRequestToJoin = &requests.AcceptRequestToJoinCommunity{ID: bobRequestToJoinID}
|
||||
_, err = base.GetControlNode().AcceptRequestToJoinCommunity(acceptRequestToJoin)
|
||||
s.Require().NoError(err)
|
||||
|
||||
expectedLength = 4
|
||||
waitAndCheckRequestsToJoin(s, newPrivilegedUser, expectedLength, community.ID(), tokenPermissionType == protobuf.CommunityTokenPermission_BECOME_TOKEN_MASTER)
|
||||
}
|
||||
|
||||
func testMemberReceiveRequestsToJoinAfterGettingNewRole(base CommunityEventsTestsInterface, bob *Messenger, tokenPermissionType protobuf.CommunityTokenPermission_Type) {
|
||||
|
@ -2102,7 +2094,6 @@ func testMemberReceiveRequestsToJoinAfterGettingNewRole(base CommunityEventsTest
|
|||
|
||||
// control node creates a community and chat
|
||||
community := createTestCommunity(base, protobuf.CommunityPermissions_MANUAL_ACCEPT)
|
||||
refreshMessengerResponses(base)
|
||||
|
||||
advertiseCommunityTo(s, community, base.GetControlNode(), base.GetEventSender())
|
||||
advertiseCommunityTo(s, community, base.GetControlNode(), base.GetMember())
|
||||
|
@ -2152,27 +2143,56 @@ func testMemberReceiveRequestsToJoinAfterGettingNewRole(base CommunityEventsTest
|
|||
s.Require().NoError(err)
|
||||
assertCheckTokenPermissionCreated(s, ownerCommunity, rolePermission.Type)
|
||||
|
||||
// receive request to join msg
|
||||
_, err = WaitOnMessengerResponse(
|
||||
base.GetEventSender(),
|
||||
func(r *MessengerResponse) bool {
|
||||
return len(r.RequestsToJoinCommunity) > 2
|
||||
return len(r.Communities()) > 0 &&
|
||||
len(r.Communities()[0].TokenPermissionsByType(tokenPermissionType)) > 0 &&
|
||||
r.Communities()[0].HasPermissionToSendCommunityEvents()
|
||||
},
|
||||
"Event sender did not receive all requests to join from the control node",
|
||||
"event sender did not receive privileged role",
|
||||
)
|
||||
|
||||
s.Require().NoError(err)
|
||||
|
||||
expectedLength := 3
|
||||
waitAndCheckRequestsToJoin(s, base.GetEventSender(), expectedLength, community.ID(), tokenPermissionType == protobuf.CommunityTokenPermission_BECOME_TOKEN_MASTER)
|
||||
}
|
||||
|
||||
func waitAndCheckRequestsToJoin(s *suite.Suite, user *Messenger, expectedLength int, communityID types.HexBytes, checkRevealedAddresses bool) {
|
||||
_, err := WaitOnMessengerResponse(
|
||||
user,
|
||||
func(r *MessengerResponse) bool {
|
||||
requestsToJoin, err := user.communitiesManager.GetCommunityRequestsToJoinWithRevealedAddresses(communityID)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if len(requestsToJoin) != expectedLength {
|
||||
s.T().Log("invalid requests to join count:", len(requestsToJoin))
|
||||
return false
|
||||
}
|
||||
|
||||
for _, request := range requestsToJoin {
|
||||
if request.PublicKey == common.PubkeyToHex(&user.identity.PublicKey) {
|
||||
if len(request.RevealedAccounts) != 1 {
|
||||
s.T().Log("our own requests to join must always have accounts revealed")
|
||||
return false
|
||||
}
|
||||
} else if checkRevealedAddresses {
|
||||
if len(request.RevealedAccounts) != 1 {
|
||||
s.T().Log("no accounts revealed")
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if len(request.RevealedAccounts) != 0 {
|
||||
s.T().Log("unexpected accounts revealed")
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
"user did not receive all requests to join from the control node",
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
requestsToJoin, err := base.GetEventSender().communitiesManager.GetCommunityRequestsToJoinWithRevealedAddresses(community.ID())
|
||||
s.Require().NoError(err)
|
||||
// event sender, bob and alice requests
|
||||
s.Require().Len(requestsToJoin, 3)
|
||||
|
||||
// check if revealed addresses are present based on the role
|
||||
for _, request := range requestsToJoin {
|
||||
if tokenPermissionType == protobuf.CommunityTokenPermission_BECOME_TOKEN_MASTER {
|
||||
s.Require().Len(request.RevealedAccounts, 1)
|
||||
} else {
|
||||
s.Require().Len(request.RevealedAccounts, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3026,18 +3026,18 @@ func (m *Messenger) handleCommunityPrivilegedUserSyncMessage(state *ReceivedMess
|
|||
return err
|
||||
}
|
||||
|
||||
if community == nil {
|
||||
return communities.ErrOrgNotFound
|
||||
}
|
||||
|
||||
// Currently this type of msg coming from the control node.
|
||||
// If it will change in the future, check that events types starting from
|
||||
// CONTROL_NODE were sent by a control node
|
||||
isControlNodeMsg := common.IsPubKeyEqual(community.PublicKey(), signer)
|
||||
isControlNodeMsg := common.IsPubKeyEqual(community.ControlNode(), signer)
|
||||
if !isControlNodeMsg {
|
||||
return errors.New("accepted/requested to join sync messages can be send only by the control node")
|
||||
}
|
||||
|
||||
if community == nil {
|
||||
return errors.New("community not found")
|
||||
}
|
||||
|
||||
err = m.communitiesManager.ValidateCommunityPrivilegedUserSyncMessage(message)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -3054,11 +3054,11 @@ func (m *Messenger) handleCommunityPrivilegedUserSyncMessage(state *ReceivedMess
|
|||
state.Response.AddRequestsToJoinCommunity(requestsToJoin)
|
||||
|
||||
case protobuf.CommunityPrivilegedUserSyncMessage_CONTROL_NODE_ALL_SYNC_REQUESTS_TO_JOIN:
|
||||
requestsToJoin, err := m.communitiesManager.HandleSyncAllRequestToJoinForNewPrivilegedMember(message, community.ID())
|
||||
nonAcceptedRequestsToJoin, err := m.communitiesManager.HandleSyncAllRequestToJoinForNewPrivilegedMember(message, community.ID())
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
state.Response.AddRequestsToJoinCommunity(requestsToJoin)
|
||||
state.Response.AddRequestsToJoinCommunity(nonAcceptedRequestsToJoin)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
Loading…
Reference in New Issue