Many updates

This commit is contained in:
Dan Milne
2025-11-13 14:42:43 +11:00
parent 5e5198f113
commit df94ac9720
41 changed files with 4760 additions and 516 deletions

View File

@@ -3,25 +3,30 @@
require "test_helper"
class RuleTest < ActiveSupport::TestCase
# Validation tests
test "should create valid network_v4 rule" do
test "should create valid network rule" do
network_range = NetworkRange.create!(cidr: "10.0.0.0/8")
rule = Rule.new(
rule_type: "network_v4",
action: "deny",
conditions: { cidr: "10.0.0.0/8" },
source: "manual"
waf_rule_type: "network",
waf_action: "deny",
network_range: network_range,
source: "manual",
user: users(:one)
)
assert rule.valid?
rule.save!
assert_equal 8, rule.priority # Auto-calculated from CIDR prefix
end
test "should create valid network_v6 rule" do
test "should create valid network rule with IPv6" do
network_range = NetworkRange.create!(cidr: "2001:db8::/32")
rule = Rule.new(
rule_type: "network_v6",
action: "deny",
conditions: { cidr: "2001:db8::/32" },
source: "manual"
waf_rule_type: "network",
waf_action: "deny",
network_range: network_range,
source: "manual",
user: users(:one)
)
assert rule.valid?
rule.save!
@@ -30,53 +35,58 @@ class RuleTest < ActiveSupport::TestCase
test "should create valid rate_limit rule" do
rule = Rule.new(
rule_type: "rate_limit",
action: "rate_limit",
waf_rule_type: "rate_limit",
waf_action: "rate_limit",
conditions: { cidr: "0.0.0.0/0", scope: "global" },
metadata: { limit: 100, window: 60 },
source: "manual"
source: "manual",
user: users(:one)
)
assert rule.valid?
end
test "should create valid path_pattern rule" do
rule = Rule.new(
rule_type: "path_pattern",
action: "log",
waf_rule_type: "path_pattern",
waf_action: "log",
conditions: { patterns: ["/.env", "/.git"] },
source: "default"
source: "default",
user: users(:one)
)
assert rule.valid?
end
test "should require rule_type" do
rule = Rule.new(action: "deny", conditions: { cidr: "10.0.0.0/8" })
test "should require waf_rule_type" do
rule = Rule.new(waf_action: "deny", waf_rule_type: nil, conditions: { patterns: ["/test"] }, user: users(:one))
assert_not rule.valid?
assert_includes rule.errors[:rule_type], "can't be blank"
assert_includes rule.errors[:waf_rule_type], "can't be blank"
end
test "should require action" do
rule = Rule.new(rule_type: "network_v4", conditions: { cidr: "10.0.0.0/8" })
test "should require waf_action" do
rule = Rule.new(waf_rule_type: "path_pattern", waf_action: nil, conditions: { patterns: ["/test"] }, user: users(:one))
assert_not rule.valid?
assert_includes rule.errors[:action], "can't be blank"
assert_includes rule.errors[:waf_action], "can't be blank"
end
test "should validate network_v4 has valid IPv4 CIDR" do
test "should validate network has valid CIDR" do
rule = Rule.new(
rule_type: "network_v4",
action: "deny",
conditions: { cidr: "2001:db8::/32" } # IPv6 in IPv4 rule
waf_rule_type: "network",
waf_action: "deny",
conditions: { cidr: "invalid-cidr" }, # Invalid CIDR
user: users(:one)
)
assert_not rule.valid?
assert_includes rule.errors[:conditions], "cidr must be IPv4 for network_v4 rules"
# Network rules now validate differently - they need a network_range
assert_includes rule.errors[:network_range], "is required for network rules"
end
test "should validate rate_limit has limit and window in metadata" do
rule = Rule.new(
rule_type: "rate_limit",
action: "rate_limit",
waf_rule_type: "rate_limit",
waf_action: "rate_limit",
conditions: { cidr: "0.0.0.0/0", scope: "global" },
metadata: { limit: 100 } # Missing window
metadata: { limit: 100 }, # Missing window
user: users(:one)
)
assert_not rule.valid?
assert_includes rule.errors[:metadata], "must include 'limit' and 'window' for rate_limit rules"
@@ -84,46 +94,56 @@ class RuleTest < ActiveSupport::TestCase
# Default value tests
test "should default enabled to true" do
network_range = NetworkRange.create!(cidr: "10.0.0.0/8")
rule = Rule.create!(
rule_type: "network_v4",
action: "deny",
conditions: { cidr: "10.0.0.0/8" }
waf_rule_type: "network",
waf_action: "deny",
network_range: network_range,
user: users(:one)
)
assert rule.enabled?
end
# Priority calculation tests
test "should calculate priority from IPv4 CIDR prefix" do
network_range = NetworkRange.create!(cidr: "192.168.1.0/24")
rule = Rule.create!(
rule_type: "network_v4",
action: "deny",
conditions: { cidr: "192.168.1.0/24" }
waf_rule_type: "network",
waf_action: "deny",
network_range: network_range,
user: users(:one)
)
assert_equal 24, rule.priority
end
# Scope tests
test "active scope returns enabled and non-expired rules" do
active_range = NetworkRange.create!(cidr: "10.0.0.0/8")
active = Rule.create!(
rule_type: "network_v4",
action: "deny",
conditions: { cidr: "10.0.0.0/8" },
enabled: true
)
disabled = Rule.create!(
rule_type: "network_v4",
action: "deny",
conditions: { cidr: "192.168.0.0/16" },
enabled: false
)
expired = Rule.create!(
rule_type: "network_v4",
action: "deny",
conditions: { cidr: "172.16.0.0/12" },
waf_rule_type: "network",
waf_action: "deny",
network_range: active_range,
enabled: true,
expires_at: 1.hour.ago
user: users(:one)
)
disabled_range = NetworkRange.create!(cidr: "192.168.0.0/16")
disabled = Rule.create!(
waf_rule_type: "network",
waf_action: "deny",
network_range: disabled_range,
enabled: false,
user: users(:one)
)
expired_range = NetworkRange.create!(cidr: "172.16.0.0/12")
expired = Rule.create!(
waf_rule_type: "network",
waf_action: "deny",
network_range: expired_range,
enabled: true,
expires_at: 1.hour.ago,
user: users(:one)
)
results = Rule.active.to_a
@@ -134,20 +154,24 @@ class RuleTest < ActiveSupport::TestCase
# Instance method tests
test "active? returns true for enabled non-expired rule" do
network_range = NetworkRange.create!(cidr: "10.0.0.0/8")
rule = Rule.create!(
rule_type: "network_v4",
action: "deny",
conditions: { cidr: "10.0.0.0/8" },
enabled: true
waf_rule_type: "network",
waf_action: "deny",
network_range: network_range,
enabled: true,
user: users(:one)
)
assert rule.active?
end
test "disable! sets enabled to false and adds metadata" do
network_range = NetworkRange.create!(cidr: "10.0.0.0/8")
rule = Rule.create!(
rule_type: "network_v4",
action: "deny",
conditions: { cidr: "10.0.0.0/8" }
waf_rule_type: "network",
waf_action: "deny",
network_range: network_range,
user: users(:one)
)
rule.disable!(reason: "False positive")
@@ -159,20 +183,22 @@ class RuleTest < ActiveSupport::TestCase
# Agent format tests
test "to_agent_format returns correct structure" do
network_range = NetworkRange.create!(cidr: "10.0.0.0/8")
rule = Rule.create!(
rule_type: "network_v4",
action: "deny",
conditions: { cidr: "10.0.0.0/8" },
waf_rule_type: "network",
waf_action: "deny",
network_range: network_range,
expires_at: 1.day.from_now,
source: "manual",
metadata: { reason: "Test" }
metadata: { reason: "Test" },
user: users(:one)
)
format = rule.to_agent_format
assert_equal rule.id, format[:id]
assert_equal "network_v4", format[:rule_type]
assert_equal "deny", format[:action]
assert_equal "network", format[:waf_rule_type]
assert_equal "deny", format[:waf_action]
assert_equal 8, format[:priority]
assert_equal true, format[:enabled]
end