Add missing files
This commit is contained in:
33
app/views/rules/_compact_rule.html.erb
Normal file
33
app/views/rules/_compact_rule.html.erb
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<%# Compact rule display for showing rules on network range pages %>
|
||||||
|
<div class="flex items-center justify-between text-sm py-1.5 hover:bg-gray-50 px-2 -mx-2 rounded">
|
||||||
|
<div class="flex items-center space-x-2 min-w-0 flex-1">
|
||||||
|
<%= link_to rule, class: "flex items-center space-x-2 min-w-0 hover:text-blue-600" do %>
|
||||||
|
<%# Action badge %>
|
||||||
|
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium <%= rule.waf_action == 'deny' ? 'bg-red-100 text-red-800' : rule.waf_action == 'allow' ? 'bg-green-100 text-green-800' : 'bg-blue-100 text-blue-800' %>">
|
||||||
|
<%= rule.waf_action.upcase %>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<%# Network CIDR %>
|
||||||
|
<span class="font-mono text-gray-900 truncate"><%= rule.network_range.cidr %></span>
|
||||||
|
|
||||||
|
<%# Priority %>
|
||||||
|
<span class="text-xs text-gray-500">P:<%= rule.priority %></span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center space-x-2 flex-shrink-0">
|
||||||
|
<%# Disabled badge %>
|
||||||
|
<% unless rule.enabled? %>
|
||||||
|
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs bg-gray-200 text-gray-600" title="<%= rule.metadata_hash['disabled_reason'] %>">
|
||||||
|
Disabled
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%# Policy badge if policy-generated %>
|
||||||
|
<% if rule.waf_policy.present? %>
|
||||||
|
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs bg-purple-100 text-purple-800" title="<%= rule.waf_policy.name %>">
|
||||||
|
Policy
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class RemoveLegacyColumnsFromRules < ActiveRecord::Migration[8.1]
|
||||||
|
def change
|
||||||
|
# Remove indexes first
|
||||||
|
remove_index :rules, name: "index_rules_on_action" if index_exists?(:rules, name: "index_rules_on_action")
|
||||||
|
remove_index :rules, name: "index_rules_on_rule_type" if index_exists?(:rules, name: "index_rules_on_rule_type")
|
||||||
|
remove_index :rules, name: "idx_rules_type_enabled" if index_exists?(:rules, name: "idx_rules_type_enabled")
|
||||||
|
|
||||||
|
# Remove the legacy columns
|
||||||
|
remove_column :rules, :action, :string
|
||||||
|
remove_column :rules, :rule_type, :string
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddTimeAwareUniqueIndexesToRules < ActiveRecord::Migration[8.1]
|
||||||
|
def up
|
||||||
|
# First, clean up existing duplicate records to allow unique constraints
|
||||||
|
cleanup_duplicate_rules
|
||||||
|
|
||||||
|
# Add time-aware unique indexes for policy-generated rules
|
||||||
|
# This prevents exact duplicate time windows while allowing temporal flexibility
|
||||||
|
|
||||||
|
# For temporary rules (with expiration dates)
|
||||||
|
add_index :rules,
|
||||||
|
[:network_range_id, :waf_action, :waf_policy_id, :expires_at],
|
||||||
|
name: 'index_rules_on_network_policy_expires_unique',
|
||||||
|
unique: true,
|
||||||
|
where: "source = 'policy' AND expires_at IS NOT NULL"
|
||||||
|
|
||||||
|
# For permanent rules (no expiration date)
|
||||||
|
add_index :rules,
|
||||||
|
[:network_range_id, :waf_action, :waf_policy_id],
|
||||||
|
name: 'index_rules_on_network_policy_unique',
|
||||||
|
unique: true,
|
||||||
|
where: "source = 'policy' AND expires_at IS NULL"
|
||||||
|
|
||||||
|
# Additional indexes for performance
|
||||||
|
add_index :rules, [:source, :expires_at], name: 'index_rules_on_source_expires'
|
||||||
|
add_index :rules, [:waf_policy_id, :expires_at], name: 'index_rules_on_policy_expires'
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_index :rules, name: 'index_rules_on_network_policy_expires_unique'
|
||||||
|
remove_index :rules, name: 'index_rules_on_network_policy_unique'
|
||||||
|
remove_index :rules, name: 'index_rules_on_source_expires'
|
||||||
|
remove_index :rules, name: 'index_rules_on_policy_expires'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def cleanup_duplicate_rules
|
||||||
|
# Clean up duplicates for policy rules with the same expiration time
|
||||||
|
duplicate_sql = <<~SQL
|
||||||
|
WITH ranked_rules AS (
|
||||||
|
SELECT id,
|
||||||
|
ROW_NUMBER() OVER (
|
||||||
|
PARTITION BY network_range_id, waf_action, waf_policy_id, expires_at
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
) as rn
|
||||||
|
FROM rules
|
||||||
|
WHERE source = 'policy'
|
||||||
|
)
|
||||||
|
DELETE FROM rules
|
||||||
|
WHERE id IN (SELECT id FROM ranked_rules WHERE rn > 1)
|
||||||
|
SQL
|
||||||
|
|
||||||
|
execute duplicate_sql
|
||||||
|
Rails.logger.info "Cleaned up duplicate policy rules with same expiration times"
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user