mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-12-17 19:12:37 -05:00
FEATURE: rolls up 1.2.*.* IP ranges when number of entries > 10
This commit is contained in:
parent
062e954122
commit
5b90ceb71d
5 changed files with 99 additions and 17 deletions
|
@ -21,8 +21,16 @@ export default Ember.ArrayController.extend(Discourse.Presence, {
|
||||||
return bootbox.confirm(I18n.t("admin.logs.screened_ips.roll_up_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function (confirmed) {
|
return bootbox.confirm(I18n.t("admin.logs.screened_ips.roll_up_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function (confirmed) {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
self.set("loading", true)
|
self.set("loading", true)
|
||||||
return Discourse.ScreenedIpAddress.rollUp().then(function() {
|
return Discourse.ScreenedIpAddress.rollUp().then(function(results) {
|
||||||
self.send("show");
|
if (results && results.subnets) {
|
||||||
|
if (results.subnets.length > 0) {
|
||||||
|
self.send("show");
|
||||||
|
bootbox.alert(I18n.t("admin.logs.screened_ips.rolled_up_some_subnets", { subnets: results.subnets.join(", ") }));
|
||||||
|
} else {
|
||||||
|
self.set("loading", false);
|
||||||
|
bootbox.alert(I18n.t("admin.logs.screened_ips.rolled_up_no_subnet"));
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,21 +29,51 @@ class Admin::ScreenedIpAddressesController < Admin::AdminController
|
||||||
render json: success_json
|
render json: success_json
|
||||||
end
|
end
|
||||||
|
|
||||||
def roll_up
|
def star_subnets_query
|
||||||
# 1 - retrieve all subnets that needs roll up
|
@star_subnets_query ||= <<-SQL
|
||||||
sql = <<-SQL
|
SELECT network(inet(host(ip_address) || '/24')) AS ip_range
|
||||||
SELECT network(inet(host(ip_address) || './24')) AS ip_range
|
|
||||||
FROM screened_ip_addresses
|
FROM screened_ip_addresses
|
||||||
WHERE action_type = :action_type
|
WHERE action_type = #{ScreenedIpAddress.actions[:block]}
|
||||||
AND family(ip_address) = 4
|
AND family(ip_address) = 4
|
||||||
AND masklen(ip_address) = 32
|
AND masklen(ip_address) = 32
|
||||||
GROUP BY ip_range
|
GROUP BY ip_range
|
||||||
HAVING COUNT(*) >= :min_count
|
HAVING COUNT(*) >= :min_count
|
||||||
SQL
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
subnets = ScreenedIpAddress.exec_sql(sql,
|
def star_star_subnets_query
|
||||||
action_type: ScreenedIpAddress.actions[:block],
|
@star_star_subnets_query ||= <<-SQL
|
||||||
min_count: SiteSetting.min_ban_entries_for_roll_up).values.flatten
|
WITH weighted_subnets AS (
|
||||||
|
SELECT network(inet(host(ip_address) || '/16')) AS ip_range,
|
||||||
|
CASE masklen(ip_address)
|
||||||
|
WHEN 32 THEN 1
|
||||||
|
WHEN 24 THEN :roll_up_weight
|
||||||
|
ELSE 0
|
||||||
|
END AS weight
|
||||||
|
FROM screened_ip_addresses
|
||||||
|
WHERE action_type = #{ScreenedIpAddress.actions[:block]}
|
||||||
|
AND family(ip_address) = 4
|
||||||
|
)
|
||||||
|
SELECT ip_range
|
||||||
|
FROM weighted_subnets
|
||||||
|
GROUP BY ip_range
|
||||||
|
HAVING SUM(weight) >= :min_count
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def star_subnets
|
||||||
|
min_count = SiteSetting.min_ban_entries_for_roll_up
|
||||||
|
ScreenedIpAddress.exec_sql(star_subnets_query, min_count: min_count).values.flatten
|
||||||
|
end
|
||||||
|
|
||||||
|
def star_star_subnets
|
||||||
|
weight = SiteSetting.min_ban_entries_for_roll_up
|
||||||
|
ScreenedIpAddress.exec_sql(star_star_subnets_query, min_count: 10, roll_up_weight: weight).values.flatten
|
||||||
|
end
|
||||||
|
|
||||||
|
def roll_up
|
||||||
|
# 1 - retrieve all subnets that needs roll up
|
||||||
|
subnets = [star_subnets, star_star_subnets].flatten
|
||||||
|
|
||||||
# 2 - log the call
|
# 2 - log the call
|
||||||
StaffActionLogger.new(current_user).log_roll_up(subnets) unless subnets.blank?
|
StaffActionLogger.new(current_user).log_roll_up(subnets) unless subnets.blank?
|
||||||
|
@ -63,25 +93,23 @@ class Admin::ScreenedIpAddressesController < Admin::AdminController
|
||||||
MIN(created_at) AS min_created_at,
|
MIN(created_at) AS min_created_at,
|
||||||
MAX(last_match_at) AS max_last_match_at
|
MAX(last_match_at) AS max_last_match_at
|
||||||
FROM screened_ip_addresses
|
FROM screened_ip_addresses
|
||||||
WHERE action_type = :action_type
|
WHERE action_type = #{ScreenedIpAddress.actions[:block]}
|
||||||
AND family(ip_address) = 4
|
AND family(ip_address) = 4
|
||||||
AND masklen(ip_address) = 32
|
|
||||||
AND ip_address << :ip_address
|
AND ip_address << :ip_address
|
||||||
) s
|
) s
|
||||||
WHERE ip_address = :ip_address
|
WHERE ip_address = :ip_address
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
ScreenedIpAddress.exec_sql(sql, action_type: ScreenedIpAddress.actions[:block], ip_address: subnet)
|
ScreenedIpAddress.exec_sql(sql, ip_address: subnet)
|
||||||
|
|
||||||
# 5 - remove old matches
|
# 5 - remove old matches
|
||||||
ScreenedIpAddress.where(action_type: ScreenedIpAddress.actions[:block])
|
ScreenedIpAddress.where(action_type: ScreenedIpAddress.actions[:block])
|
||||||
.where("family(ip_address) = 4")
|
.where("family(ip_address) = 4")
|
||||||
.where("masklen(ip_address) = 32")
|
|
||||||
.where("ip_address << ?", subnet)
|
.where("ip_address << ?", subnet)
|
||||||
.delete_all
|
.delete_all
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: success_json
|
render json: success_json.merge!({ subnets: subnets })
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -1862,6 +1862,8 @@ en:
|
||||||
description: 'IP addresses that are being watched. Use "Allow" to whitelist IP addresses.'
|
description: 'IP addresses that are being watched. Use "Allow" to whitelist IP addresses.'
|
||||||
delete_confirm: "Are you sure you want to remove the rule for %{ip_address}?"
|
delete_confirm: "Are you sure you want to remove the rule for %{ip_address}?"
|
||||||
roll_up_confirm: "Are you sure you want to roll up ban entries?"
|
roll_up_confirm: "Are you sure you want to roll up ban entries?"
|
||||||
|
rolled_up_some_subnets: "Successfully rolled up IP ban entries to these subnets: %{subnets}."
|
||||||
|
rolled_up_no_subnet: "There was nothing to roll up."
|
||||||
actions:
|
actions:
|
||||||
block: "Block"
|
block: "Block"
|
||||||
do_nothing: "Allow"
|
do_nothing: "Allow"
|
||||||
|
|
24
script/import_scripts/tnation.rb
Normal file
24
script/import_scripts/tnation.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# custom importer for www.t-nation.com, feel free to borrow ideas
|
||||||
|
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + "/base.rb")
|
||||||
|
require "mysql2"
|
||||||
|
|
||||||
|
class ImportScripts::Tnation < ImportScripts::Base
|
||||||
|
|
||||||
|
DATABASE = "tnation"
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super
|
||||||
|
|
||||||
|
@client = Mysql2::Client.new(
|
||||||
|
host: "localhost",
|
||||||
|
database: DATABASE
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
ImportScripts::Tnation.new.perform
|
|
@ -20,7 +20,7 @@ describe Admin::ScreenedIpAddressesController do
|
||||||
|
|
||||||
describe 'roll_up' do
|
describe 'roll_up' do
|
||||||
|
|
||||||
it "works" do
|
it "rolls up 1.2.3.* entries" do
|
||||||
Fabricate(:screened_ip_address, ip_address: "1.2.3.4", match_count: 1)
|
Fabricate(:screened_ip_address, ip_address: "1.2.3.4", match_count: 1)
|
||||||
Fabricate(:screened_ip_address, ip_address: "1.2.3.5", match_count: 1)
|
Fabricate(:screened_ip_address, ip_address: "1.2.3.5", match_count: 1)
|
||||||
Fabricate(:screened_ip_address, ip_address: "1.2.3.6", match_count: 1)
|
Fabricate(:screened_ip_address, ip_address: "1.2.3.6", match_count: 1)
|
||||||
|
@ -29,7 +29,7 @@ describe Admin::ScreenedIpAddressesController do
|
||||||
Fabricate(:screened_ip_address, ip_address: "42.42.42.5", match_count: 1)
|
Fabricate(:screened_ip_address, ip_address: "42.42.42.5", match_count: 1)
|
||||||
|
|
||||||
StaffActionLogger.any_instance.expects(:log_roll_up)
|
StaffActionLogger.any_instance.expects(:log_roll_up)
|
||||||
SiteSetting.expects(:min_ban_entries_for_roll_up).returns(3)
|
SiteSetting.stubs(:min_ban_entries_for_roll_up).returns(3)
|
||||||
|
|
||||||
xhr :post, :roll_up
|
xhr :post, :roll_up
|
||||||
response.should be_success
|
response.should be_success
|
||||||
|
@ -39,6 +39,26 @@ describe Admin::ScreenedIpAddressesController do
|
||||||
subnet.match_count.should == 3
|
subnet.match_count.should == 3
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "rolls up 1.2.*.* entries" do
|
||||||
|
Fabricate(:screened_ip_address, ip_address: "1.2.3.4", match_count: 1)
|
||||||
|
Fabricate(:screened_ip_address, ip_address: "1.2.3.5", match_count: 1)
|
||||||
|
Fabricate(:screened_ip_address, ip_address: "1.2.4.6", match_count: 1)
|
||||||
|
Fabricate(:screened_ip_address, ip_address: "1.2.7.8", match_count: 1)
|
||||||
|
Fabricate(:screened_ip_address, ip_address: "1.2.9.1", match_count: 1)
|
||||||
|
|
||||||
|
Fabricate(:screened_ip_address, ip_address: "1.2.42.0/24", match_count: 1)
|
||||||
|
|
||||||
|
StaffActionLogger.any_instance.expects(:log_roll_up)
|
||||||
|
SiteSetting.stubs(:min_ban_entries_for_roll_up).returns(5)
|
||||||
|
|
||||||
|
xhr :post, :roll_up
|
||||||
|
response.should be_success
|
||||||
|
|
||||||
|
subnet = ScreenedIpAddress.where(ip_address: "1.2.0.0/16").first
|
||||||
|
subnet.should be_present
|
||||||
|
subnet.match_count.should == 6
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue