FEATURE: roll up function for 123.456.789.* ranges
This commit is contained in:
parent
a91d5fc726
commit
1023191315
|
@ -14,6 +14,14 @@ export default Ember.ArrayController.extend(Discourse.Presence, {
|
||||||
actions: {
|
actions: {
|
||||||
recordAdded: function(arg) {
|
recordAdded: function(arg) {
|
||||||
this.get("model").unshiftObject(arg);
|
this.get("model").unshiftObject(arg);
|
||||||
|
},
|
||||||
|
|
||||||
|
rollUp: function() {
|
||||||
|
var self = this;
|
||||||
|
this.set("loading", true)
|
||||||
|
return Discourse.ScreenedIpAddress.rollUp().then(function() {
|
||||||
|
self.send("show");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -51,5 +51,9 @@ Discourse.ScreenedIpAddress.reopenClass({
|
||||||
return Discourse.ScreenedIpAddress.create(b);
|
return Discourse.ScreenedIpAddress.create(b);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
rollUp: function() {
|
||||||
|
return Discourse.ajax("/admin/logs/screened_ip_addresses/roll_up", { type: "POST" });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<p>{{i18n admin.logs.screened_ips.description}}</p>
|
<p>{{i18n admin.logs.screened_ips.description}}</p>
|
||||||
|
<button class="btn pull-right" {{action "rollUp"}} title="{{i18n admin.logs.screened_ips.roll_up.title}}">{{i18n admin.logs.screened_ips.roll_up.text}}</button>
|
||||||
{{screened-ip-address-form action="recordAdded"}}
|
{{screened-ip-address-form action="recordAdded"}}
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<b>{{i18n admin.logs.screened_ips.form.label}}</b>
|
<b>{{i18n admin.logs.screened_ips.form.label}}</b>
|
||||||
{{text-field value=ip_address disabled=formSubmitted class="ip-address-input" placeholderKey="admin.logs.screened_ips.form.ip_address" autocorrect="off" autocapitalize="off"}}
|
{{text-field value=ip_address disabled=formSubmitted class="ip-address-input" placeholderKey="admin.logs.screened_ips.form.ip_address" autocorrect="off" autocapitalize="off"}}
|
||||||
{{combo-box content=actionNames value=actionName}}
|
{{combo-box content=actionNames value=actionName}}
|
||||||
<button class="btn btn-small" {{action "submit" target="view"}} {{bind-attr disabled="formSubmitted"}}>{{i18n admin.logs.screened_ips.form.add}}</button>
|
<button class="btn" {{action "submit" target="view"}} {{bind-attr disabled="formSubmitted"}}>{{i18n admin.logs.screened_ips.form.add}}</button>
|
||||||
|
|
|
@ -29,6 +29,58 @@ class Admin::ScreenedIpAddressesController < Admin::AdminController
|
||||||
render json: success_json
|
render json: success_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def roll_up
|
||||||
|
# 1 - retrieve all subnets that needs roll up
|
||||||
|
sql = <<-SQL
|
||||||
|
SELECT network(inet(host(ip_address) || './24')) AS ip_range
|
||||||
|
FROM screened_ip_addresses
|
||||||
|
WHERE action_type = :action_type
|
||||||
|
AND family(ip_address) = 4
|
||||||
|
AND masklen(ip_address) = 32
|
||||||
|
GROUP BY ip_range
|
||||||
|
HAVING COUNT(*) >= :min_count
|
||||||
|
SQL
|
||||||
|
|
||||||
|
subnets = ScreenedIpAddress.exec_sql(sql,
|
||||||
|
action_type: ScreenedIpAddress.actions[:block],
|
||||||
|
min_count: SiteSetting.min_ban_entries_for_roll_up).values.flatten
|
||||||
|
|
||||||
|
subnets.each do |subnet|
|
||||||
|
# 2 - create subnet if not already exists
|
||||||
|
ScreenedIpAddress.new(ip_address: subnet).save unless ScreenedIpAddress.where(ip_address: subnet).first
|
||||||
|
|
||||||
|
# 3 - update stats
|
||||||
|
sql = <<-SQL
|
||||||
|
UPDATE screened_ip_addresses
|
||||||
|
SET match_count = sum_match_count,
|
||||||
|
created_at = min_created_at,
|
||||||
|
last_match_at = max_last_match_at
|
||||||
|
FROM (
|
||||||
|
SELECT SUM(match_count) AS sum_match_count,
|
||||||
|
MIN(created_at) AS min_created_at,
|
||||||
|
MAX(last_match_at) AS max_last_match_at
|
||||||
|
FROM screened_ip_addresses
|
||||||
|
WHERE action_type = :action_type
|
||||||
|
AND family(ip_address) = 4
|
||||||
|
AND masklen(ip_address) = 32
|
||||||
|
AND ip_address << :ip_address
|
||||||
|
) s
|
||||||
|
WHERE ip_address = :ip_address
|
||||||
|
SQL
|
||||||
|
|
||||||
|
ScreenedIpAddress.exec_sql(sql, action_type: ScreenedIpAddress.actions[:block], ip_address: subnet)
|
||||||
|
|
||||||
|
# 4 - remove old matches
|
||||||
|
ScreenedIpAddress.where(action_type: ScreenedIpAddress.actions[:block])
|
||||||
|
.where("family(ip_address) = 4")
|
||||||
|
.where("masklen(ip_address) = 32")
|
||||||
|
.where("ip_address << ?", subnet)
|
||||||
|
.delete_all
|
||||||
|
end
|
||||||
|
|
||||||
|
render json: success_json
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def allowed_params
|
def allowed_params
|
||||||
|
|
|
@ -1870,6 +1870,9 @@ en:
|
||||||
label: "New:"
|
label: "New:"
|
||||||
ip_address: "IP address"
|
ip_address: "IP address"
|
||||||
add: "Add"
|
add: "Add"
|
||||||
|
roll_up:
|
||||||
|
text: "Roll up"
|
||||||
|
title: "Creates new subnet ban entries if there are at least 'min_ban_entries_for_roll_up' entries."
|
||||||
logster:
|
logster:
|
||||||
title: "Error Logs"
|
title: "Error Logs"
|
||||||
|
|
||||||
|
|
|
@ -942,6 +942,7 @@ en:
|
||||||
|
|
||||||
levenshtein_distance_spammer_emails: "When matching spammer emails, number of characters difference that will still allow a fuzzy match."
|
levenshtein_distance_spammer_emails: "When matching spammer emails, number of characters difference that will still allow a fuzzy match."
|
||||||
max_new_accounts_per_registration_ip: "If there are already (n) trust level 0 accounts from this IP (and none is a staff member or at TL2 or higher), stop accepting new signups from that IP."
|
max_new_accounts_per_registration_ip: "If there are already (n) trust level 0 accounts from this IP (and none is a staff member or at TL2 or higher), stop accepting new signups from that IP."
|
||||||
|
min_ban_entries_for_roll_up: "When clicking the Roll up button, will create a new subnet ban entry if there are at least (N) entries."
|
||||||
|
|
||||||
reply_by_email_enabled: "Enable replying to topics via email."
|
reply_by_email_enabled: "Enable replying to topics via email."
|
||||||
reply_by_email_address: "Template for reply by email incoming email address, for example: %{reply_key}@reply.example.com or replies+%{reply_key}@example.com"
|
reply_by_email_address: "Template for reply by email incoming email address, for example: %{reply_key}@reply.example.com or replies+%{reply_key}@example.com"
|
||||||
|
|
|
@ -101,7 +101,11 @@ Discourse::Application.routes.draw do
|
||||||
scope "/logs" do
|
scope "/logs" do
|
||||||
resources :staff_action_logs, only: [:index]
|
resources :staff_action_logs, only: [:index]
|
||||||
resources :screened_emails, only: [:index, :destroy]
|
resources :screened_emails, only: [:index, :destroy]
|
||||||
resources :screened_ip_addresses, only: [:index, :create, :update, :destroy]
|
resources :screened_ip_addresses, only: [:index, :create, :update, :destroy] do
|
||||||
|
collection do
|
||||||
|
post "roll_up"
|
||||||
|
end
|
||||||
|
end
|
||||||
resources :screened_urls, only: [:index]
|
resources :screened_urls, only: [:index]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -577,6 +577,7 @@ spam:
|
||||||
min: 0
|
min: 0
|
||||||
max: 3
|
max: 3
|
||||||
max_new_accounts_per_registration_ip: 3
|
max_new_accounts_per_registration_ip: 3
|
||||||
|
min_ban_entries_for_roll_up: 5
|
||||||
|
|
||||||
rate_limits:
|
rate_limits:
|
||||||
unique_posts_mins:
|
unique_posts_mins:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Admin::ScreenedIpAddressesController do
|
describe Admin::ScreenedIpAddressesController do
|
||||||
|
|
||||||
it "is a subclass of AdminController" do
|
it "is a subclass of AdminController" do
|
||||||
(Admin::ScreenedIpAddressesController < Admin::AdminController).should == true
|
(Admin::ScreenedIpAddressesController < Admin::AdminController).should == true
|
||||||
end
|
end
|
||||||
|
@ -8,15 +9,35 @@ describe Admin::ScreenedIpAddressesController do
|
||||||
let!(:user) { log_in(:admin) }
|
let!(:user) { log_in(:admin) }
|
||||||
|
|
||||||
describe 'index' do
|
describe 'index' do
|
||||||
before do
|
|
||||||
xhr :get, :index
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { response }
|
|
||||||
it { should be_success }
|
|
||||||
|
|
||||||
it 'returns JSON' do
|
it 'returns JSON' do
|
||||||
::JSON.parse(subject.body).should be_a(Array)
|
xhr :get, :index
|
||||||
|
response.should be_success
|
||||||
|
JSON.parse(response.body).should be_a(Array)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'roll_up' do
|
||||||
|
|
||||||
|
it "works" do
|
||||||
|
SiteSetting.expects(:min_ban_entries_for_roll_up).returns(3)
|
||||||
|
|
||||||
|
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.6", match_count: 1)
|
||||||
|
|
||||||
|
Fabricate(:screened_ip_address, ip_address: "42.42.42.4", match_count: 1)
|
||||||
|
Fabricate(:screened_ip_address, ip_address: "42.42.42.5", match_count: 1)
|
||||||
|
|
||||||
|
xhr :post, :roll_up
|
||||||
|
response.should be_success
|
||||||
|
|
||||||
|
subnet = ScreenedIpAddress.where(ip_address: "1.2.3.0/24").first
|
||||||
|
subnet.should be_present
|
||||||
|
subnet.match_count.should == 3
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue