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")
func NewSimpleListener(ctx *Context, buffer int) (*Node, *ListenerExt) {
policy := NewAllNodesPolicy([]Action{Action("status")})
policy := NewAllNodesPolicy(Actions{MakeAction("status")})
listener_extension := NewListenerExt(buffer)
listener := NewNode(ctx,
RandID(),

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

@ -22,7 +22,6 @@ type Policy interface {
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 {
return policy.Actions.Allows(action)
}
@ -32,11 +31,7 @@ func (policy *PerNodePolicy) Allows(principal_id NodeID, action Action, node *No
if id != principal_id {
continue
}
for _, a := range(actions) {
if a == action {
return nil
}
}
return actions.Allows(action)
}
return fmt.Errorf("%s is not in per node policy of %s", principal_id, node.ID)
}
@ -72,16 +67,8 @@ func NewRequirementOfPolicy(actions Actions) RequirementOfPolicy {
func MergeActions(first Actions, second Actions) Actions {
ret := second
for _, action := range(first) {
found := false
for _, a := range(second) {
if a == action {
break
}
}
if found == false {
ret = append(ret, action)
}
}
return ret
}
@ -114,12 +101,45 @@ func (policy *RequirementOfPolicy) Merge(p Policy) 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
func (actions Actions) Allows(action Action) error {
for _, a := range(actions) {
if a == action {
if a.Allows(action) == true {
return nil
}
}

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