metasploit_data_models 0.18.1 → 0.19.0
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/app/models/mdm/host.rb +7 -0
- data/app/models/mdm/service.rb +30 -1
- data/app/models/mdm/tag.rb +10 -0
- data/app/models/metasploit_data_models/ip_address/v4/cidr.rb +14 -0
- data/app/models/metasploit_data_models/ip_address/v4/nmap.rb +14 -0
- data/app/models/metasploit_data_models/ip_address/v4/range.rb +12 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list.rb +126 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range.rb +12 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/single.rb +123 -0
- data/app/models/metasploit_data_models/ip_address/v4/segmented.rb +200 -0
- data/app/models/metasploit_data_models/ip_address/v4/single.rb +53 -0
- data/app/models/metasploit_data_models/search/operation/ip_address.rb +60 -0
- data/app/models/metasploit_data_models/search/operator/ip_address.rb +33 -0
- data/app/models/metasploit_data_models/search/visitor/attribute.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/includes.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/joins.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/where.rb +51 -0
- data/config/locales/en.yml +35 -4
- data/lib/metasploit_data_models/ip_address.rb +5 -0
- data/lib/metasploit_data_models/ip_address/cidr.rb +174 -0
- data/lib/metasploit_data_models/ip_address/range.rb +181 -0
- data/lib/metasploit_data_models/match/child.rb +48 -0
- data/lib/metasploit_data_models/match/parent.rb +103 -0
- data/lib/metasploit_data_models/version.rb +4 -4
- data/metasploit_data_models.gemspec +2 -1
- data/spec/app/models/mdm/cred_spec.rb +164 -31
- data/spec/app/models/mdm/service_spec.rb +33 -44
- data/spec/app/models/metasploit_data_models/ip_address/v4/cidr_spec.rb +121 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/nmap_spec.rb +151 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/range_spec.rb +300 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list_spec.rb +278 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range_spec.rb +304 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/segmented_spec.rb +29 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/single_spec.rb +315 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/single_spec.rb +183 -0
- data/spec/app/models/metasploit_data_models/search/operation/ip_address_spec.rb +182 -0
- data/spec/app/models/metasploit_data_models/search/operator/ip_address_spec.rb +19 -0
- data/spec/app/models/metasploit_data_models/search/visitor/relation_spec.rb +229 -36
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/db/structure.sql +3011 -0
- data/spec/factories/mdm/services.rb +3 -1
- data/spec/lib/metasploit_data_models/ip_address/cidr_spec.rb +350 -0
- data/spec/lib/metasploit_data_models/ip_address/range_spec.rb +77 -0
- data/spec/lib/metasploit_data_models/match/child_spec.rb +61 -0
- data/spec/lib/metasploit_data_models/match/parent_spec.rb +155 -0
- data/spec/support/matchers/match_regex_exactly.rb +28 -0
- data/spec/support/shared/contexts/rex/text.rb +15 -0
- data/spec/support/shared/examples/metasploit_data_models/search/operation/ipaddress/match.rb +109 -0
- metadata +58 -9
- data/spec/dummy/db/schema.rb +0 -609
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::Search::Operation::IPAddress do
|
4
|
+
subject(:operation) {
|
5
|
+
described_class.new(
|
6
|
+
operator: operator,
|
7
|
+
value: formatted_value
|
8
|
+
)
|
9
|
+
}
|
10
|
+
|
11
|
+
let(:operator) {
|
12
|
+
MetasploitDataModels::Search::Operator::IPAddress.new
|
13
|
+
}
|
14
|
+
|
15
|
+
context 'validation' do
|
16
|
+
#
|
17
|
+
# lets
|
18
|
+
#
|
19
|
+
|
20
|
+
let(:blank_error) {
|
21
|
+
I18n.translate!('errors.messages.blank')
|
22
|
+
}
|
23
|
+
|
24
|
+
let(:invalid_error) {
|
25
|
+
I18n.translate!('errors.messages.invalid')
|
26
|
+
}
|
27
|
+
|
28
|
+
#
|
29
|
+
# Callbacks
|
30
|
+
#
|
31
|
+
|
32
|
+
before(:each) do
|
33
|
+
operation.valid?
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'errors on #value' do
|
37
|
+
subject(:value_error) do
|
38
|
+
operation.errors[:value]
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with IPv4' do
|
42
|
+
context 'with CIDR' do
|
43
|
+
context 'with valid prefix_length' do
|
44
|
+
let(:formatted_value) {
|
45
|
+
'1.2.3.4/8'
|
46
|
+
}
|
47
|
+
|
48
|
+
it { should be_empty }
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'without valid prefix_length' do
|
52
|
+
let(:formatted_value) {
|
53
|
+
'1.2.3.4/36'
|
54
|
+
}
|
55
|
+
|
56
|
+
it { should include invalid_error }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'with Nmap', pending: 'MSP-10712' do
|
61
|
+
context 'with valid segment range' do
|
62
|
+
let(:formatted_value) {
|
63
|
+
'1-2.3.4.5'
|
64
|
+
}
|
65
|
+
|
66
|
+
it { should be_empty }
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'without valid segment range' do
|
70
|
+
let(:formatted_value) {
|
71
|
+
'2-1.3.4.5'
|
72
|
+
}
|
73
|
+
|
74
|
+
it { should include invalid_error }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'with Range' do
|
79
|
+
context 'with ordered range' do
|
80
|
+
let(:formatted_value) {
|
81
|
+
'2.2.2.2-1.1.1.1'
|
82
|
+
}
|
83
|
+
|
84
|
+
it { should include invalid_error }
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'without ordered range' do
|
88
|
+
let(:formatted_value) {
|
89
|
+
'1.1.1.1-2.2.2.2'
|
90
|
+
}
|
91
|
+
|
92
|
+
it { should be_empty }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'with address' do
|
97
|
+
let(:formatted_value) {
|
98
|
+
'1.2.3.4'
|
99
|
+
}
|
100
|
+
|
101
|
+
it { be_empty }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'with nil' do
|
106
|
+
let(:formatted_value) {
|
107
|
+
nil
|
108
|
+
}
|
109
|
+
|
110
|
+
it { should include blank_error }
|
111
|
+
it { should_not include invalid_error }
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'with empty string' do
|
115
|
+
let(:formatted_value) {
|
116
|
+
''
|
117
|
+
}
|
118
|
+
|
119
|
+
it { should include blank_error }
|
120
|
+
it { should_not include invalid_error }
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'without matching formatted value' do
|
124
|
+
let(:formatted_value) {
|
125
|
+
'non_matching_value'
|
126
|
+
}
|
127
|
+
|
128
|
+
it { should include invalid_error }
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context '#value' do
|
134
|
+
subject(:value) {
|
135
|
+
operation.value
|
136
|
+
}
|
137
|
+
|
138
|
+
context 'with IPv4' do
|
139
|
+
context 'with CIDR' do
|
140
|
+
let(:formatted_value) {
|
141
|
+
'1.2.3.4/8'
|
142
|
+
}
|
143
|
+
|
144
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::CIDR }
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'with Nmap', pending: 'MSP-10712' do
|
148
|
+
let(:formatted_value) {
|
149
|
+
'1.2.3.4-5'
|
150
|
+
}
|
151
|
+
|
152
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Nmap }
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'with Range' do
|
156
|
+
let(:formatted_value) {
|
157
|
+
'1.1.1.1-2.2.2.2'
|
158
|
+
}
|
159
|
+
|
160
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Range }
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'with address' do
|
164
|
+
let(:formatted_value) {
|
165
|
+
'1.2.3.4'
|
166
|
+
}
|
167
|
+
|
168
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Single }
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'without support format' do
|
173
|
+
let(:formatted_value) {
|
174
|
+
'unsupported_formated'
|
175
|
+
}
|
176
|
+
|
177
|
+
it 'is the passed formatted value' do
|
178
|
+
expect(value).to eq(formatted_value)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::Search::Operator::IPAddress do
|
4
|
+
subject(:operator) {
|
5
|
+
described_class.new
|
6
|
+
}
|
7
|
+
|
8
|
+
context '#operate_on' do
|
9
|
+
subject(:operate_on) {
|
10
|
+
operator.operate_on(formatted_value)
|
11
|
+
}
|
12
|
+
|
13
|
+
let(:formatted_value) {
|
14
|
+
nil
|
15
|
+
}
|
16
|
+
|
17
|
+
it { should be_a MetasploitDataModels::Search::Operation::IPAddress }
|
18
|
+
end
|
19
|
+
end
|
@@ -158,46 +158,80 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
158
158
|
context 'matching record' do
|
159
159
|
context 'Metasploit::Model::Search::Query#klass' do
|
160
160
|
context 'with Mdm::Service' do
|
161
|
+
include_context 'Rex::Text'
|
162
|
+
|
163
|
+
#
|
164
|
+
# lets
|
165
|
+
#
|
166
|
+
|
161
167
|
let(:klass) {
|
162
168
|
Mdm::Service
|
163
169
|
}
|
164
170
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
171
|
+
#
|
172
|
+
# Don't use factories to prevent prefix aliasing when sequences go from 1 to 10 or 10 to 100
|
173
|
+
#
|
174
|
+
|
175
|
+
let(:non_matching_info) {
|
176
|
+
'mdm_service_info_c'
|
170
177
|
}
|
171
178
|
|
172
|
-
let(:
|
173
|
-
|
179
|
+
let(:non_matching_name) {
|
180
|
+
'mdm_service_name_c'
|
174
181
|
}
|
175
182
|
|
176
183
|
let(:non_matching_port) {
|
177
184
|
3
|
178
185
|
}
|
179
186
|
|
187
|
+
let(:non_matching_proto) {
|
188
|
+
'udp'
|
189
|
+
}
|
190
|
+
|
180
191
|
#
|
181
192
|
# let!s
|
182
193
|
#
|
183
194
|
|
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
195
|
let!(:non_matching_record) {
|
194
196
|
FactoryGirl.create(
|
195
197
|
:mdm_service,
|
196
|
-
|
198
|
+
info: non_matching_info,
|
199
|
+
name: non_matching_name,
|
200
|
+
port: non_matching_port,
|
201
|
+
proto: non_matching_proto
|
197
202
|
)
|
198
203
|
}
|
204
|
+
p
|
199
205
|
|
200
206
|
context 'with port' do
|
207
|
+
#
|
208
|
+
# lets
|
209
|
+
#
|
210
|
+
|
211
|
+
let(:matching_ports) {
|
212
|
+
[
|
213
|
+
1,
|
214
|
+
2
|
215
|
+
]
|
216
|
+
}
|
217
|
+
|
218
|
+
let(:matching_records) {
|
219
|
+
matching_record_by_port.values
|
220
|
+
}
|
221
|
+
|
222
|
+
#
|
223
|
+
# let!s
|
224
|
+
#
|
225
|
+
|
226
|
+
let!(:matching_record_by_port) {
|
227
|
+
matching_ports.each_with_object({}) { |matching_port, matching_record_by_port|
|
228
|
+
matching_record_by_port[matching_port] = FactoryGirl.create(
|
229
|
+
:mdm_service,
|
230
|
+
port: matching_port
|
231
|
+
)
|
232
|
+
}
|
233
|
+
}
|
234
|
+
|
201
235
|
context 'with single port number' do
|
202
236
|
let(:formatted) {
|
203
237
|
"port:#{matching_port}"
|
@@ -251,26 +285,77 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
251
285
|
end
|
252
286
|
end
|
253
287
|
|
254
|
-
context 'with
|
255
|
-
|
256
|
-
|
288
|
+
context 'with single matching record' do
|
289
|
+
#
|
290
|
+
# lets
|
291
|
+
#
|
292
|
+
|
293
|
+
#
|
294
|
+
# Don't use factories to prevent prefix aliasing when sequences go from 1 to 10 or 10 to 100
|
295
|
+
#
|
296
|
+
|
297
|
+
let(:matching_info) {
|
298
|
+
'mdm_service_info_a'
|
299
|
+
}
|
300
|
+
|
301
|
+
let(:matching_name) {
|
302
|
+
'mdm_service_name_a'
|
303
|
+
}
|
304
|
+
|
305
|
+
let(:matching_port) {
|
306
|
+
1
|
307
|
+
}
|
308
|
+
|
309
|
+
let(:matching_proto) {
|
310
|
+
'tcp'
|
311
|
+
}
|
312
|
+
|
313
|
+
#
|
314
|
+
# let!s
|
315
|
+
#
|
316
|
+
|
317
|
+
let!(:matching_record) {
|
318
|
+
FactoryGirl.create(
|
319
|
+
:mdm_service,
|
320
|
+
info: matching_info,
|
321
|
+
name: matching_name,
|
322
|
+
port: matching_port,
|
323
|
+
proto: matching_proto
|
324
|
+
)
|
257
325
|
}
|
326
|
+
|
327
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
328
|
+
attribute: :info
|
329
|
+
|
330
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
331
|
+
attribute: :name
|
332
|
+
|
333
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
334
|
+
attribute: :proto
|
335
|
+
|
336
|
+
context 'with all operators' do
|
337
|
+
let(:formatted) {
|
338
|
+
%Q{name:#{matching_name} port:#{matching_port} proto:#{matching_proto}}
|
339
|
+
}
|
340
|
+
|
341
|
+
it 'finds only matching record' do
|
342
|
+
expect(visit).to match_array([matching_record])
|
343
|
+
end
|
344
|
+
end
|
258
345
|
end
|
259
346
|
end
|
260
347
|
|
261
348
|
context 'with Mdm::Host' do
|
262
349
|
#
|
263
350
|
# lets
|
264
|
-
#
|
265
|
-
|
266
|
-
let(:klass) {
|
267
|
-
Mdm::Host
|
268
|
-
}
|
269
|
-
|
270
351
|
#
|
271
352
|
# Don't use factories to prevent prefix aliasing when sequences go from 1 to 10 or 10 to 100
|
272
353
|
#
|
273
354
|
|
355
|
+
let(:matching_record_address) {
|
356
|
+
'1.2.3.4'
|
357
|
+
}
|
358
|
+
|
274
359
|
let(:matching_record_os_flavor) {
|
275
360
|
'mdm_host_os_flavor_a'
|
276
361
|
}
|
@@ -283,10 +368,6 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
283
368
|
'mdm_host_os_sp_a'
|
284
369
|
}
|
285
370
|
|
286
|
-
let(:matching_service_name) {
|
287
|
-
'mdm_service_name_a'
|
288
|
-
}
|
289
|
-
|
290
371
|
let(:matching_record_name) {
|
291
372
|
'mdm_host_name_a'
|
292
373
|
}
|
@@ -295,6 +376,10 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
295
376
|
'mdm_service_name_a'
|
296
377
|
}
|
297
378
|
|
379
|
+
let(:non_matching_record_address) {
|
380
|
+
'5.6.7.8'
|
381
|
+
}
|
382
|
+
|
298
383
|
let(:non_matching_record_os_flavor) {
|
299
384
|
'mdm_host_os_flavor_b'
|
300
385
|
}
|
@@ -307,10 +392,6 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
307
392
|
'mdm_host_os_sp_b'
|
308
393
|
}
|
309
394
|
|
310
|
-
let(:non_matching_service_name) {
|
311
|
-
'mdm_service_name_b'
|
312
|
-
}
|
313
|
-
|
314
395
|
let(:non_matching_record_name) {
|
315
396
|
'mdm_host_name_b'
|
316
397
|
}
|
@@ -326,6 +407,7 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
326
407
|
let!(:matching_record) do
|
327
408
|
FactoryGirl.build(
|
328
409
|
:mdm_host,
|
410
|
+
address: matching_record_address,
|
329
411
|
name: matching_record_name,
|
330
412
|
os_flavor: matching_record_os_flavor,
|
331
413
|
os_name: matching_record_os_name,
|
@@ -344,6 +426,7 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
344
426
|
let!(:non_matching_record) do
|
345
427
|
FactoryGirl.build(
|
346
428
|
:mdm_host,
|
429
|
+
address: non_matching_record_address,
|
347
430
|
name: non_matching_record_name,
|
348
431
|
os_flavor: non_matching_record_os_flavor,
|
349
432
|
os_name: non_matching_record_os_name,
|
@@ -359,6 +442,42 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
359
442
|
)
|
360
443
|
end
|
361
444
|
|
445
|
+
context 'with address operator' do
|
446
|
+
let(:formatted) do
|
447
|
+
"address:#{formatted_address}"
|
448
|
+
end
|
449
|
+
|
450
|
+
context 'with CIDR' do
|
451
|
+
let(:formatted_address) {
|
452
|
+
'1.3.4.5/8'
|
453
|
+
}
|
454
|
+
|
455
|
+
it 'should find only matching record' do
|
456
|
+
expect(visit).to match_array([matching_record])
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
context 'with Range' do
|
461
|
+
let(:formatted_address) {
|
462
|
+
'1.1.1.1-5.6.7.7'
|
463
|
+
}
|
464
|
+
|
465
|
+
it 'should find only matching record' do
|
466
|
+
expect(visit).to match_array([matching_record])
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
context 'with single' do
|
471
|
+
let(:formatted_address) {
|
472
|
+
'1.2.3.4'
|
473
|
+
}
|
474
|
+
|
475
|
+
it 'should find only matching record' do
|
476
|
+
expect(visit).to match_array([matching_record])
|
477
|
+
end
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
362
481
|
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
363
482
|
:attribute => :name
|
364
483
|
|
@@ -425,7 +544,17 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
425
544
|
|
426
545
|
context 'with all operators' do
|
427
546
|
let(:formatted) {
|
428
|
-
%Q{
|
547
|
+
%Q{
|
548
|
+
address:1.3.4.5/8
|
549
|
+
address:1.1.1.1-5.6.7.7
|
550
|
+
address:1.2.3.4
|
551
|
+
name:"#{matching_record_name}"
|
552
|
+
os:"#{matching_record_os_name} #{matching_record_os_flavor} #{matching_record_os_sp}"
|
553
|
+
os_flavor:"#{matching_record_os_flavor}"
|
554
|
+
os_name:"#{matching_record_os_name}"
|
555
|
+
os_sp:"#{matching_record_os_sp}"
|
556
|
+
services.name:"#{matching_service_name}"
|
557
|
+
}
|
429
558
|
}
|
430
559
|
|
431
560
|
it 'should find only matching record' do
|
@@ -437,6 +566,70 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
437
566
|
end
|
438
567
|
end
|
439
568
|
end
|
569
|
+
|
570
|
+
|
571
|
+
end
|
572
|
+
|
573
|
+
context 'with Mdm::Tag' do
|
574
|
+
#
|
575
|
+
# lets
|
576
|
+
#
|
577
|
+
|
578
|
+
let(:klass) {
|
579
|
+
Mdm::Tag
|
580
|
+
}
|
581
|
+
|
582
|
+
let(:matching_desc) {
|
583
|
+
'This is a description'
|
584
|
+
}
|
585
|
+
|
586
|
+
let(:matching_name) {
|
587
|
+
'matching.tag'
|
588
|
+
}
|
589
|
+
|
590
|
+
let(:non_matching_desc) {
|
591
|
+
'This could be a description'
|
592
|
+
}
|
593
|
+
|
594
|
+
let(:non_matching_name) {
|
595
|
+
'tag.does.not.match'
|
596
|
+
}
|
597
|
+
|
598
|
+
#
|
599
|
+
# let!s
|
600
|
+
#
|
601
|
+
|
602
|
+
let!(:matching_record) {
|
603
|
+
FactoryGirl.create(
|
604
|
+
:mdm_tag,
|
605
|
+
desc: matching_desc,
|
606
|
+
name: matching_name
|
607
|
+
)
|
608
|
+
}
|
609
|
+
|
610
|
+
let!(:non_matching_record) {
|
611
|
+
FactoryGirl.create(
|
612
|
+
:mdm_tag,
|
613
|
+
desc: non_matching_desc,
|
614
|
+
name: non_matching_name
|
615
|
+
)
|
616
|
+
}
|
617
|
+
|
618
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
619
|
+
attribute: :desc
|
620
|
+
|
621
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
622
|
+
attribute: :name
|
623
|
+
|
624
|
+
context 'with all operators' do
|
625
|
+
let(:formatted) {
|
626
|
+
%Q{desc:"#{matching_desc}" name:"#{matching_name}"}
|
627
|
+
}
|
628
|
+
|
629
|
+
it 'should find only matching record' do
|
630
|
+
expect(visit).to match_array([matching_record])
|
631
|
+
end
|
632
|
+
end
|
440
633
|
end
|
441
634
|
end
|
442
635
|
end
|
@@ -460,4 +653,4 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
460
653
|
its([:includes]) { should == MetasploitDataModels::Search::Visitor::Includes }
|
461
654
|
its([:where]) { should == MetasploitDataModels::Search::Visitor::Where }
|
462
655
|
end
|
463
|
-
end
|
656
|
+
end
|