From 3323207f40f7e150a49c87adb99a529b87477b63 Mon Sep 17 00:00:00 2001 From: Dwi Siswanto Date: Wed, 27 Mar 2024 13:51:13 +0700 Subject: [PATCH] refactor(dsl): remove `dsl` pkg Signed-off-by: Dwi Siswanto --- dsl/compile.go | 140 -------------------------------------------- dsl/compile_test.go | 24 -------- dsl/dsl.go | 103 -------------------------------- dsl/dsl_test.go | 18 ------ dsl/run.go | 48 --------------- dsl/run_test.go | 36 ------------ dsl/utils.go | 17 ------ dsl/utils_test.go | 22 ------- 8 files changed, 408 deletions(-) delete mode 100644 dsl/compile.go delete mode 100644 dsl/compile_test.go delete mode 100644 dsl/dsl.go delete mode 100644 dsl/dsl_test.go delete mode 100644 dsl/run.go delete mode 100644 dsl/run_test.go delete mode 100644 dsl/utils.go delete mode 100644 dsl/utils_test.go diff --git a/dsl/compile.go b/dsl/compile.go deleted file mode 100644 index d86cac87..00000000 --- a/dsl/compile.go +++ /dev/null @@ -1,140 +0,0 @@ -// Licensed to Dwi Siswanto under one or more agreements. -// Dwi Siswanto licenses this file to you under the Apache 2.0 License. -// See the LICENSE-APACHE file in the project root for more information. - -package dsl - -import ( - "github.com/antonmedv/expr" - "github.com/antonmedv/expr/vm" -) - -/* -Compile will compiles the given code string into a [vm.Program]. - -The code string contains DSL (Domain Specific Language) expressions -that can be used to define conditions for evaluating incoming requests. -Here are some examples of DSL expression code: - -# Examples of DSL expression code: - -Check if the incoming request headers contains "curl": - - request.Headers contains "curl" - -Check if the incoming request method is "GET": - - request.Method == "GET" - -Check if the incoming request method is "GET" or "POST" -using regular expression [operator] matching: - - request.Method matches "^(POS|GE)T$" - -Check if the incoming request IP address is from localhost: - - request.IP in ["127.0.0.1", "::1", "0.0.0.0"] - -Check if the any element in request contains the string "foo": - - one(request.ALL, # contains "foo") - -Check if the incoming request body contains "foo": - - request.Body contains "foo" - -Check whether the current threat category being analyzed -is [threat.BadCrawler] or [threat.DirectoryBruteforce]: - - threat in [BadCrawler, DirectoryBruteforce] - -# Available variables: - -# Threat category - -All constant identifiers of the [threat.Threat] type are valid variables. - -# request - - request - -Represents the incoming request fields (URI, Headers, Body, etc.) and its values. - - request.URI - -Represents the incoming request URI (path, queries, parameters, and a fragments). - - request.Headers - -Represents the incoming request headers in multiple lines. - - request.Body - -Represents the incoming request body. - - request.Method - -Represents the incoming request method. - - request.IP - -Represents the client IP address of the incoming request. - - request.ALL - -Represents all the string values from the request fields above in slice. - -# threat - - threat - -Represents the threat category being analyzed (type of [threat.Threat]). - -# Available functions: - -The functions available in this package include both -[built-in functions from the expr package] and those -specifically defined for this package. The following -is a list of the functions provided by, which utilize -the functionalities offered by the [strings] package. - - - cidr - - clone - - containsAny - - equalFold - - hasPrefix - - hasSuffix - - join - - repeat - - replace - - replaceAll - - request - - threat - - title - - toLower - - toTitle - - toUpper - - toValidUTF8 - - trim - - trimLeft - - trimPrefix - - trimRight - - trimSpace - - trimSuffix - -For more information on operators and built-in functions, please refer to -the [operator] and [built-in functions from the expr package] documentation. - -[operator]: https://expr.medv.io/docs/Language-Definition#operators -[built-in functions from the expr package]: https://expr.medv.io/docs/Language-Definition#built-in-functions -*/ -func (e *Env) Compile(code string) (*vm.Program, error) { - // Compile the code into a program using the defined options. - program, err := expr.Compile(code, e.opts...) - if err != nil { - return nil, err - } - - // Return the compiled program. - return program, nil -} diff --git a/dsl/compile_test.go b/dsl/compile_test.go deleted file mode 100644 index 26967a37..00000000 --- a/dsl/compile_test.go +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to Dwi Siswanto under one or more agreements. -// Dwi Siswanto licenses this file to you under the Apache 2.0 License. -// See the LICENSE-APACHE file in the project root for more information. - -package dsl - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestCompileDSL(t *testing.T) { - env := New() - expr := `1 + 1` - - _, err := env.Compile(expr) - assert.ErrorIs(t, err, nil) - - t.Run("err", func(t *testing.T) { - _, err := env.Compile(expr + "0O") - assert.NotNil(t, err) - }) -} diff --git a/dsl/dsl.go b/dsl/dsl.go deleted file mode 100644 index bf0474b9..00000000 --- a/dsl/dsl.go +++ /dev/null @@ -1,103 +0,0 @@ -// Licensed to Dwi Siswanto under one or more agreements. -// Dwi Siswanto licenses this file to you under the Apache 2.0 License. -// See the LICENSE-APACHE file in the project root for more information. - -/* -Package dsl provides a Domain Specific Language (DSL) for -defining conditions and evaluating incoming requests. - -The DSL provided by this package allows users to define -custom conditions and rules for evaluating incoming requests. -It provides an environment (Env) where the DSL expressions -can be compiled and executed. - -This package provides a flexible and extensible DSL for -defining conditions and rules in order to evaluate incoming -requests in a customizable manner. -*/ -package dsl - -import ( - "strings" - - "github.com/antonmedv/expr" - "github.com/daniel-hutao/spinlock" - "github.com/kitabisa/teler-waf/threat" - "github.com/projectdiscovery/mapcidr" - "golang.org/x/text/cases" - "golang.org/x/text/language" -) - -// Env represents the environment for the DSL. -type Env struct { - // Threat represents a threat category. - Threat threat.Threat - - // Requests is a map that holds incoming request information. - Requests map[string]any - - // funcs is a map that associates function names with their respective functions. - funcs map[string]any - - // vars is a map that associates variable names with their respective values. - vars map[string]any - - // opts is a slice of Expr config options - opts []expr.Option - - // sl (SpinLock) is a is a simple spin lock implementation with - // exponential backoff and adaptive spinning. - sl spinlock.SpinLock -} - -// Env represents the environment for the DSL. -func New() *Env { - // Create a new Env instance. - env := &Env{} - - // Initialize vars to a map of variable names and their corresponding values. - env.vars = map[string]any{ - "request": env.Requests, - "threat": env.Threat, - } - - // Assign each threat category to the funcs map. - for _, t := range threat.List() { - env.vars[t.String()] = t - } - - // Initialize funcs to a map of function names and their corresponding functions. - env.funcs = map[string]any{ - "cidr": mapcidr.IPAddresses, - "clone": strings.Clone, - "containsAny": strings.ContainsAny, - "equalFold": strings.EqualFold, - "hasPrefix": strings.HasPrefix, - "hasSuffix": strings.HasSuffix, - "join": strings.Join, - "repeat": strings.Repeat, - "replace": strings.Replace, - "replaceAll": strings.ReplaceAll, - "title": cases.Title(language.Und).String, - "toLower": strings.ToLower, - "toTitle": strings.ToTitle, - "toUpper": strings.ToUpper, - "toValidUTF8": strings.ToValidUTF8, - "trim": strings.Trim, - "trimLeft": strings.TrimLeft, - "trimPrefix": strings.TrimPrefix, - "trimRight": strings.TrimRight, - "trimSpace": strings.TrimSpace, - "trimSuffix": strings.TrimSuffix, - } - - // Define the options for compilation. - env.opts = []expr.Option{ - expr.Env(env.vars), // Use the environment's variables. - expr.Env(env.funcs), // Use the environment's functions. - expr.AllowUndefinedVariables(), // Allow the use of undefined variables. - } - - // Return the initialized Env instance. - return env -} diff --git a/dsl/dsl_test.go b/dsl/dsl_test.go deleted file mode 100644 index ae9536ee..00000000 --- a/dsl/dsl_test.go +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to Dwi Siswanto under one or more agreements. -// Dwi Siswanto licenses this file to you under the Apache 2.0 License. -// See the LICENSE-APACHE file in the project root for more information. - -package dsl - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestNewDSL(t *testing.T) { - env := new(Env) - expectedEnv := New() - - assert.NotEqual(t, env, expectedEnv) -} diff --git a/dsl/run.go b/dsl/run.go deleted file mode 100644 index 7b957ff2..00000000 --- a/dsl/run.go +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to Dwi Siswanto under one or more agreements. -// Dwi Siswanto licenses this file to you under the Apache 2.0 License. -// See the LICENSE-APACHE file in the project root for more information. - -package dsl - -import ( - "github.com/antonmedv/expr" - "github.com/antonmedv/expr/vm" - "github.com/kitabisa/teler-waf/threat" - "github.com/samber/lo" -) - -// Run executes the provided expr.Program in the DSL environment. -func (e *Env) Run(program *vm.Program) (any, error) { - // Lock - e.sl.Lock() - defer e.sl.Unlock() - - // If the Threat field in the environment is defined, assign it to the "threat" function in the environment. - if e.Threat != threat.Undefined { - e.vars["threat"] = e.Threat - } - - // Combine all requests - e.Requests["ALL"] = lo.MapToSlice(e.Requests, func(k string, v any) string { - if s, ok := v.(string); ok && s != "" { - return s - } - - return "" - }) - - // Assign the Requests map to the "request" variable in the environment. - e.vars["request"] = e.Requests - - // Merge maps of variables and functions - envMaps := lo.Assign[string, any](e.vars, e.funcs) - - // Run the provided program using the merged environments. - out, err := expr.Run(program, envMaps) - if err != nil { - return nil, err - } - - // Return the output. - return out, nil -} diff --git a/dsl/run_test.go b/dsl/run_test.go deleted file mode 100644 index 1190f10a..00000000 --- a/dsl/run_test.go +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to Dwi Siswanto under one or more agreements. -// Dwi Siswanto licenses this file to you under the Apache 2.0 License. -// See the LICENSE-APACHE file in the project root for more information. - -package dsl - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestRunDSL(t *testing.T) { - env := New() - - program, err := env.Compile("1+1") - assert.ErrorIs(t, err, nil) - - env.Requests = map[string]any{ - "BAR": nil, - "FOO": "bar", - } - - res, err := env.Run(program) - assert.ErrorIs(t, err, nil) - - assert.Equal(t, 2, res) - - t.Run("err", func(t *testing.T) { - program, err := env.Compile(`"1+10O`) - assert.NotNil(t, err) - - _, err = env.Run(program) - assert.NotNil(t, err) - }) -} diff --git a/dsl/utils.go b/dsl/utils.go deleted file mode 100644 index 2173305b..00000000 --- a/dsl/utils.go +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to Dwi Siswanto under one or more agreements. -// Dwi Siswanto licenses this file to you under the Apache 2.0 License. -// See the LICENSE-APACHE file in the project root for more information. - -package dsl - -// GetRequestValue from the Requests environment -func (e *Env) GetRequestValue(k string) string { - e.sl.Lock() - defer e.sl.Unlock() - - if v, ok := e.Requests[k]; ok { - return v.(string) - } - - return "" -} diff --git a/dsl/utils_test.go b/dsl/utils_test.go deleted file mode 100644 index 472570bf..00000000 --- a/dsl/utils_test.go +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to Dwi Siswanto under one or more agreements. -// Dwi Siswanto licenses this file to you under the Apache 2.0 License. -// See the LICENSE-APACHE file in the project root for more information. - -package dsl - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestGetRequestValue(t *testing.T) { - clientIP := "127.0.0.1" - - env := New() - env.Requests = map[string]any{"IP": clientIP} - - get := env.GetRequestValue("IP") - - assert.Equal(t, get, clientIP) -}