metasploit-model 2.0.4 → 3.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.travis.yml +8 -3
  5. data/.yardopts +2 -1
  6. data/Gemfile +2 -2
  7. data/app/validators/address_format_validator.rb +26 -0
  8. data/app/validators/ip_format_validator.rb +13 -19
  9. data/app/validators/nil_validator.rb +3 -3
  10. data/app/validators/parameters_validator.rb +18 -10
  11. data/app/validators/password_is_strong_validator.rb +93 -67
  12. data/lib/metasploit/model.rb +1 -0
  13. data/lib/metasploit/model/base.rb +2 -2
  14. data/lib/metasploit/model/engine.rb +2 -2
  15. data/lib/metasploit/model/file.rb +1 -0
  16. data/lib/metasploit/model/search/attribute.rb +1 -1
  17. data/lib/metasploit/model/search/operator/help.rb +1 -1
  18. data/lib/metasploit/model/translation.rb +2 -2
  19. data/lib/metasploit/model/version.rb +1 -1
  20. data/metasploit-model.gemspec +11 -13
  21. data/spec/app/models/metasploit/model/association/reflection_spec.rb +2 -2
  22. data/spec/app/models/metasploit/model/search/operator/association_spec.rb +1 -1
  23. data/spec/app/models/metasploit/model/search/operator/attribute_spec.rb +1 -1
  24. data/spec/app/validators/address_format_validator_spec.rb +136 -0
  25. data/spec/app/validators/ip_format_validator_spec.rb +0 -24
  26. data/spec/app/validators/password_is_strong_validator_spec.rb +31 -42
  27. data/spec/dummy/app/models/application_record.rb +3 -0
  28. data/spec/dummy/config/application.rb +1 -5
  29. data/spec/dummy/config/environments/development.rb +0 -10
  30. data/spec/dummy/db/schema.rb +0 -1
  31. data/spec/factories/metasploit/model/association/reflections.rb +1 -1
  32. data/spec/factories/metasploit/model/bases.rb +1 -1
  33. data/spec/factories/metasploit/model/search/operator/associations.rb +1 -1
  34. data/spec/factories/metasploit/model/search/operator/attributes.rb +1 -1
  35. data/spec/factories/metasploit/model/search/operator/bases.rb +1 -1
  36. data/spec/lib/metasploit/model/engine_spec.rb +3 -3
  37. data/spec/lib/metasploit/model/search/attribute_spec.rb +2 -2
  38. metadata +106 -99
  39. metadata.gz.sig +0 -0
  40. data/spec/dummy/config/initializers/assets.rb +0 -8
@@ -22,12 +22,12 @@ class Metasploit::Model::Engine < Rails::Engine
22
22
  end
23
23
 
24
24
  initializer 'metasploit-model.prepend_factory_path', :after => 'factory_girl.set_factory_paths' do
25
- if defined? FactoryGirl
25
+ if defined? FactoryBot
26
26
  relative_definition_file_path = config.generators.options[:factory_girl][:dir]
27
27
  definition_file_path = root.join(relative_definition_file_path)
28
28
 
29
29
  # unshift so that dependent gems can modify metasploit-model's factories
30
- FactoryGirl.definition_file_paths.unshift definition_file_path
30
+ FactoryBot.definition_file_paths.unshift definition_file_path
31
31
  end
32
32
  end
33
33
  end
@@ -41,5 +41,6 @@ if RUBY_PLATFORM =~ /java/ && Gem::Version.new(JRUBY_VERSION) < Gem::Version.new
41
41
  end
42
42
  end
43
43
  else
44
+ # Alias for ::File when not in jruby.
44
45
  Metasploit::Model::File = ::File
45
46
  end
@@ -16,7 +16,7 @@
16
16
  # The help for each operator is uses the `I18n` system, so the help for an attribute operator on a given class can
17
17
  # added to `config/locales/<lang>.yml`. The scope of the lookup, under the language key is the `Class`'s
18
18
  # `i18n_scope`, which is `metasploit.model` if the `Class` includes {Metasploit::Model::Translation} or
19
- # `active_record` for `ActiveRecord::Base` subclasses. Under the `i18n_scope`, any `Module#ancestor`'s
19
+ # `active_record` for `ApplicationRecord` subclasses. Under the `i18n_scope`, any `Module#ancestor`'s
20
20
  # `model_name.i18n_key` can be used to look up the help for an attribute's operator. This allows for super
21
21
  # classes or mixins to define the search operator help for subclasses.
22
22
  #
@@ -72,6 +72,6 @@ module Metasploit::Model::Search::Operator::Help
72
72
  name: name
73
73
  }
74
74
 
