security_guard 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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