Added more policy types, removed tags

graph-rework-2
noah metz 2023-07-24 22:52:15 -06:00
parent f118dde221
commit 59df9f04d5
5 changed files with 84 additions and 67 deletions

@ -203,11 +203,15 @@ func NewContext(db * badger.DB, log Logger) * Context {
if err != nil { if err != nil {
panic(err) panic(err)
} }
err = ctx.RegisterNodeType(NewNodeDef((*PerTagPolicy)(nil), LoadPerTagPolicy, GQLTypeSimpleNode.Type)) err = ctx.RegisterNodeType(NewNodeDef((*DependencyPolicy)(nil), LoadSimplePolicy, GQLTypeSimpleNode.Type))
if err != nil { if err != nil {
panic(err) panic(err)
} }
err = ctx.RegisterNodeType(NewNodeDef((*DependencyPolicy)(nil), LoadSimplePolicy, GQLTypeSimpleNode.Type)) err = ctx.RegisterNodeType(NewNodeDef((*ParentPolicy)(nil), LoadSimplePolicy, GQLTypeSimpleNode.Type))
if err != nil {
panic(err)
}
err = ctx.RegisterNodeType(NewNodeDef((*ChildrenPolicy)(nil), LoadSimplePolicy, GQLTypeSimpleNode.Type))
if err != nil { if err != nil {
panic(err) panic(err)
} }

@ -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, []string{"gql"}) new_user := NewUser(fmt.Sprintf("GQL_USER %s", key_id.String()), time.Now(), remote_id, shared)
context := NewWriteContext(ctx) context := NewWriteContext(ctx)
err := UpdateStates(context, server, NewLockMap(LockMap{ err := UpdateStates(context, server, NewLockMap(LockMap{
server.ID(): LockInfo{ server.ID(): LockInfo{

@ -31,7 +31,7 @@ func TestGQLDBLoad(t * testing.T) {
u1_key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) u1_key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
fatalErr(t, err) fatalErr(t, err)
u1 := NewUser("Test User", time.Now(), &u1_key.PublicKey, []byte{}, []string{"gql"}) u1 := NewUser("Test User", time.Now(), &u1_key.PublicKey, []byte{})
ctx.Log.Logf("test", "U1_ID: %s", u1.ID().String()) ctx.Log.Logf("test", "U1_ID: %s", u1.ID().String())
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
@ -137,13 +137,12 @@ func TestGQLAuth(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 := NewPerTagPolicy(RandID(), map[string]NodeActions{"gql": NewNodeActions(nil, []string{"read"})})
p2 := NewSimplePolicy(RandID(), NewNodeActions(NodeActions{ p2 := NewSimplePolicy(RandID(), NewNodeActions(NodeActions{
"signal": []string{"status"}, "signal": []string{"status"},
}, nil)) }, nil))
l1 := NewListener(RandID(), "GQL Thread") l1 := NewListener(RandID(), "GQL Thread")
err = AttachPolicies(ctx, &l1, &p1, &p2) err = AttachPolicies(ctx, &l1, &p2)
fatalErr(t, err) fatalErr(t, err)
p3 := NewPerNodePolicy(RandID(), map[NodeID]NodeActions{ p3 := NewPerNodePolicy(RandID(), map[NodeID]NodeActions{
@ -151,7 +150,7 @@ func TestGQLAuth(t * testing.T) {
}) })
gql := NewGQLThread(RandID(), "GQL Thread", "init", ":0", ecdh.P256(), key, nil, nil) gql := NewGQLThread(RandID(), "GQL Thread", "init", ":0", ecdh.P256(), key, nil, nil)
err = AttachPolicies(ctx, &gql, &p1, &p2, &p3) err = AttachPolicies(ctx, &gql, &p2, &p3)
context := NewWriteContext(ctx) context := NewWriteContext(ctx)
err = LinkLockables(context, &l1, &l1, []LockableNode{&gql}) err = LinkLockables(context, &l1, &l1, []LockableNode{&gql})

@ -175,106 +175,123 @@ func (policy *SimplePolicy) Allows(node Node, resource string, action string, pr
return policy.Actions.Allows(resource, action) return policy.Actions.Allows(resource, action)
} }
type PerTagPolicy struct {
SimpleNode type DependencyPolicy struct {
Actions map[string]NodeActions SimplePolicy
} }
type PerTagPolicyJSON struct {
SimpleNodeJSON func (policy *DependencyPolicy) Type() NodeType {
Actions map[string]map[string][]string `json:"json"` return NodeType("dependency_policy")
} }
func (policy *PerTagPolicy) Type() NodeType { func NewDependencyPolicy(id NodeID, actions NodeActions) DependencyPolicy {
return NodeType("per_tag_policy") return DependencyPolicy{
SimplePolicy: NewSimplePolicy(id, actions),
}
} }
func (policy *PerTagPolicy) Serialize() ([]byte, error) { func (policy *DependencyPolicy) Allows(node Node, resource string, action string, principal Node) bool {
actions := map[string]map[string][]string{} lockable, ok := node.(LockableNode)
for tag, tag_actions := range(policy.Actions) { if ok == false {
actions[tag] = tag_actions return false
} }
return json.MarshalIndent(&PerTagPolicyJSON{ for _, dep := range(lockable.LockableHandle().Dependencies) {
SimpleNodeJSON: NewSimpleNodeJSON(&policy.SimpleNode), if dep.ID() == principal.ID() {
Actions: actions, return policy.Actions.Allows(resource, action)
}, "", " ") }
}
return false
} }
func NewPerTagPolicy(id NodeID, actions map[string]NodeActions) PerTagPolicy { type RequirementPolicy struct {
if actions == nil { SimplePolicy
actions = map[string]NodeActions{} }
}
return PerTagPolicy{
SimpleNode: NewSimpleNode(id), func (policy *RequirementPolicy) Type() NodeType {
Actions: actions, return NodeType("dependency_policy")
}
func NewRequirementPolicy(id NodeID, actions NodeActions) RequirementPolicy {
return RequirementPolicy{
SimplePolicy: NewSimplePolicy(id, actions),
} }
} }
func LoadPerTagPolicy(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Node, error) { func (policy *RequirementPolicy) Allows(node Node, resource string, action string, principal Node) bool {
var j PerTagPolicyJSON lockable_node, ok := node.(LockableNode)
err := json.Unmarshal(data, &j) if ok == false {
if err != nil { return false
return nil, err
} }
lockable := lockable_node.LockableHandle()
actions := map[string]NodeActions{} for _, req := range(lockable.Requirements) {
for tag, tag_actions := range(j.Actions) { if req.ID() == principal.ID() {
actions[tag] = tag_actions return policy.Actions.Allows(resource, action)
}
} }
policy := NewPerTagPolicy(id, actions) return false
nodes[id] = &policy }
err = RestoreSimpleNode(ctx, &policy.SimpleNode, j.SimpleNodeJSON, nodes) type ParentPolicy struct {
if err != nil { SimplePolicy
return nil, err }
}
return &policy, nil
func (policy *ParentPolicy) Type() NodeType {
return NodeType("parent_policy")
}
func NewParentPolicy(id NodeID, actions NodeActions) ParentPolicy {
return ParentPolicy{
SimplePolicy: NewSimplePolicy(id, actions),
}
} }
func (policy *PerTagPolicy) Allows(node Node, resource string, action string, principal Node) bool { func (policy *ParentPolicy) Allows(node Node, resource string, action string, principal Node) bool {
user, ok := principal.(*User) thread_node, ok := node.(ThreadNode)
if ok == false { if ok == false {
return false return false
} }
thread := thread_node.ThreadHandle()
for _, tag := range(user.Tags) { if thread.Owner != nil {
tag_actions, exists := policy.Actions[tag] if thread.Owner.ID() == principal.ID() {
if exists == true { return policy.Actions.Allows(resource, action)
if tag_actions.Allows(resource, action) == true {
return true
}
} }
} }
return false return false
} }
type DependencyPolicy struct { type ChildrenPolicy struct {
SimplePolicy SimplePolicy
} }
func (policy *DependencyPolicy) Type() NodeType { func (policy *ChildrenPolicy) Type() NodeType {
return NodeType("parent_policy") return NodeType("children_policy")
} }
func NewDependencyPolicy(id NodeID, actions NodeActions) DependencyPolicy { func NewChildrenPolicy(id NodeID, actions NodeActions) ChildrenPolicy {
return DependencyPolicy{ return ChildrenPolicy{
SimplePolicy: NewSimplePolicy(id, actions), SimplePolicy: NewSimplePolicy(id, actions),
} }
} }
func (policy *DependencyPolicy) Allows(node Node, resource string, action string, principal Node) bool { func (policy *ChildrenPolicy) Allows(node Node, resource string, action string, principal Node) bool {
lockable, ok := node.(LockableNode) thread_node, ok := node.(ThreadNode)
if ok == false { if ok == false {
return false return false
} }
thread := thread_node.ThreadHandle()
for _, dep := range(lockable.LockableHandle().Dependencies) { for _, info := range(thread.Children) {
if dep.ID() == principal.ID() { if info.Child.ID() == principal.ID() {
return policy.Actions.Allows(resource, action) return policy.Actions.Allows(resource, action)
} }
} }

@ -22,7 +22,6 @@ 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 {
@ -41,7 +40,6 @@ 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,
}, "", " ") }, "", " ")
} }
@ -66,7 +64,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, j.Tags) user := NewUser(j.Name, j.Granted, pubkey, j.Shared)
nodes[id] = &user nodes[id] = &user
err = RestoreLockable(ctx, &user.Lockable, j.LockableJSON, nodes) err = RestoreLockable(ctx, &user.Lockable, j.LockableJSON, nodes)
@ -77,13 +75,12 @@ 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, tags []string) User { func NewUser(name string, granted time.Time, pubkey *ecdsa.PublicKey, shared []byte) User {
id := KeyID(pubkey) id := KeyID(pubkey)
return User{ return User{
Lockable: NewLockable(id, name), Lockable: NewLockable(id, name),
Granted: granted, Granted: granted,
Pubkey: pubkey, Pubkey: pubkey,
Shared: shared, Shared: shared,
Tags: tags,
} }
} }