security_guard 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,4 +15,5 @@ rdoc
15
15
  spec/reports
16
16
  test/tmp
17
17
  test/version_tmp
18
+ spec/tmp
18
19
  tmp
data/README.md CHANGED
@@ -36,7 +36,7 @@ country_ips.ips = ['4.4.4.4', '8.8.8.8', '203.206.0.1']
36
36
  # the above is equivalent to:
37
37
 
38
38
  country_ips = SecurityGuard::CountryIps.new(
39
- :countries => ['Australia', 'United Kingdom']
39
+ :countries => ['Australia', 'United Kingdom'],
40
40
  :ips => ['4.4.4.4', '8.8.8.8', '203.206.0.1']
41
41
  )
42
42
  ```
@@ -46,9 +46,10 @@ country_ips = SecurityGuard::CountryIps.new(
46
46
  Returns a list of the IPs from given country and IP dictionaries. Useful for auditing IPs from higher risk nations.
47
47
 
48
48
  ```ruby
49
- country_ips = SecurityGuard::CountryIps.new
50
- country_ips.countries = ['Australia', 'United Kingdom']
51
- country_ips.ips = ['4.4.4.4', '8.8.8.8', '203.206.0.1']
49
+ country_ips = SecurityGuard::CountryIps.new(
50
+ :countries => ['Australia'],
51
+ :ips => ['4.4.4.4', '8.8.8.8', '203.206.0.1']
52
+ )
52
53
  country_ips.result # => ['203.206.0.1']
53
54
  ```
54
55
 
@@ -59,8 +60,24 @@ country_ips.countries_from_file = '/path/to/the/file'
59
60
  country_ips.ips_from_file = '/path/to/the/file'
60
61
  ```
61
62
 
63
+ ### Deduplication
64
+
65
+ Deduplicates content contained within a list of files. Useful for deduplicating email newsletter subscription lists.
66
+
67
+ ```ruby
68
+ dedupe = SecurityGuard::Deduplication.new(
69
+ :input_folder => '/path/to/the/input/folder',
70
+ :output_folder => '/path/to/the/output/folder'
71
+ ).process
72
+ ```
73
+
62
74
  ## Changelog
63
75
 
76
+ ### v0.0.4 [2012-02-08]
77
+
78
+ - Fixed Concerns::Initializable for CountryIps
79
+ - Added Deduplication
80
+
64
81
  ### v0.0.3 [2012-01-20]
65
82
 
66
83
  - Added Concerns::Initializable
data/bin/sguard CHANGED
@@ -12,10 +12,10 @@ module SecurityGuard
12
12
  parameter '[output_path]', 'output the results in a text file'
13
13
 
14
14
  def execute
15
- country_ips = SecurityGuard::CountryIps.new
16
-
17
- country_ips.ips_from_file = ip_addresses_path
18
- country_ips.countries_from_file = countries_path
15
+ country_ips = SecurityGuard::CountryIps.new(
16
+ :ips_from_file => ip_addresses_path,
17
+ :countries_from_file => countries_path
18
+ )
19
19
 
20
20
  if output_path
21
21
  MainCommand.output_result(country_ips.result, output_path)
@@ -25,6 +25,20 @@ module SecurityGuard
25
25
  end
26
26
  end
27
27
 
28
+ class DeduplicationCommand < Clamp::Command
29
+ parameter 'input_folder', 'folder containing the input files'
30
+ parameter 'output_folder', 'folder for outputing deduped files'
31
+
32
+ def execute
33
+ SecurityGuard::Deduplication.new(
34
+ :input_folder => input_folder,
35
+ :output_folder => output_folder
36
+ ).process
37
+
38
+ ap "Deduplicated results published to '#{output_folder}'."
39
+ end
40
+ end
41
+
28
42
  class MainCommand < Clamp::Command
29
43
  def self.output_result(result, output_path)
30
44
  `echo #{result} > #{output_path}`
@@ -34,6 +48,10 @@ module SecurityGuard
34
48
  subcommand 'country_ips',
35
49
  'Returns a list of the IPs from given country and IP dictionaries.',
36
50
  SecurityGuard::CountryIpsCommand
51
+
52
+ subcommand 'deduplication',
53
+ 'Deduplicates content contained within a list of files.',
54
+ SecurityGuard::DeduplicationCommand
37
55
  end
38
56
  end
39
57
 
@@ -4,3 +4,4 @@ require 'security_guard/utils/geo_ips'
4
4
  require 'security_guard/concerns/accepts_from_file'
5
5
  require 'security_guard/concerns/initializable'
6
6
  require 'security_guard/country_ips'
7
+ require 'security_guard/deduplication'
@@ -5,10 +5,10 @@ module SecurityGuard
5
5
  klass.extend ClassMethods
6
6
  end
7
7
 
8
- def initializable_attrs(attributes)
8
+ def initializable_attrs(attributes = nil)
9
9
  attributes.each do |name, value|
