/ip_addresses: allow grouping IPs by subnet.
This commit is contained in:
@@ -4,10 +4,10 @@ class IpAddressesController < ApplicationController
|
|||||||
|
|
||||||
def index
|
def index
|
||||||
if search_params[:group_by] == "ip_addr"
|
if search_params[:group_by] == "ip_addr"
|
||||||
@ip_addresses = IpAddress.search(search_params).group_by_ip_addr
|
@ip_addresses = IpAddress.search(search_params).group_by_ip_addr(search_params[:ipv4_masklen], search_params[:ipv6_masklen]).paginate(params[:page], limit: params[:limit] || 1000)
|
||||||
respond_with(@ip_addresses)
|
respond_with(@ip_addresses)
|
||||||
elsif search_params[:group_by] == "user"
|
elsif search_params[:group_by] == "user"
|
||||||
@ip_addresses = IpAddress.search(search_params).group_by_user
|
@ip_addresses = IpAddress.includes(:user).search(search_params).group_by_user.paginate(params[:page], limit: params[:limit] || 1000)
|
||||||
respond_with(@ip_addresses)
|
respond_with(@ip_addresses)
|
||||||
else
|
else
|
||||||
@ip_addresses = IpAddress.includes(:user, :model).paginated_search(params)
|
@ip_addresses = IpAddress.includes(:user, :model).paginated_search(params)
|
||||||
|
|||||||
@@ -14,14 +14,31 @@ class IpAddress < ApplicationRecord
|
|||||||
q.order(created_at: :desc)
|
q.order(created_at: :desc)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.group_by_ip_addr
|
def self.group_by_ip_addr(ipv4_masklen = nil, ipv6_masklen = nil)
|
||||||
group(:ip_addr).select("ip_addr, COUNT(*) AS count_all").reorder("count_all DESC, ip_addr")
|
ipv4_masklen ||= 32
|
||||||
|
ipv6_masklen ||= 128
|
||||||
|
|
||||||
|
q = select(sanitize_sql([<<~SQL, ipv4_masklen, ipv6_masklen]))
|
||||||
|
CASE
|
||||||
|
WHEN family(ip_addr) = 4
|
||||||
|
THEN network(set_masklen(ip_addr, ?))
|
||||||
|
ELSE network(set_masklen(ip_addr, ?))
|
||||||
|
END AS ip_addr,
|
||||||
|
COUNT(*) AS count_all
|
||||||
|
SQL
|
||||||
|
|
||||||
|
q.group("1").reorder("count_all DESC, ip_addr")
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.group_by_user
|
def self.group_by_user
|
||||||
group(:user_id).select("user_id, COUNT(*) AS count_all").reorder("count_all DESC, user_id")
|
group(:user_id).select("user_id, COUNT(*) AS count_all").reorder("count_all DESC, user_id")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
# include the subnet mask only when the IP denotes a subnet.
|
||||||
|
ip_addr.size > 1 ? ip_addr.to_string : ip_addr.to_s
|
||||||
|
end
|
||||||
|
|
||||||
def readonly?
|
def readonly?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
<% @ip_addresses.each do |ip| %>
|
<% @ip_addresses.each do |ip| %>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<%= link_to ip.ip_addr, ip_addresses_path(search: { ip_addr: ip.ip_addr }) %>
|
<%= link_to ip.to_s, ip_addresses_path(search: { ip_addr: ip.to_s }) %>
|
||||||
<%= link_to "»", ip_addresses_path(search: { ip_addr: ip.ip_addr, group_by: "user" }) %>
|
<%= link_to "»", ip_addresses_path(search: { ip_addr: ip.to_s, group_by: "user" }) %>
|
||||||
</td>
|
</td>
|
||||||
<td><%= link_to ip.count_all, ip_addresses_path(search: { ip_addr: ip.ip_addr }) %></td>
|
<td><%= link_to ip.count_all, ip_addresses_path(search: { ip_addr: ip.to_s }) %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
<%= f.input :created_at, label: "Date", input_html: { value: params[:search][:created_at] } %>
|
<%= f.input :created_at, label: "Date", input_html: { value: params[:search][:created_at] } %>
|
||||||
<%= f.input :model_type, label: "Source", collection: IpAddress.model_types, include_blank: true, selected: params[:search][:model_type] %>
|
<%= f.input :model_type, label: "Source", collection: IpAddress.model_types, include_blank: true, selected: params[:search][:model_type] %>
|
||||||
<%= f.input :group_by, label: "Group By", collection: [["User", "user"], ["IP Address", "ip_addr"]], include_blank: true, selected: params[:search][:group_by] %>
|
<%= f.input :group_by, label: "Group By", collection: [["User", "user"], ["IP Address", "ip_addr"]], include_blank: true, selected: params[:search][:group_by] %>
|
||||||
|
<% if params[:search][:group_by] == "ip_addr" %>
|
||||||
|
<%= f.input :ipv4_masklen, label: "IPv4 Subnet", collection: [["/32", 32], ["/24", 24], ["/16", 16], ["/8", 8]], include_blank: false, selected: params[:search][:ipv4_masklen], hint: "Lower to group together IPs with the same prefix." %>
|
||||||
|
<%= f.input :ipv6_masklen, label: "IPv6 Subnet", collection: [["/128", 128], ["/80", 80], ["/64", 64], ["/48", 48]], include_blank: false, selected: params[:search][:ipv6_masklen] %>
|
||||||
|
<% end %>
|
||||||
<%= f.submit "Search" %>
|
<%= f.submit "Search" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user