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.
This commit is contained in:
Patryk Osmaczko 2024-03-09 22:36:40 +01:00 committed by osmaczko
parent 2995518939
commit 1de61d1933
2 changed files with 36 additions and 32 deletions

View File

@ -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 {

View File

@ -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) {