Fix #4666: Broken network link for some IPs.
This commit is contained in:
@@ -17,7 +17,7 @@ class IpAddressesController < ApplicationController
|
|||||||
|
|
||||||
def show
|
def show
|
||||||
@ip_address = authorize IpAddress.new(ip_addr: params[:id])
|
@ip_address = authorize IpAddress.new(ip_addr: params[:id])
|
||||||
@ip_info = @ip_address.lookup.response
|
@ip_info = @ip_address.ip_addr.ip_info
|
||||||
respond_with(@ip_info)
|
respond_with(@ip_info)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -24,6 +24,20 @@ module Danbooru
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# If we're being reverse proxied behind Cloudflare, then Tor connections
|
||||||
|
# will appear to originate from 2405:8100:8000::/48.
|
||||||
|
# https://blog.cloudflare.com/cloudflare-onion-service/
|
||||||
|
def is_tor?
|
||||||
|
Danbooru::IpAddress.new("2405:8100:8000::/48").include?(ip_address)
|
||||||
|
end
|
||||||
|
|
||||||
|
def include?(other)
|
||||||
|
other = Danbooru::IpAddress.new(other)
|
||||||
|
return false if (ipv4? && other.ipv6?) || (ipv6? && other.ipv4?)
|
||||||
|
|
||||||
|
ip_address.include?(other.ip_address)
|
||||||
|
end
|
||||||
|
|
||||||
# "1.2.3.4/24" if the address is a subnet, "1.2.3.4" otherwise.
|
# "1.2.3.4/24" if the address is a subnet, "1.2.3.4" otherwise.
|
||||||
def to_s
|
def to_s
|
||||||
ip_address.size > 1 ? ip_address.to_string : ip_address.to_s
|
ip_address.size > 1 ? ip_address.to_string : ip_address.to_s
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class IpLookup
|
|||||||
|
|
||||||
def ip_info
|
def ip_info
|
||||||
return {} if ip_addr.is_local?
|
return {} if ip_addr.is_local?
|
||||||
|
return {} if ip_addr.is_tor?
|
||||||
return {} if response.blank?
|
return {} if response.blank?
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -45,6 +46,7 @@ class IpLookup
|
|||||||
end
|
end
|
||||||
|
|
||||||
def is_proxy?
|
def is_proxy?
|
||||||
|
return true if ip_addr.is_tor?
|
||||||
response[:security].present? && response[:security].values.any?
|
response[:security].present? && response[:security].values.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,70 +1,84 @@
|
|||||||
<div class="space-x-4">
|
<div class="space-x-4">
|
||||||
<div class="inline-block">
|
<div class="inline-block">
|
||||||
<table class="aligned-vertical">
|
<table class="aligned-vertical">
|
||||||
<tr>
|
<% if ip_info[:country].present? %>
|
||||||
<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.ip_matches(ip_address.ip_addr.to_s).exists? %>
|
|
||||||
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>
|
<tr>
|
||||||
<th>Mobile Carrier</th>
|
<th>Location</th>
|
||||||
<td><%= ip_info.dig(:carrier, :name) %></td>
|
<td>
|
||||||
|
<% if ip_info[:city] %>
|
||||||
|
<%= ip_info[:city] %>,
|
||||||
|
<% end %>
|
||||||
|
<% if ip_info[:region].present? %>
|
||||||
|
<%= ip_info[:region] %>,
|
||||||
|
<% end %>
|
||||||
|
<%= ip_info[:country] %>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<% if ip_info[:network].present? %>
|
||||||
|
<tr>
|
||||||
|
<th>Network</th>
|
||||||
|
<td>
|
||||||
|
<%= link_to ip_info[:network], ip_addresses_path(search: { ip_addr: ip_info[:network] }) %>
|
||||||
|
(<%= link_to "info", "https://ipinfo.io/AS#{ip_info[:asn]}/#{ip_info[:network]}" %>)
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>Website</th>
|
<th>Proxy?</th>
|
||||||
<td><%= external_link_to("http://#{ip_info.dig(:connection, :domain)}") %></td>
|
<td><%= ip_address.ip_addr.is_proxy? ? "Yes" : "No" %></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<% if ip_address.ip_addr.is_tor? %>
|
||||||
|
<tr>
|
||||||
|
<th>Tor?</th>
|
||||||
|
<td>Yes</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th>IP Banned?</th>
|
||||||
|
<td>
|
||||||
|
<% if IpBan.ip_matches(ip_address.ip_addr.to_s).exists? %>
|
||||||
|
Yes (<%= link_to "info", ip_bans_path(search: { ip_addr: ip_address.ip_addr.to_s }) %>)
|
||||||
|
<% else %>
|
||||||
|
No
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<% if ip_info[:asn].present? %>
|
||||||
|
<tr>
|
||||||
|
<th>ASN</th>
|
||||||
|
<td>
|
||||||
|
<%= link_to "AS#{ip_info[:asn]}", "https://ipinfo.io/AS#{ip_info[:asn]}" %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if ip_info[:organization].present? %>
|
||||||
|
<tr>
|
||||||
|
<th>Organization</th>
|
||||||
|
<td>
|
||||||
|
<%= ip_info[:organization] %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if ip_info[:carrier].present? %>
|
||||||
|
<tr>
|
||||||
|
<th>Mobile Carrier</th>
|
||||||
|
<td><%= ip_info[:carrier] %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>Details</th>
|
<th>Details</th>
|
||||||
<td>
|
<td>
|
||||||
<details>
|
<details>
|
||||||
<pre><%= JSON.pretty_generate(ip_info) %></pre>
|
<pre><%= JSON.pretty_generate(ip_address.lookup.response) %></pre>
|
||||||
</details>
|
</details>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -72,6 +86,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="inline-block align-top">
|
<div class="inline-block align-top">
|
||||||
<%= embedded_map(ip_info.dig(:location, :latitude), ip_info.dig(:location, :longitude), 300, 200) %>
|
<% if ip_info[:latitude].present? && ip_info[:longitude].present? %>
|
||||||
|
<%= embedded_map(ip_info[:latitude], ip_info[:longitude], 300, 200) %>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -51,6 +51,11 @@ class IpAddressesControllerTest < ActionDispatch::IntegrationTest
|
|||||||
get_auth ip_address_path("1.2.3.4"), @user
|
get_auth ip_address_path("1.2.3.4"), @user
|
||||||
assert_response 403
|
assert_response 403
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "work for a Tor address" do
|
||||||
|
get_auth ip_address_path("2405:8100:8000::1"), @mod
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user