105 lines
2.9 KiB
Go
105 lines
2.9 KiB
Go
package csprofiles
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/antonmedv/expr"
|
|
"github.com/antonmedv/expr/vm"
|
|
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
|
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
|
|
"github.com/crowdsecurity/crowdsec/pkg/models"
|
|
)
|
|
|
|
var (
|
|
scope = "Country"
|
|
typ = "ban"
|
|
simulated = false
|
|
duration = "1h"
|
|
|
|
value = "CH"
|
|
scenario = "ssh-bf"
|
|
)
|
|
|
|
func TestEvaluateProfile(t *testing.T) {
|
|
type args struct {
|
|
profile *csconfig.ProfileCfg
|
|
Alert *models.Alert
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
expectedDecisionCount int // count of expected decisions
|
|
expectedMatchStatus bool
|
|
}{
|
|
{
|
|
name: "simple pass single expr",
|
|
args: args{
|
|
profile: &csconfig.ProfileCfg{
|
|
Filters: []string{fmt.Sprintf("Alert.GetScenario() == \"%s\"", scenario)},
|
|
RuntimeFilters: []*vm.Program{},
|
|
},
|
|
Alert: &models.Alert{Remediation: true, Scenario: &scenario},
|
|
},
|
|
expectedDecisionCount: 0,
|
|
expectedMatchStatus: true,
|
|
},
|
|
{
|
|
name: "simple fail single expr",
|
|
args: args{
|
|
profile: &csconfig.ProfileCfg{
|
|
Filters: []string{"Alert.GetScenario() == \"Foo\""},
|
|
RuntimeFilters: []*vm.Program{},
|
|
},
|
|
Alert: &models.Alert{Remediation: true},
|
|
},
|
|
expectedDecisionCount: 0,
|
|
expectedMatchStatus: false,
|
|
},
|
|
{
|
|
name: "1 expr fail 1 expr pass should still eval to match",
|
|
args: args{
|
|
profile: &csconfig.ProfileCfg{
|
|
Filters: []string{"1==1", "1!=1"},
|
|
RuntimeFilters: []*vm.Program{},
|
|
},
|
|
Alert: &models.Alert{Remediation: true},
|
|
},
|
|
expectedDecisionCount: 0,
|
|
expectedMatchStatus: true,
|
|
},
|
|
{
|
|
name: "simple filter with 2 decision",
|
|
args: args{
|
|
profile: &csconfig.ProfileCfg{
|
|
Filters: []string{"1==1"},
|
|
RuntimeFilters: []*vm.Program{},
|
|
Decisions: []models.Decision{
|
|
{Type: &typ, Scope: &scope, Simulated: &simulated, Duration: &duration},
|
|
{Type: &typ, Scope: &scope, Simulated: &simulated, Duration: &duration},
|
|
},
|
|
},
|
|
Alert: &models.Alert{Remediation: true, Scenario: &scenario, Source: &models.Source{Value: &value}},
|
|
},
|
|
expectedDecisionCount: 2,
|
|
expectedMatchStatus: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
for _, filter := range tt.args.profile.Filters {
|
|
runtimeFilter, _ := expr.Compile(filter, expr.Env(exprhelpers.GetExprEnv(map[string]interface{}{"Alert": &models.Alert{}})))
|
|
tt.args.profile.RuntimeFilters = append(tt.args.profile.RuntimeFilters, runtimeFilter)
|
|
}
|
|
got, got1, _ := EvaluateProfile(tt.args.profile, tt.args.Alert)
|
|
if !reflect.DeepEqual(len(got), tt.expectedDecisionCount) {
|
|
t.Errorf("EvaluateProfile() got = %+v, want %+v", got, tt.expectedDecisionCount)
|
|
}
|
|
if got1 != tt.expectedMatchStatus {
|
|
t.Errorf("EvaluateProfile() got1 = %v, want %v", got1, tt.expectedMatchStatus)
|
|
}
|
|
})
|
|
}
|
|
}
|