mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-05 09:30:26 +08:00
136 lines
2.8 KiB
Go
136 lines
2.8 KiB
Go
|
|
package waf
|
||
|
|
|
||
|
|
import (
|
||
|
|
"github.com/TeaOSLab/EdgeNode/internal/waf/requests"
|
||
|
|
"github.com/iwind/TeaGo/maps"
|
||
|
|
"github.com/iwind/TeaGo/utils/string"
|
||
|
|
)
|
||
|
|
|
||
|
|
type RuleConnector = string
|
||
|
|
|
||
|
|
const (
|
||
|
|
RuleConnectorAnd = "and"
|
||
|
|
RuleConnectorOr = "or"
|
||
|
|
)
|
||
|
|
|
||
|
|
type RuleSet struct {
|
||
|
|
Id string `yaml:"id" json:"id"`
|
||
|
|
Code string `yaml:"code" json:"code"`
|
||
|
|
IsOn bool `yaml:"isOn" json:"isOn"`
|
||
|
|
Name string `yaml:"name" json:"name"`
|
||
|
|
Description string `yaml:"description" json:"description"`
|
||
|
|
Rules []*Rule `yaml:"rules" json:"rules"`
|
||
|
|
Connector RuleConnector `yaml:"connector" json:"connector"` // rules connector
|
||
|
|
|
||
|
|
Action ActionString `yaml:"action" json:"action"`
|
||
|
|
ActionOptions maps.Map `yaml:"actionOptions" json:"actionOptions"` // TODO TO BE IMPLEMENTED
|
||
|
|
|
||
|
|
hasRules bool
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewRuleSet() *RuleSet {
|
||
|
|
return &RuleSet{
|
||
|
|
Id: stringutil.Rand(16),
|
||
|
|
IsOn: true,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (this *RuleSet) Init() error {
|
||
|
|
this.hasRules = len(this.Rules) > 0
|
||
|
|
if this.hasRules {
|
||
|
|
for _, rule := range this.Rules {
|
||
|
|
err := rule.Init()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (this *RuleSet) AddRule(rule ...*Rule) {
|
||
|
|
this.Rules = append(this.Rules, rule...)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (this *RuleSet) MatchRequest(req *requests.Request) (b bool, err error) {
|
||
|
|
if !this.hasRules {
|
||
|
|
return false, nil
|
||
|
|
}
|
||
|
|
switch this.Connector {
|
||
|
|
case RuleConnectorAnd:
|
||
|
|
for _, rule := range this.Rules {
|
||
|
|
b1, err1 := rule.MatchRequest(req)
|
||
|
|
if err1 != nil {
|
||
|
|
return false, err1
|
||
|
|
}
|
||
|
|
if !b1 {
|
||
|
|
return false, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return true, nil
|
||
|
|
case RuleConnectorOr:
|
||
|
|
for _, rule := range this.Rules {
|
||
|
|
b1, err1 := rule.MatchRequest(req)
|
||
|
|
if err1 != nil {
|
||
|
|
return false, err1
|
||
|
|
}
|
||
|
|
if b1 {
|
||
|
|
return true, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
default: // same as And
|
||
|
|
for _, rule := range this.Rules {
|
||
|
|
b1, err1 := rule.MatchRequest(req)
|
||
|
|
if err1 != nil {
|
||
|
|
return false, err1
|
||
|
|
}
|
||
|
|
if !b1 {
|
||
|
|
return false, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return true, nil
|
||
|
|
}
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
func (this *RuleSet) MatchResponse(req *requests.Request, resp *requests.Response) (b bool, err error) {
|
||
|
|
if !this.hasRules {
|
||
|
|
return false, nil
|
||
|
|
}
|
||
|
|
switch this.Connector {
|
||
|
|
case RuleConnectorAnd:
|
||
|
|
for _, rule := range this.Rules {
|
||
|
|
b1, err1 := rule.MatchResponse(req, resp)
|
||
|
|
if err1 != nil {
|
||
|
|
return false, err1
|
||
|
|
}
|
||
|
|
if !b1 {
|
||
|
|
return false, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return true, nil
|
||
|
|
case RuleConnectorOr:
|
||
|
|
for _, rule := range this.Rules {
|
||
|
|
b1, err1 := rule.MatchResponse(req, resp)
|
||
|
|
if err1 != nil {
|
||
|
|
return false, err1
|
||
|
|
}
|
||
|
|
if b1 {
|
||
|
|
return true, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
default: // same as And
|
||
|
|
for _, rule := range this.Rules {
|
||
|
|
b1, err1 := rule.MatchResponse(req, resp)
|
||
|
|
if err1 != nil {
|
||
|
|
return false, err1
|
||
|
|
}
|
||
|
|
if !b1 {
|
||
|
|
return false, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return true, nil
|
||
|
|
}
|
||
|
|
return
|
||
|
|
}
|