mirror of
https://github.com/alibaba/higress.git
synced 2026-05-22 19:57:29 +08:00
feat: ext-auth plugin: Blacklist and whitelist modes support HTTP request method matching (#1798)
This commit is contained in:
@@ -260,19 +260,28 @@ func parseMatchRules(json gjson.Result, config *ExtAuthConfig) error {
|
||||
var err error
|
||||
|
||||
matchListConfig.ForEach(func(key, value gjson.Result) bool {
|
||||
pathMatcher, buildErr := expr.BuildStringMatcher(
|
||||
value.Get("match_rule_type").Str,
|
||||
value.Get("match_rule_path").Str, false)
|
||||
if buildErr != nil {
|
||||
err = fmt.Errorf("failed to build string matcher for rule with domain %q, path %q, type %q: %w",
|
||||
value.Get("match_rule_domain").Str,
|
||||
value.Get("match_rule_path").Str,
|
||||
value.Get("match_rule_type").Str,
|
||||
buildErr)
|
||||
return false // stop iterating
|
||||
domain := value.Get("match_rule_domain").Str
|
||||
methodArray := value.Get("match_rule_method").Array()
|
||||
matchRuleType := value.Get("match_rule_type").Str
|
||||
matchRulePath := value.Get("match_rule_path").Str
|
||||
|
||||
var pathMatcher expr.Matcher
|
||||
var buildErr error
|
||||
|
||||
if matchRuleType == "" && matchRulePath == "" {
|
||||
pathMatcher = nil
|
||||
} else {
|
||||
pathMatcher, buildErr = expr.BuildStringMatcher(matchRuleType, matchRulePath, false)
|
||||
if buildErr != nil {
|
||||
err = fmt.Errorf("failed to build string matcher for rule with domain %q, method %v, path %q, type %q: %w",
|
||||
domain, methodArray, matchRulePath, matchRuleType, buildErr)
|
||||
return false // stop iterating
|
||||
}
|
||||
}
|
||||
|
||||
ruleList = append(ruleList, expr.Rule{
|
||||
Domain: value.Get("match_rule_domain").Str,
|
||||
Domain: domain,
|
||||
Method: convertToStringList(methodArray),
|
||||
Path: pathMatcher,
|
||||
})
|
||||
return true // keep iterating
|
||||
@@ -297,3 +306,11 @@ func convertToStringMap(result gjson.Result) map[string]string {
|
||||
})
|
||||
return m
|
||||
}
|
||||
|
||||
func convertToStringList(results []gjson.Result) []string {
|
||||
interfaces := make([]string, len(results))
|
||||
for i, result := range results {
|
||||
interfaces[i] = result.String()
|
||||
}
|
||||
return interfaces
|
||||
}
|
||||
|
||||
@@ -218,6 +218,7 @@ func TestParseConfig(t *testing.T) {
|
||||
RuleList: []expr.Rule{
|
||||
{
|
||||
Domain: "*.bar.com",
|
||||
Method: []string{},
|
||||
Path: func() expr.Matcher {
|
||||
pathMatcher, err := expr.BuildStringMatcher(expr.MatchPatternPrefix, "/headers", false)
|
||||
if err != nil {
|
||||
@@ -248,6 +249,7 @@ func TestParseConfig(t *testing.T) {
|
||||
"match_list": [
|
||||
{
|
||||
"match_rule_domain": "*.foo.com",
|
||||
"match_rule_method": ["GET"],
|
||||
"match_rule_path": "/api",
|
||||
"match_rule_type": "exact"
|
||||
}
|
||||
@@ -269,6 +271,7 @@ func TestParseConfig(t *testing.T) {
|
||||
RuleList: []expr.Rule{
|
||||
{
|
||||
Domain: "*.foo.com",
|
||||
Method: []string{"GET"},
|
||||
Path: func() expr.Matcher {
|
||||
pathMatcher, err := expr.BuildStringMatcher(expr.MatchPatternExact, "/api", false)
|
||||
if err != nil {
|
||||
@@ -284,6 +287,50 @@ func TestParseConfig(t *testing.T) {
|
||||
StatusOnError: 403,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid Match Rules with Whitelist - Only Method",
|
||||
json: `{
|
||||
"http_service": {
|
||||
"endpoint_mode": "envoy",
|
||||
"endpoint": {
|
||||
"service_name": "example.com",
|
||||
"service_port": 80,
|
||||
"path_prefix": "/auth"
|
||||
}
|
||||
},
|
||||
"match_type": "whitelist",
|
||||
"match_list": [
|
||||
{
|
||||
"match_rule_method": ["GET"]
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expected: ExtAuthConfig{
|
||||
HttpService: HttpService{
|
||||
EndpointMode: "envoy",
|
||||
Client: wrapper.NewClusterClient(wrapper.FQDNCluster{
|
||||
FQDN: "example.com",
|
||||
Port: 80,
|
||||
Host: "",
|
||||
}),
|
||||
PathPrefix: "/auth",
|
||||
Timeout: 1000,
|
||||
},
|
||||
MatchRules: expr.MatchRules{
|
||||
Mode: "whitelist",
|
||||
RuleList: []expr.Rule{
|
||||
{
|
||||
Domain: "",
|
||||
Method: []string{"GET"},
|
||||
Path: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
FailureModeAllow: false,
|
||||
FailureModeAllowHeaderAdd: false,
|
||||
StatusOnError: 403,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Missing Match Type",
|
||||
json: `{
|
||||
@@ -342,12 +389,13 @@ func TestParseConfig(t *testing.T) {
|
||||
"match_list": [
|
||||
{
|
||||
"match_rule_domain": "*.bar.com",
|
||||
"match_rule_method": ["POST","PUT","DELETE"],
|
||||
"match_rule_path": "/headers",
|
||||
"match_rule_type": "invalid_type"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
expectedErr: `failed to build string matcher for rule with domain "*.bar.com", path "/headers", type "invalid_type": unknown string matcher type`,
|
||||
expectedErr: `failed to build string matcher for rule with domain "*.bar.com", method [POST PUT DELETE], path "/headers", type "invalid_type": unknown string matcher type`,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user