Added SimplePolicy

graph-rework-2
noah metz 2023-07-21 13:33:04 -06:00
parent 230ff2b883
commit 6cf2d2d957
5 changed files with 85 additions and 41 deletions

@ -192,6 +192,10 @@ func NewContext(db * badger.DB, log Logger) * Context {
if err != nil { if err != nil {
panic(err) panic(err)
} }
err = ctx.RegisterNodeType(NewNodeDef((*SimplePolicy)(nil), LoadSimplePolicy, GQLTypeGraphNode()))
if err != nil {
panic(err)
}
ctx.AddGQLType(GQLTypeSignal()) ctx.AddGQLType(GQLTypeSignal())

@ -203,7 +203,7 @@ func AuthHandler(ctx *Context, server *GQLThread) func(http.ResponseWriter, *htt
} else { } else {
ctx.Log.Logf("gql", "AUTHORIZING NEW USER %s - %s", key_id, shared) ctx.Log.Logf("gql", "AUTHORIZING NEW USER %s - %s", key_id, shared)
new_user := NewUser(fmt.Sprintf("GQL_USER %s", key_id.String()), time.Now(), remote_id, shared) new_user := NewUser(fmt.Sprintf("GQL_USER %s", key_id.String()), time.Now(), remote_id, shared, []string{"gql"})
err := UpdateStates(ctx, []Node{server, &new_user}, func(nodes NodeMap) error { err := UpdateStates(ctx, []Node{server, &new_user}, func(nodes NodeMap) error {
server.Users[key_id] = &new_user server.Users[key_id] = &new_user
return nil return nil

@ -23,9 +23,6 @@ func TestGQLThread(t * testing.T) {
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
fatalErr(t, err) fatalErr(t, err)
p1_r := NewPerNodePolicy(RandID(), nil, NewNodeActions(nil, []string{"enumerate"}))
p1 := &p1_r
gql_t_r := NewGQLThread(RandID(), "GQL Thread", "init", ":0", ecdh.P256(), key, nil, nil) gql_t_r := NewGQLThread(RandID(), "GQL Thread", "init", ":0", ecdh.P256(), key, nil, nil)
gql_t := &gql_t_r gql_t := &gql_t_r
@ -34,13 +31,9 @@ func TestGQLThread(t * testing.T) {
t2_r := NewSimpleThread(RandID(), "Test thread 2", "init", nil, BaseThreadActions, BaseThreadHandlers) t2_r := NewSimpleThread(RandID(), "Test thread 2", "init", nil, BaseThreadActions, BaseThreadHandlers)
t2 := &t2_r t2 := &t2_r
err = UpdateStates(ctx, []Node{gql_t, t1, t2, p1}, func(nodes NodeMap) error { err = UpdateStates(ctx, []Node{gql_t, t1, t2}, func(nodes NodeMap) error {
err := gql_t.AddPolicy(p1)
if err != nil {
return err
}
i1 := NewParentThreadInfo(true, "start", "restore") i1 := NewParentThreadInfo(true, "start", "restore")
err = LinkThreads(ctx, gql_t, t1, &i1, nodes) err := LinkThreads(ctx, gql_t, t1, &i1, nodes)
if err != nil { if err != nil {
return err return err
} }
@ -76,10 +69,10 @@ func TestGQLDBLoad(t * testing.T) {
u1_shared := []byte{0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x23, 0x45, 0x67} u1_shared := []byte{0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x23, 0x45, 0x67}
u1_r := NewUser("Test User", time.Now(), &u1_key.PublicKey, u1_shared) u1_r := NewUser("Test User", time.Now(), &u1_key.PublicKey, u1_shared, []string{"gql"})
u1 := &u1_r u1 := &u1_r
p1_r := NewPerNodePolicy(RandID(), nil, NewNodeActions(nil, []string{"enumerate"})) p1_r := NewSimplePolicy(RandID(), NewNodeActions(nil, []string{"enumerate"}))
p1 := &p1_r p1 := &p1_r
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
@ -160,11 +153,11 @@ func TestGQLDBLoad(t * testing.T) {
} }
func TestGQLAuth(t * testing.T) { func TestGQLAuth(t * testing.T) {
ctx := logTestContext(t, []string{"test", "gql", "db"}) ctx := logTestContext(t, []string{"test", "gql"})
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
fatalErr(t, err) fatalErr(t, err)
p1_r := NewPerNodePolicy(RandID(), nil, NewNodeActions(nil, []string{"*"})) p1_r := NewSimplePolicy(RandID(), NewNodeActions(nil, []string{"*"}))
p1 := &p1_r p1 := &p1_r
gql_t_r := NewGQLThread(RandID(), "GQL Thread", "init", ":0", ecdh.P256(), key, nil, nil) gql_t_r := NewGQLThread(RandID(), "GQL Thread", "init", ":0", ecdh.P256(), key, nil, nil)

@ -45,14 +45,12 @@ func NewNodeActions(resource_actions NodeActions, wildcard_actions []string) Nod
type PerNodePolicy struct { type PerNodePolicy struct {
GraphNode GraphNode
NodeActions map[NodeID]NodeActions Actions map[NodeID]NodeActions
WildcardActions NodeActions
} }
type PerNodePolicyJSON struct { type PerNodePolicyJSON struct {
GraphNodeJSON GraphNodeJSON
NodeActions map[string]map[string][]string `json:"allowed_actions"` Actions map[string]map[string][]string `json:"actions"`
WildcardActions map[string][]string `json:"wildcard_actions"`
} }
func (policy *PerNodePolicy) Type() NodeType { func (policy *PerNodePolicy) Type() NodeType {
@ -61,30 +59,24 @@ func (policy *PerNodePolicy) Type() NodeType {
func (policy *PerNodePolicy) Serialize() ([]byte, error) { func (policy *PerNodePolicy) Serialize() ([]byte, error) {
allowed_actions := map[string]map[string][]string{} allowed_actions := map[string]map[string][]string{}
for principal, actions := range(policy.NodeActions) { for principal, actions := range(policy.Actions) {
allowed_actions[principal.String()] = actions allowed_actions[principal.String()] = actions
} }
return json.MarshalIndent(&PerNodePolicyJSON{ return json.MarshalIndent(&PerNodePolicyJSON{
GraphNodeJSON: NewGraphNodeJSON(&policy.GraphNode), GraphNodeJSON: NewGraphNodeJSON(&policy.GraphNode),
NodeActions: allowed_actions, Actions: allowed_actions,
WildcardActions: policy.WildcardActions,
}, "", " ") }, "", " ")
} }
func NewPerNodePolicy(id NodeID, node_actions map[NodeID]NodeActions, wildcard_actions NodeActions) PerNodePolicy { func NewPerNodePolicy(id NodeID, actions map[NodeID]NodeActions) PerNodePolicy {
if node_actions == nil { if actions == nil {
node_actions = map[NodeID]NodeActions{} actions = map[NodeID]NodeActions{}
}
if wildcard_actions == nil {
wildcard_actions = NewNodeActions(nil, nil)
} }
return PerNodePolicy{ return PerNodePolicy{
GraphNode: NewGraphNode(id), GraphNode: NewGraphNode(id),
NodeActions: node_actions, Actions: actions,
WildcardActions: wildcard_actions,
} }
} }
@ -95,17 +87,17 @@ func LoadPerNodePolicy(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Nod
return nil, err return nil, err
} }
allowed_actions := map[NodeID]NodeActions{} actions := map[NodeID]NodeActions{}
for principal_str, actions := range(j.NodeActions) { for principal_str, node_actions := range(j.Actions) {
principal_id, err := ParseID(principal_str) principal_id, err := ParseID(principal_str)
if err != nil { if err != nil {
return nil, err return nil, err
} }
allowed_actions[principal_id] = actions actions[principal_id] = node_actions
} }
policy := NewPerNodePolicy(id, allowed_actions, j.WildcardActions) policy := NewPerNodePolicy(id, actions)
nodes[id] = &policy nodes[id] = &policy
err = RestoreGraphNode(ctx, &policy.GraphNode, j.GraphNodeJSON, nodes) err = RestoreGraphNode(ctx, &policy.GraphNode, j.GraphNodeJSON, nodes)
@ -117,11 +109,7 @@ func LoadPerNodePolicy(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Nod
} }
func (policy *PerNodePolicy) Allows(action string, resource string, principal NodeID) bool { func (policy *PerNodePolicy) Allows(action string, resource string, principal NodeID) bool {
if policy.WildcardActions.Allows(action, resource) == true { node_actions, exists := policy.Actions[principal]
return true
}
node_actions, exists := policy.NodeActions[principal]
if exists == false { if exists == false {
return false return false
} }
@ -132,3 +120,58 @@ func (policy *PerNodePolicy) Allows(action string, resource string, principal No
return false return false
} }
type SimplePolicy struct {
GraphNode
Actions NodeActions
}
type SimplePolicyJSON struct {
GraphNodeJSON
Actions map[string][]string `json:"actions"`
}
func (policy *SimplePolicy) Type() NodeType {
return NodeType("simple_policy")
}
func (policy *SimplePolicy) Serialize() ([]byte, error) {
return json.MarshalIndent(&SimplePolicyJSON{
GraphNodeJSON: NewGraphNodeJSON(&policy.GraphNode),
Actions: policy.Actions,
}, "", " ")
}
func NewSimplePolicy(id NodeID, actions NodeActions) SimplePolicy {
if actions == nil {
actions = NodeActions{}
}
return SimplePolicy{
GraphNode: NewGraphNode(id),
Actions: actions,
}
}
func LoadSimplePolicy(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Node, error) {
var j SimplePolicyJSON
err := json.Unmarshal(data, &j)
if err != nil {
return nil, err
}
policy := NewSimplePolicy(id, j.Actions)
nodes[id] = &policy
err = RestoreGraphNode(ctx, &policy.GraphNode, j.GraphNodeJSON, nodes)
if err != nil {
return nil, err
}
return &policy, nil
}
func (policy *SimplePolicy) Allows(action string, resource string, principal NodeID) bool {
return policy.Actions.Allows(action, resource)
}

@ -14,6 +14,7 @@ type User struct {
Granted time.Time Granted time.Time
Pubkey *ecdsa.PublicKey Pubkey *ecdsa.PublicKey
Shared []byte Shared []byte
Tags []string
} }
type UserJSON struct { type UserJSON struct {
@ -21,6 +22,7 @@ type UserJSON struct {
Granted time.Time `json:"granted"` Granted time.Time `json:"granted"`
Pubkey []byte `json:"pubkey"` Pubkey []byte `json:"pubkey"`
Shared []byte `json:"shared"` Shared []byte `json:"shared"`
Tags []string `json:"tags"`
} }
func (user *User) Type() NodeType { func (user *User) Type() NodeType {
@ -39,6 +41,7 @@ func (user *User) Serialize() ([]byte, error) {
Granted: user.Granted, Granted: user.Granted,
Shared: user.Shared, Shared: user.Shared,
Pubkey: pubkey, Pubkey: pubkey,
Tags: user.Tags,
}, "", " ") }, "", " ")
} }
@ -62,7 +65,7 @@ func LoadUser(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Node, error)
return nil, fmt.Errorf("Invalid key type") return nil, fmt.Errorf("Invalid key type")
} }
user := NewUser(j.Name, j.Granted, pubkey, j.Shared) user := NewUser(j.Name, j.Granted, pubkey, j.Shared, j.Tags)
nodes[id] = &user nodes[id] = &user
err = RestoreSimpleLockable(ctx, &user, j.SimpleLockableJSON, nodes) err = RestoreSimpleLockable(ctx, &user, j.SimpleLockableJSON, nodes)
@ -73,12 +76,13 @@ func LoadUser(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Node, error)
return &user, nil return &user, nil
} }
func NewUser(name string, granted time.Time, pubkey *ecdsa.PublicKey, shared []byte) User { func NewUser(name string, granted time.Time, pubkey *ecdsa.PublicKey, shared []byte, tags []string) User {
id := KeyID(pubkey) id := KeyID(pubkey)
return User{ return User{
SimpleLockable: NewSimpleLockable(id, name), SimpleLockable: NewSimpleLockable(id, name),
Granted: granted, Granted: granted,
Pubkey: pubkey, Pubkey: pubkey,
Shared: shared, Shared: shared,
Tags: tags,
} }
} }