75
- ::I18n.translate(key, options)
75
+ ::I18n.translate(key, **options)
76
76
  end
77
77
  end
@@ -1,6 +1,6 @@
1
1
  # ActiveRecord::Translation is a dirty bastard and overrides `ActiveModel::Translation#lookup_ancestors`, so that it
2
2
  # will only count superclasses, and not all ancestors. Metasploit::Model needs the original behavior so that its
3
- # {Metasploit::Model::Module} modules can supply translations to both `ActiveRecord::Base` descendants in `Mdm` and
3
+ # {Metasploit::Model::Module} modules can supply translations to both `ApplicationRecord` descendants in `Mdm` and
4
4
  # `ActiveModel` descendants in `Metasploit::Framework`
5
5
  #
6
6
  # @see https://github.com/rails/rails/issues/11409
@@ -28,4 +28,4 @@ module Metasploit::Model::Translation
28
28
  'metasploit.model'
29
29
  end
30
30
  end
31
- end
31
+ end
@@ -1,7 +1,7 @@
1
1
  module Metasploit
2
2
  module Model
3
3
  # VERSION is managed by GemRelease
4
- VERSION = '2.0.4'
4
+ VERSION = '3.1.3'
5
5
 
6
6
  # @return [String]
7
7
  #
@@ -6,33 +6,31 @@ require 'metasploit/model/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'metasploit-model'
8
8
  spec.version = Metasploit::Model::VERSION
9
- spec.authors = ['Luke Imhoff']
10
- spec.email = ['luke_imhoff@rapid7.com']
9
+ spec.authors = ['Metasploit Hackers']
10
+ spec.email = ['msfdev@metasploit.com']
11
11
  spec.description = %q{Common code, such as validators and mixins, that are shared between ActiveModels in metasploit-framework and ActiveRecords in metasploit_data_models.}
12
12
  spec.summary = %q{Metasploit Model Mixins and Validators}
13
13
 
14
- spec.files = `git ls-files`.split($/)
15
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
14
+ spec.files = `git ls-files`.split($/).reject { |file|
15
+ file =~ /^bin/
16
+ }
16
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
18
  spec.require_paths = %w{app/models app/validators lib}
18
19
 
19
- spec.required_ruby_version = '>= 2.2.0'
20
+ spec.required_ruby_version = '>= 2.4.0'
20
21
 
21
- spec.add_development_dependency 'bundler', '~> 1.3'
22
22
  spec.add_development_dependency 'metasploit-yard'
23
23
  spec.add_development_dependency 'metasploit-erd'
24
24
  spec.add_development_dependency 'rake'
25
-
26
- # documentation
27
- # 0.8.7.4 has a bug where attribute setters show up as undocumented
28
- spec.add_development_dependency 'yard', '< 0.8.7.4'
25
+ spec.add_development_dependency 'yard'
26
+ spec.add_development_dependency 'e2mmap'
29
27
 
30
28
  # Dependency loading
31
29
 
32
- spec.add_runtime_dependency 'activemodel', '~> 4.2.6'
33
- spec.add_runtime_dependency 'activesupport', '~> 4.2.6'
30
+ spec.add_runtime_dependency 'activemodel', '~> 5.2.2'
31
+ spec.add_runtime_dependency 'activesupport', '~> 5.2.2'
34
32
 
35
- spec.add_runtime_dependency 'railties', '~> 4.2.6'
33
+ spec.add_runtime_dependency 'railties', '~> 5.2.2'
36
34
 
37
35
  if RUBY_PLATFORM =~ /java/
38
36
  # markdown formatting for yard
@@ -12,7 +12,7 @@ RSpec.describe Metasploit::Model::Association::Reflection, type: :model do
12
12
 
13
13
 
14
14
  let(:class_name) do
15
- FactoryGirl.generate :metasploit_model_association_reflection_class_name
15
+ FactoryBot.generate :metasploit_model_association_reflection_class_name
16
16
  end
17
17
 
18
18
  let(:class_name_class) do
@@ -24,7 +24,7 @@ RSpec.describe Metasploit::Model::Association::Reflection, type: :model do
24
24
  end
25
25
 
26
26
  let(:name) do
27
- FactoryGirl.generate :metasploit_model_association_reflection_name
27
+ FactoryBot.generate :metasploit_model_association_reflection_name
28
28
  end
29
29
 
30
30
  let(:reflection) do
@@ -7,7 +7,7 @@ RSpec.describe Metasploit::Model::Search::Operator::Association, type: :model do
7
7
  end
8
8
 
9
9
  let(:association) do
