diff --git a/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6
index 0427fe0fb..a60297340 100644
--- a/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6
@@ -3,15 +3,16 @@ import { outputExportResult } from 'discourse/lib/export-result';
export default Ember.ArrayController.extend(Discourse.Presence, {
loading: false,
itemController: 'admin-log-screened-ip-address',
+ filter: null,
- show: function() {
+ show: Discourse.debounce(function() {
var self = this;
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('loading', false);
});
- },
+ }, 250).observes("filter"),
actions: {
recordAdded: function(arg) {
diff --git a/app/assets/javascripts/admin/models/screened_ip_address.js b/app/assets/javascripts/admin/models/screened_ip_address.js
index 22ff7d915..4aafe4df9 100644
--- a/app/assets/javascripts/admin/models/screened_ip_address.js
+++ b/app/assets/javascripts/admin/models/screened_ip_address.js
@@ -45,8 +45,8 @@ Discourse.ScreenedIpAddress = Discourse.Model.extend({
});
Discourse.ScreenedIpAddress.reopenClass({
- findAll: function() {
- return Discourse.ajax("/admin/logs/screened_ip_addresses.json").then(function(screened_ips) {
+ findAll: function(filter) {
+ return Discourse.ajax("/admin/logs/screened_ip_addresses.json", { data: { filter: filter } }).then(function(screened_ips) {
return screened_ips.map(function(b) {
return Discourse.ScreenedIpAddress.create(b);
});
diff --git a/app/assets/javascripts/admin/templates/logs/screened_ip_addresses.hbs b/app/assets/javascripts/admin/templates/logs/screened_ip_addresses.hbs
index c1b27eb88..27fa42371 100644
--- a/app/assets/javascripts/admin/templates/logs/screened_ip_addresses.hbs
+++ b/app/assets/javascripts/admin/templates/logs/screened_ip_addresses.hbs
@@ -1,5 +1,6 @@
{{i18n 'admin.logs.screened_ips.description'}}
+ {{text-field value=filter class="ip-address-input" placeholderKey="admin.logs.screened_ips.form.filter" autocorrect="off" autocapitalize="off"}}
diff --git a/app/controllers/admin/screened_ip_addresses_controller.rb b/app/controllers/admin/screened_ip_addresses_controller.rb
index 079e674fb..95281a55a 100644
--- a/app/controllers/admin/screened_ip_addresses_controller.rb
+++ b/app/controllers/admin/screened_ip_addresses_controller.rb
@@ -1,9 +1,24 @@
+require_dependency 'ip_addr'
+
class Admin::ScreenedIpAddressesController < Admin::AdminController
before_filter :fetch_screened_ip_address, only: [:update, :destroy]
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)
end
diff --git a/app/models/screened_ip_address.rb b/app/models/screened_ip_address.rb
index d55476602..d25540a85 100644
--- a/app/models/screened_ip_address.rb
+++ b/app/models/screened_ip_address.rb
@@ -24,23 +24,20 @@ class ScreenedIpAddress < ActiveRecord::Base
return
end
- return write_attribute(:ip_address, val) if val.is_a?(IPAddr)
-
- num_wildcards = val.count('*')
- if num_wildcards == 0
+ if val.is_a?(IPAddr)
write_attribute(:ip_address, val)
- else
- 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)}")
+ return
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
# handle both exceptions
rescue ArgumentError, IPAddr::InvalidAddressError
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 3d1daeb24..b4b708d79 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1928,6 +1928,7 @@ en:
label: "New:"
ip_address: "IP address"
add: "Add"
+ filter: "Search"
roll_up:
text: "Roll up"
title: "Creates new subnet ban entries if there are at least 'min_ban_entries_for_roll_up' entries."
diff --git a/lib/ip_addr.rb b/lib/ip_addr.rb
index c8afcde48..c80501c3b 100644
--- a/lib/ip_addr.rb
+++ b/lib/ip_addr.rb
@@ -1,5 +1,24 @@
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
if @addr
mask = @mask_addr.to_s(2).count('1')
diff --git a/spec/controllers/admin/screened_ip_addresses_controller_spec.rb b/spec/controllers/admin/screened_ip_addresses_controller_spec.rb
index dd106862d..e814c7abf 100644
--- a/spec/controllers/admin/screened_ip_addresses_controller_spec.rb
+++ b/spec/controllers/admin/screened_ip_addresses_controller_spec.rb
@@ -10,10 +10,18 @@ describe Admin::ScreenedIpAddressesController do
describe 'index' do
- it 'returns JSON' do
- xhr :get, :index
+ it 'filters screened ip addresses' do
+ 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(JSON.parse(response.body)).to be_a(Array)
+
+ result = JSON.parse(response.body)
+ expect(result.length).to eq(1)
end
end