3
0

Add actionlog policies

This commit is contained in:
Denis Arh
2020-06-01 23:12:46 +02:00
parent 686b10fd1b
commit f05d2fc257
3 changed files with 242 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
package actionlog
func MakeDebugPolicy() policyMatcher {
return NewPolicyAll()
}
func MakeProductionPolicy() policyMatcher {
return NewPolicyAll(
// Ignore debug actions
NewPolicyNegate(NewPolicyMatchSeverity(Debug)),
)
}
+118
View File
@@ -0,0 +1,118 @@
package actionlog
import "github.com/cortezaproject/corteza-server/pkg/slice"
type (
policyMatcher interface {
Match(*Action) bool
}
logPolicyAny struct {
mm []policyMatcher
}
logPolicyAll struct {
mm []policyMatcher
}
logPolicyNegate struct {
m policyMatcher
}
logPolicyMatchRequestOrigin struct {
origin map[string]bool
}
logPolicyMatchResource struct {
resources map[string]bool
}
logPolicyMatchAction struct {
actions map[string]bool
}
logPolicyMatchSeverity struct {
severities map[Severity]bool
}
)
// NewPolicyAny returns policy where at least one of the subpolicies should match
func NewPolicyAny(mm ...policyMatcher) policyMatcher {
return &logPolicyAny{mm: mm}
}
func (p logPolicyAny) Match(a *Action) bool {
for _, m := range p.mm {
if m.Match(a) {
return true
}
}
return false
}
// NewPolicyAll returns policy where all subpolicies should match
func NewPolicyAll(mm ...policyMatcher) policyMatcher {
return &logPolicyAll{mm: mm}
}
func (p logPolicyAll) Match(a *Action) bool {
for _, m := range p.mm {
if !m.Match(a) {
return false
}
}
return true
}
// NewPolicyNegate negates passed policy
func NewPolicyNegate(m policyMatcher) policyMatcher {
return &logPolicyNegate{m: m}
}
func (p logPolicyNegate) Match(a *Action) bool {
return !p.m.Match(a)
}
// NewPolicyMatchResource matches resources
func NewPolicyMatchResource(rr ...string) policyMatcher {
return &logPolicyMatchResource{resources: slice.ToStringBoolMap(rr)}
}
func (p logPolicyMatchResource) Match(a *Action) bool {
return p.resources[a.Resource]
}
// NewPolicyMatchAction matches action
func NewPolicyMatchAction(aa ...string) policyMatcher {
return &logPolicyMatchAction{actions: slice.ToStringBoolMap(aa)}
}
func (p logPolicyMatchAction) Match(a *Action) bool {
return p.actions[a.Action]
}
// NewPolicyMatchSeverity matches severity
func NewPolicyMatchSeverity(ss ...Severity) policyMatcher {
var p = &logPolicyMatchSeverity{severities: make(map[Severity]bool)}
for _, s := range ss {
p.severities[s] = true
}
return p
}
func (p logPolicyMatchSeverity) Match(a *Action) bool {
return p.severities[a.Severity]
}
// NewPolicyMatchRequestOrigin matches resources
func NewPolicyMatchRequestOrigin(rr ...string) policyMatcher {
return &logPolicyMatchRequestOrigin{origin: slice.ToStringBoolMap(rr)}
}
func (p logPolicyMatchRequestOrigin) Match(a *Action) bool {
return p.origin[a.RequestOrigin]
}
+112
View File
@@ -0,0 +1,112 @@
package actionlog
import (
"testing"
)
func TestPolicyMatchers(t *testing.T) {
tests := []struct {
name string
actn *Action
mtch policyMatcher
want bool
}{
{
"simple any",
&Action{},
NewPolicyAny(),
false,
},
{
"simple all",
&Action{},
NewPolicyAll(),
true,
},
{
"should match resource",
&Action{Resource: "foo"},
NewPolicyMatchResource("foo"),
true,
},
{
"should not match resource",
&Action{Resource: "bar"},
NewPolicyMatchResource("foo"),
false,
},
{
"should match one of resource",
&Action{Resource: "baz"},
NewPolicyMatchResource("foo", "bar", "baz"),
true,
},
{
"should match action",
&Action{Action: "foo"},
NewPolicyMatchAction("foo"),
true,
},
{
"should not match action",
&Action{Action: "bar"},
NewPolicyMatchAction("foo"),
false,
},
{
"should match one of action",
&Action{Action: "baz"},
NewPolicyMatchAction("foo", "bar", "baz"),
true,
},
{
"should match severity",
&Action{Severity: Emergency},
NewPolicyMatchSeverity(Emergency),
true,
},
{
"should not match severity",
&Action{Severity: Debug},
NewPolicyMatchSeverity(Alert),
false,
},
{
"should match one of severity",
&Action{Severity: Warning},
NewPolicyMatchSeverity(Emergency, Debug, Warning),
true,
},
{
"complex match",
&Action{Severity: Warning, Resource: "foo", Action: "do"},
NewPolicyAll(
NewPolicyMatchResource("foo"),
NewPolicyMatchAction("do"),
NewPolicyMatchSeverity(Warning),
),
true,
},
{
"complex miss",
&Action{Severity: Warning, Resource: "bar", Action: "do"},
NewPolicyAll(
NewPolicyMatchResource("foo"),
NewPolicyMatchAction("do"),
NewPolicyMatchSeverity(Warning),
),
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.want != tt.mtch.Match(tt.actn) {
if tt.want {
t.Errorf("expecting to match")
} else {
t.Errorf("expecting not to match ")
}
}
})
}
}