270 lines
12 KiB
Plaintext
270 lines
12 KiB
Plaintext
<% content_for :title, @waf_policy.name %>
|
|
|
|
<div class="space-y-6">
|
|
<!-- Header -->
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<h1 class="text-3xl font-bold text-gray-900"><%= @waf_policy.name %></h1>
|
|
<p class="mt-2 text-gray-600"><%= @waf_policy.description %></p>
|
|
</div>
|
|
<div class="flex space-x-3">
|
|
<%= link_to "← Back to Policies", waf_policies_path,
|
|
class: "inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50" %>
|
|
<%= link_to "Edit", edit_waf_policy_path(@waf_policy),
|
|
class: "inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50" %>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Policy Details -->
|
|
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
|
|
<div class="px-4 py-5 sm:px-6">
|
|
<h3 class="text-lg leading-6 font-medium text-gray-900">📋 Policy Details</h3>
|
|
</div>
|
|
<div class="border-t border-gray-200">
|
|
<dl>
|
|
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
|
<dt class="text-sm font-medium text-gray-500">Policy Type</dt>
|
|
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
|
|
<%= @waf_policy.policy_type.humanize %>
|
|
</span>
|
|
</dd>
|
|
</div>
|
|
|
|
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
|
<dt class="text-sm font-medium text-gray-500">Policy Action</dt>
|
|
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
|
|
<%= case @waf_policy.policy_action
|
|
when 'deny' then 'bg-red-100 text-red-800'
|
|
when 'allow' then 'bg-green-100 text-green-800'
|
|
when 'redirect' then 'bg-yellow-100 text-yellow-800'
|
|
when 'challenge' then 'bg-purple-100 text-purple-800'
|
|
end %>">
|
|
<%= @waf_policy.policy_action.upcase %>
|
|
</span>
|
|
</dd>
|
|
</div>
|
|
|
|
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
|
<dt class="text-sm font-medium text-gray-500">Targets</dt>
|
|
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
|
<% if @waf_policy.targets.any? %>
|
|
<div class="flex flex-wrap gap-2">
|
|
<% @waf_policy.targets.each do |target| %>
|
|
<% if @waf_policy.country_policy? %>
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
|
|
<%= CountryHelper.display_with_flag(target) %>
|
|
</span>
|
|
<% else %>
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
|
|
<%= target %>
|
|
</span>
|
|
<% end %>
|
|
<% end %>
|
|
</div>
|
|
<% else %>
|
|
<span class="text-gray-400">No targets configured</span>
|
|
<% end %>
|
|
</dd>
|
|
</div>
|
|
|
|
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
|
<dt class="text-sm font-medium text-gray-500">Status</dt>
|
|
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
|
<div class="flex items-center space-x-4">
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
|
|
<%= @waf_policy.active? ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800' %>">
|
|
<%= @waf_policy.active? ? 'Active' : 'Inactive' %>
|
|
</span>
|
|
|
|
<% if @waf_policy.active? %>
|
|
<%= link_to "Deactivate", deactivate_waf_policy_path(@waf_policy), method: :post,
|
|
data: { confirm: "Are you sure you want to deactivate this policy?" },
|
|
class: "text-sm text-red-600 hover:text-red-900" %>
|
|
<% else %>
|
|
<%= link_to "Activate", activate_waf_policy_path(@waf_policy), method: :post,
|
|
class: "text-sm text-green-600 hover:text-green-900" %>
|
|
<% end %>
|
|
</div>
|
|
</dd>
|
|
</div>
|
|
|
|
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
|
<dt class="text-sm font-medium text-gray-500">Expires At</dt>
|
|
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
|
<% if @waf_policy.expires_at.present? %>
|
|
<%= @waf_policy.expires_at.strftime("%B %d, %Y at %I:%M %p") %>
|
|
<% if @waf_policy.expired? %>
|
|
<span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
|
|
Expired
|
|
</span>
|
|
<% end %>
|
|
<% else %>
|
|
<span class="text-gray-400">Never expires</span>
|
|
<% end %>
|
|
</dd>
|
|
</div>
|
|
|
|
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
|
<dt class="text-sm font-medium text-gray-500">Created By</dt>
|
|
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
|
<%= @waf_policy.user.email_address %>
|
|
</dd>
|
|
</div>
|
|
|
|
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
|
<dt class="text-sm font-medium text-gray-500">Created</dt>
|
|
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
|
<%= @waf_policy.created_at.strftime("%B %d, %Y at %I:%M %p") %>
|
|
</dd>
|
|
</div>
|
|
|
|
<!-- Additional Configuration -->
|
|
<% if @waf_policy.additional_data && @waf_policy.additional_data.any? %>
|
|
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
|
<dt class="text-sm font-medium text-gray-500">Additional Config</dt>
|
|
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
|
<% @waf_policy.additional_data.each do |key, value| %>
|
|
<div class="mb-2">
|
|
<span class="font-medium"><%= key.humanize %>:</span>
|
|
<span class="text-gray-600"><%= value %></span>
|
|
</div>
|
|
<% end %>
|
|
</dd>
|
|
</div>
|
|
<% end %>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Statistics -->
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
<div class="bg-white overflow-hidden shadow rounded-lg">
|
|
<div class="p-5">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-6 w-6 text-blue-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt class="text-sm font-medium text-gray-500 truncate">Generated Rules</dt>
|
|
<dd class="text-lg font-medium text-gray-900"><%= @waf_policy.generated_rules_count %></dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white overflow-hidden shadow rounded-lg">
|
|
<div class="p-5">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-6 w-6 text-green-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt class="text-sm font-medium text-gray-500 truncate">Active Rules</dt>
|
|
<dd class="text-lg font-medium text-gray-900"><%= @waf_policy.active_rules_count %></dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white overflow-hidden shadow rounded-lg">
|
|
<div class="p-5">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-6 w-6 text-yellow-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt class="text-sm font-medium text-gray-500 truncate">Rules Last 7 Days</dt>
|
|
<dd class="text-lg font-medium text-gray-900"><%= @waf_policy.effectiveness_stats[:rules_last_7_days] %></dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white overflow-hidden shadow rounded-lg">
|
|
<div class="p-5">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-6 w-6 text-purple-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt class="text-sm font-medium text-gray-500 truncate">Efficiency Rate</dt>
|
|
<dd class="text-lg font-medium text-gray-900">
|
|
<%= @waf_policy.active_rules_count.to_f / [@waf_policy.generated_rules_count, 1].max * 100 %>%
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Generated Rules -->
|
|
<% if @generated_rules.any? %>
|
|
<div class="bg-white shadow overflow-hidden sm:rounded-md">
|
|
<div class="px-4 py-5 sm:px-6">
|
|
<h3 class="text-lg leading-6 font-medium text-gray-900">🔧 Generated Rules</h3>
|
|
<p class="mt-1 max-w-2xl text-sm text-gray-500">
|
|
Specific rules created by this policy that are enforced by baffle-agents.
|
|
</p>
|
|
</div>
|
|
<div class="border-t border-gray-200">
|
|
<ul class="divide-y divide-gray-200">
|
|
<% @generated_rules.each do |rule| %>
|
|
<li class="hover:bg-gray-50">
|
|
<div class="px-4 py-4 sm:px-6">
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<%= link_to "📋", rule_path(rule), class: "text-blue-600 hover:text-blue-900" %>
|
|
</div>
|
|
<div class="ml-4">
|
|
<div class="text-sm font-medium text-gray-900">
|
|
Rule #<%= rule.id %> - <%= rule.network_range&.cidr || "Unknown" %>
|
|
</div>
|
|
<div class="text-sm text-gray-500">
|
|
<%= rule.waf_action.upcase %> • Created <%= time_ago_in_words(rule.created_at) %> ago
|
|
<% if rule.redirect_action? %>
|
|
• Redirect to <%= rule.redirect_url %>
|
|
<% elsif rule.challenge_action? %>
|
|
• <%= rule.challenge_type.humanize %> challenge
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center space-x-2">
|
|
<% if rule.active? %>
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
|
|
Active
|
|
</span>
|
|
<% else %>
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
|
|
Inactive
|
|
</span>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<% end %>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</div> |