mirror of
https://github.com/discourse/discourse.git
synced 2024-11-29 18:51:05 +08:00
FEATURE: filter screened IP addresses
This commit is contained in:
parent
9b12e53d9c
commit
c4e427cf73
|
@ -3,15 +3,16 @@ import { outputExportResult } from 'discourse/lib/export-result';
|
||||||
export default Ember.ArrayController.extend(Discourse.Presence, {
|
export default Ember.ArrayController.extend(Discourse.Presence, {
|
||||||
loading: false,
|
loading: false,
|
||||||
itemController: 'admin-log-screened-ip-address',
|
itemController: 'admin-log-screened-ip-address',
|
||||||
|
filter: null,
|
||||||
|
|
||||||
show: function() {
|
show: Discourse.debounce(function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.set('loading', true);
|
self.set('loading', true);
|
||||||
Discourse.ScreenedIpAddress.findAll().then(function(result) {
|
Discourse.ScreenedIpAddress.findAll(this.get("filter")).then(function(result) {
|
||||||
self.set('model', result);
|
self.set('model', result);
|
||||||
self.set('loading', false);
|
self.set('loading', false);
|
||||||
});
|
});
|
||||||
},
|
}, 250).observes("filter"),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
recordAdded: function(arg) {
|
recordAdded: function(arg) {
|
||||||
|
|
|
@ -45,8 +45,8 @@ Discourse.ScreenedIpAddress = Discourse.Model.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
Discourse.ScreenedIpAddress.reopenClass({
|
Discourse.ScreenedIpAddress.reopenClass({
|
||||||
findAll: function() {
|
findAll: function(filter) {
|
||||||
return Discourse.ajax("/admin/logs/screened_ip_addresses.json").then(function(screened_ips) {
|
return Discourse.ajax("/admin/logs/screened_ip_addresses.json", { data: { filter: filter } }).then(function(screened_ips) {
|
||||||
return screened_ips.map(function(b) {
|
return screened_ips.map(function(b) {
|
||||||
return Discourse.ScreenedIpAddress.create(b);
|
return Discourse.ScreenedIpAddress.create(b);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<p>{{i18n 'admin.logs.screened_ips.description'}}</p>
|
<p>{{i18n 'admin.logs.screened_ips.description'}}</p>
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
|
{{text-field value=filter class="ip-address-input" placeholderKey="admin.logs.screened_ips.form.filter" autocorrect="off" autocapitalize="off"}}
|
||||||
<button class="btn" {{action "rollUp"}} title="{{i18n 'admin.logs.screened_ips.roll_up.title'}}">{{i18n 'admin.logs.screened_ips.roll_up.text'}}</button>
|
<button class="btn" {{action "rollUp"}} title="{{i18n 'admin.logs.screened_ips.roll_up.title'}}">{{i18n 'admin.logs.screened_ips.roll_up.text'}}</button>
|
||||||
<button class="btn" {{action "exportScreenedIpList"}} title="{{i18n 'admin.export_csv.button_title.screened_ip'}}">{{fa-icon "download"}}{{i18n 'admin.export_csv.button_text'}}</button>
|
<button class="btn" {{action "exportScreenedIpList"}} title="{{i18n 'admin.export_csv.button_title.screened_ip'}}">{{fa-icon "download"}}{{i18n 'admin.export_csv.button_text'}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,9 +1,24 @@
|
||||||
|
require_dependency 'ip_addr'
|
||||||
|
|
||||||
class Admin::ScreenedIpAddressesController < Admin::AdminController
|
class Admin::ScreenedIpAddressesController < Admin::AdminController
|
||||||
|
|
||||||
before_filter :fetch_screened_ip_address, only: [:update, :destroy]
|
before_filter :fetch_screened_ip_address, only: [:update, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
screened_ip_addresses = ScreenedIpAddress.limit(200).order('match_count desc').to_a
|
filter = params[:filter]
|
||||||
|
filter = IPAddr.handle_wildcards(filter)
|
||||||
|
|
||||||
|
screened_ip_addresses = ScreenedIpAddress
|
||||||
|
screened_ip_addresses = screened_ip_addresses.where("cidr '#{filter}' >>= ip_address") if filter.present?
|
||||||
|
screened_ip_addresses = screened_ip_addresses.limit(200).order('match_count desc')
|
||||||
|
|
||||||
|
begin
|
||||||
|
screened_ip_addresses = screened_ip_addresses.to_a
|
||||||
|
rescue ActiveRecord::StatementInvalid
|
||||||
|
# postgresql throws a PG::InvalidTextRepresentation exception when filter isn't a valid cidr expression
|
||||||
|
screened_ip_addresses = []
|
||||||
|
end
|
||||||
|
|
||||||
render_serialized(screened_ip_addresses, ScreenedIpAddressSerializer)
|
render_serialized(screened_ip_addresses, ScreenedIpAddressSerializer)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -24,23 +24,20 @@ class ScreenedIpAddress < ActiveRecord::Base
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
return write_attribute(:ip_address, val) if val.is_a?(IPAddr)
|
if val.is_a?(IPAddr)
|
||||||
|
|
||||||
num_wildcards = val.count('*')
|
|
||||||
if num_wildcards == 0
|
|
||||||
write_attribute(:ip_address, val)
|
write_attribute(:ip_address, val)
|
||||||
else
|
return
|
||||||
v = val.gsub(/\/.*/, '') # strip ranges like "/16" from the end if present
|
|
||||||
if v[v.index('*')..-1] =~ /[^\.\*]/
|
|
||||||
self.errors.add(:ip_address, :invalid)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
parts = v.split('.')
|
|
||||||
(4 - parts.size).times { parts << '*' } # support strings like 192.*
|
|
||||||
v = parts.join('.')
|
|
||||||
write_attribute(:ip_address, "#{v.gsub('*', '0')}/#{32 - (v.count('*') * 8)}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
v = IPAddr.handle_wildcards(val)
|
||||||
|
|
||||||
|
if v.nil?
|
||||||
|
self.errors.add(:ip_address, :invalid)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
write_attribute(:ip_address, v)
|
||||||
|
|
||||||
# this gets even messier, Ruby 1.9.2 raised a different exception to Ruby 2.0.0
|
# this gets even messier, Ruby 1.9.2 raised a different exception to Ruby 2.0.0
|
||||||
# handle both exceptions
|
# handle both exceptions
|
||||||
rescue ArgumentError, IPAddr::InvalidAddressError
|
rescue ArgumentError, IPAddr::InvalidAddressError
|
||||||
|
|
|
@ -1928,6 +1928,7 @@ en:
|
||||||
label: "New:"
|
label: "New:"
|
||||||
ip_address: "IP address"
|
ip_address: "IP address"
|
||||||
add: "Add"
|
add: "Add"
|
||||||
|
filter: "Search"
|
||||||
roll_up:
|
roll_up:
|
||||||
text: "Roll up"
|
text: "Roll up"
|
||||||
title: "Creates new subnet ban entries if there are at least 'min_ban_entries_for_roll_up' entries."
|
title: "Creates new subnet ban entries if there are at least 'min_ban_entries_for_roll_up' entries."
|
||||||
|
|
|
@ -1,5 +1,24 @@
|
||||||
class IPAddr
|
class IPAddr
|
||||||
|
|
||||||
|
def self.handle_wildcards(val)
|
||||||
|
return if val.blank?
|
||||||
|
|
||||||
|
num_wildcards = val.count('*')
|
||||||
|
|
||||||
|
return val if num_wildcards == 0
|
||||||
|
|
||||||
|
# strip ranges like "/16" from the end if present
|
||||||
|
v = val.gsub(/\/.*/, '')
|
||||||
|
|
||||||
|
return if v[v.index('*')..-1] =~ /[^\.\*]/
|
||||||
|
|
||||||
|
parts = v.split('.')
|
||||||
|
(4 - parts.size).times { parts << '*' } # support strings like 192.*
|
||||||
|
v = parts.join('.')
|
||||||
|
|
||||||
|
"#{v.gsub('*', '0')}/#{32 - (v.count('*') * 8)}"
|
||||||
|
end
|
||||||
|
|
||||||
def to_cidr_s
|
def to_cidr_s
|
||||||
if @addr
|
if @addr
|
||||||
mask = @mask_addr.to_s(2).count('1')
|
mask = @mask_addr.to_s(2).count('1')
|
||||||
|
|
|
@ -10,10 +10,18 @@ describe Admin::ScreenedIpAddressesController do
|
||||||
|
|
||||||
describe 'index' do
|
describe 'index' do
|
||||||
|
|
||||||
it 'returns JSON' do
|
it 'filters screened ip addresses' do
|
||||||
xhr :get, :index
|
Fabricate(:screened_ip_address, ip_address: "1.2.3.4")
|
||||||
|
Fabricate(:screened_ip_address, ip_address: "1.2.3.5")
|
||||||
|
Fabricate(:screened_ip_address, ip_address: "1.2.3.6")
|
||||||
|
Fabricate(:screened_ip_address, ip_address: "4.5.6.7")
|
||||||
|
|
||||||
|
xhr :get, :index, filter: "4.*"
|
||||||
|
|
||||||
expect(response).to be_success
|
expect(response).to be_success
|
||||||
expect(JSON.parse(response.body)).to be_a(Array)
|
|
||||||
|
result = JSON.parse(response.body)
|
||||||
|
expect(result.length).to eq(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user