mirror of
https://github.com/discourse/discourse.git
synced 2025-02-22 18:43:11 +08:00
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: {
|
||||
recordAdded: function(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);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
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>
|
||||
|
||||
<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"}}
|
||||
<br/>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<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"}}
|
||||
{{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
|
||||
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
|
||||
|
||||
def allowed_params
|
||||
|
@ -1870,6 +1870,9 @@ en:
|
||||
label: "New:"
|
||||
ip_address: "IP address"
|
||||
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:
|
||||
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."
|
||||
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_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
|
||||
resources :staff_action_logs, only: [:index]
|
||||
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]
|
||||
end
|
||||
|
||||
|
@ -577,6 +577,7 @@ spam:
|
||||
min: 0
|
||||
max: 3
|
||||
max_new_accounts_per_registration_ip: 3
|
||||
min_ban_entries_for_roll_up: 5
|
||||
|
||||
rate_limits:
|
||||
unique_posts_mins:
|
||||
|
@ -1,6 +1,7 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Admin::ScreenedIpAddressesController do
|
||||
|
||||
it "is a subclass of AdminController" do
|
||||
(Admin::ScreenedIpAddressesController < Admin::AdminController).should == true
|
||||
end
|
||||
@ -8,15 +9,35 @@ describe Admin::ScreenedIpAddressesController do
|
||||
let!(:user) { log_in(:admin) }
|
||||
|
||||
describe 'index' do
|
||||
before do
|
||||
xhr :get, :index
|
||||
end
|
||||
|
||||
subject { response }
|
||||
it { should be_success }
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user