|  |  |  | @ -7,57 +7,90 @@ import ( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type Policy interface { | 
		
	
		
			
				|  |  |  |  |   Serializable[PolicyType] | 
		
	
		
			
				|  |  |  |  |   Allows(context *StateContext, principal_id NodeID, action string, node *Node) bool | 
		
	
		
			
				|  |  |  |  |   Allows(context *StateContext, principal_id NodeID, action string, node *Node) error | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | //TODO
 | 
		
	
		
			
				|  |  |  |  | func (policy *AllNodesPolicy) Allows(context *StateContext, principal_id NodeID, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  | //TODO: Update with change from principal *Node to principal_id so sane policies can still be made
 | 
		
	
		
			
				|  |  |  |  | func (policy *AllNodesPolicy) Allows(context *StateContext, principal_id NodeID, action string, node *Node) error { | 
		
	
		
			
				|  |  |  |  |   return policy.Actions.Allows(action) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy *RequirementOfPolicy) Allows(context *StateContext, principal_id NodeID, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  |   return false | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy *PerNodePolicy) Allows(context *StateContext, principal_id NodeID, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  | func (policy *PerNodePolicy) Allows(context *StateContext, principal_id NodeID, action string, node *Node) error { | 
		
	
		
			
				|  |  |  |  |   for id, actions := range(policy.NodeActions) { | 
		
	
		
			
				|  |  |  |  |     if id != principal_id { | 
		
	
		
			
				|  |  |  |  |       continue | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     for _, a := range(actions) { | 
		
	
		
			
				|  |  |  |  |       if a == action { | 
		
	
		
			
				|  |  |  |  |         return true | 
		
	
		
			
				|  |  |  |  |         return nil | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return false | 
		
	
		
			
				|  |  |  |  |   return fmt.Errorf("%s is not in per node policy of %s", principal_id, node.ID) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy *ParentOfPolicy) Allows(context *StateContext, principal_id NodeID, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  |   return false | 
		
	
		
			
				|  |  |  |  | func (policy *RequirementOfPolicy) Allows(context *StateContext, principal_id NodeID, action string, node *Node) error { | 
		
	
		
			
				|  |  |  |  |   lockable_ext, err := GetExt[*LockableExt](node) | 
		
	
		
			
				|  |  |  |  |   if err != nil { | 
		
	
		
			
				|  |  |  |  |     return err | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   for id, _ := range(lockable_ext.Requirements) { | 
		
	
		
			
				|  |  |  |  |     if id == principal_id { | 
		
	
		
			
				|  |  |  |  |       return policy.Actions.Allows(action) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return fmt.Errorf("%s is not a requirement of %s", principal_id, node.ID) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy *ChildOfPolicy) Allows(context *StateContext, principal_id NodeID, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  |   return false | 
		
	
		
			
				|  |  |  |  | func (policy *ParentOfPolicy) Allows(context *StateContext, principal_id NodeID, action string, node *Node) error { | 
		
	
		
			
				|  |  |  |  |   thread_ext, err := GetExt[*ThreadExt](node) | 
		
	
		
			
				|  |  |  |  |   if err != nil { | 
		
	
		
			
				|  |  |  |  |     return err | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if thread_ext.Parent != nil { | 
		
	
		
			
				|  |  |  |  |     if thread_ext.Parent.ID == principal_id { | 
		
	
		
			
				|  |  |  |  |       return policy.Actions.Allows(action) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return fmt.Errorf("%s is not a parent of %s", principal_id, node.ID) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (policy *ChildOfPolicy) Allows(context *StateContext, principal_id NodeID, action string, node *Node) error { | 
		
	
		
			
				|  |  |  |  |   thread_ext, err := GetExt[*ThreadExt](node) | 
		
	
		
			
				|  |  |  |  |   if err != nil { | 
		
	
		
			
				|  |  |  |  |     return err | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   for id, _ := range(thread_ext.Children) { | 
		
	
		
			
				|  |  |  |  |     if id == principal_id { | 
		
	
		
			
				|  |  |  |  |       return policy.Actions.Allows(action) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return fmt.Errorf("%s is not a child of %s", principal_id, node.ID) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | const RequirementOfPolicyType = PolicyType("REQUIREMENT_OF") | 
		
	
		
			
				|  |  |  |  | type RequirementOfPolicy struct { | 
		
	
		
			
				|  |  |  |  |   PerNodePolicy | 
		
	
		
			
				|  |  |  |  |   AllNodesPolicy | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | func (policy *RequirementOfPolicy) Type() PolicyType { | 
		
	
		
			
				|  |  |  |  |   return RequirementOfPolicyType | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewRequirementOfPolicy(nodes NodeActions) RequirementOfPolicy { | 
		
	
		
			
				|  |  |  |  | func NewRequirementOfPolicy(actions Actions) RequirementOfPolicy { | 
		
	
		
			
				|  |  |  |  |   return RequirementOfPolicy{ | 
		
	
		
			
				|  |  |  |  |     PerNodePolicy: NewPerNodePolicy(nodes), | 
		
	
		
			
				|  |  |  |  |     AllNodesPolicy: NewAllNodesPolicy(actions), | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | const ChildOfPolicyType = PolicyType("CHILD_OF") | 
		
	
		
			
				|  |  |  |  | type ChildOfPolicy struct { | 
		
	
		
			
				|  |  |  |  |   PerNodePolicy | 
		
	
		
			
				|  |  |  |  |   AllNodesPolicy | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | func (policy *ChildOfPolicy) Type() PolicyType { | 
		
	
		
			
				|  |  |  |  |   return ChildOfPolicyType | 
		
	
	
		
			
				
					|  |  |  | @ -65,17 +98,34 @@ func (policy *ChildOfPolicy) Type() PolicyType { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type Actions []string | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (actions Actions) Allows(action string) bool { | 
		
	
		
			
				|  |  |  |  | func (actions Actions) Allows(action string) error { | 
		
	
		
			
				|  |  |  |  |   for _, a := range(actions) { | 
		
	
		
			
				|  |  |  |  |     if a == action { | 
		
	
		
			
				|  |  |  |  |       return true | 
		
	
		
			
				|  |  |  |  |       return nil | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return false | 
		
	
		
			
				|  |  |  |  |   return fmt.Errorf("%s not in allows list", action) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type NodeActions map[NodeID]Actions | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type AllNodesPolicyJSON struct { | 
		
	
		
			
				|  |  |  |  |   Actions Actions `json:"actions"` | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func AllNodesPolicyLoad(init_fn func(Actions)(Policy, error)) func(*Context, []byte)(Policy, error) { | 
		
	
		
			
				|  |  |  |  |   return func(ctx *Context, data []byte)(Policy, error){ | 
		
	
		
			
				|  |  |  |  |     var j AllNodesPolicyJSON | 
		
	
		
			
				|  |  |  |  |     err := json.Unmarshal(data, &j) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if err != nil { | 
		
	
		
			
				|  |  |  |  |       return nil, err | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     return init_fn(j.Actions) | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func PerNodePolicyLoad(init_fn func(NodeActions)(Policy, error)) func(*Context, []byte)(Policy, error) { | 
		
	
		
			
				|  |  |  |  |   return func(ctx *Context, data []byte)(Policy, error){ | 
		
	
		
			
				|  |  |  |  |     var j PerNodePolicyJSON | 
		
	
	
		
			
				
					|  |  |  | @ -103,23 +153,23 @@ func PerNodePolicyLoad(init_fn func(NodeActions)(Policy, error)) func(*Context, | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewChildOfPolicy(node_actions NodeActions) ChildOfPolicy { | 
		
	
		
			
				|  |  |  |  | func NewChildOfPolicy(actions Actions) ChildOfPolicy { | 
		
	
		
			
				|  |  |  |  |   return ChildOfPolicy{ | 
		
	
		
			
				|  |  |  |  |     PerNodePolicy: NewPerNodePolicy(node_actions), | 
		
	
		
			
				|  |  |  |  |     AllNodesPolicy: NewAllNodesPolicy(actions), | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | const ParentOfPolicyType = PolicyType("PARENT_OF") | 
		
	
		
			
				|  |  |  |  | type ParentOfPolicy struct { | 
		
	
		
			
				|  |  |  |  |   PerNodePolicy | 
		
	
		
			
				|  |  |  |  |   AllNodesPolicy | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | func (policy *ParentOfPolicy) Type() PolicyType { | 
		
	
		
			
				|  |  |  |  |   return ParentOfPolicyType | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewParentOfPolicy(node_actions NodeActions) ParentOfPolicy { | 
		
	
		
			
				|  |  |  |  | func NewParentOfPolicy(actions Actions) ParentOfPolicy { | 
		
	
		
			
				|  |  |  |  |   return ParentOfPolicy{ | 
		
	
		
			
				|  |  |  |  |     PerNodePolicy: NewPerNodePolicy(node_actions), | 
		
	
		
			
				|  |  |  |  |     AllNodesPolicy: NewAllNodesPolicy(actions), | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -168,7 +218,7 @@ func NewAllNodesPolicy(actions Actions) AllNodesPolicy { | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type AllNodesPolicy struct { | 
		
	
		
			
				|  |  |  |  |   Actions Actions `json:"actions"` | 
		
	
		
			
				|  |  |  |  |   Actions Actions | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | const AllNodesPolicyType = PolicyType("ALL_NODES") | 
		
	
	
		
			
				
					|  |  |  | @ -181,7 +231,7 @@ func (policy *AllNodesPolicy) Serialize() ([]byte, error) { | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Extension to allow a node to hold ACL policies
 | 
		
	
		
			
				|  |  |  |  | type ACLPolicyExt struct { | 
		
	
		
			
				|  |  |  |  | type ACLExt struct { | 
		
	
		
			
				|  |  |  |  |   Policies map[PolicyType]Policy | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -199,13 +249,19 @@ type PolicyInfo struct { | 
		
	
		
			
				|  |  |  |  |   Load PolicyLoadFunc | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | type ACLPolicyExtContext struct { | 
		
	
		
			
				|  |  |  |  | type ACLExtContext struct { | 
		
	
		
			
				|  |  |  |  |   Types map[PolicyType]PolicyInfo | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewACLPolicyExtContext() *ACLPolicyExtContext { | 
		
	
		
			
				|  |  |  |  |   return &ACLPolicyExtContext{ | 
		
	
		
			
				|  |  |  |  | func NewACLExtContext() *ACLExtContext { | 
		
	
		
			
				|  |  |  |  |   return &ACLExtContext{ | 
		
	
		
			
				|  |  |  |  |     Types: map[PolicyType]PolicyInfo{ | 
		
	
		
			
				|  |  |  |  |       AllNodesPolicyType: PolicyInfo{ | 
		
	
		
			
				|  |  |  |  |         Load: AllNodesPolicyLoad(func(actions Actions)(Policy, error){ | 
		
	
		
			
				|  |  |  |  |           policy := NewAllNodesPolicy(actions) | 
		
	
		
			
				|  |  |  |  |           return &policy, nil | 
		
	
		
			
				|  |  |  |  |         }), | 
		
	
		
			
				|  |  |  |  |       }, | 
		
	
		
			
				|  |  |  |  |       PerNodePolicyType: PolicyInfo{ | 
		
	
		
			
				|  |  |  |  |         Load: PerNodePolicyLoad(func(nodes NodeActions)(Policy,error){ | 
		
	
		
			
				|  |  |  |  |           policy := NewPerNodePolicy(nodes) | 
		
	
	
		
			
				
					|  |  |  | @ -213,38 +269,28 @@ func NewACLPolicyExtContext() *ACLPolicyExtContext { | 
		
	
		
			
				|  |  |  |  |         }), | 
		
	
		
			
				|  |  |  |  |       }, | 
		
	
		
			
				|  |  |  |  |       ParentOfPolicyType: PolicyInfo{ | 
		
	
		
			
				|  |  |  |  |         Load: PerNodePolicyLoad(func(nodes NodeActions)(Policy,error){ | 
		
	
		
			
				|  |  |  |  |           policy := NewParentOfPolicy(nodes) | 
		
	
		
			
				|  |  |  |  |         Load: AllNodesPolicyLoad(func(actions Actions)(Policy, error){ | 
		
	
		
			
				|  |  |  |  |           policy := NewParentOfPolicy(actions) | 
		
	
		
			
				|  |  |  |  |           return &policy, nil | 
		
	
		
			
				|  |  |  |  |         }), | 
		
	
		
			
				|  |  |  |  |       }, | 
		
	
		
			
				|  |  |  |  |       ChildOfPolicyType: PolicyInfo{ | 
		
	
		
			
				|  |  |  |  |         Load: PerNodePolicyLoad(func(nodes NodeActions)(Policy,error){ | 
		
	
		
			
				|  |  |  |  |           policy := NewChildOfPolicy(nodes) | 
		
	
		
			
				|  |  |  |  |         Load: AllNodesPolicyLoad(func(actions Actions)(Policy, error){ | 
		
	
		
			
				|  |  |  |  |           policy := NewChildOfPolicy(actions) | 
		
	
		
			
				|  |  |  |  |           return &policy, nil | 
		
	
		
			
				|  |  |  |  |         }), | 
		
	
		
			
				|  |  |  |  |       }, | 
		
	
		
			
				|  |  |  |  |       RequirementOfPolicyType: PolicyInfo{ | 
		
	
		
			
				|  |  |  |  |         Load: PerNodePolicyLoad(func(nodes NodeActions)(Policy,error){ | 
		
	
		
			
				|  |  |  |  |           policy := NewRequirementOfPolicy(nodes) | 
		
	
		
			
				|  |  |  |  |         Load: AllNodesPolicyLoad(func(actions Actions)(Policy, error){ | 
		
	
		
			
				|  |  |  |  |           policy := NewRequirementOfPolicy(actions) | 
		
	
		
			
				|  |  |  |  |           return &policy, nil | 
		
	
		
			
				|  |  |  |  |         }), | 
		
	
		
			
				|  |  |  |  |       }, | 
		
	
		
			
				|  |  |  |  |       AllNodesPolicyType: PolicyInfo{ | 
		
	
		
			
				|  |  |  |  |         Load: func(ctx *Context, data []byte) (Policy, error) { | 
		
	
		
			
				|  |  |  |  |           var policy AllNodesPolicy | 
		
	
		
			
				|  |  |  |  |           err := json.Unmarshal(data, &policy) | 
		
	
		
			
				|  |  |  |  |           if err != nil { | 
		
	
		
			
				|  |  |  |  |             return nil, err | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |           return &policy, nil | 
		
	
		
			
				|  |  |  |  |         }, | 
		
	
		
			
				|  |  |  |  |       }, | 
		
	
		
			
				|  |  |  |  |     }, | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (ext *ACLPolicyExt) Serialize() ([]byte, error) { | 
		
	
		
			
				|  |  |  |  | func (ext *ACLExt) Serialize() ([]byte, error) { | 
		
	
		
			
				|  |  |  |  |   policies := map[string][]byte{} | 
		
	
		
			
				|  |  |  |  |   for name, policy := range(ext.Policies) { | 
		
	
		
			
				|  |  |  |  |     ser, err := policy.Serialize() | 
		
	
	
		
			
				
					|  |  |  | @ -261,11 +307,11 @@ func (ext *ACLPolicyExt) Serialize() ([]byte, error) { | 
		
	
		
			
				|  |  |  |  |   }, "", "  ") | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func (ext *ACLPolicyExt) Process(context *StateContext, node *Node, signal Signal) error { | 
		
	
		
			
				|  |  |  |  | func (ext *ACLExt) Process(context *StateContext, node *Node, signal Signal) error { | 
		
	
		
			
				|  |  |  |  |   return nil | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func NewACLPolicyExt(policies map[PolicyType]Policy) *ACLPolicyExt { | 
		
	
		
			
				|  |  |  |  | func NewACLExt(policies map[PolicyType]Policy) *ACLExt { | 
		
	
		
			
				|  |  |  |  |   if policies == nil { | 
		
	
		
			
				|  |  |  |  |     policies = map[PolicyType]Policy{} | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
	
		
			
				
					|  |  |  | @ -276,12 +322,12 @@ func NewACLPolicyExt(policies map[PolicyType]Policy) *ACLPolicyExt { | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return &ACLPolicyExt{ | 
		
	
		
			
				|  |  |  |  |   return &ACLExt{ | 
		
	
		
			
				|  |  |  |  |     Policies: policies, | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | func LoadACLPolicyExt(ctx *Context, data []byte) (Extension, error) { | 
		
	
		
			
				|  |  |  |  | func LoadACLExt(ctx *Context, data []byte) (Extension, error) { | 
		
	
		
			
				|  |  |  |  |   var j struct { | 
		
	
		
			
				|  |  |  |  |     Policies map[string][]byte `json:"policies"` | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
	
		
			
				
					|  |  |  | @ -291,7 +337,7 @@ func LoadACLPolicyExt(ctx *Context, data []byte) (Extension, error) { | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   policies := map[PolicyType]Policy{} | 
		
	
		
			
				|  |  |  |  |   acl_ctx := ctx.ExtByType(ACLPolicyExtType).Data.(*ACLPolicyExtContext) | 
		
	
		
			
				|  |  |  |  |   acl_ctx := ctx.ExtByType(ACLExtType).Data.(*ACLExtContext) | 
		
	
		
			
				|  |  |  |  |   for name, ser := range(j.Policies) { | 
		
	
		
			
				|  |  |  |  |     policy_def, exists := acl_ctx.Types[PolicyType(name)] | 
		
	
		
			
				|  |  |  |  |     if exists == false { | 
		
	
	
		
			
				
					|  |  |  | @ -305,22 +351,24 @@ func LoadACLPolicyExt(ctx *Context, data []byte) (Extension, error) { | 
		
	
		
			
				|  |  |  |  |     policies[PolicyType(name)] = policy | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return NewACLPolicyExt(policies), nil | 
		
	
		
			
				|  |  |  |  |   return NewACLExt(policies), nil | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | const ACLPolicyExtType = ExtType("ACL_POLICIES") | 
		
	
		
			
				|  |  |  |  | func (ext *ACLPolicyExt) Type() ExtType { | 
		
	
		
			
				|  |  |  |  |   return ACLPolicyExtType | 
		
	
		
			
				|  |  |  |  | const ACLExtType = ExtType("ACL_POLICIES") | 
		
	
		
			
				|  |  |  |  | func (ext *ACLExt) Type() ExtType { | 
		
	
		
			
				|  |  |  |  |   return ACLExtType | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Check if the extension allows the principal to perform action on node
 | 
		
	
		
			
				|  |  |  |  | func (ext *ACLPolicyExt) Allows(context *StateContext, principal_id NodeID, action string, node *Node) bool { | 
		
	
		
			
				|  |  |  |  | func (ext *ACLExt) Allows(context *StateContext, principal_id NodeID, action string, node *Node) error { | 
		
	
		
			
				|  |  |  |  |   context.Graph.Log.Logf("policy", "POLICY_EXT_ALLOWED: %+v", ext) | 
		
	
		
			
				|  |  |  |  |   errs := []error{} | 
		
	
		
			
				|  |  |  |  |   for _, policy := range(ext.Policies) { | 
		
	
		
			
				|  |  |  |  |     context.Graph.Log.Logf("policy", "POLICY_CHECK_POLICY: %+v", policy) | 
		
	
		
			
				|  |  |  |  |     if policy.Allows(context, principal_id, action, node) == true { | 
		
	
		
			
				|  |  |  |  |       return true | 
		
	
		
			
				|  |  |  |  |     err := policy.Allows(context, principal_id, action, node) | 
		
	
		
			
				|  |  |  |  |     if err == nil { | 
		
	
		
			
				|  |  |  |  |       return nil | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     errs = append(errs, err) | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return false | 
		
	
		
			
				|  |  |  |  |   return fmt.Errorf("POLICY_CHECK_ERRORS: %s %s.%s - %+v", principal_id, node.ID, action, errs) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					|  |  |  | 
 |