fix: privileged member accepted/rejected request to join action is not approved by the control node after the member leaved and tries to join the community again (#4487)
This commit is contained in:
parent
0818c98fca
commit
a5f6a6c2f6
|
@ -2422,6 +2422,14 @@ func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, receiver
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
case RequestToJoinStateAccepted:
|
||||||
|
// if member leaved the community and tries to request to join again
|
||||||
|
if !community.HasMember(signer) {
|
||||||
|
err = m.SaveRequestToJoin(requestToJoin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -274,3 +274,11 @@ func (s *TokenMasterCommunityEventsSuite) TestReceiveRequestsToJoinWithRevealedA
|
||||||
bob := s.newMessenger(accountPassword, []string{bobAccountAddress})
|
bob := s.newMessenger(accountPassword, []string{bobAccountAddress})
|
||||||
testMemberReceiveRequestsToJoinAfterGettingNewRole(s, bob, protobuf.CommunityTokenPermission_BECOME_TOKEN_MASTER)
|
testMemberReceiveRequestsToJoinAfterGettingNewRole(s, bob, protobuf.CommunityTokenPermission_BECOME_TOKEN_MASTER)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *TokenMasterCommunityEventsSuite) TestTokenMasterAcceptsRequestToJoinAfterMemberLeave() {
|
||||||
|
community := setUpOnRequestCommunityAndRoles(s, protobuf.CommunityMember_ROLE_TOKEN_MASTER, []*Messenger{})
|
||||||
|
|
||||||
|
// set up additional user that will send request to join
|
||||||
|
user := s.newMessenger("", []string{})
|
||||||
|
testPrivilegedMemberAcceptsRequestToJoinAfterMemberLeave(s, community, user)
|
||||||
|
}
|
||||||
|
|
|
@ -2224,3 +2224,236 @@ func waitAndCheckRequestsToJoin(s *suite.Suite, user *Messenger, expectedLength
|
||||||
)
|
)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testPrivilegedMemberAcceptsRequestToJoinAfterMemberLeave(base CommunityEventsTestsInterface, community *communities.Community, user *Messenger) {
|
||||||
|
// set up additional user that will send request to join
|
||||||
|
_, err := user.Start()
|
||||||
|
|
||||||
|
s := base.GetSuite()
|
||||||
|
|
||||||
|
s.Require().NoError(err)
|
||||||
|
defer TearDownMessenger(s, user)
|
||||||
|
|
||||||
|
advertiseCommunityToUserOldWay(s, community, base.GetControlNode(), user)
|
||||||
|
|
||||||
|
// user sends request to join
|
||||||
|
requestToJoin := &requests.RequestToJoinCommunity{CommunityID: community.ID(), ENSName: "testName"}
|
||||||
|
response, err := user.RequestToJoinCommunity(requestToJoin)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NotNil(response)
|
||||||
|
s.Require().Len(response.RequestsToJoinCommunity, 1)
|
||||||
|
|
||||||
|
sentRequest := response.RequestsToJoinCommunity[0]
|
||||||
|
|
||||||
|
checkRequestToJoin := func(r *MessengerResponse) bool {
|
||||||
|
if len(r.RequestsToJoinCommunity) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, request := range r.RequestsToJoinCommunity {
|
||||||
|
if request.ENSName == requestToJoin.ENSName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// event sender receives request to join
|
||||||
|
response, err = WaitOnMessengerResponse(
|
||||||
|
base.GetEventSender(),
|
||||||
|
checkRequestToJoin,
|
||||||
|
"event sender did not receive community request to join",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(response.RequestsToJoinCommunity, 1)
|
||||||
|
|
||||||
|
// control node receives request to join
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
base.GetControlNode(),
|
||||||
|
checkRequestToJoin,
|
||||||
|
"event sender did not receive community request to join",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
acceptRequestToJoin := &requests.AcceptRequestToJoinCommunity{ID: sentRequest.ID}
|
||||||
|
response, err = base.GetEventSender().AcceptRequestToJoinCommunity(acceptRequestToJoin)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NotNil(response)
|
||||||
|
s.Require().Len(response.Communities(), 1)
|
||||||
|
// we don't expect `user` to be a member already, because `eventSender` merely
|
||||||
|
// forwards its accept decision to the control node
|
||||||
|
s.Require().False(response.Communities()[0].HasMember(&user.identity.PublicKey))
|
||||||
|
|
||||||
|
// at this point, the request to join is marked as accepted by GetEventSender node
|
||||||
|
acceptedRequestsPending, err := base.GetEventSender().AcceptedPendingRequestsToJoinForCommunity(community.ID())
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(acceptedRequestsPending, 1)
|
||||||
|
s.Require().Equal(acceptedRequestsPending[0].PublicKey, common.PubkeyToHex(&user.identity.PublicKey))
|
||||||
|
|
||||||
|
// control node receives community event with accepted membership request
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
base.GetControlNode(),
|
||||||
|
func(r *MessengerResponse) bool {
|
||||||
|
return len(r.Communities()) > 0 && r.Communities()[0].HasMember(&user.identity.PublicKey)
|
||||||
|
},
|
||||||
|
"control node did not receive community request to join response",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// at this point, the request to join is marked as accepted by control node
|
||||||
|
acceptedRequests, err := base.GetControlNode().AcceptedRequestsToJoinForCommunity(community.ID())
|
||||||
|
s.Require().NoError(err)
|
||||||
|
// we expect 3 here (1 event senders, 1 member + 1 from user)
|
||||||
|
s.Require().Len(acceptedRequests, 3)
|
||||||
|
s.Require().Equal(acceptedRequests[2].PublicKey, common.PubkeyToHex(&user.identity.PublicKey))
|
||||||
|
|
||||||
|
// user receives updated community
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
user,
|
||||||
|
func(r *MessengerResponse) bool {
|
||||||
|
return len(r.Communities()) > 0 && r.Communities()[0].HasMember(&user.identity.PublicKey)
|
||||||
|
},
|
||||||
|
"alice did not receive community request to join response",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// event sender receives updated community
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
base.GetEventSender(),
|
||||||
|
func(r *MessengerResponse) bool {
|
||||||
|
return len(r.Communities()) > 0 && r.Communities()[0].HasMember(&user.identity.PublicKey)
|
||||||
|
},
|
||||||
|
"event sender did not receive community with the new member",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// check control node notify event sender about accepting request to join
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
base.GetEventSender(),
|
||||||
|
func(r *MessengerResponse) bool {
|
||||||
|
acceptedRequests, err := base.GetEventSender().AcceptedRequestsToJoinForCommunity(community.ID())
|
||||||
|
return err == nil && len(acceptedRequests) == 2 && (acceptedRequests[1].PublicKey == common.PubkeyToHex(&user.identity.PublicKey))
|
||||||
|
},
|
||||||
|
"no updates from control node",
|
||||||
|
)
|
||||||
|
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
acceptedRequestsPending, err = base.GetEventSender().AcceptedPendingRequestsToJoinForCommunity(community.ID())
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(acceptedRequestsPending, 0)
|
||||||
|
|
||||||
|
// user leaves the community
|
||||||
|
response, err = user.LeaveCommunity(community.ID())
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(response.Communities(), 1)
|
||||||
|
s.Require().False(response.Communities()[0].Joined())
|
||||||
|
|
||||||
|
checkMemberLeave := func(r *MessengerResponse) bool {
|
||||||
|
return len(r.Communities()) > 0 && !r.Communities()[0].HasMember(&user.identity.PublicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check control node received member leave msg
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
base.GetControlNode(),
|
||||||
|
checkMemberLeave,
|
||||||
|
"control node did not receive member leave msg",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// check event sender received member leave update from ControlNode
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
base.GetControlNode(),
|
||||||
|
checkMemberLeave,
|
||||||
|
"event sender did not receive member leave update",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// user tries to rejoin again
|
||||||
|
response, err = user.RequestToJoinCommunity(requestToJoin)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NotNil(response)
|
||||||
|
s.Require().Len(response.RequestsToJoinCommunity, 1)
|
||||||
|
|
||||||
|
// event sender receives request to join
|
||||||
|
response, err = WaitOnMessengerResponse(
|
||||||
|
base.GetEventSender(),
|
||||||
|
checkRequestToJoin,
|
||||||
|
"event sender did not receive community request to join",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(response.RequestsToJoinCommunity, 1)
|
||||||
|
|
||||||
|
// control node receives request to join
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
base.GetControlNode(),
|
||||||
|
checkRequestToJoin,
|
||||||
|
"event sender did not receive community request to join",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
response, err = base.GetEventSender().AcceptRequestToJoinCommunity(acceptRequestToJoin)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NotNil(response)
|
||||||
|
s.Require().Len(response.Communities(), 1)
|
||||||
|
// we don't expect `user` to be a member already, because `eventSender` merely
|
||||||
|
// forwards its accept decision to the control node
|
||||||
|
s.Require().False(response.Communities()[0].HasMember(&user.identity.PublicKey))
|
||||||
|
|
||||||
|
// at this point, the request to join is marked as accepted pending by GetEventSender node
|
||||||
|
acceptedRequestsPending, err = base.GetEventSender().AcceptedPendingRequestsToJoinForCommunity(community.ID())
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(acceptedRequestsPending, 1)
|
||||||
|
s.Require().Equal(acceptedRequestsPending[0].PublicKey, common.PubkeyToHex(&user.identity.PublicKey))
|
||||||
|
|
||||||
|
// control node receives community event with accepted membership request
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
base.GetControlNode(),
|
||||||
|
func(r *MessengerResponse) bool {
|
||||||
|
return len(r.Communities()) > 0 && r.Communities()[0].HasMember(&user.identity.PublicKey)
|
||||||
|
},
|
||||||
|
"control node did not receive community request to join response",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// at this point, the request to join is marked as accepted by control node
|
||||||
|
acceptedRequests, err = base.GetControlNode().AcceptedRequestsToJoinForCommunity(community.ID())
|
||||||
|
s.Require().NoError(err)
|
||||||
|
// we expect 3 here (1 event senders, 1 member + 1 from user)
|
||||||
|
s.Require().Len(acceptedRequests, 3)
|
||||||
|
s.Require().Equal(acceptedRequests[2].PublicKey, common.PubkeyToHex(&user.identity.PublicKey))
|
||||||
|
|
||||||
|
// user receives updated community
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
user,
|
||||||
|
func(r *MessengerResponse) bool {
|
||||||
|
return len(r.Communities()) > 0 && r.Communities()[0].HasMember(&user.identity.PublicKey)
|
||||||
|
},
|
||||||
|
"user did not receive community request to join response",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// event sender receives updated community
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
base.GetEventSender(),
|
||||||
|
func(r *MessengerResponse) bool {
|
||||||
|
return len(r.Communities()) > 0 && r.Communities()[0].HasMember(&user.identity.PublicKey)
|
||||||
|
},
|
||||||
|
"event sender did not receive community with the new member",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// check control node notify event sender about accepting request to join
|
||||||
|
_, err = WaitOnMessengerResponse(
|
||||||
|
base.GetEventSender(),
|
||||||
|
func(r *MessengerResponse) bool {
|
||||||
|
acceptedRequests, err := base.GetEventSender().AcceptedRequestsToJoinForCommunity(community.ID())
|
||||||
|
return err == nil && len(acceptedRequests) == 2 && (acceptedRequests[1].PublicKey == common.PubkeyToHex(&user.identity.PublicKey))
|
||||||
|
},
|
||||||
|
"no updates from control node",
|
||||||
|
)
|
||||||
|
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
acceptedRequestsPending, err = base.GetEventSender().AcceptedPendingRequestsToJoinForCommunity(community.ID())
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(acceptedRequestsPending, 0)
|
||||||
|
}
|
||||||
|
|
|
@ -433,3 +433,11 @@ func (s *AdminCommunityEventsSuite) TestAdminDoesNotHaveRejectedEventsLoop() {
|
||||||
}, "no communities in response")
|
}, "no communities in response")
|
||||||
s.Require().Error(err)
|
s.Require().Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *AdminCommunityEventsSuite) TestAdminAcceptsRequestToJoinAfterMemberLeave() {
|
||||||
|
community := setUpOnRequestCommunityAndRoles(s, protobuf.CommunityMember_ROLE_ADMIN, []*Messenger{})
|
||||||
|
|
||||||
|
// set up additional user that will send request to join
|
||||||
|
user := s.newMessenger("", []string{})
|
||||||
|
testPrivilegedMemberAcceptsRequestToJoinAfterMemberLeave(s, community, user)
|
||||||
|
}
|
||||||
|
|
|
@ -351,10 +351,13 @@ func (m *Messenger) handleCommunitiesSubscription(c chan *communities.Subscripti
|
||||||
accept := &requests.AcceptRequestToJoinCommunity{
|
accept := &requests.AcceptRequestToJoinCommunity{
|
||||||
ID: requestID,
|
ID: requestID,
|
||||||
}
|
}
|
||||||
_, err := m.AcceptRequestToJoinCommunity(accept)
|
response, err := m.AcceptRequestToJoinCommunity(accept)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.logger.Warn("failed to accept request to join ", zap.Error(err))
|
m.logger.Warn("failed to accept request to join ", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
if m.config.messengerSignalsHandler != nil {
|
||||||
|
m.config.messengerSignalsHandler.MessengerResponse(response)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,10 +366,13 @@ func (m *Messenger) handleCommunitiesSubscription(c chan *communities.Subscripti
|
||||||
reject := &requests.DeclineRequestToJoinCommunity{
|
reject := &requests.DeclineRequestToJoinCommunity{
|
||||||
ID: requestID,
|
ID: requestID,
|
||||||
}
|
}
|
||||||
_, err := m.DeclineRequestToJoinCommunity(reject)
|
response, err := m.DeclineRequestToJoinCommunity(reject)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.logger.Warn("failed to decline request to join ", zap.Error(err))
|
m.logger.Warn("failed to decline request to join ", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
if m.config.messengerSignalsHandler != nil {
|
||||||
|
m.config.messengerSignalsHandler.MessengerResponse(response)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue