metasploit-model 2.0.3 → 3.1.2
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.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -1
- data/.travis.yml +8 -3
- data/.yardopts +2 -1
- data/Gemfile +2 -2
- data/app/validators/address_format_validator.rb +26 -0
- data/app/validators/ip_format_validator.rb +13 -19
- data/app/validators/nil_validator.rb +3 -3
- data/app/validators/parameters_validator.rb +18 -10
- data/app/validators/password_is_strong_validator.rb +93 -67
- data/lib/metasploit/model.rb +1 -0
- data/lib/metasploit/model/base.rb +2 -2
- data/lib/metasploit/model/engine.rb +2 -2
- data/lib/metasploit/model/search/attribute.rb +1 -1
- data/lib/metasploit/model/translation.rb +2 -2
- data/lib/metasploit/model/version.rb +1 -1
- data/metasploit-model.gemspec +9 -9
- data/spec/app/models/metasploit/model/association/reflection_spec.rb +2 -2
- data/spec/app/models/metasploit/model/search/operator/association_spec.rb +1 -1
- data/spec/app/models/metasploit/model/search/operator/attribute_spec.rb +1 -1
- data/spec/app/validators/address_format_validator_spec.rb +136 -0
- data/spec/app/validators/ip_format_validator_spec.rb +0 -24
- data/spec/app/validators/password_is_strong_validator_spec.rb +31 -42
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/config/application.rb +1 -5
- data/spec/dummy/config/environments/development.rb +0 -10
- data/spec/dummy/db/schema.rb +0 -1
- data/spec/factories/metasploit/model/association/reflections.rb +1 -1
- data/spec/factories/metasploit/model/bases.rb +1 -1
- data/spec/factories/metasploit/model/search/operator/associations.rb +1 -1
- data/spec/factories/metasploit/model/search/operator/attributes.rb +1 -1
- data/spec/factories/metasploit/model/search/operator/bases.rb +1 -1
- data/spec/lib/metasploit/model/engine_spec.rb +3 -3
- data/spec/lib/metasploit/model/search/attribute_spec.rb +2 -2
- metadata +93 -100
- metadata.gz.sig +0 -0
- 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?
|
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
|
-
|
30
|
+
FactoryBot.definition_file_paths.unshift definition_file_path
|
31
31
|
end
|
32
32
|
end
|
33
33
|
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 `
|
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
|
#
|
@@ -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 `
|
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
|
data/metasploit-model.gemspec
CHANGED
@@ -6,19 +6,19 @@ 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 = ['
|
10
|
-
spec.email = ['
|
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
|
-
|
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.
|
20
|
+
spec.required_ruby_version = '>= 2.2.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'
|
@@ -29,10 +29,10 @@ Gem::Specification.new do |spec|
|
|
29
29
|
|
30
30
|
# Dependency loading
|
31
31
|
|
32
|
-
spec.add_runtime_dependency 'activemodel', '~>
|
33
|
-
spec.add_runtime_dependency 'activesupport', '~>
|
32
|
+
spec.add_runtime_dependency 'activemodel', '~> 5.2.2'
|
33
|
+
spec.add_runtime_dependency 'activesupport', '~> 5.2.2'
|
34
34
|
|
35
|
-
spec.add_runtime_dependency 'railties', '~>
|
35
|
+
spec.add_runtime_dependency 'railties', '~> 5.2.2'
|
36
36
|
|
37
37
|
if RUBY_PLATFORM =~ /java/
|
38
38
|
# 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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 '#
|
19
|
-
subject(:
|
20
|
-
password_is_strong_validator.send(:
|
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
|
-
|
70
|
-
|
71
|
-
|
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
|
87
|
-
let(:
|
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 '
|
81
|
+
context 'with reserved regex characters in username' do
|
95
82
|
let(:username) do
|
96
|
-
|
83
|
+
"user(with)regex"
|
97
84
|
end
|
98
85
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
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
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
-
|
115
|
-
|
116
|
-
username
|
117
|
-
end
|
100
|
+
it { is_expected.to eq(true) }
|
101
|
+
end
|
118
102
|
|
119
|
-
|
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@
|
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
|
@@ -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
|
|
@@ -20,16 +20,6 @@ Rails.application.configure do
|
|
20
20
|
# Raise an error on page load if there are pending migrations.
|
21
21
|
config.active_record.migration_error = :page_load
|
22
22
|
|
23
|
-
# Debug mode disables concatenation and preprocessing of assets.
|
24
|
-
# This option may cause significant delays in view rendering with a large
|
25
|
-
# number of complex assets.
|
26
|
-
config.assets.debug = true
|
27
|
-
|
28
|
-
# Adds additional error checking when serving assets at runtime.
|
29
|
-
# Checks for improperly declared sprockets dependencies.
|
30
|
-
# Raises helpful error messages.
|
31
|
-
config.assets.raise_runtime_errors = true
|
32
|
-
|
33
23
|
# Raises error for missing translations
|
34
24
|
# config.action_view.raise_on_missing_translations = true
|
35
25
|
end
|