ip addresses: add ip address show page.

* Add IP address show page at /ip_addresses/1.2.3.4.
* Add "Details", "Ban IP", "Ban User" options to the /ip_addresses listing.
This commit is contained in:
evazion
2020-03-22 23:28:40 -05:00
parent 13dab1510c
commit f23df47c09
11 changed files with 130 additions and 9 deletions

View File

@@ -14,4 +14,10 @@ class IpAddressesController < ApplicationController
respond_with(@ip_addresses)
end
def show
@ip_address = IpAddress.new(ip_addr: params[:id])
@ip_info = @ip_address.lookup.info
respond_with(@ip_info)
end
end

View File

@@ -0,0 +1,11 @@
module IpAddressesHelper
def embedded_google_map(location, width, height, api_key: Danbooru.config.google_maps_api_key)
tag.iframe(
width: width,
height: height,
frameborder: 0,
allowfullscreen: true,
src: "https://www.google.com/maps/embed/v1/search?q=#{location}&key=#{api_key}"
)
end
end

View File

@@ -0,0 +1,7 @@
#c-ip-addresses {
.ip-address-details, .ip-address-map {
display: inline-block;
margin-right: 2em;
vertical-align: top;
}
}

View File

@@ -1,14 +1,14 @@
<%= table_for @ip_addresses, {class: "striped autofit"} do |t| %>
<% t.column "IP Address" do |ip| %>
<%= link_to ip.ip_addr, ip_addresses_path(search: { ip_addr: ip.ip_addr }) %>
<%= link_to "»", ip_addresses_path(search: { ip_addr: ip.ip_addr, group_by: "user" }) %>
<% end %>
<% t.column "Source" do |ip| %>
<%= link_to ip.model_type.underscore.humanize, ip_addresses_path(search: { model_type: ip.model_type }) %>
<% end %>
<% t.column "ID" do |ip| %>
<%= link_to "##{ip.model_id}", ip.model %>
<% end %>
<% t.column "IP Address" do |ip| %>
<%= link_to ip.ip_addr, ip_addresses_path(search: { ip_addr: ip.ip_addr }) %>
<%= link_to "»", ip_addresses_path(search: { ip_addr: ip.ip_addr, group_by: "user" }) %>
<% end %>
<% t.column "User" do |ip| %>
<%= link_to_user ip.user %>
<%= link_to "»", ip_addresses_path(search: { user_id: ip.user_id, group_by: "ip_addr" }) %>
@@ -17,6 +17,8 @@
<%= time_ago_in_words_tagged ip.created_at %>
<% end %>
<% t.column column: "ip-info" do |ip| %>
<%= link_to "IP info", "https://ipinfo.io/#{ip.ip_addr}" %>
<%= link_to "Details", ip_address_path(ip.ip_addr.to_s) %>
| <%= link_to "Ban IP", new_ip_ban_path(ip_ban: { ip_addr: ip.ip_addr.to_s }) %>
| <%= link_to "Ban User", new_ban_path(ban: { user_name: ip.user.name, duration: 999999 }) %>
<% end %>
<% end %>

View File

@@ -11,6 +11,6 @@
<%= link_to ip.count_all, ip_addresses_path(search: { ip_addr: ip.to_s }) %>
<% end %>
<% t.column column: "ip-info" do |ip| %>
<%= link_to "IP info", "https://ipinfo.io/#{ip.ip_addr}" %>
<%= link_to "Details", ip_address_path(ip.ip_addr.to_s) %>
<% end %>
<% end %>

View File