10
10
  self.send "#{name}=", value
11
- end
11
+ end if attributes
12
12
  end
13
13
 
14
14
  module ClassMethods
@@ -1,11 +1,14 @@
1
1
  module SecurityGuard
2
2
  class CountryIps
3
3
  include Concerns::AcceptsFromFile
4
+ include Concerns::Initializable
4
5
 
5
6
  accepts_from_file :countries, :ips
7
+ initializable :countries, :ips
6
8
 
7
- def initialize
9
+ def initialize(args = nil)
8
10
  @geoip ||= Utils::GeoIps.new(Utils::Files.load('GeoIP.dat'))
11
+ initializable_attrs args
9
12
  end
10
13
 
11
14
  def result
@@ -0,0 +1,64 @@
1
+ module SecurityGuard
2
+ class Deduplication
3
+ include Concerns::Initializable
4
+
5
+ initializable :input_folder, :output_folder
6
+ attr_accessor :source_data, :deduped_data
7
+
8
+ def initialize(args = nil)
9
+ @source_data ||= []
10
+ @deduped_data ||= []
11
+ initializable_attrs args
12
+ end
13
+
14
+ def process
15
+ read_data_from input_folder
16
+ dedupe source_data
17
+ write_data_to output_folder
18
+ end
19
+
20
+ private
21
+
22
+ def read_data_from(folder)
23
+ files = Dir["#{folder}/*"]
24
+
25
+ raise Exception.new('Input folder is invalid or is empty.') if files.empty?
26
+
27
+ files.each do |file|
28
+ source_data << File.readlines(file).map{ |line| line.downcase.strip }
29
+ end
30
+ end
31
+
32
+ def write_data_to(folder)
33
+ deduped_data.each_with_index do |array, index|
34
+ File.open("#{folder}/#{index+1}.txt", 'w') do |f|
35
+ f.puts array
36
+ end
37
+ end
38
+ end
39
+
40
+ def dedupe(data)
41
+ # start from the lowest array (in terms of dedupe priority)
42
+ data.reverse!
43
+ data_original = data.clone
44
+ data_original.each do |array|
45
+ data.shift
46
+ deduped_data << _deduped_multi(array, data)
47
+ end
48
+ # the top array doesn't need to be compared, just needs to be unique
49
+ deduped_data.last.uniq!
50
+ deduped_data.reverse!
51
+ end
52
+
53
+ def _deduped_multi(target, others)
54
+ others.each do |array|
55
+ target = _deduped(target, array)
56
+ end
57
+ target
58
+ end
59
+
60
+ def _deduped(target, other)
61
+ (target - other & target).uniq
62
+ end
63
+ end
64
+ end
@@ -1,3 +1,3 @@
1
1
  module SecurityGuard
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
3
  class TestInitializableWithInitializer
4
4
  include SecurityGuard::Concerns::Initializable
5
5
  initializable :attr1, :attr2
6
- def initialize(args)
6
+ def initialize(args = nil)
7
7
  initializable_attrs args
8
8
  end
9
9
  end
@@ -21,4 +21,12 @@ describe SecurityGuard::Concerns::Initializable do
21
21
  test.attr2.must_equal 'test2'
22
22
  end
23
23
  end
24
+
25
+ it 'without any initialiser arguments' do
26
+ test = TestInitializableWithInitializer.new
27
+ test.attr1 = 'test1'
28
+ test.attr2 = 'test2'
29
+ test.attr1.must_equal 'test1'
30
+ test.attr2.must_equal 'test2'
31
+ end
24
32
  end
@@ -2,9 +2,10 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe SecurityGuard::CountryIps do
4
4
  before do
5
- @country_ips = SecurityGuard::CountryIps.new
6
- @country_ips.countries = ['Australia']
7
- @country_ips.ips = ['4.4.4.4', '8.8.8.8', '203.206.0.1']
5
+ @country_ips = SecurityGuard::CountryIps.new(
6
+ :countries => ['Australia'],
7
+ :ips => ['4.4.4.4', '8.8.8.8', '203.206.0.1']
8
+ )
8
9
  end
9
10
 
10
11
  it 'contains GeoIP data' do
