fix: remove redundancy in permissions check when handling request to join
- Fixed redundant permissions check. If community is set to auto-accept, then permissions would be checked twice, in `HandleCommunityRequestToJoin` and `AcceptRequestToJoinCommunity`. Mitigated it by returning from `HandleCommunityRequestToJoin` immediately in case of auto-accept. - Extracted `accountsSatisfyPermissionsToJoin` to remove code duplication and simplify the logic.
This commit is contained in:
parent
631962ce88
commit
f1db6d1615
|
@ -1506,6 +1506,27 @@ func (m *Manager) CheckPermissionToJoin(id []byte, addresses []gethcommon.Addres
|
|||
return m.checkPermissionToJoin(permissionsToJoin, accountsAndChainIDs, false)
|
||||
}
|
||||
|
||||
func (m *Manager) accountsSatisfyPermissionsToJoin(community *Community, accounts []*protobuf.RevealedAccount) (satisfy bool, isAdmin bool, err error) {
|
||||
accountsAndChainIDs := revealedAccountsToAccountsAndChainIDsCombination(accounts)
|
||||
becomeAdminPermissions := community.TokenPermissionsByType(protobuf.CommunityTokenPermission_BECOME_ADMIN)
|
||||
becomeMemberPermissions := community.TokenPermissionsByType(protobuf.CommunityTokenPermission_BECOME_MEMBER)
|
||||
|
||||
if len(becomeAdminPermissions) > 0 && m.accountsHasAdminPermission(becomeAdminPermissions, accountsAndChainIDs) {
|
||||
return true, true, nil
|
||||
}
|
||||
|
||||
if len(becomeMemberPermissions) > 0 {
|
||||
permissionResponse, err := m.checkPermissionToJoin(becomeMemberPermissions, accountsAndChainIDs, true)
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
}
|
||||
|
||||
return permissionResponse.Satisfied, false, nil
|
||||
}
|
||||
|
||||
return true, false, nil
|
||||
}
|
||||
|
||||
func (m *Manager) AcceptRequestToJoin(request *requests.AcceptRequestToJoinCommunity) (*Community, error) {
|
||||
dbRequest, err := m.persistence.GetRequestToJoin(request.ID)
|
||||
if err != nil {
|
||||
|
@ -1517,38 +1538,23 @@ func (m *Manager) AcceptRequestToJoin(request *requests.AcceptRequestToJoinCommu
|
|||
return nil, err
|
||||
}
|
||||
|
||||
becomeAdminPermissions := community.TokenPermissionsByType(protobuf.CommunityTokenPermission_BECOME_ADMIN)
|
||||
becomeMemberPermissions := community.TokenPermissionsByType(protobuf.CommunityTokenPermission_BECOME_MEMBER)
|
||||
|
||||
revealedAccounts, err := m.persistence.GetRequestToJoinRevealedAddresses(dbRequest.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
memberRole := protobuf.CommunityMember_ROLE_NONE
|
||||
permissionsSatisfied, isAdmin, err := m.accountsSatisfyPermissionsToJoin(community, revealedAccounts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(becomeMemberPermissions) > 0 || len(becomeAdminPermissions) > 0 {
|
||||
if !permissionsSatisfied {
|
||||
return community, ErrNoPermissionToJoin
|
||||
}
|
||||
|
||||
accountsAndChainIDs := revealedAccountsToAccountsAndChainIDsCombination(revealedAccounts)
|
||||
|
||||
// admin token permissions required to became an admin must not cancel request to join
|
||||
// if requirements were not met
|
||||
hasPermission := m.accountsHasAdminPermission(becomeAdminPermissions, accountsAndChainIDs)
|
||||
|
||||
if hasPermission {
|
||||
memberRole = protobuf.CommunityMember_ROLE_ADMIN
|
||||
} else if len(becomeMemberPermissions) > 0 {
|
||||
permissionResponse, err := m.checkPermissionToJoin(becomeMemberPermissions, accountsAndChainIDs, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hasPermission := permissionResponse.Satisfied
|
||||
|
||||
if !hasPermission {
|
||||
return community, ErrNoPermissionToJoin
|
||||
}
|
||||
}
|
||||
memberRoles := []protobuf.CommunityMember_Roles{}
|
||||
if isAdmin {
|
||||
memberRoles = []protobuf.CommunityMember_Roles{protobuf.CommunityMember_ROLE_ADMIN}
|
||||
}
|
||||
|
||||
pk, err := common.HexToPubkey(dbRequest.PublicKey)
|
||||
|
@ -1556,19 +1562,7 @@ func (m *Manager) AcceptRequestToJoin(request *requests.AcceptRequestToJoinCommu
|
|||
return nil, err
|
||||
}
|
||||
|
||||
role := []protobuf.CommunityMember_Roles{}
|
||||
if memberRole != protobuf.CommunityMember_ROLE_NONE {
|
||||
role = []protobuf.CommunityMember_Roles{memberRole}
|
||||
}
|
||||
|
||||
// _, err = community.AddMember(pk, role)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// _, err = community.AddMemberRevealedAccounts(dbRequest.PublicKey, revealedAccounts, dbRequest.Clock)
|
||||
// TODOM: resolve
|
||||
_, err = community.AddMemberWithRevealedAccounts(dbRequest, role, revealedAccounts)
|
||||
_, err = community.AddMemberWithRevealedAccounts(dbRequest, memberRoles, revealedAccounts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1725,10 +1719,6 @@ func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, request
|
|||
if !matching {
|
||||
// if ownership of only one wallet address cannot be verified,
|
||||
// we mark the request as cancelled and stop
|
||||
err = m.markRequestToJoinAsCanceled(signer, community)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
requestToJoin.State = RequestToJoinStateDeclined
|
||||
return requestToJoin, nil
|
||||
}
|
||||
|
@ -1742,68 +1732,27 @@ func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, request
|
|||
}
|
||||
}
|
||||
|
||||
becomeAdminPermissions := community.TokenPermissionsByType(protobuf.CommunityTokenPermission_BECOME_ADMIN)
|
||||
becomeMemberPermissions := community.TokenPermissionsByType(protobuf.CommunityTokenPermission_BECOME_MEMBER)
|
||||
|
||||
// If user is already a member, then accept request automatically
|
||||
// It may happen when member removes itself from community and then tries to rejoin
|
||||
// More specifically, CommunityRequestToLeave may be delivered later than CommunityRequestToJoin, or not delivered at all
|
||||
acceptAutomatically := community.AcceptRequestToJoinAutomatically() || community.HasMember(signer)
|
||||
hasPermission := false
|
||||
|
||||
// if we have admin or member permission and user revealed the address - process verification
|
||||
// if user does not reveal the address and we have member permission only - we decline this request
|
||||
// if user does not reveal the address and we have admin permission only - user allowed to join as a member
|
||||
// in non private community
|
||||
if (len(becomeMemberPermissions) > 0 || len(becomeAdminPermissions) > 0) && len(request.RevealedAccounts) > 0 {
|
||||
accountsAndChainIDs := revealedAccountsToAccountsAndChainIDsCombination(request.RevealedAccounts)
|
||||
|
||||
// admin token permissions required to become an admin must not cancel request to join
|
||||
// if requirements were not met
|
||||
hasPermission = m.accountsHasAdminPermission(becomeAdminPermissions, accountsAndChainIDs)
|
||||
|
||||
// if user does not have admin permissions, check on member permissions
|
||||
if !hasPermission && len(becomeMemberPermissions) > 0 {
|
||||
permissionResponse, err := m.checkPermissionToJoin(becomeMemberPermissions, accountsAndChainIDs, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hasPermission = permissionResponse.Satisfied
|
||||
|
||||
if !hasPermission {
|
||||
err = m.markRequestToJoinAsCanceled(signer, community)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
requestToJoin.State = RequestToJoinStateDeclined
|
||||
return requestToJoin, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Save revealed addresses + signatures so they can later be added
|
||||
// to the community member list when the request is accepted
|
||||
err = m.persistence.SaveRequestToJoinRevealedAddresses(requestToJoin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if len(becomeMemberPermissions) > 0 && len(request.RevealedAccounts) == 0 {
|
||||
// we have member token permissions but requester hasn't revealed
|
||||
// any addresses
|
||||
err = m.markRequestToJoinAsCanceled(signer, community)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
requestToJoin.State = RequestToJoinStateDeclined
|
||||
return requestToJoin, nil
|
||||
}
|
||||
|
||||
if (len(becomeMemberPermissions) == 0 || hasPermission) && acceptAutomatically {
|
||||
if acceptAutomatically {
|
||||
err = m.markRequestToJoin(signer, community)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Don't check permissions here,
|
||||
// it will be done further in the processing pipeline.
|
||||
requestToJoin.State = RequestToJoinStateAccepted
|
||||
return requestToJoin, nil
|
||||
}
|
||||
|
||||
permissionsSatisfied, _, err := m.accountsSatisfyPermissionsToJoin(community, request.RevealedAccounts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !permissionsSatisfied {
|
||||
requestToJoin.State = RequestToJoinStateDeclined
|
||||
}
|
||||
|
||||
return requestToJoin, nil
|
||||
|
|
|
@ -1414,7 +1414,11 @@ func (m *Messenger) HandleCommunityRequestToJoin(state *ReceivedMessageState, si
|
|||
}
|
||||
_, err = m.AcceptRequestToJoinCommunity(accept)
|
||||
if err != nil {
|
||||
return err
|
||||
if err == communities.ErrNoPermissionToJoin {
|
||||
requestToJoin.State = communities.RequestToJoinStateDeclined
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue