github.com/status-im/status-go@v1.1.0/protocol/communities/check_permissions_response.go (about) 1 package communities 2 3 import ( 4 "encoding/json" 5 "sort" 6 7 gethcommon "github.com/ethereum/go-ethereum/common" 8 "github.com/status-im/status-go/protocol/protobuf" 9 ) 10 11 type CheckPermissionsResponse struct { 12 Satisfied bool `json:"satisfied"` 13 Permissions map[string]*PermissionTokenCriteriaResult `json:"permissions"` 14 ValidCombinations []*AccountChainIDsCombination `json:"validCombinations"` 15 NetworksNotSupported bool `json:"networksNotSupported"` 16 } 17 18 type CheckPermissionToJoinResponse = CheckPermissionsResponse 19 20 type HighestRoleResponse struct { 21 Role protobuf.CommunityTokenPermission_Type `json:"type"` 22 Satisfied bool `json:"satisfied"` 23 Criteria []*PermissionTokenCriteriaResult `json:"criteria"` 24 } 25 26 var roleOrders = map[protobuf.CommunityTokenPermission_Type]int{ 27 protobuf.CommunityTokenPermission_BECOME_MEMBER: 1, 28 protobuf.CommunityTokenPermission_CAN_VIEW_CHANNEL: 2, 29 protobuf.CommunityTokenPermission_CAN_VIEW_AND_POST_CHANNEL: 3, 30 protobuf.CommunityTokenPermission_BECOME_ADMIN: 4, 31 protobuf.CommunityTokenPermission_BECOME_TOKEN_MASTER: 5, 32 protobuf.CommunityTokenPermission_BECOME_TOKEN_OWNER: 6, 33 } 34 35 type ByRoleDesc []*HighestRoleResponse 36 37 func (a ByRoleDesc) Len() int { return len(a) } 38 func (a ByRoleDesc) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 39 func (a ByRoleDesc) Less(i, j int) bool { 40 return roleOrders[a[i].Role] > roleOrders[a[j].Role] 41 } 42 43 type rolesAndHighestRole struct { 44 Roles []*HighestRoleResponse 45 HighestRole *HighestRoleResponse 46 } 47 48 func calculateRolesAndHighestRole(permissions map[string]*PermissionTokenCriteriaResult) *rolesAndHighestRole { 49 item := &rolesAndHighestRole{} 50 byRoleMap := make(map[protobuf.CommunityTokenPermission_Type]*HighestRoleResponse) 51 for _, p := range permissions { 52 if roleOrders[p.Role] == 0 { 53 continue 54 } 55 if byRoleMap[p.Role] == nil { 56 byRoleMap[p.Role] = &HighestRoleResponse{ 57 Role: p.Role, 58 } 59 } 60 61 satisfied := true 62 for _, tr := range p.TokenRequirements { 63 if !tr.Satisfied { 64 satisfied = false 65 break 66 } 67 68 } 69 70 if satisfied { 71 byRoleMap[p.Role].Satisfied = true 72 // we prepend 73 byRoleMap[p.Role].Criteria = append([]*PermissionTokenCriteriaResult{p}, byRoleMap[p.Role].Criteria...) 74 } else { 75 // we append then 76 byRoleMap[p.Role].Criteria = append(byRoleMap[p.Role].Criteria, p) 77 } 78 } 79 if byRoleMap[protobuf.CommunityTokenPermission_BECOME_MEMBER] == nil { 80 byRoleMap[protobuf.CommunityTokenPermission_BECOME_MEMBER] = &HighestRoleResponse{Satisfied: true, Role: protobuf.CommunityTokenPermission_BECOME_MEMBER} 81 } 82 for _, p := range byRoleMap { 83 item.Roles = append(item.Roles, p) 84 } 85 86 sort.Sort(ByRoleDesc(item.Roles)) 87 for _, r := range item.Roles { 88 if r.Satisfied { 89 item.HighestRole = r 90 break 91 } 92 93 } 94 return item 95 } 96 97 func (c *CheckPermissionsResponse) MarshalJSON() ([]byte, error) { 98 type CheckPermissionsTypeAlias struct { 99 Satisfied bool `json:"satisfied"` 100 Permissions map[string]*PermissionTokenCriteriaResult `json:"permissions"` 101 ValidCombinations []*AccountChainIDsCombination `json:"validCombinations"` 102 Roles []*HighestRoleResponse `json:"roles"` 103 HighestRole *HighestRoleResponse `json:"highestRole"` 104 NetworksNotSupported bool `json:"networksNotSupported"` 105 } 106 c.calculateSatisfied() 107 item := &CheckPermissionsTypeAlias{ 108 Satisfied: c.Satisfied, 109 Permissions: c.Permissions, 110 ValidCombinations: c.ValidCombinations, 111 NetworksNotSupported: c.NetworksNotSupported, 112 } 113 rolesAndHighestRole := calculateRolesAndHighestRole(c.Permissions) 114 115 item.Roles = rolesAndHighestRole.Roles 116 item.HighestRole = rolesAndHighestRole.HighestRole 117 return json.Marshal(item) 118 } 119 120 type TokenRequirementResponse struct { 121 Satisfied bool `json:"satisfied"` 122 TokenCriteria *protobuf.TokenCriteria `json:"criteria"` 123 } 124 125 type PermissionTokenCriteriaResult struct { 126 Role protobuf.CommunityTokenPermission_Type `json:"roles"` 127 TokenRequirements []TokenRequirementResponse `json:"tokenRequirement"` 128 Criteria []bool `json:"criteria"` 129 ID string `json:"id"` 130 } 131 132 type AccountChainIDsCombination struct { 133 Address gethcommon.Address `json:"address"` 134 ChainIDs []uint64 `json:"chainIds"` 135 } 136 137 func (c *CheckPermissionsResponse) calculateSatisfied() { 138 if len(c.Permissions) == 0 { 139 c.Satisfied = true 140 return 141 } 142 143 c.Satisfied = false 144 for _, p := range c.Permissions { 145 satisfied := true 146 for _, criteria := range p.Criteria { 147 if !criteria { 148 satisfied = false 149 break 150 } 151 } 152 if satisfied { 153 c.Satisfied = true 154 return 155 } 156 } 157 }