From 1de61d19331400ee97c04905e39e76ab95a67f8e Mon Sep 17 00:00:00 2001 From: Patryk Osmaczko Date: Sat, 9 Mar 2024 22:36:40 +0100 Subject: [PATCH] fix: channel members evaluation on request acceptance If there is only `viewAndPost` permission set on a channel, members who don't satisfy the criteria shouldn't be able to view the channel. --- .../communities/check_permissions_response.go | 16 +++--- protocol/communities/manager.go | 52 ++++++++++--------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/protocol/communities/check_permissions_response.go b/protocol/communities/check_permissions_response.go index ac7d1568d..9688f03a3 100644 --- a/protocol/communities/check_permissions_response.go +++ b/protocol/communities/check_permissions_response.go @@ -23,11 +23,13 @@ type HighestRoleResponse struct { Criteria []*PermissionTokenCriteriaResult `json:"criteria"` } -var joiningRoleOrders = map[protobuf.CommunityTokenPermission_Type]int{ - protobuf.CommunityTokenPermission_BECOME_MEMBER: 1, - protobuf.CommunityTokenPermission_BECOME_ADMIN: 2, - protobuf.CommunityTokenPermission_BECOME_TOKEN_MASTER: 3, - protobuf.CommunityTokenPermission_BECOME_TOKEN_OWNER: 4, +var roleOrders = map[protobuf.CommunityTokenPermission_Type]int{ + protobuf.CommunityTokenPermission_BECOME_MEMBER: 1, + protobuf.CommunityTokenPermission_CAN_VIEW_CHANNEL: 2, + protobuf.CommunityTokenPermission_CAN_VIEW_AND_POST_CHANNEL: 3, + protobuf.CommunityTokenPermission_BECOME_ADMIN: 4, + protobuf.CommunityTokenPermission_BECOME_TOKEN_MASTER: 5, + protobuf.CommunityTokenPermission_BECOME_TOKEN_OWNER: 6, } type ByRoleDesc []*HighestRoleResponse @@ -35,7 +37,7 @@ type ByRoleDesc []*HighestRoleResponse func (a ByRoleDesc) Len() int { return len(a) } func (a ByRoleDesc) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByRoleDesc) Less(i, j int) bool { - return joiningRoleOrders[a[i].Role] > joiningRoleOrders[a[j].Role] + return roleOrders[a[i].Role] > roleOrders[a[j].Role] } type rolesAndHighestRole struct { @@ -47,7 +49,7 @@ func calculateRolesAndHighestRole(permissions map[string]*PermissionTokenCriteri item := &rolesAndHighestRole{} byRoleMap := make(map[protobuf.CommunityTokenPermission_Type]*HighestRoleResponse) for _, p := range permissions { - if joiningRoleOrders[p.Role] == 0 { + if roleOrders[p.Role] == 0 { continue } if byRoleMap[p.Role] == nil { diff --git a/protocol/communities/manager.go b/protocol/communities/manager.go index ce0ffed6a..a644d0c86 100644 --- a/protocol/communities/manager.go +++ b/protocol/communities/manager.go @@ -2320,39 +2320,41 @@ func (m *Manager) accountsSatisfyPermissionsToJoin(community *Community, account } func (m *Manager) accountsSatisfyPermissionsToJoinChannels(community *Community, accounts []*protobuf.RevealedAccount) (map[string]*protobuf.CommunityChat, map[string]*protobuf.CommunityChat, error) { + viewChats := make(map[string]*protobuf.CommunityChat) + viewAndPostChats := make(map[string]*protobuf.CommunityChat) + accountsAndChainIDs := revealedAccountsToAccountsAndChainIDsCombination(accounts) - viewChats, err := m.accountsSatisfyPermissionTypeToJoinChannels(community, accountsAndChainIDs, protobuf.CommunityTokenPermission_CAN_VIEW_CHANNEL) - if err != nil { - return nil, nil, err - } - - postChats, err := m.accountsSatisfyPermissionTypeToJoinChannels(community, accountsAndChainIDs, protobuf.CommunityTokenPermission_CAN_VIEW_AND_POST_CHANNEL) - if err != nil { - return nil, nil, err - } - - return viewChats, postChats, nil -} - -func (m *Manager) accountsSatisfyPermissionTypeToJoinChannels(community *Community, accounts []*AccountChainIDsCombination, permissionType protobuf.CommunityTokenPermission_Type) (map[string]*protobuf.CommunityChat, error) { - result := make(map[string]*protobuf.CommunityChat) - for channelID, channel := range community.config.CommunityDescription.Chats { - permissions := community.ChannelTokenPermissionsByType(community.IDString()+channelID, permissionType) - if len(permissions) > 0 { - permissionResponse, err := m.PermissionChecker.CheckPermissions(permissions, accounts, true) - if err != nil { - return nil, err + channelViewOnlyPermissions := community.ChannelTokenPermissionsByType(community.IDString()+channelID, protobuf.CommunityTokenPermission_CAN_VIEW_CHANNEL) + channelViewAndPostPermissions := community.ChannelTokenPermissionsByType(community.IDString()+channelID, protobuf.CommunityTokenPermission_CAN_VIEW_AND_POST_CHANNEL) + channelPermissions := append(channelViewOnlyPermissions, channelViewAndPostPermissions...) + + if len(channelPermissions) == 0 { + viewAndPostChats[channelID] = channel + continue + } + + permissionResponse, err := m.PermissionChecker.CheckPermissions(channelPermissions, accountsAndChainIDs, true) + if err != nil { + return nil, nil, err + } + + if permissionResponse.Satisfied { + highestRole := calculateRolesAndHighestRole(permissionResponse.Permissions).HighestRole + if highestRole == nil { + return nil, nil, errors.New("failed to calculate highest role") } - if !permissionResponse.Satisfied { - continue + switch highestRole.Role { + case protobuf.CommunityTokenPermission_CAN_VIEW_CHANNEL: + viewChats[channelID] = channel + case protobuf.CommunityTokenPermission_CAN_VIEW_AND_POST_CHANNEL: + viewAndPostChats[channelID] = channel } } - result[channelID] = channel } - return result, nil + return viewChats, viewAndPostChats, nil } func (m *Manager) AcceptRequestToJoin(dbRequest *RequestToJoin) (*Community, error) {