ip bans: add hit counter, deleted flag, new ban type.

* Make IP bans soft deletable.
* Add a hit counter to track how many times an IP ban has blocked someone.
* Add a last hit timestamp to track when the IP ban last blocked someone.
* Add a new type of IP ban, the signup ban. Signup bans restrict new
  signups from editing anything until they've verified their email
  address.
This commit is contained in:
evazion
2020-04-06 14:12:56 -05:00
parent 98e84d83fb
commit b2ee1f0766
18 changed files with 178 additions and 40 deletions

View File

@@ -21,6 +21,11 @@ class IpBansControllerTest < ActionDispatch::IntegrationTest
assert_response :redirect
end
end
should "log a mod action" do
post_auth ip_bans_path, @admin, params: { ip_ban: { ip_addr: "1.2.3.4", reason: "xyz" }}
assert_equal("ip_ban_create", ModAction.last.category)
end
end
context "index action" do
@@ -37,12 +42,12 @@ class IpBansControllerTest < ActionDispatch::IntegrationTest
end
end
context "destroy action" do
should "destroy an ip ban" do
assert_difference("IpBan.count", -1) do
delete_auth ip_ban_path(@ip_ban), @admin, params: {:format => "js"}
assert_response :success
end
context "update action" do
should "mark an ip ban as deleted" do
put_auth ip_ban_path(@ip_ban), @admin, params: { ip_ban: { is_deleted: true }, format: "js" }
assert_response :success
assert_equal(true, @ip_ban.reload.is_deleted)
assert_equal("ip_ban_delete", ModAction.last.category)
end
end
end

View File

@@ -35,11 +35,33 @@ class SessionsControllerTest < ActionDispatch::IntegrationTest
end
should "not allow IP banned users to login" do
create(:ip_ban, ip_addr: "1.2.3.4")
@ip_ban = create(:ip_ban, category: :normal, ip_addr: "1.2.3.4")
post session_path, params: { name: @user.name, password: "password" }, headers: { REMOTE_ADDR: "1.2.3.4" }
assert_response 403
assert_not_equal(@user.id, session[:user_id])
assert_equal(1, @ip_ban.reload.hit_count)
assert(@ip_ban.last_hit_at > 1.minute.ago)
end
should "allow signup-restricted IP banned users to login" do
@ip_ban = create(:ip_ban, category: :signup, ip_addr: "1.2.3.4")
post session_path, params: { name: @user.name, password: "password" }, headers: { REMOTE_ADDR: "1.2.3.4" }
assert_redirected_to posts_path
assert_equal(@user.id, session[:user_id])
assert_equal(0, @ip_ban.reload.hit_count)
assert_nil(@ip_ban.last_hit_at)
end
should "ignore deleted IP bans when logging in" do
@ip_ban = create(:ip_ban, is_deleted: true, category: :normal, ip_addr: "1.2.3.4")
post session_path, params: { name: @user.name, password: "password" }, headers: { REMOTE_ADDR: "1.2.3.4" }
assert_redirected_to posts_path
assert_equal(@user.id, session[:user_id])
assert_equal(0, @ip_ban.reload.hit_count)
assert_nil(@ip_ban.last_hit_at)
end
end

View File

@@ -168,6 +168,19 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
assert_equal(true, User.last.requires_verification)
end
should "mark users signing up from a signup banned IP as requiring verification" do
skip unless IpLookup.enabled?
self.remote_addr = "187.37.226.17"
@ip_ban = create(:ip_ban, ip_addr: self.remote_addr, category: :signup)
post users_path, params: { user: { name: "xxx", password: "xxxxx1", password_confirmation: "xxxxx1" }}
assert_redirected_to User.last
assert_equal(true, User.last.requires_verification)
assert_equal(1, @ip_ban.reload.hit_count)
assert(@ip_ban.last_hit_at > 1.minute.ago)
end
should "not mark users signing up from non-proxies as requiring verification" do
skip unless IpLookup.enabled?
self.remote_addr = "187.37.226.17"

View File

@@ -5,18 +5,19 @@ class IpBanTest < ActiveSupport::TestCase
ip_ban = create(:ip_ban, ip_addr: "1.2.3.4")
assert_equal("1.2.3.4", ip_ban.subnetted_ip)
assert(IpBan.is_banned?("1.2.3.4"))
assert(IpBan.ip_matches("1.2.3.4").exists?)
end
should "be able to ban a subnet" do
ip_ban = create(:ip_ban, ip_addr: "1.2.3.4/24")
assert_equal("1.2.3.0/24", ip_ban.subnetted_ip)
assert(IpBan.is_banned?("1.2.3.0"))
assert(IpBan.is_banned?("1.2.3.255"))
assert(IpBan.ip_matches("1.2.3.0").exists?)
assert(IpBan.ip_matches("1.2.3.255").exists?)
end
context "validation" do
setup { create(:ip_ban: ip_addr: "5.6.7.8") }
subject { build(:ip_ban) }
should allow_value("1.2.3.4").for(:ip_addr)
@@ -26,6 +27,7 @@ class IpBanTest < ActiveSupport::TestCase
should_not allow_value("").for(:ip_addr)
should_not allow_value("foo").for(:ip_addr)
should_not allow_value("5.6.7.8").for(:ip_addr)
should_not allow_value("10.0.0.1").for(:ip_addr)
should_not allow_value("127.0.0.1").for(:ip_addr)
should_not allow_value("1.2.3.4/16").for(:ip_addr)