metasploit_data_models 0.17.3 → 0.18.0.pre.compatibility
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CONTRIBUTING.md +164 -0
- data/README.md +6 -2
- data/app/models/mdm/host.rb +18 -0
- data/app/models/mdm/service.rb +12 -1
- data/app/models/metasploit_data_models/search/operation/port/number.rb +25 -0
- data/app/models/metasploit_data_models/search/operation/port/range.rb +79 -0
- data/app/models/metasploit_data_models/search/operation/range.rb +56 -0
- data/app/models/metasploit_data_models/search/operator/multitext.rb +73 -0
- data/app/models/metasploit_data_models/search/operator/port/list.rb +67 -0
- data/app/models/metasploit_data_models/search/visitor/attribute.rb +2 -1
- data/app/models/metasploit_data_models/search/visitor/includes.rb +3 -2
- data/app/models/metasploit_data_models/search/visitor/joins.rb +5 -3
- data/app/models/metasploit_data_models/search/visitor/method.rb +3 -2
- data/app/models/metasploit_data_models/search/visitor/where.rb +8 -2
- data/config/locales/en.yml +17 -1
- data/lib/metasploit_data_models.rb +1 -9
- data/lib/metasploit_data_models/version.rb +29 -6
- data/metasploit_data_models.gemspec +2 -2
- data/spec/app/models/metasploit_data_models/search/operation/port/number_spec.rb +41 -0
- data/spec/app/models/metasploit_data_models/search/operation/port/range_spec.rb +140 -0
- data/spec/app/models/metasploit_data_models/search/operation/range_spec.rb +235 -0
- data/spec/app/models/metasploit_data_models/search/operator/multitext_spec.rb +162 -0
- data/spec/app/models/metasploit_data_models/search/operator/port/list_spec.rb +164 -0
- data/spec/app/models/metasploit_data_models/search/visitor/attribute_spec.rb +48 -26
- data/spec/app/models/metasploit_data_models/search/visitor/includes_spec.rb +10 -7
- data/spec/app/models/metasploit_data_models/search/visitor/joins_spec.rb +44 -30
- data/spec/app/models/metasploit_data_models/search/visitor/method_spec.rb +16 -0
- data/spec/app/models/metasploit_data_models/search/visitor/relation_spec.rb +273 -65
- data/spec/app/models/metasploit_data_models/search/visitor/where_spec.rb +42 -2
- data/spec/factories/mdm/services.rb +1 -2
- data/spec/lib/metasploit_data_models/version_spec.rb +141 -0
- data/spec/support/shared/examples/metasploit_data_models/search/visitor/where/visit/with_metasploit_model_search_group_base.rb +1 -1
- metadata +27 -11
- data/lib/metasploit_data_models/models.rb +0 -21
- data/lib/metasploit_data_models/validators.rb +0 -19
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::Search::Operation::Range do
|
4
|
+
subject(:range_operation) {
|
5
|
+
described_class.new(attributes)
|
6
|
+
}
|
7
|
+
|
8
|
+
context 'CONSTANTS' do
|
9
|
+
context 'SEPARATOR' do
|
10
|
+
subject(:separator) {
|
11
|
+
described_class::SEPARATOR
|
12
|
+
}
|
13
|
+
|
14
|
+
it { should == '-' }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'validations' do
|
19
|
+
#
|
20
|
+
# lets
|
21
|
+
#
|
22
|
+
|
23
|
+
let(:attributes) {
|
24
|
+
{
|
25
|
+
value: value
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
#
|
30
|
+
# Callbacks
|
31
|
+
#
|
32
|
+
|
33
|
+
before(:each) do
|
34
|
+
range_operation.valid?
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'errors on #value' do
|
38
|
+
subject(:errors) {
|
39
|
+
range_operation.errors[:value]
|
40
|
+
}
|
41
|
+
|
42
|
+
context '#ordered' do
|
43
|
+
let(:error) {
|
44
|
+
I18n.translate!('metasploit.model.errors.models.metasploit_data_models/search/operation/range.attributes.value.order', error_attributes)
|
45
|
+
}
|
46
|
+
|
47
|
+
context 'with Range' do
|
48
|
+
context 'with begin before end' do
|
49
|
+
let(:error_attributes) {
|
50
|
+
{
|
51
|
+
begin: '"1"',
|
52
|
+
end: '"2"'
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
let(:value) {
|
57
|
+
'1-2'
|
58
|
+
}
|
59
|
+
|
60
|
+
it { should_not include(error) }
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'with begin same as end' do
|
64
|
+
let(:error_attributes) {
|
65
|
+
{
|
66
|
+
begin: '"1"',
|
67
|
+
end: '"1"'
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
let(:value) {
|
72
|
+
'1-1'
|
73
|
+
}
|
74
|
+
|
75
|
+
it { should_not include(error) }
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'with begin after end' do
|
79
|
+
let(:error_attributes) {
|
80
|
+
{
|
81
|
+
begin: '"2"',
|
82
|
+
end: '"1"'
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
let(:value) {
|
87
|
+
'2-1'
|
88
|
+
}
|
89
|
+
|
90
|
+
it { should include error }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'without Range' do
|
95
|
+
let(:error_attributes) {
|
96
|
+
{
|
97
|
+
begin: '"1"',
|
98
|
+
end: '"2"'
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
let(:value) {
|
103
|
+
'1..2'
|
104
|
+
}
|
105
|
+
|
106
|
+
it { should_not include(error) }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context '#range' do
|
111
|
+
context 'with Range' do
|
112
|
+
let(:value) {
|
113
|
+
'1-2'
|
114
|
+
}
|
115
|
+
|
116
|
+
it { should be_empty }
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'without Range' do
|
120
|
+
let(:error) {
|
121
|
+
I18n.translate!('metasploit.model.errors.models.metasploit_data_models/search/operation/range.attributes.value.range')
|
122
|
+
}
|
123
|
+
|
124
|
+
let(:value) {
|
125
|
+
'1..2'
|
126
|
+
}
|
127
|
+
|
128
|
+
it { should include error }
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context '#value' do
|
135
|
+
subject(:value) {
|
136
|
+
range_operation.value
|
137
|
+
}
|
138
|
+
|
139
|
+
#
|
140
|
+
# lets
|
141
|
+
#
|
142
|
+
|
143
|
+
let(:attributes) {
|
144
|
+
{
|
145
|
+
value: formatted_value
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
context "without '-'" do
|
150
|
+
let(:formatted_value) {
|
151
|
+
'a..b'
|
152
|
+
}
|
153
|
+
|
154
|
+
it 'returns unconvertable value' do
|
155
|
+
expect(value).to eq(formatted_value)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context "with one '-'" do
|
160
|
+
let(:formatted_begin) {
|
161
|
+
'a'
|
162
|
+
}
|
163
|
+
|
164
|
+
let(:formatted_end) {
|
165
|
+
'b'
|
166
|
+
}
|
167
|
+
|
168
|
+
let(:formatted_value) {
|
169
|
+
"#{formatted_begin}-#{formatted_end}"
|
170
|
+
}
|
171
|
+
|
172
|
+
it 'returns Ranges' do
|
173
|
+
expect(value).to be_a Range
|
174
|
+
end
|
175
|
+
|
176
|
+
context '#begin' do
|
177
|
+
subject(:range_begin) {
|
178
|
+
value.begin
|
179
|
+
}
|
180
|
+
|
181
|
+
it "is part before '-'" do
|
182
|
+
expect(range_begin).to eq(formatted_begin)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context '#end' do
|
187
|
+
subject(:range_end) {
|
188
|
+
value.end
|
189
|
+
}
|
190
|
+
|
191
|
+
it "is part after '-'" do
|
192
|
+
expect(range_end).to eq(formatted_end)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context "with multiple '-'" do
|
198
|
+
let(:formatted_begin) {
|
199
|
+
'a'
|
200
|
+
}
|
201
|
+
|
202
|
+
let(:formatted_end) {
|
203
|
+
'b-c'
|
204
|
+
}
|
205
|
+
|
206
|
+
let(:formatted_value) {
|
207
|
+
"#{formatted_begin}-#{formatted_end}"
|
208
|
+
}
|
209
|
+
|
210
|
+
it 'returns Ranges' do
|
211
|
+
expect(value).to be_a Range
|
212
|
+
end
|
213
|
+
|
214
|
+
context '#begin' do
|
215
|
+
subject(:range_begin) {
|
216
|
+
value.begin
|
217
|
+
}
|
218
|
+
|
219
|
+
it "is part before first '-'" do
|
220
|
+
expect(range_begin).to eq(formatted_begin)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
context '#end' do
|
225
|
+
subject(:range_end) {
|
226
|
+
value.end
|
227
|
+
}
|
228
|
+
|
229
|
+
it "is part after first '-'" do
|
230
|
+
expect(range_end).to eq(formatted_end)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::Search::Operator::Multitext do
|
4
|
+
subject(:multitext_operator) {
|
5
|
+
described_class.new(
|
6
|
+
attributes
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
let(:attributes) {
|
11
|
+
{}
|
12
|
+
}
|
13
|
+
|
14
|
+
context 'validations' do
|
15
|
+
it { should ensure_length_of(:operator_names).is_at_least(2) }
|
16
|
+
it { should validate_presence_of :name }
|
17
|
+
end
|
18
|
+
|
19
|
+
context '#children' do
|
20
|
+
subject(:children) {
|
21
|
+
multitext_operator.children(formatted_value)
|
22
|
+
}
|
23
|
+
|
24
|
+
let(:attributes) {
|
25
|
+
{
|
26
|
+
klass: klass,
|
27
|
+
operator_names: operator_names
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
let(:klass) {
|
32
|
+
Mdm::Host
|
33
|
+
}
|
34
|
+
|
35
|
+
let(:operator_names) {
|
36
|
+
[
|
37
|
+
:os_flavor,
|
38
|
+
:os_name,
|
39
|
+
:os_sp
|
40
|
+
]
|
41
|
+
}
|
42
|
+
|
43
|
+
context 'with nil' do
|
44
|
+
let(:formatted_value) {
|
45
|
+
nil
|
46
|
+
}
|
47
|
+
|
48
|
+
it { should == [] }
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with empty String' do
|
52
|
+
let(:formatted_value) {
|
53
|
+
''
|
54
|
+
}
|
55
|
+
|
56
|
+
it { should == [] }
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'without quotes' do
|
60
|
+
let(:formatted_value) {
|
61
|
+
words.join(' ')
|
62
|
+
}
|
63
|
+
|
64
|
+
let(:words) {
|
65
|
+
%w{multiple words}
|
66
|
+
}
|
67
|
+
|
68
|
+
it 'generates a union for each word' do
|
69
|
+
children.each_with_index do |child, index|
|
70
|
+
expect(child).to be_a Metasploit::Model::Search::Operation::Group::Union
|
71
|
+
|
72
|
+
child.children.each do |grandchild|
|
73
|
+
expect(grandchild.value).to eq(words[index])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'with quotes' do
|
80
|
+
let(:formatted_value) {
|
81
|
+
%Q{"quoted words"}
|
82
|
+
}
|
83
|
+
|
84
|
+
it 'generates a single union for quoted words as a single argument' do
|
85
|
+
expect(children).to have(1).items
|
86
|
+
|
87
|
+
child = children.first
|
88
|
+
|
89
|
+
expect(child).to be_a Metasploit::Model::Search::Operation::Group::Union
|
90
|
+
|
91
|
+
child.children.each do |grandchild|
|
92
|
+
expect(grandchild.value).to eq('quoted words')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context '#name' do
|
99
|
+
subject(:name) {
|
100
|
+
multitext_operator.name
|
101
|
+
}
|
102
|
+
|
103
|
+
context 'default' do
|
104
|
+
it { should be_nil }
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'setter' do
|
108
|
+
let(:new_name) {
|
109
|
+
:new_name
|
110
|
+
}
|
111
|
+
|
112
|
+
it 'sets #name' do
|
113
|
+
expect {
|
114
|
+
multitext_operator.name = new_name
|
115
|
+
}.to change(multitext_operator, :name).to(new_name)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context '#operator_names' do
|
121
|
+
subject(:operator_names) {
|
122
|
+
multitext_operator.operator_names
|
123
|
+
}
|
124
|
+
|
125
|
+
context 'default' do
|
126
|
+
it { should == [] }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context '#operators' do
|
131
|
+
subject(:operators) {
|
132
|
+
multitext_operator.operators
|
133
|
+
}
|
134
|
+
|
135
|
+
let(:attributes) {
|
136
|
+
{
|
137
|
+
klass: klass,
|
138
|
+
operator_names: operator_names
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
let(:klass) {
|
143
|
+
Mdm::Host
|
144
|
+
}
|
145
|
+
|
146
|
+
let(:operator_names) {
|
147
|
+
[
|
148
|
+
:os_flavor,
|
149
|
+
:os_name,
|
150
|
+
:os_sp
|
151
|
+
]
|
152
|
+
}
|
153
|
+
|
154
|
+
it 'looks up all operators by name using #operator' do
|
155
|
+
operator_names.each do |operator_name|
|
156
|
+
expect(multitext_operator).to receive(:operator).with(operator_name).and_call_original
|
157
|
+
end
|
158
|
+
|
159
|
+
operators
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::Search::Operator::Port::List do
|
4
|
+
subject(:port_list_operator) {
|
5
|
+
described_class.new(
|
6
|
+
klass: klass
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
let(:klass) {
|
11
|
+
Mdm::Service
|
12
|
+
}
|
13
|
+
|
14
|
+
context 'CONSTANTS' do
|
15
|
+
context 'SEPARATOR' do
|
16
|
+
subject(:separator) {
|
17
|
+
described_class::SEPARATOR
|
18
|
+
}
|
19
|
+
|
20
|
+
it { should == ',' }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context '#attribute' do
|
25
|
+
subject(:attribute) {
|
26
|
+
port_list_operator.attribute
|
27
|
+
}
|
28
|
+
|
29
|
+
context 'default' do
|
30
|
+
it { should == :port }
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'setter' do
|
34
|
+
let(:value) {
|
35
|
+
:alternate_port
|
36
|
+
}
|
37
|
+
|
38
|
+
#
|
39
|
+
# Callbacks
|
40
|
+
#
|
41
|
+
|
42
|
+
before(:each) do
|
43
|
+
port_list_operator.attribute = value
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'sets #attribute' do
|
47
|
+
expect(port_list_operator.attribute).to eq(value)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context '#children' do
|
53
|
+
subject(:children) {
|
54
|
+
port_list_operator.children(formatted_value)
|
55
|
+
}
|
56
|
+
|
57
|
+
context "with ','" do
|
58
|
+
end
|
59
|
+
|
60
|
+
context "without ','" do
|
61
|
+
context "with '-'" do
|
62
|
+
let(:formatted_value) {
|
63
|
+
'1-2'
|
64
|
+
}
|
65
|
+
|
66
|
+
it 'includes a MetasploitDataModels::Search::Operation::Port::Range' do
|
67
|
+
expect(children.map(&:class)).to include(MetasploitDataModels::Search::Operation::Port::Range)
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'MetasploitDataModels::Search::Operation::Port::Range' do
|
71
|
+
subject(:operation_range) {
|
72
|
+
children.first
|
73
|
+
}
|
74
|
+
|
75
|
+
context '#operator' do
|
76
|
+
subject(:operator) {
|
77
|
+
operation_range.operator
|
78
|
+
}
|
79
|
+
|
80
|
+
it 'is this MetasploitDataModels::Search::Operator::Port::List' do
|
81
|
+
expect(operator).to be(port_list_operator)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context '#value' do
|
86
|
+
subject(:value) {
|
87
|
+
operation_range.value
|
88
|
+
}
|
89
|
+
|
90
|
+
it { should be_a Range }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "without '-'" do
|
96
|
+
let(:formatted_value) {
|
97
|
+
'1'
|
98
|
+
}
|
99
|
+
|
100
|
+
it 'includes a MetasploitDataModels::Search::Operation::Port::Number' do
|
101
|
+
expect(children.map(&:class)).to include(MetasploitDataModels::Search::Operation::Port::Number)
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'MetasploitDataModels::Search::Operation::Port::Number' do
|
105
|
+
subject(:operation_range) {
|
106
|
+
children.first
|
107
|
+
}
|
108
|
+
|
109
|
+
context '#operator' do
|
110
|
+
subject(:operator) {
|
111
|
+
operation_range.operator
|
112
|
+
}
|
113
|
+
|
114
|
+
it 'is this MetasploitDataModels::Search::Operator::Port::List' do
|
115
|
+
expect(operator).to be(port_list_operator)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context '#value' do
|
120
|
+
subject(:value) {
|
121
|
+
operation_range.value
|
122
|
+
}
|
123
|
+
|
124
|
+
it { should be_an Integer }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context '#name' do
|
132
|
+
subject(:name) {
|
133
|
+
port_list_operator.name
|
134
|
+
}
|
135
|
+
|
136
|
+
#
|
137
|
+
# lets
|
138
|
+
#
|
139
|
+
|
140
|
+
let(:attribute) {
|
141
|
+
:alternate_port_list
|
142
|
+
}
|
143
|
+
|
144
|
+
#
|
145
|
+
# Callbacks
|
146
|
+
#
|
147
|
+
|
148
|
+
before(:each) do
|
149
|
+
port_list_operator.attribute = attribute
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'is #attribute' do
|
153
|
+
expect(name).to eq(attribute)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'operator_name' do
|
158
|
+
subject(:operator_name) {
|
159
|
+
described_class.operator_name
|
160
|
+
}
|
161
|
+
|
162
|
+
it { should == 'port_list' }
|
163
|
+
end
|
164
|
+
end
|