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:
Mykhailo Prakhov 2023-12-19 14:45:34 +01:00 committed by GitHub
parent 0818c98fca
commit a5f6a6c2f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 265 additions and 2 deletions

View File

@ -2422,6 +2422,14 @@ func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, receiver
if err != nil {
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
}
}
}
}

View File

@ -274,3 +274,11 @@ func (s *TokenMasterCommunityEventsSuite) TestReceiveRequestsToJoinWithRevealedA
bob := s.newMessenger(accountPassword, []string{bobAccountAddress})
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)
}

View File

@ -2224,3 +2224,236 @@ func waitAndCheckRequestsToJoin(s *suite.Suite, user *Messenger, expectedLength
)
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)
}

View File

@ -433,3 +433,11 @@ func (s *AdminCommunityEventsSuite) TestAdminDoesNotHaveRejectedEventsLoop() {
}, "no communities in response")
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)
}

View File

@ -351,10 +351,13 @@ func (m *Messenger) handleCommunitiesSubscription(c chan *communities.Subscripti
accept := &requests.AcceptRequestToJoinCommunity{
ID: requestID,
}
_, err := m.AcceptRequestToJoinCommunity(accept)
response, err := m.AcceptRequestToJoinCommunity(accept)
if err != nil {
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{
ID: requestID,
}
_, err := m.DeclineRequestToJoinCommunity(reject)
response, err := m.DeclineRequestToJoinCommunity(reject)
if err != nil {
m.logger.Warn("failed to decline request to join ", zap.Error(err))
}
if m.config.messengerSignalsHandler != nil {
m.config.messengerSignalsHandler.MessengerResponse(response)
}
}
}