Skip to content

Commit

Permalink
refactor: EventSenders forward RequestToJoin decision to control node
Browse files Browse the repository at this point in the history
This is a bigger change in how community membership requests are handled
among admins, token masters, owners, and control nodes.

Prior to this commit, all privileged users, also known as
`EventSenders`, were able to accept and reject community membership
requests and those changes would be applied by all users.

This commit changes this behaviour such that:

1. EventSenders can make a decision (accept, reject), but merely forward
   their decision to the control node, which ultimately has to confirm
   it
2. EventSenders are no longer removing or adding members to and from
   communities
3. When an eventsender signaled a decision, the membership request will
   enter a pending state (acceptedPending or rejectedPending)
4. Once a decision was made by one eventsender, no other eventsender can
   override that decision

This implementation is covered with a bunch of tests:

- Ensure that decision made by event sender is shared with other event
  senders
  - `testAcceptMemberRequestToJoinResponseSharedWithOtherEventSenders()`
  - `testRejectMemberRequestToJoinResponseSharedWithOtherEventSenders()`
- Ensure memebrship request stays pending, until control node has
  confirmed decision by event senders
  - `testAcceptMemberRequestToJoinNotConfirmedByControlNode()`
  - `testRejectMemberRequestToJoinNotConfirmedByControlNode()`
- Ensure that decision made by event sender cannot be overriden by other
  event senders
  - `testEventSenderCannotOverrideRequestToJoinState()`

These test cases live in three test suites for different event sender
types respectively

- `OwnerWithoutCommunityKeyCommunityEventsSuite`
- `TokenMasterCommunityEventsSuite`
- `AdminCommunityEventsSuite`

In addition to the changes mentioned above, there's also a smaller
changes that ensures membership requests to *not* attached revealed wallet
addresses when the requests are sent to event senders (in addition to
control nodes).

Requests send to a control node will still include revealed addresses as
the control node needs them to verify token permissions.

This commit does not yet handle the case of event senders attempting to
kick and ban members.

Similar to accepting and rejecting membership requests, kicking and
banning need a new pending state. However, we don't track such state in
local databases yet so those two cases will be handled in future commit
to not have this commit grow larger.
  • Loading branch information
0x-r4bbit committed Aug 2, 2023
1 parent 0cd140c commit 5bc0083
Show file tree
Hide file tree
Showing 13 changed files with 798 additions and 158 deletions.
2 changes: 2 additions & 0 deletions protocol/activity_center.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const (
ActivityCenterMembershipStatusPending
ActivityCenterMembershipStatusAccepted
ActivityCenterMembershipStatusDeclined
ActivityCenterMembershipStatusAcceptedPending
ActivityCenterMembershipStatusDeclinedPending
)

type ActivityCenterQueryParamsRead uint
Expand Down
24 changes: 3 additions & 21 deletions protocol/communities/community.go
Original file line number Diff line number Diff line change
Expand Up @@ -824,9 +824,8 @@ func (o *Community) RemoveUserFromOrg(pk *ecdsa.PublicKey) (*protobuf.CommunityD
}
}

o.removeMemberFromOrg(pk)

if isControlNode {
o.removeMemberFromOrg(pk)
o.increaseClock()
}

Expand Down Expand Up @@ -1995,31 +1994,14 @@ func (o *Community) AddMemberWithRevealedAccounts(dbRequest *RequestToJoin, role
defer o.mutex.Unlock()

isControlNode := o.IsControlNode()
allowedToSendEvents := o.HasPermissionToSendCommunityEvents()

if !isControlNode && !allowedToSendEvents {
if !isControlNode {
return nil, ErrNotAdmin
}

changes := o.addMemberWithRevealedAccounts(dbRequest.PublicKey, roles, accounts, dbRequest.Clock)

if allowedToSendEvents {
acceptedRequestsToJoin := make(map[string]*protobuf.CommunityRequestToJoin)
acceptedRequestsToJoin[dbRequest.PublicKey] = dbRequest.ToCommunityRequestToJoinProtobuf()

adminChanges := &CommunityEventChanges{
CommunityChanges: changes,
AcceptedRequestsToJoin: acceptedRequestsToJoin,
}
err := o.addNewCommunityEvent(o.ToCommunityRequestToJoinAcceptCommunityEvent(adminChanges))
if err != nil {
return nil, err
}
}

if isControlNode {
o.increaseClock()
}
o.increaseClock()

return changes, nil
}
Expand Down
21 changes: 0 additions & 21 deletions protocol/communities/community_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ func (o *Community) ToCommunityRequestToJoinAcceptCommunityEvent(changes *Commun
return &CommunityEvent{
CommunityEventClock: o.NewCommunityEventClock(),
Type: protobuf.CommunityEvent_COMMUNITY_REQUEST_TO_JOIN_ACCEPT,
MembersAdded: changes.MembersAdded,
AcceptedRequestsToJoin: changes.AcceptedRequestsToJoin,
}
}
Expand Down Expand Up @@ -315,26 +314,6 @@ func (o *Community) updateCommunityDescriptionByCommunityEvent(communityEvent Co
return err
}

case protobuf.CommunityEvent_COMMUNITY_REQUEST_TO_JOIN_ACCEPT:
for pkString, addedMember := range communityEvent.MembersAdded {
pk, err := common.HexToPubkey(pkString)
if err != nil {
return err
}
if !o.HasMember(pk) {
o.addCommunityMember(pk, addedMember)
}
}

case protobuf.CommunityEvent_COMMUNITY_REQUEST_TO_JOIN_REJECT:
for pkString := range communityEvent.RejectedRequestsToJoin {
pk, err := common.HexToPubkey(pkString)
if err != nil {
return err
}
o.removeMemberFromOrg(pk)
}

case protobuf.CommunityEvent_COMMUNITY_MEMBER_KICK:
pk, err := common.HexToPubkey(communityEvent.MemberToAction)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion protocol/communities/community_event_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func validateCommunityEvent(communityEvent *CommunityEvent) error {
}

case protobuf.CommunityEvent_COMMUNITY_REQUEST_TO_JOIN_ACCEPT:
if len(communityEvent.MembersAdded) == 0 {
if len(communityEvent.AcceptedRequestsToJoin) == 0 {
return errors.New("invalid community request to join accepted event")
}

Expand Down
Loading

0 comments on commit 5bc0083

Please sign in to comment.