mirror of
https://github.com/status-im/status-go.git
synced 2025-01-18 10:42:07 +00:00
daef5c56e2
This commit adds HighestRole & a list of permissions in order of importance to the CheckPermissionToJoinResponse. This simplify client code so that it doesn't need to be calculated on the client.
152 lines
4.4 KiB
Go
152 lines
4.4 KiB
Go
package communities
|
|
|
|
import (
|
|
"encoding/json"
|
|
"sort"
|
|
|
|
gethcommon "github.com/ethereum/go-ethereum/common"
|
|
"github.com/status-im/status-go/protocol/protobuf"
|
|
)
|
|
|
|
type CheckPermissionsResponse struct {
|
|
Satisfied bool `json:"satisfied"`
|
|
Permissions map[string]*PermissionTokenCriteriaResult `json:"permissions"`
|
|
ValidCombinations []*AccountChainIDsCombination `json:"validCombinations"`
|
|
}
|
|
|
|
type CheckPermissionToJoinResponse = CheckPermissionsResponse
|
|
|
|
type HighestRoleResponse struct {
|
|
Role protobuf.CommunityTokenPermission_Type `json:"type"`
|
|
Satisfied bool `json:"satisfied"`
|
|
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,
|
|
}
|
|
|
|
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]
|
|
}
|
|
|
|
type rolesAndHighestRole struct {
|
|
Roles []*HighestRoleResponse
|
|
HighestRole *HighestRoleResponse
|
|
}
|
|
|
|
func calculateRolesAndHighestRole(permissions map[string]*PermissionTokenCriteriaResult) *rolesAndHighestRole {
|
|
item := &rolesAndHighestRole{}
|
|
byRoleMap := make(map[protobuf.CommunityTokenPermission_Type]*HighestRoleResponse)
|
|
for _, p := range permissions {
|
|
if joiningRoleOrders[p.Role] == 0 {
|
|
continue
|
|
}
|
|
if byRoleMap[p.Role] == nil {
|
|
byRoleMap[p.Role] = &HighestRoleResponse{
|
|
Role: p.Role,
|
|
}
|
|
}
|
|
|
|
satisfied := true
|
|
for _, tr := range p.TokenRequirements {
|
|
if !tr.Satisfied {
|
|
satisfied = false
|
|
break
|
|
}
|
|
|
|
}
|
|
|
|
if satisfied {
|
|
byRoleMap[p.Role].Satisfied = true
|
|
// we prepend
|
|
byRoleMap[p.Role].Criteria = append([]*PermissionTokenCriteriaResult{p}, byRoleMap[p.Role].Criteria...)
|
|
} else {
|
|
// we append then
|
|
byRoleMap[p.Role].Criteria = append(byRoleMap[p.Role].Criteria, p)
|
|
}
|
|
}
|
|
if byRoleMap[protobuf.CommunityTokenPermission_BECOME_MEMBER] == nil {
|
|
byRoleMap[protobuf.CommunityTokenPermission_BECOME_MEMBER] = &HighestRoleResponse{Satisfied: true, Role: protobuf.CommunityTokenPermission_BECOME_MEMBER}
|
|
}
|
|
for _, p := range byRoleMap {
|
|
item.Roles = append(item.Roles, p)
|
|
}
|
|
|
|
sort.Sort(ByRoleDesc(item.Roles))
|
|
for _, r := range item.Roles {
|
|
if r.Satisfied {
|
|
item.HighestRole = r
|
|
break
|
|
}
|
|
|
|
}
|
|
return item
|
|
}
|
|
|
|
func (c *CheckPermissionsResponse) MarshalJSON() ([]byte, error) {
|
|
type CheckPermissionsTypeAlias struct {
|
|
Satisfied bool `json:"satisfied"`
|
|
Permissions map[string]*PermissionTokenCriteriaResult `json:"permissions"`
|
|
ValidCombinations []*AccountChainIDsCombination `json:"validCombinations"`
|
|
Roles []*HighestRoleResponse `json:"roles"`
|
|
HighestRole *HighestRoleResponse `json:"highestRole"`
|
|
}
|
|
c.calculateSatisfied()
|
|
item := &CheckPermissionsTypeAlias{
|
|
Satisfied: c.Satisfied,
|
|
Permissions: c.Permissions,
|
|
ValidCombinations: c.ValidCombinations,
|
|
}
|
|
rolesAndHighestRole := calculateRolesAndHighestRole(c.Permissions)
|
|
|
|
item.Roles = rolesAndHighestRole.Roles
|
|
item.HighestRole = rolesAndHighestRole.HighestRole
|
|
return json.Marshal(item)
|
|
}
|
|
|
|
type TokenRequirementResponse struct {
|
|
Satisfied bool `json:"satisfied"`
|
|
TokenCriteria *protobuf.TokenCriteria `json:"criteria"`
|
|
}
|
|
|
|
type PermissionTokenCriteriaResult struct {
|
|
Role protobuf.CommunityTokenPermission_Type `json:"roles"`
|
|
TokenRequirements []TokenRequirementResponse `json:"tokenRequirement"`
|
|
Criteria []bool `json:"criteria"`
|
|
}
|
|
|
|
type AccountChainIDsCombination struct {
|
|
Address gethcommon.Address `json:"address"`
|
|
ChainIDs []uint64 `json:"chainIds"`
|
|
}
|
|
|
|
func (c *CheckPermissionsResponse) calculateSatisfied() {
|
|
if len(c.Permissions) == 0 {
|
|
c.Satisfied = true
|
|
return
|
|
}
|
|
|
|
c.Satisfied = false
|
|
for _, p := range c.Permissions {
|
|
satisfied := true
|
|
for _, criteria := range p.Criteria {
|
|
if !criteria {
|
|
satisfied = false
|
|
break
|
|
}
|
|
}
|
|
if satisfied {
|
|
c.Satisfied = true
|
|
return
|
|
}
|
|
}
|
|
}
|