10
- FactoryGirl.generate :metasploit_model_search_operator_association_association
10
+ FactoryBot.generate :metasploit_model_search_operator_association_association
11
11
  end
12
12
 
13
13
  let(:source_operator) do
@@ -86,7 +86,7 @@ RSpec.describe Metasploit::Model::Search::Operator::Attribute, type: :model do
86
86
  end
87
87
 
88
88
  let(:attribute) do
89
- FactoryGirl.generate :metasploit_model_search_operator_attribute_attribute
89
+ FactoryBot.generate :metasploit_model_search_operator_attribute_attribute
90
90
  end
91
91
 
92
92
  let(:attribute_operator) do
@@ -0,0 +1,136 @@
1
+ RSpec.describe AddressFormatValidator do
2
+ subject(:address_format_validator) do
3
+ described_class.new(
4
+ :attributes => attributes
5
+ )
6
+ end
7
+
8
+ let(:attribute) do
9
+ :address
10
+ end
11
+
12
+ let(:attributes) do
13
+ [
14
+ attribute
15
+ ]
16
+ end
17
+
18
+ context '#validate_each' do
19
+ subject(:validate_each) do
20
+ address_format_validator.validate_each(record, attribute, value)
21
+ end
22
+
23
+ let(:error) do
24
+ 'must be a valid (IP or hostname) address'
25
+ end
26
+
27
+ let(:record) do
28
+ record_class.new
29
+ end
30
+
31
+ let(:record_class) do
32
+ # capture for Class.new scope
33
+ attribute = self.attribute
34
+
35
+ Class.new do
36
+ include ActiveModel::Validations
37
+
38
+ #
39
+ # Validations
40
+ #
41
+
42
+ validates attribute,
43
+ :address_format => true
44
+ end
45
+ end
46
+
47
+ context 'address' do
48
+ context 'in IPv4 format' do
49
+ let(:value) do
50
+ '192.168.0.1'
51
+ end
52
+
53
+ it 'should not record any errors' do
54
+ validate_each
55
+
56
+ expect(record.errors).to be_empty
57
+ end
58
+ end
59
+
60
+ context 'in IPv6 format' do
61
+ let(:value) do
62
+ '::1'
63
+ end
64
+
65
+ it 'should not record any errors' do
66
+ validate_each
67
+
68
+ expect(record.errors).to be_empty
69
+ end
70
+ end
71
+
72
+ context 'with a valid hostname' do
73
+ let(:value) do
74
+ 'testvalue.test.com'
75
+ end
76
+
77
+ it 'should not record any errors' do
78
+ validate_each
79
+
80
+ expect(record.errors).to be_empty
81
+ end
82
+ end
83
+
84
+ context 'with localhost' do
85
+ let(:value) do
86
+ 'localhost'
87
+ end
88
+
89
+ it 'should not record any errors' do
90
+ validate_each
91
+
92
+ expect(record.errors).to be_empty
93
+ end
94
+ end
95
+
96
+ context 'with blank address' do
97
+ let(:value) do
98
+ ''
99
+ end
100
+
101
+ it 'should record error' do
102
+ validate_each
103
+
104
+ expect(record.errors[attribute]).to include(error)
105
+ end
106
+ end
107
+
108
+ context 'with nil value' do
109
+ let(:value) do
110
+ nil
111
+ end
112
+
113
+ it 'should record error on attribute' do
114
+ validate_each
115
+
116
+ expect(record.errors[attribute]).to include(error)
117
+ end
118
+ end
119
+
120
+ context 'with a malformed hostname should record an error' do
121
+ invalid_hostnames = ['testvalue.test.com:', 'testvalue-.test.com', '[testvalue.test.com]']
122
+ invalid_hostnames.each do | entry |
123
+ let(:value) do
124
+ entry
125
+ end
126
+
127
+ it 'should record an error on attribute' do
128
+ validate_each
129
+ expect(record.errors[attribute]).to include(error)
130
+ end
131
+ end
132
+
133
+ end
134
+ end
135
+ end
136
+ end
@@ -69,30 +69,6 @@ RSpec.describe IpFormatValidator do
69
69
  end
70
70
  end
71
71
 
72
- context 'with IPv4 range' do
73
- let(:value) do
74
- '127.0.0.1/8'
75
- end
76
-
77
- it 'should record error' do
78
- validate_each
79
-
80
- expect(record.errors[attribute]).to include("#{error} and not an IPv4 address range in CIDR or netmask notation")
81
- end
82
- end
83
-
84
- context 'with IPv6 range' do
85
- let(:value) do
86
- '3ffe:505:2::1/48'
87
- end
88
-
89
- it 'should record error' do
90
- validate_each
91
-
92
- expect(record.errors[attribute]).to include("#{error} and not an IPv6 address range in CIDR or netmask notation")
93
- end
94
- end
95
-
96
72
  context 'without IPv4 or IPv6 address' do