@@ -0,0 +1,75 @@
<div class="ip-address-details">
<table class="aligned-vertical">
<tr>
<th>Location</th>
<td>
<% if ip_info.dig(:location, :city) %>
<%= ip_info.dig(:location, :city) %>,
<% end %>
<% if ip_info.dig(:location, :region, :name).present? %>
<%= ip_info.dig(:location, :region, :name) %>,
<% end %>
<%= ip_info.dig(:location, :country, :name) %>
</td>
</tr>
<tr>
<th>Network</th>
<td>
<%= link_to ip_info.dig(:connection, :route), ip_addresses_path(search: { ip_addr: ip_info.dig(:connection, :route) }) %>
(<%= link_to "info", "https://ipinfo.io/AS#{ip_info.dig(:connection, :asn)}/#{ip_info.dig(:connection, :route)}" %>)
</td>
</tr>
<tr>
<th>Proxy</th>
<td><%= ip_address.lookup.is_proxy? ? "yes" : "no" %></td>
</tr>
<tr>
<th>IP Banned</th>
<td>
<% if IpBan.is_banned?(ip_address.ip_addr.to_s) %>
yes (<%= link_to "info", ip_bans_path(search: { ip_addr: ip_address.to_s }) %>)
<% else %>
no
<% end %>
</td>
</tr>
<tr>
<th>Type</th>
<td><%= ip_info.dig(:connection, :type) %></td>
</tr>
<tr>
<th>ASN</th>
<td>
<%= link_to "AS#{ip_info.dig(:connection, :asn)}", "https://ipinfo.io/AS#{ip_info.dig(:connection, :asn)}" %>
</td>
</tr>
<tr>
<th>Organization</th>
<td>
<%= ip_info.dig(:connection, :organization) %>
</td>
</tr>
<% if ip_info.dig(:carrier, :name).present? %>
<tr>
<th>Mobile Carrier</th>
<td><%= ip_info.dig(:carrier, :name) %></td>
</tr>
<% end %>
<tr>
<th>Website</th>
<td><%= external_link_to("http://#{ip_info.dig(:connection, :domain)}") %></td>
</tr>
<tr>
<th>Details</th>
<td>
<details>
<pre><%= JSON.pretty_generate(ip_info) %></pre>
</details>
</td>
</tr>
</table>
</div>
<div class="ip-address-map">
<%= embedded_google_map("#{ip_info.dig(:location, :latitude)},#{ip_info.dig(:location, :longitude)}", 300, 200) %>
</div>

View File

@@ -1,5 +1,11 @@
<div id="c-ip-addresses">
<div id="a-index">
<% if @ip_address %>
<h1>IP Address: <%= @ip_address.ip_addr %></h1>
<% else %>
<h1>IP Addresses</h1>
<% end %>
<%= search_form_for(ip_addresses_path) do |f| %>
<%= f.input :user_id, label: "User ID", input_html: { value: params[:search][:user_id] }, hint: "Separate with spaces" %>
<%= f.input :user_name, label: "User Name", input_html: { "data-autocomplete": "user", value: params[:search][:user_name] }, hint: "Use * for wildcard" %>

View File

@@ -0,0 +1,7 @@
<div id="c-ip-addresses">
<div id="a-show">
<h1>IP Address: <%= @ip_address.ip_addr %></h1>
<%= render "info", ip_address: @ip_address, ip_info: @ip_info %>
</div>
</div>

View File

@@ -16,8 +16,9 @@
<td>
<% if user.last_ip_addr.present? %>
<%= link_to user.last_ip_addr, ip_addresses_path(search: { ip_addr: user.last_ip_addr }) %>
(<%= link_to "users", ip_addresses_path(search: { ip_addr: user.last_ip_addr, group_by: "user" }) %>,
<%= link_to "IPs", ip_addresses_path(search: { user_id: user.id, group_by: "ip_addr" }) %>)
(<%= link_to "info", ip_address_path(user.last_ip_addr) %>,
<%= link_to "users", ip_addresses_path(search: { ip_addr: user.last_ip_addr, group_by: "user" }) %>,
<%= link_to "IPs", ip_addresses_path(search: { user_id: user.id, group_by: "ip_addr" }) %>)
<% else %>
<em>unknown</em>
(<%= link_to "IPs", ip_addresses_path(search: { user_id: user.id, group_by: "ip_addr" }) %>)

View File

@@ -519,6 +519,12 @@ module Danbooru
nil
end
# API key for Google Maps. Used for embedding maps on IP address lookup pages.
# Generate at https://console.developers.google.com/apis/credentials
def google_maps_api_key
nil
end
# Cloudflare API token. Used to purge URLs from Cloudflare's cache when a
# post is replaced. The token must have 'zone.cache_purge' permissions.
# https://support.cloudflare.com/hc/en-us/articles/200167836-Managing-API-Tokens-and-Keys

View File

@@ -130,7 +130,7 @@ Rails.application.routes.draw do
end
resources :forum_topic_visits, only: [:index]
resources :ip_bans
resources :ip_addresses, only: [:index]
resources :ip_addresses, only: [:show, :index], id: /.+?(?=\.json|\.xml|\.html)|.+/
resource :iqdb_queries, :only => [:show, :create] do
collection do
get :preview