|  |  |  | @ -6,31 +6,262 @@ import ( | 
		
	
		
			
				|  |  |  |  | ) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type Policy interface { | 
		
	
		
			
				|  |  |  |  |   Type() PolicyType | 
		
	
		
			
				|  |  |  |  |   Serialize() ([]byte, error) | 
		
	
		
			
				|  |  |  |  |   Allows(context *StateContext, principal *Node, action string, node *Node) bool | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func LoadAllNodesPolicy(ctx *Context, data []byte) (Policy, error) { | 
		
	
		
			
				|  |  |  |  |   var policy AllNodesPolicy | 
		
	
		
			
				|  |  |  |  |   err := json.Unmarshal(data, &policy) | 
		
	
		
			
				|  |  |  |  | const ChildOfPolicyType = PolicyType("CHILD_OF") | 
		
	
		
			
				|  |  |  |  | type ChildOfPolicy struct { | 
		
	
		
			
				|  |  |  |  |   NodeActions map[NodeID][]string | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy *ChildOfPolicy) Type() PolicyType { | 
		
	
		
			
				|  |  |  |  |   return ChildOfPolicyType | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy *ChildOfPolicy) Serialize() ([]byte, error) { | 
		
	
		
			
				|  |  |  |  |   node_actions := map[string][]string{} | 
		
	
		
			
				|  |  |  |  |   for id, actions := range(policy.NodeActions) { | 
		
	
		
			
				|  |  |  |  |     node_actions[id.String()] = actions | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return json.MarshalIndent(&ChildOfPolicyJSON{ | 
		
	
		
			
				|  |  |  |  |     NodeActions: node_actions, | 
		
	
		
			
				|  |  |  |  |   }, "", "  ") | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy *ChildOfPolicy) Allows(context *StateContext, principal *Node, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  |   context.Graph.Log.Logf("policy", "CHILD_OF_POLICY: %+v", policy) | 
		
	
		
			
				|  |  |  |  |   thread_ext, err := GetExt[*ThreadExt](principal) | 
		
	
		
			
				|  |  |  |  |   if err != nil { | 
		
	
		
			
				|  |  |  |  |     return false | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   parent := thread_ext.Parent | 
		
	
		
			
				|  |  |  |  |   if parent != nil { | 
		
	
		
			
				|  |  |  |  |     actions, exists := policy.NodeActions[parent.ID] | 
		
	
		
			
				|  |  |  |  |     if exists == false { | 
		
	
		
			
				|  |  |  |  |       return false | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     for _, a := range(actions) { | 
		
	
		
			
				|  |  |  |  |       if a == action { | 
		
	
		
			
				|  |  |  |  |         return true | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return false | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type ChildOfPolicyJSON struct { | 
		
	
		
			
				|  |  |  |  |   NodeActions map[string][]string `json:"node_actions"` | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func LoadChildOfPolicy(ctx *Context, data []byte) (Policy, error) { | 
		
	
		
			
				|  |  |  |  |   var j ChildOfPolicyJSON | 
		
	
		
			
				|  |  |  |  |   err := json.Unmarshal(data, &j) | 
		
	
		
			
				|  |  |  |  |   if err != nil { | 
		
	
		
			
				|  |  |  |  |     return policy, err | 
		
	
		
			
				|  |  |  |  |     return nil, err | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   node_actions := map[NodeID][]string{} | 
		
	
		
			
				|  |  |  |  |   for id_str, actions := range(j.NodeActions) { | 
		
	
		
			
				|  |  |  |  |     id, err := ParseID(id_str) | 
		
	
		
			
				|  |  |  |  |     if err != nil { | 
		
	
		
			
				|  |  |  |  |       return nil, err | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     _, err = LoadNode(ctx, id) | 
		
	
		
			
				|  |  |  |  |     if err != nil { | 
		
	
		
			
				|  |  |  |  |       return nil, err | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     node_actions[id] = actions | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return NewChildOfPolicy(node_actions), nil | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewChildOfPolicy(node_actions map[NodeID][]string) *ChildOfPolicy { | 
		
	
		
			
				|  |  |  |  |   if node_actions == nil { | 
		
	
		
			
				|  |  |  |  |     node_actions = map[NodeID][]string{} | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return &ChildOfPolicy{ | 
		
	
		
			
				|  |  |  |  |     NodeActions: node_actions, | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | const ParentOfPolicyType = PolicyType("PARENT_OF") | 
		
	
		
			
				|  |  |  |  | type ParentOfPolicy struct { | 
		
	
		
			
				|  |  |  |  |   NodeActions map[NodeID][]string | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy *ParentOfPolicy) Type() PolicyType { | 
		
	
		
			
				|  |  |  |  |   return ParentOfPolicyType | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy *ParentOfPolicy) Serialize() ([]byte, error) { | 
		
	
		
			
				|  |  |  |  |   node_actions := map[string][]string{} | 
		
	
		
			
				|  |  |  |  |   for id, actions := range(policy.NodeActions) { | 
		
	
		
			
				|  |  |  |  |     node_actions[id.String()] = actions | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return policy, nil | 
		
	
		
			
				|  |  |  |  |   return json.MarshalIndent(&ParentOfPolicyJSON{ | 
		
	
		
			
				|  |  |  |  |     NodeActions: node_actions, | 
		
	
		
			
				|  |  |  |  |   }, "", "  ") | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type AllNodesPolicy struct { | 
		
	
		
			
				|  |  |  |  |   Actions []string `json:"actions"` | 
		
	
		
			
				|  |  |  |  | func (policy *ParentOfPolicy) Allows(context *StateContext, principal *Node, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  |   context.Graph.Log.Logf("policy", "PARENT_OF_POLICY: %+v", policy) | 
		
	
		
			
				|  |  |  |  |   for id, actions := range(policy.NodeActions) { | 
		
	
		
			
				|  |  |  |  |     thread_ext, err := GetExt[*ThreadExt](context.Graph.Nodes[id]) | 
		
	
		
			
				|  |  |  |  |     if err != nil { | 
		
	
		
			
				|  |  |  |  |       continue | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       context.Graph.Log.Logf("policy", "PARENT_OF_PARENT: %s %+v", id, thread_ext.Parent) | 
		
	
		
			
				|  |  |  |  |     if thread_ext.Parent != nil { | 
		
	
		
			
				|  |  |  |  |       if thread_ext.Parent.ID == principal.ID { | 
		
	
		
			
				|  |  |  |  |         for _, a := range(actions) { | 
		
	
		
			
				|  |  |  |  |           if a == action { | 
		
	
		
			
				|  |  |  |  |             return true | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return false | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy AllNodesPolicy) Type() PolicyType { | 
		
	
		
			
				|  |  |  |  |   return PolicyType("simple_policy") | 
		
	
		
			
				|  |  |  |  | type ParentOfPolicyJSON struct { | 
		
	
		
			
				|  |  |  |  |   NodeActions map[string][]string `json:"node_actions"` | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy AllNodesPolicy) Serialize() ([]byte, error) { | 
		
	
		
			
				|  |  |  |  |   return json.MarshalIndent(&policy, "", "  ") | 
		
	
		
			
				|  |  |  |  | func LoadParentOfPolicy(ctx *Context, data []byte) (Policy, error) { | 
		
	
		
			
				|  |  |  |  |   var j ParentOfPolicyJSON | 
		
	
		
			
				|  |  |  |  |   err := json.Unmarshal(data, &j) | 
		
	
		
			
				|  |  |  |  |   if err != nil { | 
		
	
		
			
				|  |  |  |  |     return nil, err | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   node_actions := map[NodeID][]string{} | 
		
	
		
			
				|  |  |  |  |   for id_str, actions := range(j.NodeActions) { | 
		
	
		
			
				|  |  |  |  |     id, err := ParseID(id_str) | 
		
	
		
			
				|  |  |  |  |     if err != nil { | 
		
	
		
			
				|  |  |  |  |       return nil, err | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     _, err = LoadNode(ctx, id) | 
		
	
		
			
				|  |  |  |  |     if err != nil { | 
		
	
		
			
				|  |  |  |  |       return nil, err | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     node_actions[id] = actions | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return NewParentOfPolicy(node_actions), nil | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewParentOfPolicy(node_actions map[NodeID][]string) *ParentOfPolicy { | 
		
	
		
			
				|  |  |  |  |   if node_actions == nil { | 
		
	
		
			
				|  |  |  |  |     node_actions = map[NodeID][]string{} | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return &ParentOfPolicy{ | 
		
	
		
			
				|  |  |  |  |     NodeActions: node_actions, | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func LoadPerNodePolicy(ctx *Context, data []byte) (Policy, error) { | 
		
	
		
			
				|  |  |  |  |   var j PerNodePolicyJSON | 
		
	
		
			
				|  |  |  |  |   err := json.Unmarshal(data, &j) | 
		
	
		
			
				|  |  |  |  |   if err != nil { | 
		
	
		
			
				|  |  |  |  |     return nil, err | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   node_actions := map[NodeID][]string{} | 
		
	
		
			
				|  |  |  |  |   for id_str, actions := range(j.NodeActions) { | 
		
	
		
			
				|  |  |  |  |     id, err := ParseID(id_str) | 
		
	
		
			
				|  |  |  |  |     if err != nil { | 
		
	
		
			
				|  |  |  |  |       return nil, err | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     _, err = LoadNode(ctx, id) | 
		
	
		
			
				|  |  |  |  |     if err != nil { | 
		
	
		
			
				|  |  |  |  |       return nil, err | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     node_actions[id] = actions | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return NewPerNodePolicy(node_actions, j.WildcardActions), nil | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewPerNodePolicy(node_actions map[NodeID][]string, wildcard_actions []string) *PerNodePolicy { | 
		
	
		
			
				|  |  |  |  |   if node_actions == nil { | 
		
	
		
			
				|  |  |  |  |     node_actions = map[NodeID][]string{} | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if wildcard_actions == nil { | 
		
	
		
			
				|  |  |  |  |     wildcard_actions = []string{} | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return &PerNodePolicy{ | 
		
	
		
			
				|  |  |  |  |     NodeActions: node_actions, | 
		
	
		
			
				|  |  |  |  |     WildcardActions: wildcard_actions, | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type PerNodePolicy struct { | 
		
	
		
			
				|  |  |  |  |   NodeActions map[NodeID][]string | 
		
	
		
			
				|  |  |  |  |   WildcardActions []string | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type PerNodePolicyJSON struct { | 
		
	
		
			
				|  |  |  |  |   NodeActions map[string][]string `json:"node_actions"` | 
		
	
		
			
				|  |  |  |  |   WildcardActions []string `json:"wildcard_actions"` | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | const PerNodePolicyType = PolicyType("PER_NODE") | 
		
	
		
			
				|  |  |  |  | func (policy PerNodePolicy) Type() PolicyType { | 
		
	
		
			
				|  |  |  |  |   return PerNodePolicyType | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy PerNodePolicy) Serialize() ([]byte, error) { | 
		
	
		
			
				|  |  |  |  |   node_actions := map[string][]string{} | 
		
	
		
			
				|  |  |  |  |   for id, actions := range(policy.NodeActions) { | 
		
	
		
			
				|  |  |  |  |     node_actions[id.String()] = actions | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return json.MarshalIndent(&PerNodePolicyJSON{ | 
		
	
		
			
				|  |  |  |  |     NodeActions: node_actions, | 
		
	
		
			
				|  |  |  |  |     WildcardActions: policy.WildcardActions, | 
		
	
		
			
				|  |  |  |  |   }, "", "  ") | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy PerNodePolicy) Allows(context *StateContext, principal *Node, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  |   for _, a := range(policy.WildcardActions) { | 
		
	
		
			
				|  |  |  |  |     if a == action { | 
		
	
		
			
				|  |  |  |  |       return true | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   for id, actions := range(policy.NodeActions) { | 
		
	
		
			
				|  |  |  |  |     if id != principal.ID { | 
		
	
		
			
				|  |  |  |  |       continue | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     for _, a := range(actions) { | 
		
	
		
			
				|  |  |  |  |       if a == action { | 
		
	
		
			
				|  |  |  |  |         return true | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return false | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Extension to allow a node to hold ACL policies
 | 
		
	
		
			
				|  |  |  |  | type ACLPolicyExt struct { | 
		
	
		
			
				|  |  |  |  |   Policies map[PolicyType]Policy | 
		
	
	
		
			
				
					|  |  |  | @ -65,6 +296,14 @@ func LoadACLExt(ctx *Context, data []byte) (Extension, error) { | 
		
	
		
			
				|  |  |  |  |   }, nil | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NodeList(nodes ...*Node) NodeMap { | 
		
	
		
			
				|  |  |  |  |   m := NodeMap{} | 
		
	
		
			
				|  |  |  |  |   for _, node := range(nodes) { | 
		
	
		
			
				|  |  |  |  |     m[node.ID] = node | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return m | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewACLExt(delegations NodeMap) *ACLExt { | 
		
	
		
			
				|  |  |  |  |   if delegations == nil { | 
		
	
		
			
				|  |  |  |  |     delegations = NodeMap{} | 
		
	
	
		
			
				
					|  |  |  | @ -98,7 +337,6 @@ func (ext *ACLExt) Type() ExtType { | 
		
	
		
			
				|  |  |  |  | type PolicyLoadFunc func(*Context, []byte) (Policy, error) | 
		
	
		
			
				|  |  |  |  | type PolicyInfo struct { | 
		
	
		
			
				|  |  |  |  |   Load PolicyLoadFunc | 
		
	
		
			
				|  |  |  |  |   Type PolicyType | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type ACLPolicyExtContext struct { | 
		
	
	
		
			
				
					|  |  |  | @ -106,10 +344,22 @@ type ACLPolicyExtContext struct { | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewACLPolicyExtContext() *ACLPolicyExtContext { | 
		
	
		
			
				|  |  |  |  |   return nil | 
		
	
		
			
				|  |  |  |  |   return &ACLPolicyExtContext{ | 
		
	
		
			
				|  |  |  |  |     Types: map[PolicyType]PolicyInfo{ | 
		
	
		
			
				|  |  |  |  |       PerNodePolicyType: PolicyInfo{ | 
		
	
		
			
				|  |  |  |  |         Load: LoadPerNodePolicy, | 
		
	
		
			
				|  |  |  |  |       }, | 
		
	
		
			
				|  |  |  |  |       ParentOfPolicyType: PolicyInfo{ | 
		
	
		
			
				|  |  |  |  |         Load: LoadParentOfPolicy, | 
		
	
		
			
				|  |  |  |  |       }, | 
		
	
		
			
				|  |  |  |  |       ChildOfPolicyType: PolicyInfo{ | 
		
	
		
			
				|  |  |  |  |         Load: LoadChildOfPolicy, | 
		
	
		
			
				|  |  |  |  |       }, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (ext ACLPolicyExt) Serialize() ([]byte, error) { | 
		
	
		
			
				|  |  |  |  | func (ext *ACLPolicyExt) Serialize() ([]byte, error) { | 
		
	
		
			
				|  |  |  |  |   policies := map[string][]byte{} | 
		
	
		
			
				|  |  |  |  |   for name, policy := range(ext.Policies) { | 
		
	
		
			
				|  |  |  |  |     ser, err := policy.Serialize() | 
		
	
	
		
			
				
					|  |  |  | @ -126,10 +376,20 @@ func (ext ACLPolicyExt) Serialize() ([]byte, error) { | 
		
	
		
			
				|  |  |  |  |   }, "", "  ") | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (ext ACLPolicyExt) Process(context *StateContext, node *Node, signal GraphSignal) error { | 
		
	
		
			
				|  |  |  |  | func (ext *ACLPolicyExt) Process(context *StateContext, node *Node, signal GraphSignal) error { | 
		
	
		
			
				|  |  |  |  |   return nil | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewACLPolicyExt(policies map[PolicyType]Policy) *ACLPolicyExt { | 
		
	
		
			
				|  |  |  |  |   if policies == nil { | 
		
	
		
			
				|  |  |  |  |     policies = map[PolicyType]Policy{} | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return &ACLPolicyExt{ | 
		
	
		
			
				|  |  |  |  |     Policies: policies, | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func LoadACLPolicyExt(ctx *Context, data []byte) (Extension, error) { | 
		
	
		
			
				|  |  |  |  |   var j struct { | 
		
	
		
			
				|  |  |  |  |     Policies map[string][]byte `json:"policies"` | 
		
	
	
		
			
				
					|  |  |  | @ -154,32 +414,22 @@ func LoadACLPolicyExt(ctx *Context, data []byte) (Extension, error) { | 
		
	
		
			
				|  |  |  |  |     policies[PolicyType(name)] = policy | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return ACLPolicyExt{ | 
		
	
		
			
				|  |  |  |  |     Policies: policies, | 
		
	
		
			
				|  |  |  |  |   }, nil | 
		
	
		
			
				|  |  |  |  |   return NewACLPolicyExt(policies), nil | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | const ACLPolicyExtType = ExtType("ACL_POLICIES") | 
		
	
		
			
				|  |  |  |  | func (ext ACLPolicyExt) Type() ExtType { | 
		
	
		
			
				|  |  |  |  | func (ext *ACLPolicyExt) Type() ExtType { | 
		
	
		
			
				|  |  |  |  |   return ACLPolicyExtType | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Check if the extension allows the principal to perform action on node
 | 
		
	
		
			
				|  |  |  |  | func (ext ACLPolicyExt) Allows(context *StateContext, principal *Node, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  | func (ext *ACLPolicyExt) Allows(context *StateContext, principal *Node, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  |   context.Graph.Log.Logf("policy", "POLICY_EXT_ALLOWED: %+v", ext) | 
		
	
		
			
				|  |  |  |  |   for _, policy := range(ext.Policies) { | 
		
	
		
			
				|  |  |  |  |     context.Graph.Log.Logf("policy", "POLICY_CHECK_POLICY: %+v", policy) | 
		
	
		
			
				|  |  |  |  |     if policy.Allows(context, principal, action, node) == true { | 
		
	
		
			
				|  |  |  |  |       return true | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return false | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy AllNodesPolicy) Allows(context *StateContext, principal *Node, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  |   for _, a := range(policy.Actions) { | 
		
	
		
			
				|  |  |  |  |     if a == action { | 
		
	
		
			
				|  |  |  |  |       return true | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return false | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | 
 |