97
73
  let(:value) do
98
74
  'localhost'
@@ -15,9 +15,9 @@ RSpec.describe PasswordIsStrongValidator do
15
15
  ]
16
16
  end
17
17
 
18
- context '#contains_repetition' do
19
- subject(:contains_repetition?) do
20
- password_is_strong_validator.send(:contains_repetition?, password)
18
+ context '#is_only_repetition' do
19
+ subject(:is_only_repetition?) do
20
+ password_is_strong_validator.send(:is_only_repetition?, password)
21
21
  end
22
22
 
23
23
  context 'with all the same character' do
@@ -56,8 +56,8 @@ RSpec.describe PasswordIsStrongValidator do
56
56
  let(:password) do
57
57
  'abcdefgh'
58
58
  end
59
-
60
59
  it { is_expected.to eq(false) }
60
+
61
61
  end
62
62
  end
63
63
 
@@ -66,59 +66,48 @@ RSpec.describe PasswordIsStrongValidator do
66
66
  password_is_strong_validator.send(:contains_username?, username, password)
67
67
  end
68
68
 
69
- let(:username) do
70
- ''
71
- end
72
-
73
- context 'with blank password' do
74
- let(:password) do
75
- ''
76
- end
77
-
78
- it { is_expected.to eq(false) }
79
- end
80
-
81
- context 'without blank password' do
82
- let(:password) do
83
- 'password'
69
+ context 'without blank username' do
70
+ let(:username) do
71
+ 'username'
84
72
  end
85
73
 
86
- context 'with blank username' do
87
- let(:username) do
74
+ context 'with blank password' do
75
+ let(:password) do
88
76
  ''
89
77
  end
90
-
91
78
  it { is_expected.to eq(false) }
92
79
  end
93
80
 
94
- context 'without blank username' do
81
+ context 'with reserved regex characters in username' do
95
82
  let(:username) do
96
- 'username'
83
+ "user(with)regex"
97
84
  end
98
85
 
99
- it 'should escape username' do
100
- expect(Regexp).to receive(:escape).with(username).and_call_original
101
-
102
- contains_username?
86
+ context 'with username in password' do
87
+ let(:password) do
88
+ "myPassworduser(with)regexValue"
89
+ end
90
+ it { is_expected.to eq(false)}
103
91
  end
92
+ end
104
93
 
105
- context 'with matching password' do
106
- context 'of different case' do
107
- let(:password) do
108
- username.titleize
109
- end
110
-
111
- it { is_expected.to eq(true) }
94
+ context 'with matching password' do
95
+ context 'of different case' do
96
+ let(:password) do
97
+ username.titleize
112
98
  end
113
99
 
114
- context 'of same case' do
115
- let(:password) do
116
- username
117
- end
100
+ it { is_expected.to eq(true) }
101
+ end
118
102
 
119
- it { is_expected.to eq(true) }
103
+ context 'of same case' do
104
+ let(:password) do
105
+ username
120
106
  end
107
+
108
+ it { is_expected.to eq(true) }
121
109
  end
110
+
122
111
  end
123
112
  end
124
113
  end
@@ -231,7 +220,7 @@ RSpec.describe PasswordIsStrongValidator do
231
220
 
232
221
  context 'without repetition' do
233
222
  let(:value) do
234
- 'A$uperg00dp@ssw0rd'
223
+ 'A$uperg00dp@sw0rd'
235
224
  end
236
225
 
237
226
  it 'should not record any errors' do
@@ -245,4 +234,4 @@ RSpec.describe PasswordIsStrongValidator do
245
234
  end
246
235
  end
247
236
  end
248
- end
237
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ApplicationRecord
2
+ self.abstract_class = true
3
+ end
@@ -3,6 +3,7 @@ require File.expand_path('../boot', __FILE__)
3
3
  # Pick the frameworks you want:
4
4
  require 'active_model/railtie'
5
5
  require 'action_controller/railtie'
6
+ require 'active_record/railtie'
6
7
 
7
8
  Bundler.require(*Rails.groups)
8
9
 
@@ -40,11 +41,6 @@ module Dummy
40
41
  # Enable escaping HTML in JSON.
41
42
  config.active_support.escape_html_entities_in_json = true
42
43
 
43
- # Enable the asset pipeline
44
- config.assets.enabled = false
45
-
46
- # Version of your assets, change this if you want to expire all your assets
47
- config.assets.version = '1.0'
48
44
  end
49
45
  end
50
46