metasploit_data_models 0.17.3 → 0.18.0.pre.compatibility
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 +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
@@ -12,6 +12,40 @@ describe MetasploitDataModels::Search::Visitor::Attribute do
|
|
12
12
|
visitor.visit(node)
|
13
13
|
end
|
14
14
|
|
15
|
+
#
|
16
|
+
# Shared examples
|
17
|
+
#
|
18
|
+
|
19
|
+
shared_examples_for 'operator.klass.arel_table[operator.attribute]' do |options = {}|
|
20
|
+
options.assert_valid_keys(:node_class)
|
21
|
+
|
22
|
+
node_class = options.fetch(:node_class)
|
23
|
+
|
24
|
+
context "with #{node_class}" do
|
25
|
+
it { should be_a Arel::Attributes::Attribute }
|
26
|
+
|
27
|
+
context '#name' do
|
28
|
+
subject(:name) do
|
29
|
+
visit.name
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should be #{node_class}#attribute" do
|
33
|
+
name.should == node.attribute
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context '#relation' do
|
38
|
+
subject(:relation) do
|
39
|
+
visit.relation
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should be Class#arel_table for #{node_class}#klass" do
|
43
|
+
relation.should == node.klass.arel_table
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
15
49
|
context 'with Metasploit::Model::Search::Operator::Association' do
|
16
50
|
let(:attribute_operator) do
|
17
51
|
double('Attribute Operator')
|
@@ -40,37 +74,25 @@ describe MetasploitDataModels::Search::Visitor::Attribute do
|
|
40
74
|
end
|
41
75
|
end
|
42
76
|
|
43
|
-
|
44
|
-
|
77
|
+
it_should_behave_like 'operator.klass.arel_table[operator.attribute]',
|
78
|
+
node_class: Metasploit::Model::Search::Operator::Attribute do
|
79
|
+
let(:node) {
|
45
80
|
Metasploit::Model::Search::Operator::Attribute.new(
|
46
81
|
# needs to be a real column so look up on AREL table works
|
47
|
-
:
|
82
|
+
attribute: :name,
|
48
83
|
# needs to be a real class so Class#arel_table works
|
49
|
-
:
|
84
|
+
klass: Mdm::Host
|
50
85
|
)
|
51
|
-
|
52
|
-
|
53
|
-
it { should be_a Arel::Attributes::Attribute }
|
54
|
-
|
55
|
-
context 'name' do
|
56
|
-
subject(:name) do
|
57
|
-
visit.name
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'should be Metasploit::Model::Search::Operator::Attribute#attribute' do
|
61
|
-
name.should == node.attribute
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context 'relation' do
|
66
|
-
subject(:relation) do
|
67
|
-
visit.relation
|
68
|
-
end
|
86
|
+
}
|
87
|
+
end
|
69
88
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
89
|
+
it_should_behave_like 'operator.klass.arel_table[operator.attribute]',
|
90
|
+
node_class: MetasploitDataModels::Search::Operator::Port::List do
|
91
|
+
let(:node) {
|
92
|
+
Metasploit::Model::Search::Operator::Attribute.new(
|
93
|
+
klass: Mdm::Service
|
94
|
+
)
|
95
|
+
}
|
74
96
|
end
|
75
97
|
end
|
76
98
|
end
|
@@ -15,7 +15,8 @@ describe MetasploitDataModels::Search::Visitor::Includes do
|
|
15
15
|
children_classes = [
|
16
16
|
Metasploit::Model::Search::Group::Intersection,
|
17
17
|
Metasploit::Model::Search::Group::Union,
|
18
|
-
Metasploit::Model::Search::Operation::
|
18
|
+
Metasploit::Model::Search::Operation::Group::Intersection,
|
19
|
+
Metasploit::Model::Search::Operation::Group::Union
|
19
20
|
]
|
20
21
|
|
21
22
|
children_classes.each do |children_class|
|
@@ -48,12 +49,6 @@ describe MetasploitDataModels::Search::Visitor::Includes do
|
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
51
|
-
context 'with Metasploit::Model::Search::Operation::Union' do
|
52
|
-
let(:node) do
|
53
|
-
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
52
|
context 'with Metasploit::Model::Search::Operator::Association' do
|
58
53
|
let(:association) do
|
59
54
|
FactoryGirl.generate :metasploit_model_search_operator_association_association
|
@@ -78,6 +73,14 @@ describe MetasploitDataModels::Search::Visitor::Includes do
|
|
78
73
|
it { should == [] }
|
79
74
|
end
|
80
75
|
|
76
|
+
context 'with MetasploitDataModels::Search::Operator::Port::List' do
|
77
|
+
let(:node) do
|
78
|
+
MetasploitDataModels::Search::Operator::Port::List.new
|
79
|
+
end
|
80
|
+
|
81
|
+
it { should == [] }
|
82
|
+
end
|
83
|
+
|
81
84
|
context 'with Metasploit::Model::Search::Query#tree' do
|
82
85
|
let(:node) do
|
83
86
|
query.tree
|
@@ -12,48 +12,55 @@ describe MetasploitDataModels::Search::Visitor::Joins do
|
|
12
12
|
visitor.visit(node)
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
}
|
20
|
-
end
|
15
|
+
intersection_classes = [
|
16
|
+
Metasploit::Model::Search::Group::Intersection,
|
17
|
+
Metasploit::Model::Search::Operation::Group::Intersection
|
18
|
+
]
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
intersection_classes.each do |intersection_class|
|
21
|
+
context "with #{intersection_class}" do
|
22
|
+
let(:children) do
|
23
|
+
2.times.collect { |n|
|
24
|
+
double("Child #{n}")
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:node) do
|
29
|
+
intersection_class.new(
|
30
|
+
:children => children
|
31
|
+
)
|
32
|
+
end
|
27
33
|
|
28
|
-
|
29
|
-
|
30
|
-
|
34
|
+
it 'should visit each child' do
|
35
|
+
# needed for call to visit subject
|
36
|
+
visitor.should_receive(:visit).with(node).and_call_original
|
31
37
|
|
32
|
-
|
33
|
-
|
38
|
+
children.each do |child|
|
39
|
+
visitor.should_receive(:visit).with(child).and_return([])
|
40
|
+
end
|
41
|
+
|
42
|
+
visit
|
34
43
|
end
|
35
44
|
|
36
|
-
|
37
|
-
|
45
|
+
it 'should return Array of all child visits' do
|
46
|
+
child_visits = []
|
38
47
|
|
39
|
-
|
40
|
-
child_visits = []
|
48
|
+
visitor.should_receive(:visit).with(node).and_call_original
|
41
49
|
|
42
|
-
|
50
|
+
children.each_with_index do |child, i|
|
51
|
+
child_visit = ["Visited Child #{i}"]
|
52
|
+
visitor.stub(:visit).with(child).and_return(child_visit)
|
53
|
+
child_visits.concat(child_visit)
|
54
|
+
end
|
43
55
|
|
44
|
-
|
45
|
-
child_visit = ["Visited Child #{i}"]
|
46
|
-
visitor.stub(:visit).with(child).and_return(child_visit)
|
47
|
-
child_visits.concat(child_visit)
|
56
|
+
visit.should == child_visits
|
48
57
|
end
|
49
|
-
|
50
|
-
visit.should == child_visits
|
51
58
|
end
|
52
59
|
end
|
53
60
|
|
54
61
|
union_classes = [
|
55
62
|
Metasploit::Model::Search::Group::Union,
|
56
|
-
Metasploit::Model::Search::Operation::Union
|
63
|
+
Metasploit::Model::Search::Operation::Group::Union
|
57
64
|
]
|
58
65
|
|
59
66
|
union_classes.each do |union_class|
|
@@ -237,7 +244,7 @@ describe MetasploitDataModels::Search::Visitor::Joins do
|
|
237
244
|
end
|
238
245
|
end
|
239
246
|
|
240
|
-
context
|
247
|
+
context 'with Metasploit::Model::Search::Operator::Attribute' do
|
241
248
|
let(:node) do
|
242
249
|
Metasploit::Model::Search::Operator::Attribute.new
|
243
250
|
end
|
@@ -245,6 +252,14 @@ describe MetasploitDataModels::Search::Visitor::Joins do
|
|
245
252
|
it { should == [] }
|
246
253
|
end
|
247
254
|
|
255
|
+
context 'with MetasploitDataModels::Search::Operator::Port::List' do
|
256
|
+
let(:node) do
|
257
|
+
MetasploitDataModels::Search::Operator::Port::List.new
|
258
|
+
end
|
259
|
+
|
260
|
+
it { should == [] }
|
261
|
+
end
|
262
|
+
|
248
263
|
context 'with Metasploit::Model::Search::Query#tree' do
|
249
264
|
let(:node) do
|
250
265
|
query.tree
|
@@ -263,7 +278,6 @@ describe MetasploitDataModels::Search::Visitor::Joins do
|
|
263
278
|
Mdm::Host
|
264
279
|
}
|
265
280
|
|
266
|
-
|
267
281
|
context 'with name' do
|
268
282
|
let(:name) do
|
269
283
|
FactoryGirl.generate :mdm_host_name
|
@@ -24,6 +24,14 @@ describe MetasploitDataModels::Search::Visitor::Method do
|
|
24
24
|
it { should == :and }
|
25
25
|
end
|
26
26
|
|
27
|
+
context 'with Metasploit::Model::Search::Operation::Group::Intersection' do
|
28
|
+
let(:node_class) do
|
29
|
+
Metasploit::Model::Search::Operation::Group::Intersection
|
30
|
+
end
|
31
|
+
|
32
|
+
it { should == :and }
|
33
|
+
end
|
34
|
+
|
27
35
|
context 'with Metasploit::Model::Search::Group::Union' do
|
28
36
|
let(:node_class) do
|
29
37
|
Metasploit::Model::Search::Group::Union
|
@@ -31,5 +39,13 @@ describe MetasploitDataModels::Search::Visitor::Method do
|
|
31
39
|
|
32
40
|
it { should == :or }
|
33
41
|
end
|
42
|
+
|
43
|
+
context 'with Metasploit::Model::Search::Operation::Group::Union' do
|
44
|
+
let(:node_class) do
|
45
|
+
Metasploit::Model::Search::Operation::Group::Union
|
46
|
+
end
|
47
|
+
|
48
|
+
it { should == :or }
|
49
|
+
end
|
34
50
|
end
|
35
51
|
end
|
@@ -12,10 +12,14 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
12
12
|
"name:\"#{value}\""
|
13
13
|
end
|
14
14
|
|
15
|
+
let(:klass) {
|
16
|
+
Mdm::Host
|
17
|
+
}
|
18
|
+
|
15
19
|
let(:query) do
|
16
20
|
Metasploit::Model::Search::Query.new(
|
17
21
|
:formatted => formatted,
|
18
|
-
:klass =>
|
22
|
+
:klass => klass
|
19
23
|
)
|
20
24
|
end
|
21
25
|
|
@@ -152,81 +156,285 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
152
156
|
end
|
153
157
|
|
154
158
|
context 'matching record' do
|
155
|
-
context '
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
#
|
161
|
-
|
162
|
-
let(:matching_record_name) {
|
163
|
-
'mdm_host_name_a'
|
164
|
-
}
|
165
|
-
|
166
|
-
let(:matching_service_name) {
|
167
|
-
'mdm_service_name_a'
|
168
|
-
}
|
169
|
-
|
170
|
-
let(:non_matching_record_name) {
|
171
|
-
'mdm_host_name_b'
|
172
|
-
}
|
173
|
-
|
174
|
-
let(:non_matching_service_name) {
|
175
|
-
'mdm_service_name_b'
|
176
|
-
}
|
177
|
-
|
178
|
-
#
|
179
|
-
# let!s
|
180
|
-
#
|
181
|
-
|
182
|
-
let!(:matching_record) do
|
183
|
-
FactoryGirl.build(
|
184
|
-
:mdm_host,
|
185
|
-
name: matching_record_name
|
186
|
-
)
|
187
|
-
end
|
159
|
+
context 'Metasploit::Model::Search::Query#klass' do
|
160
|
+
context 'with Mdm::Service' do
|
161
|
+
let(:klass) {
|
162
|
+
Mdm::Service
|
163
|
+
}
|
188
164
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
end
|
165
|
+
let(:matching_ports) {
|
166
|
+
[
|
167
|
+
1,
|
168
|
+
2
|
169
|
+
]
|
170
|
+
}
|
196
171
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
)
|
202
|
-
|
172
|
+
let(:matching_records) {
|
173
|
+
matching_record_by_port.values
|
174
|
+
}
|
175
|
+
|
176
|
+
let(:non_matching_port) {
|
177
|
+
3
|
178
|
+
}
|
179
|
+
|
180
|
+
#
|
181
|
+
# let!s
|
182
|
+
#
|
183
|
+
|
184
|
+
let!(:matching_record_by_port) {
|
185
|
+
matching_ports.each_with_object({}) { |matching_port, matching_record_by_port|
|
186
|
+
matching_record_by_port[matching_port] = FactoryGirl.create(
|
187
|
+
:mdm_service,
|
188
|
+
port: matching_port
|
189
|
+
)
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
let!(:non_matching_record) {
|
194
|
+
FactoryGirl.create(
|
195
|
+
:mdm_service,
|
196
|
+
port: non_matching_port
|
197
|
+
)
|
198
|
+
}
|
199
|
+
|
200
|
+
context 'with port' do
|
201
|
+
context 'with single port number' do
|
202
|
+
let(:formatted) {
|
203
|
+
"port:#{matching_port}"
|
204
|
+
}
|
205
|
+
|
206
|
+
let(:matching_port) {
|
207
|
+
matching_ports.sample
|
208
|
+
}
|
209
|
+
|
210
|
+
let(:matching_record) {
|
211
|
+
matching_record_by_port[matching_port]
|
212
|
+
}
|
213
|
+
|
214
|
+
it 'should find only record with that port number' do
|
215
|
+
expect(visit).to match_array([matching_record])
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context 'with port range' do
|
220
|
+
let(:formatted) {
|
221
|
+
"port:#{matching_ports.min}-#{matching_ports.max}"
|
222
|
+
}
|
223
|
+
|
224
|
+
it 'should find all records with port numbers within the range' do
|
225
|
+
expect(visit).to match_array(matching_records)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context 'with comma separated port numbers' do
|
230
|
+
let(:formatted) {
|
231
|
+
"port:#{matching_ports.join(',')}"
|
232
|
+
}
|
233
|
+
|
234
|
+
it 'should find all records with the port numbers' do
|
235
|
+
expect(visit).to match_array(matching_records)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context 'with overlapping comma separated port number and range' do
|
240
|
+
let(:matching_port) {
|
241
|
+
matching_ports.sample
|
242
|
+
}
|
243
|
+
|
244
|
+
let(:formatted) {
|
245
|
+
%Q{port:#{matching_port},#{matching_ports.min}-#{matching_ports.max}}
|
246
|
+
}
|
203
247
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
248
|
+
it 'should find all records with the matching ports once' do
|
249
|
+
expect(visit).to match_array(matching_records)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context 'with all operators' do
|
255
|
+
let(:formatted) {
|
256
|
+
%Q{port:#{matching_port}}
|
257
|
+
}
|
258
|
+
end
|
210
259
|
end
|
211
260
|
|
212
|
-
|
213
|
-
|
261
|
+
context 'with Mdm::Host' do
|
262
|
+
#
|
263
|
+
# lets
|
264
|
+
#
|
214
265
|
|
215
|
-
|
216
|
-
|
217
|
-
|
266
|
+
let(:klass) {
|
267
|
+
Mdm::Host
|
268
|
+
}
|
218
269
|
|
219
|
-
|
220
|
-
|
221
|
-
|
270
|
+
#
|
271
|
+
# Don't use factories to prevent prefix aliasing when sequences go from 1 to 10 or 10 to 100
|
272
|
+
#
|
273
|
+
|
274
|
+
let(:matching_record_os_flavor) {
|
275
|
+
'mdm_host_os_flavor_a'
|
222
276
|
}
|
223
277
|
|
224
|
-
|
225
|
-
|
226
|
-
|
278
|
+
let(:matching_record_os_name) {
|
279
|
+
'mdm_host_os_name_a'
|
280
|
+
}
|
281
|
+
|
282
|
+
let(:matching_record_os_sp) {
|
283
|
+
'mdm_host_os_sp_a'
|
284
|
+
}
|
285
|
+
|
286
|
+
let(:matching_service_name) {
|
287
|
+
'mdm_service_name_a'
|
288
|
+
}
|
289
|
+
|
290
|
+
let(:matching_record_name) {
|
291
|
+
'mdm_host_name_a'
|
292
|
+
}
|
293
|
+
|
294
|
+
let(:matching_service_name) {
|
295
|
+
'mdm_service_name_a'
|
296
|
+
}
|
297
|
+
|
298
|
+
let(:non_matching_record_os_flavor) {
|
299
|
+
'mdm_host_os_flavor_b'
|
300
|
+
}
|
301
|
+
|
302
|
+
let(:non_matching_record_os_name) {
|
303
|
+
'mdm_host_os_name_b'
|
304
|
+
}
|
305
|
+
|
306
|
+
let(:non_matching_record_os_sp) {
|
307
|
+
'mdm_host_os_sp_b'
|
308
|
+
}
|
309
|
+
|
310
|
+
let(:non_matching_service_name) {
|
311
|
+
'mdm_service_name_b'
|
312
|
+
}
|
313
|
+
|
314
|
+
let(:non_matching_record_name) {
|
315
|
+
'mdm_host_name_b'
|
316
|
+
}
|
317
|
+
|
318
|
+
let(:non_matching_service_name) {
|
319
|
+
'mdm_service_name_b'
|
320
|
+
}
|
321
|
+
|
322
|
+
#
|
323
|
+
# let!s
|
324
|
+
#
|
325
|
+
|
326
|
+
let!(:matching_record) do
|
327
|
+
FactoryGirl.build(
|
328
|
+
:mdm_host,
|
329
|
+
name: matching_record_name,
|
330
|
+
os_flavor: matching_record_os_flavor,
|
331
|
+
os_name: matching_record_os_name,
|
332
|
+
os_sp: matching_record_os_sp
|
333
|
+
)
|
334
|
+
end
|
335
|
+
|
336
|
+
let!(:matching_service) do
|
337
|
+
FactoryGirl.create(
|
338
|
+
:mdm_service,
|
339
|
+
host: matching_record,
|
340
|
+
name: matching_service_name
|
341
|
+
)
|
342
|
+
end
|
343
|
+
|
344
|
+
let!(:non_matching_record) do
|
345
|
+
FactoryGirl.build(
|
346
|
+
:mdm_host,
|
347
|
+
name: non_matching_record_name,
|
348
|
+
os_flavor: non_matching_record_os_flavor,
|
349
|
+
os_name: non_matching_record_os_name,
|
350
|
+
os_sp: non_matching_record_os_sp
|
351
|
+
)
|
352
|
+
end
|
353
|
+
|
354
|
+
let!(:non_matching_service) do
|
355
|
+
FactoryGirl.create(
|
356
|
+
:mdm_service,
|
357
|
+
host: non_matching_record,
|
358
|
+
name: non_matching_service_name
|
359
|
+
)
|
360
|
+
end
|
361
|
+
|
362
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
363
|
+
:attribute => :name
|
364
|
+
|
365
|
+
context 'with os' do
|
366
|
+
let(:matching_record_os_flavor) {
|
367
|
+
'XP'
|
368
|
+
}
|
369
|
+
|
370
|
+
let(:matching_record_os_name) {
|
371
|
+
'Microsoft Windows'
|
372
|
+
}
|
373
|
+
|
374
|
+
let(:matching_record_os_sp) {
|
375
|
+
'SP1'
|
376
|
+
}
|
377
|
+
|
378
|
+
context 'with a combination of Mdm::Host#os_name and Mdm:Host#os_sp' do
|
379
|
+
let(:formatted) {
|
380
|
+
%Q{os:"win xp"}
|
381
|
+
}
|
382
|
+
|
383
|
+
it 'finds matching record' do
|
384
|
+
expect(visit).to match_array [matching_record]
|
385
|
+
end
|
227
386
|
end
|
228
387
|
|
229
|
-
|
388
|
+
context 'with a combination of Mdm::Host#os_flavor and Mdm::Host#os_sp' do
|
389
|
+
let(:formatted) {
|
390
|
+
%Q{os:"xp sp1"}
|
391
|
+
}
|
392
|
+
|
393
|
+
it 'finds matching record' do
|
394
|
+
expect(visit).to match_array [matching_record]
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
context 'with multiple records matching one word' do
|
399
|
+
let(:formatted) {
|
400
|
+
%Q{os:"win xp"}
|
401
|
+
}
|
402
|
+
|
403
|
+
let(:non_matching_record_os_name) {
|
404
|
+
'Microsoft Windows'
|
405
|
+
}
|
406
|
+
|
407
|
+
it 'finds only matching record by other words refining search' do
|
408
|
+
expect(visit).to match_array [matching_record]
|
409
|
+
end
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
414
|
+
:attribute => :os_flavor
|
415
|
+
|
416
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
417
|
+
:attribute => :os_name
|
418
|
+
|
419
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
420
|
+
:attribute => :os_sp
|
421
|
+
|
422
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
423
|
+
association: :services,
|
424
|
+
attribute: :name
|
425
|
+
|
426
|
+
context 'with all operators' do
|
427
|
+
let(:formatted) {
|
428
|
+
%Q{name:"#{matching_record_name}" os:"#{matching_record_os_name} #{matching_record_os_flavor} #{matching_record_os_sp}" os_flavor:"#{matching_record_os_flavor}" os_name:"#{matching_record_os_name}" os_sp:"#{matching_record_os_sp}" services.name:"#{matching_service_name}"}
|
429
|
+
}
|
430
|
+
|
431
|
+
it 'should find only matching record' do
|
432
|
+
if visit.to_a != [matching_record]
|
433
|
+
true
|
434
|
+
end
|
435
|
+
|
436
|
+
expect(visit).to match_array([matching_record])
|
437
|
+
end
|
230
438
|
end
|
231
439
|
end
|
232
440
|
end
|