Files
baffle-hub/app/controllers/waf_policies_controller.rb
2025-11-13 14:42:43 +11:00

170 lines
4.7 KiB
Ruby

# frozen_string_literal: true
class WafPoliciesController < ApplicationController
# Follow proper before_action order:
# 1. Authentication/Authorization
# All actions require authentication
# 2. Resource loading
before_action :set_waf_policy, only: [:show, :edit, :update, :destroy, :activate, :deactivate]
# GET /waf_policies
def index
@pagy, @waf_policies = pagy(policy_scope(WafPolicy).includes(:user, :generated_rules).order(created_at: :desc))
@policy_types = WafPolicy::POLICY_TYPES
@actions = WafPolicy::ACTIONS
end
# GET /waf_policies/new
def new
authorize WafPolicy
@waf_policy = WafPolicy.new
@policy_types = WafPolicy::POLICY_TYPES
@actions = WafPolicy::ACTIONS
# Set default values from URL parameters
@waf_policy.policy_type = params[:policy_type] if params[:policy_type].present?
@waf_policy.policy_action = params[:policy_action] if params[:policy_action].present?
@waf_policy.targets = params[:targets] if params[:targets].present?
end
# POST /waf_policies
def create
authorize WafPolicy
@waf_policy = WafPolicy.new(waf_policy_params)
@waf_policy.user = Current.user
@policy_types = WafPolicy::POLICY_TYPES
@actions = WafPolicy::ACTIONS
if @waf_policy.save
redirect_to @waf_policy, notice: 'WAF policy was successfully created.'
else
render :new, status: :unprocessable_entity
end
end
# GET /waf_policies/:id
def show
@generated_rules = @waf_policy.generated_rules.includes(:network_range).order(created_at: :desc).limit(20)
@effectiveness_stats = @waf_policy.effectiveness_stats
end
# GET /waf_policies/:id/edit
def edit
@policy_types = WafPolicy::POLICY_TYPES
@actions = WafPolicy::ACTIONS
end
# PATCH/PUT /waf_policies/:id
def update
@policy_types = WafPolicy::POLICY_TYPES
@actions = WafPolicy::ACTIONS
if @waf_policy.update(waf_policy_params)
redirect_to @waf_policy, notice: 'WAF policy was successfully updated.'
else
render :edit, status: :unprocessable_entity
end
end
# DELETE /waf_policies/:id
def destroy
policy_name = @waf_policy.name
# Soft delete by disabling and expiring the policy
@waf_policy.update!(enabled: false, expires_at: Time.current)
redirect_to waf_policies_url, notice: "WAF policy '#{policy_name}' was disabled."
end
# POST /waf_policies/:id/activate
def activate
@waf_policy.activate!
redirect_to @waf_policy, notice: 'WAF policy was activated.'
end
# POST /waf_policies/:id/deactivate
def deactivate
@waf_policy.deactivate!
redirect_to @waf_policy, notice: 'WAF policy was deactivated.'
end
# GET /waf_policies/new_country
def new_country
authorize WafPolicy
@waf_policy = WafPolicy.new(policy_type: 'country', policy_action: 'deny')
@policy_types = WafPolicy::POLICY_TYPES
@actions = WafPolicy::ACTIONS
end
# POST /waf_policies/create_country
def create_country
authorize WafPolicy
countries = params[:countries]&.reject(&:blank?) || []
policy_action = params[:policy_action] || 'deny'
if countries.empty?
redirect_to new_country_waf_policies_path, alert: 'Please select at least one country.'
return
end
# Build the options hash with additional_data if present
options = {
policy_action: policy_action,
user: Current.user,
description: params[:description]
}
# Add additional_data if provided (for redirect/challenge actions)
if params[:additional_data].present?
options[:additional_data] = params[:additional_data].to_unsafe_hash
end
@waf_policy = WafPolicy.create_country_policy(countries, **options)
if @waf_policy.persisted?
redirect_to @waf_policy, notice: "Country blocking policy was successfully created for #{countries.join(', ')}."
else
@policy_types = WafPolicy::POLICY_TYPES
@actions = WafPolicy::ACTIONS
render :new_country, status: :unprocessable_entity
end
end
private
def set_waf_policy
# First try to find by ID (standard Rails behavior)
if params[:id] =~ /^\d+$/
@waf_policy = WafPolicy.find_by(id: params[:id])
end
# If not found by ID, try to find by parameterized name
unless @waf_policy
# Try direct parameterized comparison by parameterizing existing policy names
@waf_policy = WafPolicy.all.find { |policy| policy.to_param == params[:id] }
end
if @waf_policy
authorize @waf_policy
else
redirect_to waf_policies_path, alert: 'WAF policy not found.'
end
end
def waf_policy_params
params.require(:waf_policy).permit(
:name,
:description,
:policy_type,
:policy_action,
:enabled,
:expires_at,
targets: [],
additional_data: {}
)
end
end