220 lines
5.0 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|
|
}
|