Reworked actions to be lists of parts, and added wildcards for both multi-level and single-level

gql_cataclysm
noah metz 2023-07-28 10:04:31 -06:00
parent 27687add1b
commit b3de3144cc
4 changed files with 56 additions and 25 deletions

@ -84,7 +84,7 @@ func (t * GraphTester) CheckForNone(listener *ListenerExt, str string) {
const SimpleListenerNodeType = NodeType("SIMPLE_LISTENER") const SimpleListenerNodeType = NodeType("SIMPLE_LISTENER")
func NewSimpleListener(ctx *Context, buffer int) (*Node, *ListenerExt) { func NewSimpleListener(ctx *Context, buffer int) (*Node, *ListenerExt) {
policy := NewAllNodesPolicy([]Action{Action("status")}) policy := NewAllNodesPolicy(Actions{MakeAction("status")})
listener_extension := NewListenerExt(buffer) listener_extension := NewListenerExt(buffer)
listener := NewNode(ctx, listener := NewNode(ctx,
RandID(), RandID(),

@ -16,8 +16,9 @@ func lockableTestContext(t *testing.T, logs []string) *Context {
} }
var link_policy = NewAllNodesPolicy([]Action{Action(LinkSignalType), Action(StatusSignalType)}) //TODO: add new finer grained signals, and probably add wildcards to not have to deal with annoying acl policies
var lock_policy = NewAllNodesPolicy([]Action{Action(LockSignalType)}) var link_policy = NewAllNodesPolicy(Actions{MakeAction(LinkSignalType, "*"), MakeAction(StatusSignalType, "+")})
var lock_policy = NewAllNodesPolicy(Actions{MakeAction(LockSignalType, "*")})
func TestLink(t *testing.T) { func TestLink(t *testing.T) {
ctx := lockableTestContext(t, []string{"lockable"}) ctx := lockableTestContext(t, []string{"lockable"})

@ -22,7 +22,6 @@ type Policy interface {
Merge(Policy) Policy Merge(Policy) Policy
} }
//TODO: Update with change from principal *Node to principal_id so sane policies can still be made
func (policy *AllNodesPolicy) Allows(principal_id NodeID, action Action, node *Node) error { func (policy *AllNodesPolicy) Allows(principal_id NodeID, action Action, node *Node) error {
return policy.Actions.Allows(action) return policy.Actions.Allows(action)
} }
@ -32,11 +31,7 @@ func (policy *PerNodePolicy) Allows(principal_id NodeID, action Action, node *No
if id != principal_id { if id != principal_id {
continue continue
} }
for _, a := range(actions) { return actions.Allows(action)
if a == action {
return nil
}
}
} }
return fmt.Errorf("%s is not in per node policy of %s", principal_id, node.ID) return fmt.Errorf("%s is not in per node policy of %s", principal_id, node.ID)
} }
@ -72,15 +67,7 @@ func NewRequirementOfPolicy(actions Actions) RequirementOfPolicy {
func MergeActions(first Actions, second Actions) Actions { func MergeActions(first Actions, second Actions) Actions {
ret := second ret := second
for _, action := range(first) { for _, action := range(first) {
found := false ret = append(ret, action)
for _, a := range(second) {
if a == action {
break
}
}
if found == false {
ret = append(ret, action)
}
} }
return ret return ret
} }
@ -114,12 +101,45 @@ func (policy *RequirementOfPolicy) Merge(p Policy) Policy {
return policy return policy
} }
type Action string type Action []string
func MakeAction(parts ...interface{}) Action {
action := make(Action, len(parts))
for i, part := range(parts) {
stringer, ok := part.(fmt.Stringer)
if ok == false {
switch p := part.(type) {
case string:
action[i] = p
default:
panic("%s can not be part of an action")
}
} else {
action[i] = stringer.String()
}
}
return action
}
func (action Action) Allows(test Action) bool {
for i, part := range(test) {
if action[i] == part || action[i] == "*" {
continue
} else if action[i] == "+" {
break
} else {
return false
}
}
return true
}
type Actions []Action type Actions []Action
func (actions Actions) Allows(action Action) error { func (actions Actions) Allows(action Action) error {
for _, a := range(actions) { for _, a := range(actions) {
if a == action { if a.Allows(action) == true {
return nil return nil
} }
} }

@ -4,6 +4,13 @@ import (
"encoding/json" "encoding/json"
) )
const (
StopSignalType = SignalType("STOP")
StatusSignalType = SignalType("STATUS")
LinkSignalType = SignalType("LINK")
LockSignalType = SignalType("LOCK")
)
type SignalDirection int type SignalDirection int
const ( const (
Up SignalDirection = iota Up SignalDirection = iota
@ -12,6 +19,9 @@ const (
) )
type SignalType string type SignalType string
func (signal_type SignalType) String() string {
return string(signal_type)
}
type Signal interface { type Signal interface {
Serializable[SignalType] Serializable[SignalType]
@ -29,7 +39,7 @@ func (signal BaseSignal) Type() SignalType {
} }
func (signal BaseSignal) Permission() Action { func (signal BaseSignal) Permission() Action {
return Action(signal.Type()) return MakeAction(signal.Type())
} }
func (signal BaseSignal) Direction() SignalDirection { func (signal BaseSignal) Direction() SignalDirection {
@ -60,7 +70,6 @@ func NewDirectSignal(signal_type SignalType) BaseSignal {
return NewBaseSignal(signal_type, Direct) return NewBaseSignal(signal_type, Direct)
} }
const StopSignalType = SignalType("STOP")
var StopSignal = NewDownSignal(StopSignalType) var StopSignal = NewDownSignal(StopSignalType)
type IDSignal struct { type IDSignal struct {
@ -96,7 +105,6 @@ func (signal StatusSignal) String() string {
return string(ser) return string(ser)
} }
const StatusSignalType = SignalType("STATUS")
func NewStatusSignal(status string, source NodeID) StatusSignal { func NewStatusSignal(status string, source NodeID) StatusSignal {
return StatusSignal{ return StatusSignal{
IDSignal: NewIDSignal(StatusSignalType, Up, source), IDSignal: NewIDSignal(StatusSignalType, Up, source),
@ -104,8 +112,6 @@ func NewStatusSignal(status string, source NodeID) StatusSignal {
} }
} }
const LinkSignalType = SignalType("LINK")
const LockSignalType = SignalType("LOCK")
type StateSignal struct { type StateSignal struct {
BaseSignal BaseSignal
State string `json:"state"` State string `json:"state"`
@ -134,6 +140,10 @@ func NewLockSignal(state string) StateSignal {
} }
} }
func (signal StateSignal) Permission() Action {
return MakeAction(signal.Type(), signal.State)
}
type StartChildSignal struct { type StartChildSignal struct {
IDSignal IDSignal
Action string `json:"action"` Action string `json:"action"`