Remove /ip_addresses page.
Remove the /ip_addresses page. This page allowed moderators to search users by IP, and to see recent activity tied to an IP. However, it was limited to IPs tied to uploads, comments, dmails, artist edits, note edits, and wiki edits. Remove this page because it was limited in scope and because there are better ways of doing what it did. The /user_events page is better at catching sockpuppets because it tracks IPs for every login, not just for certain types of edits. And the /user_actions page is better at monitoring user activity because it shows all activity associated with an account, not just for certain types of edits. Removing this allows us to drop IP addresses from all tables besides the user_events table. This is good because these IPs are no longer necessary for any purpose, and because storing them forever is a liability.
This commit is contained in:
@@ -3,21 +3,6 @@
|
||||
class IpAddressesController < ApplicationController
|
||||
respond_to :html, :xml, :json
|
||||
|
||||
def index
|
||||
@ip_addresses = authorize IpAddress.visible(CurrentUser.user).paginated_search(params)
|
||||
|
||||
case search_params[:group_by]
|
||||
when "ip_addr"
|
||||
@ip_addresses = @ip_addresses.group_by_ip_addr(search_params[:ipv4_masklen], search_params[:ipv6_masklen])
|
||||
when "user"
|
||||
@ip_addresses = @ip_addresses.group_by_user.includes(:user)
|
||||
else
|
||||
@ip_addresses = @ip_addresses.includes(:user, :model)
|
||||
end
|
||||
|
||||
respond_with(@ip_addresses)
|
||||
end
|
||||
|
||||
def show
|
||||
@ip_address = authorize IpAddress.new(ip_addr: params[:id])
|
||||
@ip_info = @ip_address.ip_addr.ip_info
|
||||
|
||||
@@ -195,7 +195,7 @@ module ApplicationHelper
|
||||
def link_to_ip(ip, shorten: false, **options)
|
||||
ip_addr = IPAddr.new(ip.to_s)
|
||||
ip_addr.prefix = 64 if ip_addr.ipv6? && shorten
|
||||
link_to ip_addr.to_s, ip_addresses_path(search: { ip_addr: ip, group_by: "user" }), **options
|
||||
link_to ip_addr.to_s, user_events_path(search: { user_session: { ip_addr: ip }}), **options
|
||||
end
|
||||
|
||||
def link_to_search(tag, **options)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class IpAddressPolicy < ApplicationPolicy
|
||||
def index?
|
||||
def show?
|
||||
user.is_moderator?
|
||||
end
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<% content_for(:secondary_links) do %>
|
||||
<%= quick_search_form_for(:user_name, bans_path, "users", autocomplete: "user") %>
|
||||
<%= subnav_link_to "Listing", bans_path %>
|
||||
<% if policy(IpAddress).index? %>
|
||||
<%= subnav_link_to "IP Addresses", ip_addresses_path %>
|
||||
<% end %>
|
||||
<% if policy(IpBan).index? %>
|
||||
<%= subnav_link_to "IP Bans", ip_bans_path %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<%= 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 "User" do |ip| %>
|
||||
<%= link_to_user ip.user %>
|
||||
<%= link_to "»", ip_addresses_path(search: { user_id: ip.user_id, group_by: "ip_addr" }) %>
|
||||
<% end %>
|
||||
<% t.column "Date" do |ip| %>
|
||||
<%= time_ago_in_words_tagged ip.created_at %>
|
||||
<% end %>
|
||||
<% t.column column: "ip-info" do |ip| %>
|
||||
<%= 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 %>
|
||||
@@ -1,16 +0,0 @@
|
||||
<p>
|
||||
<%= link_to "Find all users associated with the top 10 IP addresses", ip_addresses_path(search: { ip_addr: @ip_addresses.map(&:to_s).take(10).join(" "), group_by: "user" }) %>
|
||||
</p>
|
||||
|
||||
<%= table_for @ip_addresses, class: "striped autofit" do |t| %>
|
||||
<% t.column "IP Address" do |ip| %>
|
||||
<%= link_to ip.to_s, ip_addresses_path(search: { ip_addr: ip.to_s }) %>
|
||||
<%= link_to "»", ip_addresses_path(search: { ip_addr: ip.to_s, group_by: "user" }) %>
|
||||
<% end %>
|
||||
<% t.column "Uses" do |ip| %>
|
||||
<%= link_to ip.count_all, ip_addresses_path(search: { ip_addr: ip.to_s }) %>
|
||||
<% end %>
|
||||
<% t.column column: "ip-info" do |ip| %>
|
||||
<%= link_to "Details", ip_address_path(ip.ip_addr.to_s) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
@@ -1,14 +0,0 @@
|
||||
<p>
|
||||
<%= link_to "Find all IP addresses associated with these users", ip_addresses_path(search: { user_id: @ip_addresses.map(&:user_id).join(" "), group_by: "ip_addr" }) %>
|
||||
</p>
|
||||
|
||||
<%= table_for @ip_addresses, class: "striped autofit" do |t| %>
|
||||
<% 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" }) %>
|
||||
<% end %>
|
||||
<% t.column "Uses" do |ip| %>
|
||||
<%= link_to ip.count_all, ip_addresses_path(search: { user_id: ip.user_id, ip_addr: params[:search][:ip_addr] }) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<tr>
|
||||
<th>Network</th>
|
||||
<td>
|
||||
<%= link_to ip_info[:network], ip_addresses_path(search: { ip_addr: ip_info[:network] }) %>
|
||||
<%= link_to ip_info[:network], user_events_path(search: { user_session: { ip_addr: ip_info[:network] }}) %>
|
||||
(<%= link_to "info", "https://ipinfo.io/AS#{ip_info[:asn]}/#{ip_info[:network]}" %>)
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
<% content_for(:secondary_links) do %>
|
||||
<%= quick_search_form_for(:ip_addr, ip_addresses_path, "ip addresses") %>
|
||||
<%= subnav_link_to "Listing", ip_addresses_path %>
|
||||
<%= subnav_link_to "IP Bans", ip_bans_path %>
|
||||
<%= subnav_link_to "Bans", bans_path %>
|
||||
<%= subnav_link_to "Feedbacks", user_feedbacks_path %>
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
<%= render "secondary_links" %>
|
||||
|
||||
<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] } %>
|
||||
<%= f.input :ip_addr, label: "IP Address", input_html: { value: params[:search][:ip_addr] }, hint: '<a href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation">CIDR notation</a> supported.'.html_safe %>
|
||||
<%= 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 :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" %>
|
||||
<% end %>
|
||||
|
||||
<% if params[:search][:group_by] == "user" %>
|
||||
<%= render "index_by_user" %>
|
||||
<% elsif params[:search][:group_by] == "ip_addr" %>
|
||||
<%= render "index_by_ip_addr" %>
|
||||
<% elsif @ip_addresses.present? %>
|
||||
<%= render "index" %>
|
||||
<% end %>
|
||||
|
||||
<%= numbered_paginator(@ip_addresses) %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,9 +1,6 @@
|
||||
<% content_for(:secondary_links) do %>
|
||||
<%= quick_search_form_for(:ip_addr, ip_bans_path, "ip addresses") %>
|
||||
<%= subnav_link_to "Listing", ip_bans_path %>
|
||||
<% if policy(IpAddress).index? %>
|
||||
<%= subnav_link_to "IP Addresses", ip_addresses_path %>
|
||||
<% end %>
|
||||
<%= subnav_link_to "Bans", bans_path %>
|
||||
<%= subnav_link_to "Feedbacks", user_feedbacks_path %>
|
||||
<% if policy(IpBan).create? %>
|
||||
|
||||
@@ -184,10 +184,6 @@
|
||||
<li><%= link_to("Moderation Reports", moderation_reports_path) %></li>
|
||||
<% end %>
|
||||
|
||||
<% if policy(IpAddress).index? %>
|
||||
<li><%= link_to("IP Addresses", ip_addresses_path) %></li>
|
||||
<% end %>
|
||||
|
||||
<% if policy(NewsUpdate).index? %>
|
||||
<li><%= link_to("News Updates", news_updates_path) %></li>
|
||||
<% end %>
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<% content_for(:secondary_links) do %>
|
||||
<%= quick_search_form_for(:user_name, user_feedbacks_path, "users", autocomplete: "user") %>
|
||||
<%= subnav_link_to "Listing", user_feedbacks_path %>
|
||||
<% if policy(IpAddress).index? %>
|
||||
<%= subnav_link_to "IP Addresses", ip_addresses_path %>
|
||||
<% end %>
|
||||
<% if policy(IpBan).index? %>
|
||||
<%= subnav_link_to "IP Bans", ip_bans_path %>
|
||||
<% end %>
|
||||
|
||||
@@ -23,13 +23,9 @@
|
||||
<th>Last IP</th>
|
||||
<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 "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" }) %>)
|
||||
<%= link_to user.last_ip_addr, ip_address_path(user.last_ip_addr) %>
|
||||
<% else %>
|
||||
<em>unknown</em>
|
||||
(<%= link_to "IPs", ip_addresses_path(search: { user_id: user.id, group_by: "ip_addr" }) %>)
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -39,8 +35,12 @@
|
||||
<tr>
|
||||
<th>User Events</th>
|
||||
<td>
|
||||
<% if user.last_ip_addr.present? %>
|
||||
<%= link_to "By Name", user_events_path(search: { user_name: user.name }) %>,
|
||||
<%= link_to "By IP", user_events_path(search: { user_session: { ip_addr: user.last_ip_addr }}) %>
|
||||
<% else %>
|
||||
<%= link_to "By Name", user_events_path(search: { user_name: user.name }) %>
|
||||
<% end %>
|
||||
<td>
|
||||
</tr>
|
||||
<% end %>
|
||||
|
||||
@@ -34,11 +34,6 @@ Rails.application.routes.draw do
|
||||
end
|
||||
end
|
||||
end
|
||||
resources :ip_addrs, :only => [:index, :search] do
|
||||
collection do
|
||||
get :search
|
||||
end
|
||||
end
|
||||
end
|
||||
namespace :explore do
|
||||
resources :posts, :only => [] do
|
||||
@@ -143,7 +138,7 @@ Rails.application.routes.draw do
|
||||
end
|
||||
resources :forum_topic_visits, only: [:index]
|
||||
resources :ip_bans, only: [:index, :new, :create, :update]
|
||||
resources :ip_addresses, only: [:show, :index], id: /.+?(?=\.json|\.xml|\.html)|.+/
|
||||
resources :ip_addresses, only: [:show], id: /.+?(?=\.json|\.xml|\.html)|.+/
|
||||
resources :ip_geolocations, only: [:index]
|
||||
resource :iqdb_queries, :only => [:show, :create] do
|
||||
collection do
|
||||
|
||||
5
db/migrate/20220917204044_drop_ip_addresses_view.rb
Normal file
5
db/migrate/20220917204044_drop_ip_addresses_view.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class DropIpAddressesView < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
drop_view :ip_addresses, revert_to_version: 1
|
||||
end
|
||||
end
|
||||
302
db/structure.sql
302
db/structure.sql
@@ -837,187 +837,6 @@ CREATE TABLE public.good_jobs (
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: note_versions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.note_versions (
|
||||
id integer NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
x integer NOT NULL,
|
||||
y integer NOT NULL,
|
||||
width integer NOT NULL,
|
||||
height integer NOT NULL,
|
||||
body text NOT NULL,
|
||||
updater_ip_addr inet NOT NULL,
|
||||
is_active boolean DEFAULT true NOT NULL,
|
||||
note_id integer NOT NULL,
|
||||
post_id integer NOT NULL,
|
||||
updater_id integer NOT NULL,
|
||||
version integer DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: posts; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.posts (
|
||||
id integer NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
uploader_id integer NOT NULL,
|
||||
score integer DEFAULT 0 NOT NULL,
|
||||
source character varying DEFAULT ''::character varying NOT NULL,
|
||||
md5 character varying NOT NULL,
|
||||
last_comment_bumped_at timestamp without time zone,
|
||||
rating character(1) DEFAULT 'q'::bpchar NOT NULL,
|
||||
image_width integer NOT NULL,
|
||||
image_height integer NOT NULL,
|
||||
uploader_ip_addr inet NOT NULL,
|
||||
tag_string text DEFAULT ''::text NOT NULL,
|
||||
fav_count integer DEFAULT 0 NOT NULL,
|
||||
file_ext character varying NOT NULL,
|
||||
last_noted_at timestamp without time zone,
|
||||
parent_id integer,
|
||||
has_children boolean DEFAULT false NOT NULL,
|
||||
approver_id integer,
|
||||
tag_count_general integer DEFAULT 0 NOT NULL,
|
||||
tag_count_artist integer DEFAULT 0 NOT NULL,
|
||||
tag_count_character integer DEFAULT 0 NOT NULL,
|
||||
tag_count_copyright integer DEFAULT 0 NOT NULL,
|
||||
file_size integer NOT NULL,
|
||||
up_score integer DEFAULT 0 NOT NULL,
|
||||
down_score integer DEFAULT 0 NOT NULL,
|
||||
is_pending boolean DEFAULT false NOT NULL,
|
||||
is_flagged boolean DEFAULT false NOT NULL,
|
||||
is_deleted boolean DEFAULT false NOT NULL,
|
||||
tag_count integer DEFAULT 0 NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
is_banned boolean DEFAULT false NOT NULL,
|
||||
pixiv_id integer,
|
||||
last_commented_at timestamp without time zone,
|
||||
has_active_children boolean DEFAULT false,
|
||||
bit_flags bigint DEFAULT 0 NOT NULL,
|
||||
tag_count_meta integer DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: users; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.users (
|
||||
id integer NOT NULL,
|
||||
name character varying NOT NULL,
|
||||
level integer NOT NULL,
|
||||
inviter_id integer,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
last_logged_in_at timestamp without time zone,
|
||||
last_forum_read_at timestamp without time zone,
|
||||
comment_threshold integer NOT NULL,
|
||||
updated_at timestamp without time zone,
|
||||
default_image_size character varying NOT NULL,
|
||||
favorite_tags text,
|
||||
blacklisted_tags text,
|
||||
time_zone character varying NOT NULL,
|
||||
post_update_count integer NOT NULL,
|
||||
note_update_count integer NOT NULL,
|
||||
favorite_count integer NOT NULL,
|
||||
post_upload_count integer NOT NULL,
|
||||
bcrypt_password_hash text NOT NULL,
|
||||
per_page integer NOT NULL,
|
||||
custom_style text,
|
||||
bit_prefs bigint NOT NULL,
|
||||
last_ip_addr inet,
|
||||
unread_dmail_count integer NOT NULL,
|
||||
theme integer NOT NULL,
|
||||
upload_points integer NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: wiki_page_versions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.wiki_page_versions (
|
||||
id integer NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
title character varying NOT NULL,
|
||||
body text NOT NULL,
|
||||
updater_id integer NOT NULL,
|
||||
updater_ip_addr inet NOT NULL,
|
||||
wiki_page_id integer NOT NULL,
|
||||
is_locked boolean NOT NULL,
|
||||
other_names text[] DEFAULT '{}'::text[] NOT NULL,
|
||||
is_deleted boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ip_addresses; Type: VIEW; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE VIEW public.ip_addresses AS
|
||||
SELECT 'ArtistVersion'::text AS model_type,
|
||||
artist_versions.id AS model_id,
|
||||
artist_versions.updater_id AS user_id,
|
||||
artist_versions.updater_ip_addr AS ip_addr,
|
||||
artist_versions.created_at
|
||||
FROM public.artist_versions
|
||||
UNION ALL
|
||||
SELECT 'ArtistCommentaryVersion'::text AS model_type,
|
||||
artist_commentary_versions.id AS model_id,
|
||||
artist_commentary_versions.updater_id AS user_id,
|
||||
artist_commentary_versions.updater_ip_addr AS ip_addr,
|
||||
artist_commentary_versions.created_at
|
||||
FROM public.artist_commentary_versions
|
||||
UNION ALL
|
||||
SELECT 'Comment'::text AS model_type,
|
||||
comments.id AS model_id,
|
||||
comments.creator_id AS user_id,
|
||||
comments.creator_ip_addr AS ip_addr,
|
||||
comments.created_at
|
||||
FROM public.comments
|
||||
UNION ALL
|
||||
SELECT 'Dmail'::text AS model_type,
|
||||
dmails.id AS model_id,
|
||||
dmails.from_id AS user_id,
|
||||
dmails.creator_ip_addr AS ip_addr,
|
||||
dmails.created_at
|
||||
FROM public.dmails
|
||||
UNION ALL
|
||||
SELECT 'NoteVersion'::text AS model_type,
|
||||
note_versions.id AS model_id,
|
||||
note_versions.updater_id AS user_id,
|
||||
note_versions.updater_ip_addr AS ip_addr,
|
||||
note_versions.created_at
|
||||
FROM public.note_versions
|
||||
UNION ALL
|
||||
SELECT 'Post'::text AS model_type,
|
||||
posts.id AS model_id,
|
||||
posts.uploader_id AS user_id,
|
||||
posts.uploader_ip_addr AS ip_addr,
|
||||
posts.created_at
|
||||
FROM public.posts
|
||||
UNION ALL
|
||||
SELECT 'User'::text AS model_type,
|
||||
users.id AS model_id,
|
||||
users.id AS user_id,
|
||||
users.last_ip_addr AS ip_addr,
|
||||
users.created_at
|
||||
FROM public.users
|
||||
WHERE (users.last_ip_addr IS NOT NULL)
|
||||
UNION ALL
|
||||
SELECT 'WikiPageVersion'::text AS model_type,
|
||||
wiki_page_versions.id AS model_id,
|
||||
wiki_page_versions.updater_id AS user_id,
|
||||
wiki_page_versions.updater_ip_addr AS ip_addr,
|
||||
wiki_page_versions.created_at
|
||||
FROM public.wiki_page_versions;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ip_bans; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1273,6 +1092,28 @@ CREATE SEQUENCE public.news_updates_id_seq
|
||||
ALTER SEQUENCE public.news_updates_id_seq OWNED BY public.news_updates.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: note_versions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.note_versions (
|
||||
id integer NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
x integer NOT NULL,
|
||||
y integer NOT NULL,
|
||||
width integer NOT NULL,
|
||||
height integer NOT NULL,
|
||||
body text NOT NULL,
|
||||
updater_ip_addr inet NOT NULL,
|
||||
is_active boolean DEFAULT true NOT NULL,
|
||||
note_id integer NOT NULL,
|
||||
post_id integer NOT NULL,
|
||||
updater_id integer NOT NULL,
|
||||
version integer DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: note_versions_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1708,6 +1549,50 @@ CREATE SEQUENCE public.post_votes_id_seq
|
||||
ALTER SEQUENCE public.post_votes_id_seq OWNED BY public.post_votes.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: posts; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.posts (
|
||||
id integer NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
uploader_id integer NOT NULL,
|
||||
score integer DEFAULT 0 NOT NULL,
|
||||
source character varying DEFAULT ''::character varying NOT NULL,
|
||||
md5 character varying NOT NULL,
|
||||
last_comment_bumped_at timestamp without time zone,
|
||||
rating character(1) DEFAULT 'q'::bpchar NOT NULL,
|
||||
image_width integer NOT NULL,
|
||||
image_height integer NOT NULL,
|
||||
uploader_ip_addr inet NOT NULL,
|
||||
tag_string text DEFAULT ''::text NOT NULL,
|
||||
fav_count integer DEFAULT 0 NOT NULL,
|
||||
file_ext character varying NOT NULL,
|
||||
last_noted_at timestamp without time zone,
|
||||
parent_id integer,
|
||||
has_children boolean DEFAULT false NOT NULL,
|
||||
approver_id integer,
|
||||
tag_count_general integer DEFAULT 0 NOT NULL,
|
||||
tag_count_artist integer DEFAULT 0 NOT NULL,
|
||||
tag_count_character integer DEFAULT 0 NOT NULL,
|
||||
tag_count_copyright integer DEFAULT 0 NOT NULL,
|
||||
file_size integer NOT NULL,
|
||||
up_score integer DEFAULT 0 NOT NULL,
|
||||
down_score integer DEFAULT 0 NOT NULL,
|
||||
is_pending boolean DEFAULT false NOT NULL,
|
||||
is_flagged boolean DEFAULT false NOT NULL,
|
||||
is_deleted boolean DEFAULT false NOT NULL,
|
||||
tag_count integer DEFAULT 0 NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
is_banned boolean DEFAULT false NOT NULL,
|
||||
pixiv_id integer,
|
||||
last_commented_at timestamp without time zone,
|
||||
has_active_children boolean DEFAULT false,
|
||||
bit_flags bigint DEFAULT 0 NOT NULL,
|
||||
tag_count_meta integer DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: posts_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -2127,6 +2012,58 @@ CREATE TABLE public.user_upgrades (
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: users; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.users (
|
||||
id integer NOT NULL,
|
||||
name character varying NOT NULL,
|
||||
level integer NOT NULL,
|
||||
inviter_id integer,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
last_logged_in_at timestamp without time zone,
|
||||
last_forum_read_at timestamp without time zone,
|
||||
comment_threshold integer NOT NULL,
|
||||
updated_at timestamp without time zone,
|
||||
default_image_size character varying NOT NULL,
|
||||
favorite_tags text,
|
||||
blacklisted_tags text,
|
||||
time_zone character varying NOT NULL,
|
||||
post_update_count integer NOT NULL,
|
||||
note_update_count integer NOT NULL,
|
||||
favorite_count integer NOT NULL,
|
||||
post_upload_count integer NOT NULL,
|
||||
bcrypt_password_hash text NOT NULL,
|
||||
per_page integer NOT NULL,
|
||||
custom_style text,
|
||||
bit_prefs bigint NOT NULL,
|
||||
last_ip_addr inet,
|
||||
unread_dmail_count integer NOT NULL,
|
||||
theme integer NOT NULL,
|
||||
upload_points integer NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: wiki_page_versions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.wiki_page_versions (
|
||||
id integer NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
title character varying NOT NULL,
|
||||
body text NOT NULL,
|
||||
updater_id integer NOT NULL,
|
||||
updater_ip_addr inet NOT NULL,
|
||||
wiki_page_id integer NOT NULL,
|
||||
is_locked boolean NOT NULL,
|
||||
other_names text[] DEFAULT '{}'::text[] NOT NULL,
|
||||
is_deleted boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: user_actions; Type: VIEW; Schema: public; Owner: -
|
||||
--
|
||||
@@ -6755,6 +6692,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20220909205433'),
|
||||
('20220909211649'),
|
||||
('20220913191300'),
|
||||
('20220913191309');
|
||||
('20220913191309'),
|
||||
('20220917204044');
|
||||
|
||||
|
||||
|
||||
@@ -5,40 +5,6 @@ class IpAddressesControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
@mod = create(:mod_user, last_ip_addr: "1.2.3.4")
|
||||
@user = create(:user, last_ip_addr: "5.6.7.8")
|
||||
|
||||
CurrentUser.scoped(@user, "5.6.7.9") do
|
||||
@note = create(:note)
|
||||
@artist = create(:artist)
|
||||
end
|
||||
end
|
||||
|
||||
context "index action" do
|
||||
should "list all IP addresses" do
|
||||
get_auth ip_addresses_path, @mod
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
should "allow searching by subnet" do
|
||||
get_auth ip_addresses_path(search: { ip_addr: "5.0.0.0/8" }), @mod, as: :json
|
||||
|
||||
assert_response :success
|
||||
assert(response.parsed_body.present?)
|
||||
end
|
||||
|
||||
should "allow grouping by user" do
|
||||
get_auth ip_addresses_path(search: { ip_addr: @user.last_ip_addr, group_by: "user" }), @mod
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
should "allow grouping by IP" do
|
||||
get_auth ip_addresses_path(search: { user_id: @user.id, group_by: "ip_addr" }), @mod
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
should "not allow non-moderators to view IP addresses" do
|
||||
get_auth ip_addresses_path, @user
|
||||
assert_response 403
|
||||
end
|
||||
end
|
||||
|
||||
context "show action" do
|
||||
|
||||
Reference in New Issue
Block a user