mirror of
https://github.com/TecharoHQ/anubis.git
synced 2025-08-04 02:08:59 -04:00

* feat(config): add Thresholds to the top level config file Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(config): make String() on ExpressionOrList join the component expressions Signed-off-by: Xe Iaso <me@xeiaso.net> * test(config): ensure unparseable json fails Signed-off-by: Xe Iaso <me@xeiaso.net> * fix(config): if no thresholds are set, use the default thresholds Signed-off-by: Xe Iaso <me@xeiaso.net> * feat(policy): half implement thresholds Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(policy): continue wiring things up Signed-off-by: Xe Iaso <me@xeiaso.net> * feat(lib): wire up thresholds Signed-off-by: Xe Iaso <me@xeiaso.net> * test(lib): handle behavior from legacy configurations Signed-off-by: Xe Iaso <me@xeiaso.net> * docs: document thresholds Signed-off-by: Xe Iaso <me@xeiaso.net> * docs: update CHANGELOG, refer to threshold configuration Signed-off-by: Xe Iaso <me@xeiaso.net> * fix(lib): fix build Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(lib): fix U1000 Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Xe Iaso <me@xeiaso.net> Signed-off-by: Jason Cameron <git@jasoncameron.dev> Co-authored-by: Jason Cameron <git@jasoncameron.dev>
88 lines
2.2 KiB
Go
88 lines
2.2 KiB
Go
package expressions
|
|
|
|
import (
|
|
"math/rand/v2"
|
|
|
|
"github.com/google/cel-go/cel"
|
|
"github.com/google/cel-go/common/types"
|
|
"github.com/google/cel-go/common/types/ref"
|
|
"github.com/google/cel-go/ext"
|
|
)
|
|
|
|
// BotEnvironment creates a new CEL environment, this is the set of
|
|
// variables and functions that are passed into the CEL scope so that
|
|
// Anubis can fail loudly and early when something is invalid instead
|
|
// of blowing up at runtime.
|
|
func BotEnvironment() (*cel.Env, error) {
|
|
return New(
|
|
// Variables exposed to CEL programs:
|
|
cel.Variable("remoteAddress", cel.StringType),
|
|
cel.Variable("host", cel.StringType),
|
|
cel.Variable("method", cel.StringType),
|
|
cel.Variable("userAgent", cel.StringType),
|
|
cel.Variable("path", cel.StringType),
|
|
cel.Variable("query", cel.MapType(cel.StringType, cel.StringType)),
|
|
cel.Variable("headers", cel.MapType(cel.StringType, cel.StringType)),
|
|
)
|
|
}
|
|
|
|
// NewThreshold creates a new CEL environment for threshold checking.
|
|
func ThresholdEnvironment() (*cel.Env, error) {
|
|
return New(
|
|
cel.Variable("weight", cel.IntType),
|
|
)
|
|
}
|
|
|
|
func New(opts ...cel.EnvOption) (*cel.Env, error) {
|
|
args := []cel.EnvOption{
|
|
ext.Strings(
|
|
ext.StringsLocale("en_US"),
|
|
ext.StringsValidateFormatCalls(true),
|
|
),
|
|
|
|
// default all timestamps to UTC
|
|
cel.DefaultUTCTimeZone(true),
|
|
|
|
// Functions exposed to all CEL programs:
|
|
cel.Function("randInt",
|
|
cel.Overload("randInt_int",
|
|
[]*cel.Type{cel.IntType},
|
|
cel.IntType,
|
|
cel.UnaryBinding(func(val ref.Val) ref.Val {
|
|
n, ok := val.(types.Int)
|
|
if !ok {
|
|
return types.ValOrErr(val, "value is not an integer, but is %T", val)
|
|
}
|
|
|
|
return types.Int(rand.IntN(int(n)))
|
|
}),
|
|
),
|
|
),
|
|
}
|
|
|
|
args = append(args, opts...)
|
|
return cel.NewEnv(args...)
|
|
}
|
|
|
|
// Compile takes CEL environment and syntax tree then emits an optimized
|
|
// Program for execution.
|
|
func Compile(env *cel.Env, src string) (cel.Program, error) {
|
|
intermediate, iss := env.Compile(src)
|
|
if iss != nil {
|
|
return nil, iss.Err()
|
|
}
|
|
|
|
ast, iss := env.Check(intermediate)
|
|
if iss != nil {
|
|
return nil, iss.Err()
|
|
}
|
|
|
|
return env.Program(
|
|
ast,
|
|
cel.EvalOptions(
|
|
// optimize regular expressions right now instead of on the fly
|
|
cel.OptOptimize,
|
|
),
|
|
)
|
|
}
|