2024-08-05 14:24:06 +08:00

220 lines
5.0 KiB
Go

package mt
import (
"encoding/json"
"f5"
"fmt"
"q5"
"strings"
)
type role struct {
api *q5.ConcurrentMap[string, bool]
ui *q5.ConcurrentMap[string, bool]
}
type user struct {
accountAddress string
roleHash *q5.ConcurrentMap[string, *role]
api *q5.ConcurrentMap[string, bool]
ui *q5.ConcurrentMap[string, bool]
specApi []string
specUi []string
}
type PermissionTable struct {
f5.CustomMetaTable
apiHash *q5.ConcurrentMap[string, bool]
uiHash *q5.ConcurrentMap[string, bool]
roleHash *q5.ConcurrentMap[string, *role]
userHash *q5.ConcurrentMap[string, *user]
}
func (this *PermissionTable) Load() {
this.apiHash = new(q5.ConcurrentMap[string, bool])
this.uiHash = new(q5.ConcurrentMap[string, bool])
this.roleHash = new(q5.ConcurrentMap[string, *role])
this.userHash = new(q5.ConcurrentMap[string, *user])
this.loadPermission()
this.loadRole()
this.loadUser()
}
func (this *PermissionTable) CheckAPIPermission(accountAddress string, cmd string) bool {
u, exist := this.userHash.Load(accountAddress)
if !exist {
return false
}
ret, exist := (*u).api.Load(cmd)
if exist {
return *ret
}
ret, exist = (*u).api.Load("*")
if exist {
return *ret
}
return false
}
func (this *PermissionTable) GetUIPermission(accountAddress string) string {
u, exist := this.userHash.Load(strings.ToLower(accountAddress))
if !exist {
return "{}"
}
kvlist := map[string]bool{}
(*u).ui.Range(func(k string, v bool) bool {
kvlist[k] = v
return true
})
v, _ := json.Marshal(kvlist)
return string(v)
}
func (this *PermissionTable) loadPermission() {
}
func (this *PermissionTable) loadRole() {
roles := []string{}
{
if jsonStr, err := f5.ReadJsonFile("../config/roles.json"); err == nil {
if err := q5.DecodeJson(jsonStr, &roles); err != nil {
panic(fmt.Sprintf("parse metafile error %s %s", "roles.json", err))
}
} else {
panic(fmt.Sprintf("load metafile error %s %s", "roles.json", err))
}
}
{
for _, name := range roles {
if jsonStr, err := f5.ReadJsonFile("../config/roles/" + name + ".json"); err == nil {
rolePermission := struct {
Api []string `json:"api"`
Ui []string `json:"ui"`
}{}
if err := q5.DecodeJson(jsonStr, &rolePermission); err != nil {
panic(fmt.Sprintf("parse role metafile error %s %s", name+".json", err))
}
p := this.newRole()
for _, pName := range rolePermission.Api {
p.api.Store(pName, true)
}
for _, pName := range rolePermission.Ui {
p.ui.Store(pName, true)
}
this.roleHash.Store(name, p)
}
}
}
}
func (this *PermissionTable) loadUser() {
users := []struct {
AccountAddress string `json:"account_address"`
Roles []string `json:"roles"`
Special struct {
Api []string `json:"api"`
Ui []string `json:"ui"`
} `json:"special"`
}{}
{
if jsonStr, err := f5.ReadJsonFile("../config/users.json"); err == nil {
if err := q5.DecodeJson(jsonStr, &users); err != nil {
panic(fmt.Sprintf("parse metafile error %s %s", "usersa.json", err))
}
} else {
panic(fmt.Sprintf("load metafile error %s %s", "users.json", err))
}
}
{
for _, u := range users {
p := this.newUser()
p.accountAddress = strings.ToLower(u.AccountAddress)
for _, r := range u.Roles {
if pr, ok := this.roleHash.Load(r); ok {
p.roleHash.Store(r, *pr)
} else {
panic(fmt.Sprintf("load metafile error %s role:%s not exists", "users.json", r))
}
}
for _, pName := range u.Special.Api {
q5.AppendSlice(&p.specApi, pName)
}
for _, pName := range u.Special.Ui {
q5.AppendSlice(&p.specUi, pName)
}
this.genUserPermission(p)
this.userHash.Store(p.accountAddress, p)
}
}
}
func (this *PermissionTable) newRole() *role {
p := new(role)
p.api = new(q5.ConcurrentMap[string, bool])
p.ui = new(q5.ConcurrentMap[string, bool])
return p
}
func (this *PermissionTable) newUser() *user {
p := new(user)
p.roleHash = new(q5.ConcurrentMap[string, *role])
p.api = new(q5.ConcurrentMap[string, bool])
p.ui = new(q5.ConcurrentMap[string, bool])
p.specApi = []string{}
p.specUi = []string{}
this.apiHash.Range(func(key string, val bool) bool {
p.api.Store(key, false)
return true
})
this.uiHash.Range(func(key string, val bool) bool {
p.ui.Store(key, false)
return true
})
return p
}
func (this *PermissionTable) genUserPermission(u *user) {
u.roleHash.Range(func(key string, val *role) bool {
val.api.Range(func(key2 string, val2 bool) bool {
u.api.Store(key2, true)
return true
})
val.ui.Range(func(key2 string, val2 bool) bool {
u.ui.Store(key2, true)
return true
})
return true
})
{
for _, val := range u.specApi {
if len(val) <= 0 {
continue
}
if val[0] == '-' {
if len(val) > 1 {
u.api.Store(val[1:], false)
}
} else {
u.api.Store(val, true)
}
}
for _, val := range u.specUi {
if len(val) <= 0 {
continue
}
if val[0] == '-' {
if len(val) > 1 {
u.ui.Store(val[1:], false)
}
} else {
u.ui.Store(val, true)
}
}
}
}