quorum/core/types/permissions_cache.go

434 lines
9.2 KiB
Go
Raw Normal View History

package types
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/hashicorp/golang-lru"
2018-11-12 00:16:56 -08:00
"sync"
)
type AccessType uint8
const (
ReadOnly AccessType = iota
Transact
ContractDeploy
2019-02-11 17:54:13 -08:00
FullAccess
)
type OrgStatus uint8
const (
2019-03-28 21:28:11 -07:00
OrgProposed OrgStatus = iota + 1
OrgApproved
OrgPendingSuspension
OrgSuspended
OrgRevokeSuspension
)
type OrgInfo struct {
OrgId string
2019-03-28 21:28:11 -07:00
Status OrgStatus
}
type NodeStatus uint8
const (
2019-03-28 21:28:11 -07:00
NodePendingApproval NodeStatus = iota + 1
NodeApproved
2019-03-28 21:28:11 -07:00
NodeDeactivated
Blacklisted
)
2019-03-28 21:28:11 -07:00
type AcctStatus uint8
const (
AcctPendingApproval AcctStatus = iota + 1
AcctActive
AcctInactive
)
type NodeInfo struct {
OrgId string
Url string
2019-03-28 21:28:11 -07:00
Status NodeStatus
}
type RoleInfo struct {
OrgId string
RoleId string
IsVoter bool
2019-03-28 21:28:11 -07:00
Access AccessType
Active bool
}
type AccountInfo struct {
OrgId string
RoleId string
AcctId common.Address
IsOrgAdmin bool
2019-03-28 21:28:11 -07:00
Status AcctStatus
}
2018-09-27 04:24:38 -07:00
type OrgStruct struct {
OrgId string
Keys []string
2018-09-27 04:24:38 -07:00
}
2018-11-14 02:24:28 -08:00
// permission config for bootstrapping
type PermissionConfig struct {
UpgrdAddress string
InterfAddress string
ImplAddress string
NodeAddress string
AccountAddress string
RoleAddress string
VoterAddress string
OrgAddress string
NwAdminOrg string
NwAdminRole string
OrgAdminRole string
Accounts []string //initial list of account that need full access
}
type OrgKey struct {
OrgId string
}
type NodeKey struct {
OrgId string
Url string
}
type RoleKey struct {
OrgId string
RoleId string
}
type AccountKey struct {
OrgId string
RoleId string
AcctId common.Address
}
type OrgCache struct {
c *lru.Cache
mux sync.Mutex
}
type NodeCache struct {
c *lru.Cache
mux sync.Mutex
}
type RoleCache struct {
c *lru.Cache
mux sync.Mutex
}
type AcctCache struct {
c *lru.Cache
mux sync.Mutex
}
func NewOrgCache() *OrgCache {
c, _ := lru.New(defaultMapLimit)
return &OrgCache{c, sync.Mutex{}}
}
func NewNodeCache() *NodeCache {
c, _ := lru.New(defaultMapLimit)
return &NodeCache{c, sync.Mutex{}}
}
func NewRoleCache() *RoleCache {
c, _ := lru.New(defaultMapLimit)
return &RoleCache{c, sync.Mutex{}}
}
func NewAcctCache() *AcctCache {
c, _ := lru.New(defaultMapLimit)
return &AcctCache{c, sync.Mutex{}}
}
2018-11-13 00:15:28 -08:00
var DefaultAccess = FullAccess
2018-11-12 00:16:56 -08:00
const orgKeyMapLimit = 100
2018-09-27 04:24:38 -07:00
const defaultMapLimit = 100
2018-11-12 00:16:56 -08:00
var OrgKeyMap, _ = lru.New(orgKeyMapLimit)
var OrgInfoMap = NewOrgCache()
var NodeInfoMap = NewNodeCache()
var RoleInfoMap = NewRoleCache()
var AcctInfoMap = NewAcctCache()
2018-11-12 00:16:56 -08:00
var orgKeyLock sync.Mutex
2019-03-13 23:26:17 -07:00
func (pc *PermissionConfig) IsEmpty() bool {
return pc.InterfAddress == "" || pc.NodeAddress == "" || pc.AccountAddress == ""
2019-03-13 23:26:17 -07:00
}
// sets default access to ReadOnly
2018-11-13 00:15:28 -08:00
func SetDefaultAccess() {
DefaultAccess = ReadOnly
2018-11-13 00:15:28 -08:00
}
2019-03-28 21:28:11 -07:00
func (o *OrgCache) UpsertOrg(orgId string, status OrgStatus) {
defer o.mux.Unlock()
o.mux.Lock()
key := OrgKey{OrgId: orgId}
if _, ok := o.c.Get(key); ok {
log.Info("AJ-OrgId already exists. update it", "orgId", orgId)
o.c.Add(key, &OrgInfo{orgId, status})
} else {
log.Info("AJ-OrgId does not exist. add it", "orgId", orgId)
o.c.Add(key, &OrgInfo{orgId, status})
}
}
func (o *OrgCache) GetOrg(orgId string) *OrgInfo {
defer o.mux.Unlock()
o.mux.Lock()
key := OrgKey{OrgId: orgId}
if ent, ok := o.c.Get(key); ok {
log.Info("AJ-OrgFound", "orgId", orgId)
return ent.(*OrgInfo)
}
return nil
}
func (o *OrgCache) Show() {
for i, k := range o.c.Keys() {
v, _ := o.c.Get(k)
log.Info("AJ-Org", "i", i, "key", k, "value", v)
}
}
func (o *OrgCache) GetOrgList() []OrgInfo {
var olist []OrgInfo
for _, k := range o.c.Keys() {
v, _ := o.c.Get(k)
vp := v.(*OrgInfo)
olist = append(olist, *vp)
}
return olist
}
2019-03-28 21:28:11 -07:00
func (n *NodeCache) UpsertNode(orgId string, url string, status NodeStatus) {
defer n.mux.Unlock()
n.mux.Lock()
key := NodeKey{OrgId: orgId, Url: url}
if _, ok := n.c.Get(key); ok {
log.Info("AJ-Node already exists. update it", "orgId", orgId, "url", url)
n.c.Add(key, &NodeInfo{orgId, url, status})
} else {
log.Info("AJ-Node does not exist. add it", "orgId", orgId, "url", url)
n.c.Add(key, &NodeInfo{orgId, url, status})
}
}
func (n *NodeCache) GetNodeByUrl(url string) *NodeInfo {
defer n.mux.Unlock()
n.mux.Lock()
var key NodeKey
var found = false
for _, k := range n.c.Keys() {
ent := k.(NodeKey)
if ent.Url == url {
key = ent
found = true
break
}
}
if found {
v, _ := n.c.Get(key)
ent := v.(*NodeInfo)
log.Info("AJ-NodeFound", "url", ent.Url, "orgId", ent.OrgId)
return ent
}
return nil
}
func (o *NodeCache) Show() {
for i, k := range o.c.Keys() {
v, _ := o.c.Get(k)
log.Info("AJ-Node", "i", i, "key", k, "value", v)
}
}
func (o *NodeCache) GetNodeList() []NodeInfo {
var olist []NodeInfo
for _, k := range o.c.Keys() {
v, _ := o.c.Get(k)
vp := v.(*NodeInfo)
olist = append(olist, *vp)
}
return olist
}
2019-03-28 21:28:11 -07:00
func (a *AcctCache) UpsertAccount(orgId string, role string, acct common.Address, orgAdmin bool, status AcctStatus) {
defer a.mux.Unlock()
a.mux.Lock()
key := AccountKey{orgId, role, acct}
if _, ok := a.c.Get(key); ok {
log.Info("AJ-account already exists. update it", "orgId", orgId, "role", role, "acct", acct)
a.c.Add(key, &AccountInfo{orgId, role, acct, orgAdmin, status})
} else {
log.Info("AJ-account does not exist. add it", "orgId", orgId, "role", role, "acct", acct)
a.c.Add(key, &AccountInfo{orgId, role, acct, orgAdmin, status})
}
}
func (a *AcctCache) GetAccountByAccount(acct common.Address) *AccountInfo {
defer a.mux.Unlock()
a.mux.Lock()
var key AccountKey
var found = false
for _, k := range a.c.Keys() {
ent := k.(AccountKey)
if ent.AcctId == acct {
key = ent
found = true
break
}
}
if found {
v, _ := a.c.Get(key)
ent := v.(*AccountInfo)
log.Info("AJ-AccountFound", "org", ent.OrgId, "role", ent.RoleId, "acct", ent.AcctId)
return ent
}
return nil
}
func (o *AcctCache) Show() {
for i, k := range o.c.Keys() {
v, _ := o.c.Get(k)
log.Info("AJ-Accounts", "i", i, "key", k, "value", v)
}
}
func (o *AcctCache) GetAcctList() []AccountInfo {
var olist []AccountInfo
for _, k := range o.c.Keys() {
v, _ := o.c.Get(k)
vp := v.(*AccountInfo)
olist = append(olist, *vp)
}
return olist
}
2019-03-28 21:28:11 -07:00
func (r *RoleCache) UpsertRole(orgId string, role string, voter bool, access AccessType, active bool) {
defer r.mux.Unlock()
r.mux.Lock()
key := RoleKey{orgId, role}
if _, ok := r.c.Get(key); ok {
log.Info("AJ-role already exists. update it", "orgId", orgId, "role", role, "access", access, "voter", voter, "active", active)
r.c.Add(key, &RoleInfo{orgId, role, voter, access, active})
} else {
log.Info("AJ-role does not exist. add it", "orgId", orgId, "role", role, "access", access, "voter", voter, "active", active)
r.c.Add(key, &RoleInfo{orgId, role, voter, access, active})
}
}
func (r *RoleCache) GetRole(orgId string, roleId string) *RoleInfo {
defer r.mux.Unlock()
r.mux.Lock()
key := RoleKey{OrgId: orgId, RoleId: roleId}
if ent, ok := r.c.Get(key); ok {
log.Info("AJ-RoleFound", "orgId", orgId, "roleId", roleId)
return ent.(*RoleInfo)
}
return nil
}
func (r *RoleCache) Show() {
for i, k := range r.c.Keys() {
v, _ := r.c.Get(k)
log.Info("AJ-Role", "i", i, "key", k, "value", v)
}
}
func (o *RoleCache) GetRoleList() []RoleInfo {
var olist []RoleInfo
for _, k := range o.c.Keys() {
v, _ := o.c.Get(k)
vp := v.(*RoleInfo)
olist = append(olist, *vp)
}
return olist
}
// Returns the access type for an account. If not found returns
// default access
func GetAcctAccess(acctId common.Address) AccessType {
log.Info("AJ-get acct access ", "acct", acctId)
if a := AcctInfoMap.GetAccountByAccount(acctId); a != nil {
log.Info("AJ-Acct found", "a", a)
o := OrgInfoMap.GetOrg(a.OrgId)
r := RoleInfoMap.GetRole(a.OrgId, a.RoleId)
if o != nil && r != nil {
log.Info("AJ-org role found")
if (o.Status == OrgApproved || o.Status == OrgRevokeSuspension) && r.Active {
log.Info("AJ-access found", "access", r.Access)
return r.Access
} else {
log.Info("AJ-access org or role invalid")
}
} else {
log.Info("AJ-access org or role is missing")
}
} else {
log.Info("AJ-Acct not found", "def access", DefaultAccess)
}
return DefaultAccess
}
2018-09-27 04:24:38 -07:00
// Adds org key details to cache
func AddOrgKey(orgId string, key string) {
if OrgKeyMap.Len() != 0 {
if val, ok := OrgKeyMap.Get(orgId); ok {
2018-11-12 00:16:56 -08:00
orgKeyLock.Lock()
defer orgKeyLock.Unlock()
2018-10-02 01:28:55 -07:00
// Org record exists. Append the key only
vo := val.(*OrgStruct)
vo.Keys = append(vo.Keys, key)
2018-10-02 01:28:55 -07:00
return
}
}
OrgKeyMap.Add(orgId, &OrgStruct{OrgId: orgId, Keys: []string{key}})
2018-10-02 01:28:55 -07:00
}
// deletes org key details from cache
func DeleteOrgKey(orgId string, key string) {
if val, ok := OrgKeyMap.Get(orgId); ok {
2018-11-12 00:16:56 -08:00
orgKeyLock.Lock()
defer orgKeyLock.Unlock()
vo := val.(*OrgStruct)
for i, keyVal := range vo.Keys {
if keyVal == key {
vo.Keys = append(vo.Keys[:i], vo.Keys[i+1:]...)
break
2018-10-02 01:28:55 -07:00
}
}
}
2018-09-27 04:24:38 -07:00
}
// Givens a orgid returns the linked keys for the org
func ResolvePrivateForKeys(orgId string) []string {
2018-09-27 04:24:38 -07:00
var keys []string
if val, ok := OrgKeyMap.Get(orgId); ok {
vo := val.(*OrgStruct)
if len(vo.Keys) > 0 {
keys = vo.Keys
} else {
keys = append(keys, orgId)
2018-09-27 04:24:38 -07:00
}
return keys
2018-09-27 04:24:38 -07:00
}
keys = append(keys, orgId)
return keys
}