Tidy up homepage and navigation
This commit is contained in:
@@ -3,15 +3,14 @@
|
||||
class RulesController < ApplicationController
|
||||
# Follow proper before_action order:
|
||||
# 1. Authentication/Authorization
|
||||
allow_unauthenticated_access only: [:index, :show]
|
||||
# All actions require authentication
|
||||
|
||||
# 2. Resource loading
|
||||
before_action :set_rule, only: [:show, :edit, :update, :disable, :enable]
|
||||
before_action :set_project, only: [:index, :show]
|
||||
|
||||
# GET /rules
|
||||
def index
|
||||
@rules = policy_scope(Rule).includes(:user, :network_range).order(created_at: :desc)
|
||||
@pagy, @rules = pagy(policy_scope(Rule).includes(:user, :network_range).order(created_at: :desc))
|
||||
@rule_types = Rule::RULE_TYPES
|
||||
@actions = Rule::ACTIONS
|
||||
end
|
||||
@@ -43,6 +42,9 @@ class RulesController < ApplicationController
|
||||
@rule_types = Rule::RULE_TYPES
|
||||
@actions = Rule::ACTIONS
|
||||
|
||||
# Process additional form data for quick create
|
||||
process_quick_create_parameters
|
||||
|
||||
# Handle network range creation if CIDR is provided
|
||||
if params[:cidr].present? && @rule.network_rule?
|
||||
network_range = NetworkRange.find_or_create_by(cidr: params[:cidr]) do |range|
|
||||
@@ -53,8 +55,17 @@ class RulesController < ApplicationController
|
||||
@rule.network_range = network_range
|
||||
end
|
||||
|
||||
# Calculate priority automatically based on rule type
|
||||
calculate_rule_priority
|
||||
|
||||
if @rule.save
|
||||
redirect_to @rule, notice: 'Rule was successfully created.'
|
||||
# For quick create from NetworkRange page, redirect back to network range
|
||||
if params[:rule][:network_range_id].present? && request.referer&.include?('/network_ranges/')
|
||||
network_range = NetworkRange.find(params[:rule][:network_range_id])
|
||||
redirect_to network_range, notice: 'Rule was successfully created.'
|
||||
else
|
||||
redirect_to @rule, notice: 'Rule was successfully created.'
|
||||
end
|
||||
else
|
||||
render :new, status: :unprocessable_entity
|
||||
end
|
||||
@@ -122,13 +133,236 @@ class RulesController < ApplicationController
|
||||
params.require(:rule).permit(permitted)
|
||||
end
|
||||
|
||||
def set_project
|
||||
# For now, use the first project or create a default one
|
||||
@project = Project.first || Project.create!(
|
||||
name: 'Default Project',
|
||||
slug: 'default',
|
||||
public_key: SecureRandom.hex(32)
|
||||
)
|
||||
def calculate_rule_priority
|
||||
return unless @rule
|
||||
|
||||
case @rule.rule_type
|
||||
when 'network'
|
||||
# For network rules, priority based on prefix specificity
|
||||
if @rule.network_range
|
||||
prefix = @rule.network_range.prefix_length
|
||||
@rule.priority = case prefix
|
||||
when 32 then 200 # /32 single IP
|
||||
when 31 then 190
|
||||
when 30 then 180
|
||||
when 29 then 170
|
||||
when 28 then 160
|
||||
when 27 then 150
|
||||
when 26 then 140
|
||||
when 25 then 130
|
||||
when 24 then 120
|
||||
when 23 then 110
|
||||
when 22 then 100
|
||||
when 21 then 90
|
||||
when 20 then 80
|
||||
when 19 then 70
|
||||
when 18 then 60
|
||||
when 17 then 50
|
||||
when 16 then 40
|
||||
when 15 then 30
|
||||
when 14 then 20
|
||||
when 13 then 10
|
||||
else 0
|
||||
end
|
||||
else
|
||||
@rule.priority = 100 # Default for network rules without range
|
||||
end
|
||||
when 'protocol_violation'
|
||||
@rule.priority = 95
|
||||
when 'method_enforcement'
|
||||
@rule.priority = 90
|
||||
when 'path_pattern'
|
||||
@rule.priority = 85
|
||||
when 'header_pattern', 'query_pattern'
|
||||
@rule.priority = 80
|
||||
when 'body_signature'
|
||||
@rule.priority = 75
|
||||
when 'rate_limit'
|
||||
@rule.priority = 70
|
||||
when 'composite'
|
||||
@rule.priority = 65
|
||||
else
|
||||
@rule.priority = 50 # Default priority
|
||||
end
|
||||
end
|
||||
|
||||
def process_quick_create_parameters
|
||||
return unless @rule
|
||||
|
||||
# Handle rate limiting parameters
|
||||
if @rule.rate_limit_rule? && params[:rate_limit].present? && params[:rate_window].present?
|
||||
rate_limit_data = {
|
||||
limit: params[:rate_limit].to_i,
|
||||
window_seconds: params[:rate_window].to_i,
|
||||
scope: 'per_ip'
|
||||
}
|
||||
|
||||
# Update conditions with rate limit data
|
||||
@rule.conditions ||= {}
|
||||
@rule.conditions.merge!(rate_limit_data)
|
||||
end
|
||||
|
||||
end
|
||||
# Handle redirect URL
|
||||
if @rule.action == 'redirect' && params[:redirect_url].present?
|
||||
@rule.metadata ||= {}
|
||||
if @rule.metadata.is_a?(String)
|
||||
begin
|
||||
@rule.metadata = JSON.parse(@rule.metadata)
|
||||
rescue JSON::ParserError
|
||||
@rule.metadata = {}
|
||||
end
|
||||
end
|
||||
@rule.metadata.merge!({
|
||||
redirect_url: params[:redirect_url],
|
||||
redirect_status: 302
|
||||
})
|
||||
end
|
||||
|
||||
# Parse metadata if it's a string that looks like JSON
|
||||
if @rule.metadata.is_a?(String) && @rule.metadata.starts_with?('{')
|
||||
begin
|
||||
@rule.metadata = JSON.parse(@rule.metadata)
|
||||
rescue JSON::ParserError
|
||||
# Keep as string if not valid JSON
|
||||
end
|
||||
end
|
||||
|
||||
# Add reason to metadata if provided
|
||||
if params.dig(:rule, :metadata).present?
|
||||
if @rule.metadata.is_a?(Hash)
|
||||
@rule.metadata['reason'] = params[:rule][:metadata]
|
||||
else
|
||||
@rule.metadata = { 'reason' => params[:rule][:metadata] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_rule
|
||||
@rule = Rule.find(params[:id])
|
||||
end
|
||||
|
||||
def rule_params
|
||||
permitted = [
|
||||
:rule_type,
|
||||
:action,
|
||||
:metadata,
|
||||
:expires_at,
|
||||
:enabled,
|
||||
:source,
|
||||
:network_range_id
|
||||
]
|
||||
|
||||
# Only include conditions for non-network rules
|
||||
if params[:rule][:rule_type] != 'network'
|
||||
permitted << :conditions
|
||||
end
|
||||
|
||||
params.require(:rule).permit(permitted)
|
||||
end
|
||||
|
||||
def calculate_rule_priority
|
||||
return unless @rule
|
||||
|
||||
case @rule.rule_type
|
||||
when 'network'
|
||||
# For network rules, priority based on prefix specificity
|
||||
if @rule.network_range
|
||||
prefix = @rule.network_range.prefix_length
|
||||
@rule.priority = case prefix
|
||||
when 32 then 200 # /32 single IP
|
||||
when 31 then 190
|
||||
when 30 then 180
|
||||
when 29 then 170
|
||||
when 28 then 160
|
||||
when 27 then 150
|
||||
when 26 then 140
|
||||
when 25 then 130
|
||||
when 24 then 120
|
||||
when 23 then 110
|
||||
when 22 then 100
|
||||
when 21 then 90
|
||||
when 20 then 80
|
||||
when 19 then 70
|
||||
when 18 then 60
|
||||
when 17 then 50
|
||||
when 16 then 40
|
||||
when 15 then 30
|
||||
when 14 then 20
|
||||
when 13 then 10
|
||||
else 0
|
||||
end
|
||||
else
|
||||
@rule.priority = 100 # Default for network rules without range
|
||||
end
|
||||
when 'protocol_violation'
|
||||
@rule.priority = 95
|
||||
when 'method_enforcement'
|
||||
@rule.priority = 90
|
||||
when 'path_pattern'
|
||||
@rule.priority = 85
|
||||
when 'header_pattern', 'query_pattern'
|
||||
@rule.priority = 80
|
||||
when 'body_signature'
|
||||
@rule.priority = 75
|
||||
when 'rate_limit'
|
||||
@rule.priority = 70
|
||||
when 'composite'
|
||||
@rule.priority = 65
|
||||
else
|
||||
@rule.priority = 50 # Default priority
|
||||
end
|
||||
end
|
||||
|
||||
def process_quick_create_parameters
|
||||
return unless @rule
|
||||
|
||||
# Handle rate limiting parameters
|
||||
if @rule.rate_limit_rule? && params[:rate_limit].present? && params[:rate_window].present?
|
||||
rate_limit_data = {
|
||||
limit: params[:rate_limit].to_i,
|
||||
window_seconds: params[:rate_window].to_i,
|
||||
scope: 'per_ip'
|
||||
}
|
||||
|
||||
# Update conditions with rate limit data
|
||||
@rule.conditions ||= {}
|
||||
@rule.conditions.merge!(rate_limit_data)
|
||||
end
|
||||
|
||||
# Handle redirect URL
|
||||
if @rule.action == 'redirect' && params[:redirect_url].present?
|
||||
@rule.metadata ||= {}
|
||||
if @rule.metadata.is_a?(String)
|
||||
begin
|
||||
@rule.metadata = JSON.parse(@rule.metadata)
|
||||
rescue JSON::ParserError
|
||||
@rule.metadata = {}
|
||||
end
|
||||
end
|
||||
@rule.metadata.merge!({
|
||||
redirect_url: params[:redirect_url],
|
||||
redirect_status: 302
|
||||
})
|
||||
end
|
||||
|
||||
# Parse metadata if it's a string that looks like JSON
|
||||
if @rule.metadata.is_a?(String) && @rule.metadata.starts_with?('{')
|
||||
begin
|
||||
@rule.metadata = JSON.parse(@rule.metadata)
|
||||
rescue JSON::ParserError
|
||||
# Keep as string if not valid JSON
|
||||
end
|
||||
end
|
||||
|
||||
# Add reason to metadata if provided
|
||||
if params.dig(:rule, :metadata).present?
|
||||
if @rule.metadata.is_a?(Hash)
|
||||
@rule.metadata['reason'] = params[:rule][:metadata]
|
||||
else
|
||||
@rule.metadata = { 'reason' => params[:rule][:metadata] }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user