@@ -0,0 +1,68 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe SecurityGuard::Deduplication do
4
+ before do
5
+ @dedupe = SecurityGuard::Deduplication.new(
6
+ :input_folder => fixture_file('dedupe_lists/'),
7
+ :output_folder => fixture_file('../tmp/')
8
+ )
9
+
10
+ @source_data = [
11
+ ['a@example.com', 'b@example.com', 'c@example.com', 'c@example.com'],
12
+ ['b@example.com', 'd@example.com'],
13
+ ['c@example.com', 'd@example.com', 'e@example.com'],
14
+ ]
15
+
16
+ `rm -rf #{fixture_file('../tmp/*')}`
17
+ end
18
+
19
+ it 'reads data from the input folder' do
20
+ @dedupe.send :read_data_from, fixture_file('dedupe_lists/')
21
+ @dedupe.source_data.must_equal @source_data
22
+ end
23
+
24
+ it 'writes data to the output folder' do
25
+ @dedupe.deduped_data = [
26
+ [1, 2, 3],
27
+ [4, 5, 6],
28
+ ]
29
+ @dedupe.send :write_data_to, fixture_file('../tmp/')
30
+
31
+ File.read(fixture_file('../tmp/1.txt')).must_equal "1\n2\n3\n"
32
+ File.read(fixture_file('../tmp/2.txt')).must_equal "4\n5\n6\n"
33
+ end
34
+
35
+ it 'reads input and writes output' do
36
+ @dedupe.process
37
+
38
+ File.read(fixture_file('../tmp/1.txt')).must_equal "a@example.com\nb@example.com\nc@example.com\n"
39
+ File.read(fixture_file('../tmp/2.txt')).must_equal "d@example.com\n"
40
+ File.read(fixture_file('../tmp/3.txt')).must_equal "e@example.com\n"
41
+ end
42
+
43
+ it 'dedupes an array with another array' do
44
+ @dedupe.send(:_deduped,
45
+ ['a@example.com', 'b@example.com', 'c@example.com', 'c@example.com'],
46
+ ['b@example.com', 'd@example.com'],
47
+ ).must_equal ['a@example.com', 'c@example.com']
48
+ end
49
+
50
+ it 'dedupes an array against multiple arrays' do
51
+ @dedupe.send(:_deduped_multi,
52
+ ['c@example.com', 'd@example.com', 'e@example.com'],
53
+ [
54
+ ['a@example.com', 'b@example.com', 'c@example.com', 'c@example.com'],
55
+ ['b@example.com', 'd@example.com'],
56
+ ]
57
+ ).must_equal ['e@example.com']
58
+ end
59
+
60
+ it 'dedupes the source data' do
61
+ @dedupe.send :dedupe, @source_data
62
+ @dedupe.deduped_data.must_equal [
63
+ ['a@example.com', 'b@example.com', 'c@example.com'],
64
+ ['d@example.com'],
65
+ ['e@example.com'],
66
+ ]
67
+ end
68
+ end
@@ -0,0 +1,4 @@
1
+ a@example.com
2
+ b@example.com
3
+ c@example.com
4
+ c@example.com
@@ -0,0 +1,2 @@
1
+ b@example.com
2
+ d@example.com
@@ -0,0 +1,3 @@
1
+ c@example.com
2
+ d@example.com
3
+ e@example.com
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: security_guard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-20 00:00:00.000000000 Z
12
+ date: 2012-02-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: clamp
16
- requirement: &70250519727080 !ruby/object:Gem::Requirement
16
+ requirement: &70315493707920 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70250519727080
24
+ version_requirements: *70315493707920
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: awesome_print
27
- requirement: &70250519724280 !ruby/object:Gem::Requirement
27
+ requirement: &70315493707500 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70250519724280
35
+ version_requirements: *70315493707500
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: geoip
38
- requirement: &70250519722640 !ruby/object:Gem::Requirement
38
+ requirement: &70315493707080 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70250519722640
46
+ version_requirements: *70315493707080
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: simplecov
49
- requirement: &70250519721680 !ruby/object:Gem::Requirement
49
+ requirement: &70315493706660 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70250519721680
57
+ version_requirements: *70315493706660
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: minitest-colorize
60
- requirement: &70250519715500 !ruby/object:Gem::Requirement
60
+ requirement: &70315493706240 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70250519715500
68
+ version_requirements: *70315493706240
69
69
  description: A collection of useful tools for auditing data and performing security
70
70
  checks.
71
71
  email:
@@ -86,6 +86,7 @@ files:
86
86
  - lib/security_guard/concerns/accepts_from_file.rb
87
87
  - lib/security_guard/concerns/initializable.rb
88
88
  - lib/security_guard/country_ips.rb
89
+ - lib/security_guard/deduplication.rb
89
90
  - lib/security_guard/utils/files.rb
90
91
  - lib/security_guard/utils/geo_ips.rb
91
92
  - lib/security_guard/version.rb
@@ -93,7 +94,11 @@ files:
93
94
  - specs/concerns/accepts_from_file_spec.rb
94
95
  - specs/concerns/initializable_spec.rb
95
96
  - specs/country_ips_spec.rb
97
+ - specs/deduplication_spec.rb
96
98
  - specs/fixtures/countries.txt
99
+ - specs/fixtures/dedupe_lists/a.txt
100
+ - specs/fixtures/dedupe_lists/b.txt
101
+ - specs/fixtures/dedupe_lists/c.txt
97
102
  - specs/fixtures/ip_addresses.txt
98
103
  - specs/spec_helper.rb
99
104
  - specs/utils/files_spec.rb