feat(P1/P2): 完成TDD开发及P1/P2设计文档
## 设计文档 - multi_role_permission_design: 多角色权限设计 (CONDITIONAL GO) - audit_log_enhancement_design: 审计日志增强 (CONDITIONAL GO) - routing_strategy_template_design: 路由策略模板 (CONDITIONAL GO) - sso_saml_technical_research: SSO/SAML调研 (CONDITIONAL GO) - compliance_capability_package_design: 合规能力包设计 (CONDITIONAL GO) ## TDD开发成果 - IAM模块: supply-api/internal/iam/ (111个测试) - 审计日志模块: supply-api/internal/audit/ (40+测试) - 路由策略模块: gateway/internal/router/ (33+测试) - 合规能力包: gateway/internal/compliance/ + scripts/ci/compliance/ ## 规范文档 - parallel_agent_output_quality_standards: 并行Agent产出质量规范 - project_experience_summary: 项目经验总结 (v2) - 2026-04-02-p1-p2-tdd-execution-plan: TDD执行计划 ## 评审报告 - 5个CONDITIONAL GO设计文档评审报告 - fix_verification_report: 修复验证报告 - full_verification_report: 全面质量验证报告 - tdd_module_quality_verification: TDD模块质量验证 - tdd_execution_summary: TDD执行总结 依据: Superpowers执行框架 + TDD规范
This commit is contained in:
137
gateway/internal/compliance/rules/engine.go
Normal file
137
gateway/internal/compliance/rules/engine.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// MatchResult 匹配结果
|
||||
type MatchResult struct {
|
||||
Matched bool
|
||||
RuleID string
|
||||
Matchers []MatcherResult
|
||||
}
|
||||
|
||||
// MatcherResult 单个匹配器的结果
|
||||
type MatcherResult struct {
|
||||
MatcherIndex int
|
||||
MatcherType string
|
||||
Pattern string
|
||||
MatchValue string
|
||||
IsMatch bool
|
||||
}
|
||||
|
||||
// RuleEngine 规则引擎
|
||||
type RuleEngine struct {
|
||||
loader *RuleLoader
|
||||
compiledPatterns map[string][]*regexp.Regexp
|
||||
}
|
||||
|
||||
// NewRuleEngine 创建新的规则引擎
|
||||
func NewRuleEngine(loader *RuleLoader) *RuleEngine {
|
||||
return &RuleEngine{
|
||||
loader: loader,
|
||||
compiledPatterns: make(map[string][]*regexp.Regexp),
|
||||
}
|
||||
}
|
||||
|
||||
// Match 执行规则匹配
|
||||
func (e *RuleEngine) Match(rule Rule, content string) MatchResult {
|
||||
result := MatchResult{
|
||||
Matched: false,
|
||||
RuleID: rule.ID,
|
||||
Matchers: make([]MatcherResult, len(rule.Matchers)),
|
||||
}
|
||||
|
||||
for i, matcher := range rule.Matchers {
|
||||
matcherResult := MatcherResult{
|
||||
MatcherIndex: i,
|
||||
MatcherType: matcher.Type,
|
||||
Pattern: matcher.Pattern,
|
||||
IsMatch: false,
|
||||
}
|
||||
|
||||
switch matcher.Type {
|
||||
case "regex_match":
|
||||
matcherResult.IsMatch = e.matchRegex(matcher.Pattern, content)
|
||||
if matcherResult.IsMatch {
|
||||
matcherResult.MatchValue = e.extractMatch(matcher.Pattern, content)
|
||||
}
|
||||
default:
|
||||
// 未知匹配器类型,默认不匹配
|
||||
}
|
||||
|
||||
result.Matchers[i] = matcherResult
|
||||
if matcherResult.IsMatch {
|
||||
result.Matched = true
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// matchRegex 执行正则表达式匹配
|
||||
func (e *RuleEngine) matchRegex(pattern string, content string) bool {
|
||||
// 编译并缓存正则表达式
|
||||
regex, ok := e.compiledPatterns[pattern]
|
||||
if !ok {
|
||||
var err error
|
||||
regex = make([]*regexp.Regexp, 1)
|
||||
regex[0], err = regexp.Compile(pattern)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
e.compiledPatterns[pattern] = regex
|
||||
}
|
||||
|
||||
return regex[0].MatchString(content)
|
||||
}
|
||||
|
||||
// extractMatch 提取匹配值
|
||||
func (e *RuleEngine) extractMatch(pattern string, content string) string {
|
||||
regex, ok := e.compiledPatterns[pattern]
|
||||
if !ok {
|
||||
regex = make([]*regexp.Regexp, 1)
|
||||
regex[0], _ = regexp.Compile(pattern)
|
||||
e.compiledPatterns[pattern] = regex
|
||||
}
|
||||
|
||||
matches := regex[0].FindString(content)
|
||||
return matches
|
||||
}
|
||||
|
||||
// MatchFromConfig 从规则配置执行匹配
|
||||
func (e *RuleEngine) MatchFromConfig(ruleID string, ruleConfig Rule, content string) (bool, error) {
|
||||
// 验证规则
|
||||
if err := e.validateRuleForMatch(ruleConfig); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result := e.Match(ruleConfig, content)
|
||||
return result.Matched, nil
|
||||
}
|
||||
|
||||
// validateRuleForMatch 验证规则是否可用于匹配
|
||||
func (e *RuleEngine) validateRuleForMatch(rule Rule) error {
|
||||
if rule.ID == "" {
|
||||
return ErrInvalidRule
|
||||
}
|
||||
if len(rule.Matchers) == 0 {
|
||||
return ErrNoMatchers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Custom errors
|
||||
var (
|
||||
ErrInvalidRule = &RuleEngineError{"invalid rule: missing required fields"}
|
||||
ErrNoMatchers = &RuleEngineError{"invalid rule: no matchers defined"}
|
||||
)
|
||||
|
||||
// RuleEngineError 规则引擎错误
|
||||
type RuleEngineError struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *RuleEngineError) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
Reference in New Issue
Block a user