Fix geo rule re-enablement bug
When rules expire and are disabled by ExpiredRulesCleanupJob, the system was unable to re-enable them due to unique index constraints. This caused geo-based blocking to stop working in production. Implemented find-or-update-or-create pattern in WafPolicy#create_rule_for_network_range: - Re-enables disabled rules and sets new expiration (7 days) - Extends expiration for enabled rules - Creates new rules with 7-day TTL - Handles race conditions gracefully Added test coverage for all three scenarios. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -442,7 +442,7 @@ class WafPolicyTest < ActiveSupport::TestCase
|
||||
assert_equal 0, @policy.generated_rules_count
|
||||
|
||||
# Create some rules
|
||||
network_range = NetworkRange.create!(ip_range: "192.168.1.0/24")
|
||||
network_range = NetworkRange.create!(cidr: "192.168.1.0/24", country: "BR")
|
||||
@policy.create_rule_for_network_range(network_range)
|
||||
|
||||
assert_equal 1, @policy.generated_rules_count
|
||||
@@ -461,6 +461,75 @@ class WafPolicyTest < ActiveSupport::TestCase
|
||||
assert_equal 2, stats[:targets_count]
|
||||
end
|
||||
|
||||
# Rule creation and re-enablement tests
|
||||
test "create_rule_for_network_range re-enables disabled rule" do
|
||||
@policy.save!
|
||||
|
||||
# Create a network range that matches the policy
|
||||
network_range = NetworkRange.create!(
|
||||
cidr: "192.168.1.0/24",
|
||||
country: "BR"
|
||||
)
|
||||
|
||||
# Create a rule via policy
|
||||
rule = @policy.create_rule_for_network_range(network_range)
|
||||
assert rule.enabled?, "Rule should be enabled initially"
|
||||
assert rule.expires_at.present?, "Rule should have expiration"
|
||||
|
||||
# Disable it (simulating expiration cleanup)
|
||||
rule.update!(enabled: false)
|
||||
assert_not rule.enabled?, "Rule should be disabled"
|
||||
|
||||
# Try to create again - should re-enable
|
||||
result = @policy.create_rule_for_network_range(network_range)
|
||||
|
||||
assert_equal rule.id, result.id, "Should return same rule"
|
||||
assert result.reload.enabled?, "Rule should be re-enabled"
|
||||
assert result.expires_at.present?, "Should have new expiration"
|
||||
assert result.expires_at > Time.current, "Expiration should be in the future"
|
||||
end
|
||||
|
||||
test "create_rule_for_network_range extends enabled rule expiration" do
|
||||
@policy.save!
|
||||
|
||||
# Create a network range that matches the policy
|
||||
network_range = NetworkRange.create!(
|
||||
cidr: "192.168.1.0/24",
|
||||
country: "BR"
|
||||
)
|
||||
|
||||
# Create a rule with expiration
|
||||
rule = @policy.create_rule_for_network_range(network_range)
|
||||
original_expires_at = rule.expires_at
|
||||
|
||||
travel 3.days do
|
||||
# Try to create again - should extend expiration
|
||||
result = @policy.create_rule_for_network_range(network_range)
|
||||
|
||||
assert_equal rule.id, result.id, "Should return same rule"
|
||||
assert result.reload.expires_at > original_expires_at, "Expiration should be extended"
|
||||
assert_in_delta 7.days.from_now, result.expires_at, 5.seconds, "Expiration should be ~7 days from now"
|
||||
end
|
||||
end
|
||||
|
||||
test "create_rule_for_network_range creates new rule when none exists" do
|
||||
@policy.save!
|
||||
|
||||
# Create a network range that matches the policy
|
||||
network_range = NetworkRange.create!(
|
||||
cidr: "192.168.1.0/24",
|
||||
country: "BR"
|
||||
)
|
||||
|
||||
rule = @policy.create_rule_for_network_range(network_range)
|
||||
|
||||
assert rule.persisted?, "Rule should be persisted"
|
||||
assert rule.enabled?, "Rule should be enabled"
|
||||
assert_equal network_range, rule.network_range
|
||||
assert rule.expires_at.present?, "New rule should have expiration"
|
||||
assert_in_delta 7.days.from_now, rule.expires_at, 5.seconds, "Expiration should be ~7 days from now"
|
||||
end
|
||||
|
||||
# String representations
|
||||
test "to_s returns name" do
|
||||
assert_equal @policy.name, @policy.to_s
|
||||
|
||||
Reference in New Issue
Block a user