Path matching
This commit is contained in:
@@ -6,12 +6,10 @@
|
||||
# Network rules are associated with NetworkRange objects for rich context.
|
||||
class Rule < ApplicationRecord
|
||||
# Rule enums (prefix needed to avoid rate_limit collision)
|
||||
enum :waf_action, { allow: 0, deny: 1, rate_limit: 2, redirect: 3, log: 4, challenge: 5 }, prefix: :action
|
||||
# Canonical WAF action order - aligned with Agent and Event models
|
||||
enum :waf_action, { deny: 0, allow: 1, redirect: 2, challenge: 3, log: 4 }, prefix: :action
|
||||
enum :waf_rule_type, { network: 0, rate_limit: 1, path_pattern: 2 }, prefix: :type
|
||||
|
||||
# Legacy string constants for backward compatibility
|
||||
RULE_TYPES = %w[network rate_limit path_pattern].freeze
|
||||
ACTIONS = %w[allow deny rate_limit redirect log challenge].freeze
|
||||
SOURCES = %w[manual auto:scanner_detected auto:rate_limit_exceeded auto:bot_detected imported default manual:surgical_block manual:surgical_exception policy].freeze
|
||||
|
||||
# Associations
|
||||
@@ -27,14 +25,6 @@ class Rule < ApplicationRecord
|
||||
validates :enabled, inclusion: { in: [true, false] }
|
||||
validates :source, inclusion: { in: SOURCES }
|
||||
|
||||
# Legacy enum definitions (disabled to prevent conflicts)
|
||||
# enum :action, { allow: "allow", deny: "deny", rate_limit: "rate_limit", redirect: "redirect", log: "log", challenge: "challenge" }, scopes: false
|
||||
# enum :rule_type, { network: "network", rate_limit: "rate_limit", path_pattern: "path_pattern" }, scopes: false
|
||||
|
||||
# Legacy validations for backward compatibility during transition
|
||||
# validates :rule_type, presence: true, inclusion: { in: RULE_TYPES }, allow_nil: true
|
||||
# validates :action, presence: true, inclusion: { in: ACTIONS }, allow_nil: true
|
||||
|
||||
# Custom validations
|
||||
validate :validate_conditions_by_type
|
||||
validate :validate_metadata_by_action
|
||||
@@ -356,12 +346,12 @@ class Rule < ApplicationRecord
|
||||
[block_rule, exception_rule]
|
||||
end
|
||||
|
||||
def self.create_rate_limit_rule(cidr, limit:, window:, user: nil, **options)
|
||||
def self.create_rate_limit_rule(cidr, limit:, window:, user: nil, action: 'deny', **options)
|
||||
network_range = NetworkRange.find_or_create_by_cidr(cidr, user: user, source: 'user_created')
|
||||
|
||||
create!(
|
||||
waf_rule_type: 'rate_limit',
|
||||
waf_action: 'rate_limit',
|
||||
waf_action: action, # Action to take when rate limit exceeded (deny, redirect, challenge, log)
|
||||
network_range: network_range,
|
||||
conditions: { cidr: cidr, scope: 'ip' },
|
||||
metadata: {
|
||||
@@ -514,10 +504,6 @@ class Rule < ApplicationRecord
|
||||
if challenge_type_value && !%w[captcha javascript proof_of_work].include?(challenge_type_value)
|
||||
errors.add(:metadata, "challenge_type must be one of: captcha, javascript, proof_of_work")
|
||||
end
|
||||
when "rate_limit"
|
||||
unless metadata&.dig("limit").present? && metadata&.dig("window").present?
|
||||
errors.add(:metadata, "must include 'limit' and 'window' for rate_limit action")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user