metasploit_data_models 0.19.3-java → 0.19.4-java
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 +4 -4
- data/app/models/mdm/service.rb +1 -9
- data/app/models/metasploit_data_models/search/visitor/attribute.rb +1 -1
- data/app/models/metasploit_data_models/search/visitor/includes.rb +17 -2
- data/app/models/metasploit_data_models/search/visitor/joins.rb +16 -1
- data/app/models/metasploit_data_models/search/visitor/where.rb +4 -0
- data/lib/metasploit_data_models/version.rb +1 -1
- data/metasploit_data_models.gemspec +1 -1
- data/spec/app/models/metasploit_data_models/search/visitor/attribute_spec.rb +8 -8
- data/spec/app/models/metasploit_data_models/search/visitor/includes_spec.rb +54 -2
- data/spec/app/models/metasploit_data_models/search/visitor/joins_spec.rb +102 -12
- data/spec/app/models/metasploit_data_models/search/visitor/relation_spec.rb +109 -2
- data/spec/support/shared/examples/metasploit_data_models/search/visitor/relation/visit/matching_record.rb +30 -17
- metadata +6 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d6d17408ff12f5c425ec48ec37f3aa032c60e92
|
4
|
+
data.tar.gz: 8a444cb3f6618b2783a7ded1d69d52cb47a74588
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2182b0b0fa86f7c2f2bc5e5055b2da9cf6954799762e6e187daee9982d9657863b5286c3c3830d2a745876da22d605bdd6422485f4f9c1c7113d8ce702bf649f
|
7
|
+
data.tar.gz: d6fc50178926110ad3fd954c6871e691248ec63798f4205c7bcd14e3f00bfa14157f1d0a8fb235740285f54c4df9d295e24263e779c2db56d5f0671651de3c5e
|
data/app/models/mdm/service.rb
CHANGED
@@ -189,7 +189,7 @@ class Mdm::Service < ActiveRecord::Base
|
|
189
189
|
# Search Associations
|
190
190
|
#
|
191
191
|
|
192
|
-
|
192
|
+
search_associations host: :tags
|
193
193
|
|
194
194
|
#
|
195
195
|
# Search Attributes
|
@@ -208,14 +208,6 @@ class Mdm::Service < ActiveRecord::Base
|
|
208
208
|
# Search Withs
|
209
209
|
#
|
210
210
|
|
211
|
-
# Have to declare on Mdm::Service because non-attribute operators cannot function as association operators
|
212
|
-
search_with MetasploitDataModels::Search::Operator::Multitext,
|
213
|
-
name: :'host.os',
|
214
|
-
operator_names: [
|
215
|
-
:'host.os_name',
|
216
|
-
:'host.os_flavor',
|
217
|
-
:'host.os_sp'
|
218
|
-
]
|
219
211
|
search_with MetasploitDataModels::Search::Operator::Port::List
|
220
212
|
|
221
213
|
#
|
@@ -3,7 +3,7 @@ class MetasploitDataModels::Search::Visitor::Attribute
|
|
3
3
|
include Metasploit::Model::Visitation::Visit
|
4
4
|
|
5
5
|
visit 'Metasploit::Model::Search::Operator::Association' do |operator|
|
6
|
-
visit operator.
|
6
|
+
visit operator.source_operator
|
7
7
|
end
|
8
8
|
|
9
9
|
visit 'Metasploit::Model::Search::Operator::Attribute',
|
@@ -12,14 +12,29 @@ class MetasploitDataModels::Search::Visitor::Includes
|
|
12
12
|
parent.children.flat_map { |child|
|
13
13
|
visit child
|
14
14
|
}
|
15
|
-
|
15
|
+
end
|
16
|
+
|
17
|
+
visit 'Metasploit::Model::Search::Operation::Association' do |operation|
|
18
|
+
association = visit operation.operator
|
19
|
+
nested_associations = visit operation.source_operation
|
20
|
+
|
21
|
+
if nested_associations.empty?
|
22
|
+
[association]
|
23
|
+
else
|
24
|
+
[
|
25
|
+
{
|
26
|
+
association => nested_associations
|
27
|
+
}
|
28
|
+
]
|
29
|
+
end
|
30
|
+
end
|
16
31
|
|
17
32
|
visit 'Metasploit::Model::Search::Operation::Base' do |operation|
|
18
33
|
visit operation.operator
|
19
34
|
end
|
20
35
|
|
21
36
|
visit 'Metasploit::Model::Search::Operator::Association' do |operator|
|
22
|
-
|
37
|
+
operator.association
|
23
38
|
end
|
24
39
|
|
25
40
|
visit 'Metasploit::Model::Search::Operator::Attribute',
|
@@ -34,12 +34,27 @@ class MetasploitDataModels::Search::Visitor::Joins
|
|
34
34
|
common_join_set.to_a
|
35
35
|
end
|
36
36
|
|
37
|
+
visit 'Metasploit::Model::Search::Operation::Association' do |operation|
|
38
|
+
association = visit operation.operator
|
39
|
+
nested_associations = visit operation.source_operation
|
40
|
+
|
41
|
+
if nested_associations.empty?
|
42
|
+
[association]
|
43
|
+
else
|
44
|
+
[
|
45
|
+
{
|
46
|
+
association => nested_associations
|
47
|
+
}
|
48
|
+
]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
37
52
|
visit 'Metasploit::Model::Search::Operation::Base' do |operation|
|
38
53
|
visit operation.operator
|
39
54
|
end
|
40
55
|
|
41
56
|
visit 'Metasploit::Model::Search::Operator::Association' do |operator|
|
42
|
-
|
57
|
+
operator.association
|
43
58
|
end
|
44
59
|
|
45
60
|
visit 'Metasploit::Model::Search::Operator::Attribute',
|
@@ -38,6 +38,10 @@ class MetasploitDataModels::Search::Visitor::Where
|
|
38
38
|
attribute.eq(operation.value)
|
39
39
|
end
|
40
40
|
|
41
|
+
visit 'Metasploit::Model::Search::Operation::Association' do |operation|
|
42
|
+
visit operation.source_operation
|
43
|
+
end
|
44
|
+
|
41
45
|
visit 'Metasploit::Model::Search::Operation::String' do |operation|
|
42
46
|
attribute = attribute_visitor.visit operation.operator
|
43
47
|
match_value = "%#{operation.value}%"
|
@@ -6,7 +6,7 @@ module MetasploitDataModels
|
|
6
6
|
# The minor version number, scoped to the {MAJOR} version number.
|
7
7
|
MINOR = 19
|
8
8
|
# The patch number, scoped to the {MINOR} version number.
|
9
|
-
PATCH =
|
9
|
+
PATCH = 4
|
10
10
|
|
11
11
|
# The full version string, including the {MAJOR}, {MINOR}, {PATCH}, and optionally, the `PRERELEASE` in the
|
12
12
|
# {http://semver.org/spec/v2.0.0.html semantic versioning v2.0.0} format.
|
@@ -40,7 +40,7 @@ Gem::Specification.new do |s|
|
|
40
40
|
s.add_runtime_dependency 'activerecord', '>= 3.2.13', '< 4.0.0'
|
41
41
|
s.add_runtime_dependency 'activesupport'
|
42
42
|
s.add_runtime_dependency 'metasploit-concern', '~> 0.1.0'
|
43
|
-
s.add_runtime_dependency 'metasploit-model', '
|
43
|
+
s.add_runtime_dependency 'metasploit-model', '~> 0.26.1'
|
44
44
|
|
45
45
|
# arel-helpers: Useful tools to help construct database queries with ActiveRecord and Arel.
|
46
46
|
s.add_runtime_dependency 'arel-helpers'
|
@@ -47,28 +47,28 @@ describe MetasploitDataModels::Search::Visitor::Attribute do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
context 'with Metasploit::Model::Search::Operator::Association' do
|
50
|
-
let(:
|
51
|
-
double('
|
50
|
+
let(:source_operator) do
|
51
|
+
double('source operator')
|
52
52
|
end
|
53
53
|
|
54
54
|
let(:node) do
|
55
55
|
Metasploit::Model::Search::Operator::Association.new(
|
56
|
-
:
|
56
|
+
:source_operator => source_operator
|
57
57
|
)
|
58
58
|
end
|
59
59
|
|
60
|
-
it 'should visit Metasploit::Model::Search::Operator::Association#
|
60
|
+
it 'should visit Metasploit::Model::Search::Operator::Association#source_operator' do
|
61
61
|
visitor.should_receive(:visit).with(node).and_call_original
|
62
|
-
visitor.should_receive(:visit).with(
|
62
|
+
visitor.should_receive(:visit).with(source_operator)
|
63
63
|
|
64
64
|
visit
|
65
65
|
end
|
66
66
|
|
67
|
-
it 'should return visit of Metasploit::Model::Search::Operator::Association#
|
67
|
+
it 'should return visit of Metasploit::Model::Search::Operator::Association#source_operator' do
|
68
68
|
visitor.should_receive(:visit).with(node).and_call_original
|
69
69
|
|
70
|
-
visited = double('
|
71
|
-
visitor.stub(:visit).with(
|
70
|
+
visited = double('Source Operator Visited')
|
71
|
+
visitor.stub(:visit).with(source_operator).and_return(visited)
|
72
72
|
|
73
73
|
visit.should == visited
|
74
74
|
end
|
@@ -29,6 +29,58 @@ describe MetasploitDataModels::Search::Visitor::Includes do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
context 'with Metasploit::Model::Search::Operation::Association' do
|
33
|
+
let(:association) {
|
34
|
+
:parent_association
|
35
|
+
}
|
36
|
+
|
37
|
+
let(:node) {
|
38
|
+
operator.operate_on('formatted_value')
|
39
|
+
}
|
40
|
+
|
41
|
+
let(:operator) {
|
42
|
+
Metasploit::Model::Search::Operator::Association.new(
|
43
|
+
association: association,
|
44
|
+
source_operator: source_operator
|
45
|
+
)
|
46
|
+
}
|
47
|
+
|
48
|
+
context '#source_operation' do
|
49
|
+
let(:attribute_operator) {
|
50
|
+
Metasploit::Model::Search::Operator::Attribute.new(
|
51
|
+
type: :string
|
52
|
+
)
|
53
|
+
}
|
54
|
+
|
55
|
+
context 'with Metasploit::Model::Search::Operation::Association' do
|
56
|
+
let(:source_operator) {
|
57
|
+
Metasploit::Model::Search::Operator::Association.new(
|
58
|
+
association: source_operator_association,
|
59
|
+
source_operator: attribute_operator
|
60
|
+
)
|
61
|
+
}
|
62
|
+
|
63
|
+
let(:source_operator_association) {
|
64
|
+
:child_association
|
65
|
+
}
|
66
|
+
|
67
|
+
it 'is [{ association => nested associations }]' do
|
68
|
+
expect(visit).to eq([{association => [source_operator_association]}])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'without Metasploit::Model::Search::Operation::Association' do
|
73
|
+
let(:source_operator) {
|
74
|
+
attribute_operator
|
75
|
+
}
|
76
|
+
|
77
|
+
it 'is [association]' do
|
78
|
+
expect(visit).to eq([association])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
32
84
|
operation_classes = [
|
33
85
|
Metasploit::Model::Search::Operation::Boolean,
|
34
86
|
Metasploit::Model::Search::Operation::Date,
|
@@ -60,8 +112,8 @@ describe MetasploitDataModels::Search::Visitor::Includes do
|
|
60
112
|
)
|
61
113
|
end
|
62
114
|
|
63
|
-
it '
|
64
|
-
visit.
|
115
|
+
it 'is #association' do
|
116
|
+
expect(visit).to eq(association)
|
65
117
|
end
|
66
118
|
end
|
67
119
|
|
@@ -75,7 +75,9 @@ describe MetasploitDataModels::Search::Visitor::Joins do
|
|
75
75
|
context 'without child joins' do
|
76
76
|
let(:children) do
|
77
77
|
Array.new(2) {
|
78
|
-
Metasploit::Model::Search::Operator::Attribute.new
|
78
|
+
operator = Metasploit::Model::Search::Operator::Attribute.new(type: :string)
|
79
|
+
|
80
|
+
operator.operate_on('formatted_value')
|
79
81
|
}
|
80
82
|
end
|
81
83
|
|
@@ -87,20 +89,31 @@ describe MetasploitDataModels::Search::Visitor::Joins do
|
|
87
89
|
FactoryGirl.generate :metasploit_model_search_operator_association_association
|
88
90
|
end
|
89
91
|
|
92
|
+
let(:association_operation) {
|
93
|
+
association_operator.operate_on('formatted_value')
|
94
|
+
}
|
95
|
+
|
90
96
|
let(:association_operator) do
|
97
|
+
source_operator = Metasploit::Model::Search::Operator::Attribute.new(type: :string)
|
98
|
+
|
91
99
|
Metasploit::Model::Search::Operator::Association.new(
|
92
|
-
association: association
|
100
|
+
association: association,
|
101
|
+
source_operator: source_operator
|
93
102
|
)
|
94
103
|
end
|
95
104
|
|
105
|
+
let(:attribute_operation) {
|
106
|
+
attribute_operator.operate_on('formatted_value')
|
107
|
+
}
|
108
|
+
|
96
109
|
let(:attribute_operator) do
|
97
|
-
Metasploit::Model::Search::Operator::Attribute.new
|
110
|
+
Metasploit::Model::Search::Operator::Attribute.new(type: :string)
|
98
111
|
end
|
99
112
|
|
100
113
|
let(:children) do
|
101
114
|
[
|
102
|
-
|
103
|
-
|
115
|
+
association_operation,
|
116
|
+
attribute_operation
|
104
117
|
]
|
105
118
|
end
|
106
119
|
|
@@ -112,15 +125,22 @@ describe MetasploitDataModels::Search::Visitor::Joins do
|
|
112
125
|
FactoryGirl.generate :metasploit_model_search_operator_association_association
|
113
126
|
end
|
114
127
|
|
128
|
+
let(:association_operation) {
|
129
|
+
association_operator.operate_on('formatted_value')
|
130
|
+
}
|
131
|
+
|
115
132
|
let(:association_operator) do
|
133
|
+
source_operator = Metasploit::Model::Search::Operator::Attribute.new(type: :string)
|
134
|
+
|
116
135
|
Metasploit::Model::Search::Operator::Association.new(
|
117
|
-
association: association
|
136
|
+
association: association,
|
137
|
+
source_operator: source_operator
|
118
138
|
)
|
119
139
|
end
|
120
140
|
|
121
141
|
let(:children) do
|
122
142
|
Array.new(2) {
|
123
|
-
|
143
|
+
association_operation
|
124
144
|
}
|
125
145
|
end
|
126
146
|
|
@@ -140,10 +160,19 @@ describe MetasploitDataModels::Search::Visitor::Joins do
|
|
140
160
|
disjoint_associations[0, 1] + common_associations
|
141
161
|
end
|
142
162
|
|
163
|
+
let(:first_association_operations) {
|
164
|
+
first_association_operators.map { |association_operator|
|
165
|
+
association_operator.operate_on('formatted_value')
|
166
|
+
}
|
167
|
+
}
|
168
|
+
|
143
169
|
let(:first_association_operators) do
|
144
170
|
first_associations.collect { |association|
|
171
|
+
source_operator = Metasploit::Model::Search::Operator::Attribute.new(type: :string)
|
172
|
+
|
145
173
|
Metasploit::Model::Search::Operator::Association.new(
|
146
|
-
association: association
|
174
|
+
association: association,
|
175
|
+
source_operator: source_operator
|
147
176
|
)
|
148
177
|
}
|
149
178
|
end
|
@@ -152,16 +181,25 @@ describe MetasploitDataModels::Search::Visitor::Joins do
|
|
152
181
|
disjoint_associations[1, 1] + common_associations
|
153
182
|
end
|
154
183
|
|
184
|
+
let(:second_association_operations) {
|
185
|
+
second_association_operators.map { |association_operator|
|
186
|
+
association_operator.operate_on('formatted_value')
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
155
190
|
let(:second_association_operators) do
|
156
191
|
second_associations.collect { |association|
|
192
|
+
source_operator = Metasploit::Model::Search::Operator::Attribute.new(type: :string)
|
193
|
+
|
157
194
|
Metasploit::Model::Search::Operator::Association.new(
|
158
|
-
association: association
|
195
|
+
association: association,
|
196
|
+
source_operator: source_operator
|
159
197
|
)
|
160
198
|
}
|
161
199
|
end
|
162
200
|
|
163
201
|
let(:children) do
|
164
|
-
[
|
202
|
+
[first_association_operations, second_association_operations].collect { |grandchildren|
|
165
203
|
Metasploit::Model::Search::Group::Intersection.new(
|
166
204
|
children: grandchildren
|
167
205
|
)
|
@@ -208,6 +246,58 @@ describe MetasploitDataModels::Search::Visitor::Joins do
|
|
208
246
|
end
|
209
247
|
end
|
210
248
|
|
249
|
+
context 'with Metasploit::Model::Search::Operation::Association' do
|
250
|
+
let(:association) {
|
251
|
+
:parent_association
|
252
|
+
}
|
253
|
+
|
254
|
+
let(:node) {
|
255
|
+
operator.operate_on('formatted_value')
|
256
|
+
}
|
257
|
+
|
258
|
+
let(:operator) {
|
259
|
+
Metasploit::Model::Search::Operator::Association.new(
|
260
|
+
association: association,
|
261
|
+
source_operator: source_operator
|
262
|
+
)
|
263
|
+
}
|
264
|
+
|
265
|
+
context '#source_operation' do
|
266
|
+
let(:attribute_operator) {
|
267
|
+
Metasploit::Model::Search::Operator::Attribute.new(
|
268
|
+
type: :string
|
269
|
+
)
|
270
|
+
}
|
271
|
+
|
272
|
+
context 'with Metasploit::Model::Search::Operation::Association' do
|
273
|
+
let(:source_operator) {
|
274
|
+
Metasploit::Model::Search::Operator::Association.new(
|
275
|
+
association: source_operator_association,
|
276
|
+
source_operator: attribute_operator
|
277
|
+
)
|
278
|
+
}
|
279
|
+
|
280
|
+
let(:source_operator_association) {
|
281
|
+
:child_association
|
282
|
+
}
|
283
|
+
|
284
|
+
it 'is [{ association => nested associations }]' do
|
285
|
+
expect(visit).to eq([{association => [source_operator_association]}])
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
context 'without Metasploit::Model::Search::Operation::Association' do
|
290
|
+
let(:source_operator) {
|
291
|
+
attribute_operator
|
292
|
+
}
|
293
|
+
|
294
|
+
it 'is [association]' do
|
295
|
+
expect(visit).to eq([association])
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
211
301
|
operation_classes = [
|
212
302
|
Metasploit::Model::Search::Operation::Boolean,
|
213
303
|
Metasploit::Model::Search::Operation::Date,
|
@@ -239,8 +329,8 @@ describe MetasploitDataModels::Search::Visitor::Joins do
|
|
239
329
|
)
|
240
330
|
end
|
241
331
|
|
242
|
-
it '
|
243
|
-
visit.
|
332
|
+
it 'is #association' do
|
333
|
+
expect(visit).to eq(association)
|
244
334
|
end
|
245
335
|
end
|
246
336
|
|
@@ -175,11 +175,22 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
175
175
|
let(:non_matching_host) {
|
176
176
|
FactoryGirl.create(
|
177
177
|
:mdm_host,
|
178
|
+
address: non_matching_host_address,
|
178
179
|
name: non_matching_host_name,
|
179
180
|
os_flavor: non_matching_host_os_flavor,
|
180
181
|
os_name: non_matching_host_os_name,
|
181
182
|
os_sp: non_matching_host_os_sp
|
182
|
-
)
|
183
|
+
).tap { |host|
|
184
|
+
FactoryGirl.create(
|
185
|
+
:mdm_host_tag,
|
186
|
+
host: host,
|
187
|
+
tag: non_matching_tag
|
188
|
+
)
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
let(:non_matching_host_address) {
|
193
|
+
'5.6.7.8'
|
183
194
|
}
|
184
195
|
|
185
196
|
let(:non_matching_host_name) {
|
@@ -214,6 +225,22 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
214
225
|
'udp'
|
215
226
|
}
|
216
227
|
|
228
|
+
let(:non_matching_tag) {
|
229
|
+
FactoryGirl.create(
|
230
|
+
:mdm_tag,
|
231
|
+
desc: non_matching_tag_desc,
|
232
|
+
name: non_matching_tag_name
|
233
|
+
)
|
234
|
+
}
|
235
|
+
|
236
|
+
let(:non_matching_tag_desc) {
|
237
|
+
'Mdm::Tag#description b'
|
238
|
+
}
|
239
|
+
|
240
|
+
let(:non_matching_tag_name) {
|
241
|
+
'mdm_tag_name.b'
|
242
|
+
}
|
243
|
+
|
217
244
|
#
|
218
245
|
# let!s
|
219
246
|
#
|
@@ -323,11 +350,22 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
323
350
|
let(:matching_host) {
|
324
351
|
FactoryGirl.create(
|
325
352
|
:mdm_host,
|
353
|
+
address: matching_host_address,
|
326
354
|
name: matching_host_name,
|
327
355
|
os_flavor: matching_host_os_flavor,
|
328
356
|
os_name: matching_host_os_name,
|
329
357
|
os_sp: matching_host_os_sp
|
330
|
-
)
|
358
|
+
).tap { |host|
|
359
|
+
FactoryGirl.create(
|
360
|
+
:mdm_host_tag,
|
361
|
+
host: host,
|
362
|
+
tag: matching_tag
|
363
|
+
)
|
364
|
+
}
|
365
|
+
}
|
366
|
+
|
367
|
+
let(:matching_host_address) {
|
368
|
+
'1.2.3.4'
|
331
369
|
}
|
332
370
|
|
333
371
|
let(:matching_host_name) {
|
@@ -362,6 +400,22 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
362
400
|
'tcp'
|
363
401
|
}
|
364
402
|
|
403
|
+
let(:matching_tag) {
|
404
|
+
FactoryGirl.create(
|
405
|
+
:mdm_tag,
|
406
|
+
desc: matching_tag_desc,
|
407
|
+
name: matching_tag_name
|
408
|
+
)
|
409
|
+
}
|
410
|
+
|
411
|
+
let(:matching_tag_desc) {
|
412
|
+
'Mdm::Tag#description a'
|
413
|
+
}
|
414
|
+
|
415
|
+
let(:matching_tag_name) {
|
416
|
+
'mdm_tag_name.a'
|
417
|
+
}
|
418
|
+
|
365
419
|
#
|
366
420
|
# let!s
|
367
421
|
#
|
@@ -377,6 +431,42 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
377
431
|
)
|
378
432
|
}
|
379
433
|
|
434
|
+
context 'with host.address operator' do
|
435
|
+
let(:formatted) do
|
436
|
+
"host.address:#{formatted_address}"
|
437
|
+
end
|
438
|
+
|
439
|
+
context 'with CIDR' do
|
440
|
+
let(:formatted_address) {
|
441
|
+
'1.3.4.5/8'
|
442
|
+
}
|
443
|
+
|
444
|
+
it 'should find only matching record' do
|
445
|
+
expect(visit).to match_array([matching_record])
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
context 'with Range' do
|
450
|
+
let(:formatted_address) {
|
451
|
+
'1.1.1.1-5.6.7.7'
|
452
|
+
}
|
453
|
+
|
454
|
+
it 'should find only matching record' do
|
455
|
+
expect(visit).to match_array([matching_record])
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
context 'with single' do
|
460
|
+
let(:formatted_address) {
|
461
|
+
'1.2.3.4'
|
462
|
+
}
|
463
|
+
|
464
|
+
it 'should find only matching record' do
|
465
|
+
expect(visit).to match_array([matching_record])
|
466
|
+
end
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
380
470
|
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
381
471
|
association: :host,
|
382
472
|
attribute: :name
|
@@ -441,6 +531,18 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
441
531
|
association: :host,
|
442
532
|
attribute: :os_sp
|
443
533
|
|
534
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
535
|
+
association: {
|
536
|
+
host: :tags
|
537
|
+
},
|
538
|
+
attribute: :desc
|
539
|
+
|
540
|
+
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
541
|
+
association: {
|
542
|
+
host: :tags
|
543
|
+
},
|
544
|
+
attribute: :name
|
545
|
+
|
444
546
|
it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
|
445
547
|
attribute: :info
|
446
548
|
|
@@ -453,11 +555,16 @@ describe MetasploitDataModels::Search::Visitor::Relation do
|
|
453
555
|
context 'with all operators' do
|
454
556
|
let(:formatted) {
|
455
557
|
%Q{
|
558
|
+
host.address:1.3.4.5/8
|
559
|
+
host.address:1.1.1.1-5.6.7.7
|
560
|
+
host.address:1.2.3.4
|
456
561
|
host.name:#{matching_host_name}
|
457
562
|
host.os:"#{matching_host_os_name} #{matching_host_os_flavor} #{matching_host_os_sp}"
|
458
563
|
host.os_flavor:#{matching_host_os_flavor}
|
459
564
|
host.os_name:#{matching_host_os_name}
|
460
565
|
host.os_sp:#{matching_host_os_sp}
|
566
|
+
host.tags.desc:"#{matching_tag_desc}"
|
567
|
+
host.tags.name:#{matching_tag_name}
|
461
568
|
name:#{matching_name}
|
462
569
|
port:#{matching_port}
|
463
570
|
proto:#{matching_proto}
|
@@ -4,30 +4,43 @@ shared_examples_for 'MetasploitDataModels::Search::Visitor::Relation#visit match
|
|
4
4
|
attribute = options.fetch(:attribute)
|
5
5
|
association = options[:association]
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
def self.nested_hash_to_array(association)
|
8
|
+
case association
|
9
|
+
when Hash
|
10
|
+
hash = association
|
11
|
+
keys = hash.keys
|
12
|
+
|
13
|
+
unless keys.length == 1
|
14
|
+
raise ArgumentError, 'Only single key Hashes are allowed to nest associations'
|
15
|
+
end
|
16
|
+
|
17
|
+
parent_association = keys.first
|
18
|
+
child_association = hash[parent_association]
|
19
|
+
|
20
|
+
[parent_association, *nested_hash_to_array(child_association)]
|
21
|
+
when Symbol
|
22
|
+
[association]
|
23
|
+
when nil
|
24
|
+
[]
|
25
|
+
else
|
26
|
+
raise TypeError, "Cannot convert #{association.class} (#{association}) to array"
|
27
|
+
end
|
11
28
|
end
|
12
29
|
|
30
|
+
associations = nested_hash_to_array(association)
|
31
|
+
messages = [*associations, attribute]
|
32
|
+
formatted_operator = messages.map(&:to_s).join('.')
|
33
|
+
|
13
34
|
context "with #{formatted_operator}" do
|
14
35
|
let(:formatted) do
|
15
36
|
"#{formatted_operator}:\"#{value}\""
|
16
37
|
end
|
17
38
|
|
18
|
-
|
19
|
-
|
20
|
-
# wrap in array so
|
21
|
-
Array.wrap(
|
22
|
-
|
23
|
-
|
24
|
-
let(:value) do
|
25
|
-
associated.send(attribute)
|
26
|
-
end
|
27
|
-
else
|
28
|
-
let(:value) do
|
29
|
-
matching_record.send(attribute)
|
30
|
-
end
|
39
|
+
let(:value) do
|
40
|
+
messages.inject(matching_record) { |instance, message|
|
41
|
+
# wrap in array so singel and plural associatins can be handled the same
|
42
|
+
Array.wrap(instance.send(message)).first
|
43
|
+
}
|
31
44
|
end
|
32
45
|
|
33
46
|
it 'should find only matching record' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metasploit_data_models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.19.
|
4
|
+
version: 0.19.4
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Samuel Huckins
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2014-07-
|
14
|
+
date: 2014-07-29 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rake
|
@@ -107,20 +107,14 @@ dependencies:
|
|
107
107
|
name: metasploit-model
|
108
108
|
version_requirements: !ruby/object:Gem::Requirement
|
109
109
|
requirements:
|
110
|
-
- -
|
111
|
-
- !ruby/object:Gem::Version
|
112
|
-
version: 0.25.1
|
113
|
-
- - <
|
110
|
+
- - ~>
|
114
111
|
- !ruby/object:Gem::Version
|
115
|
-
version:
|
112
|
+
version: 0.26.1
|
116
113
|
requirement: !ruby/object:Gem::Requirement
|
117
114
|
requirements:
|
118
|
-
- -
|
119
|
-
- !ruby/object:Gem::Version
|
120
|
-
version: 0.25.1
|
121
|
-
- - <
|
115
|
+
- - ~>
|
122
116
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
117
|
+
version: 0.26.1
|
124
118
|
prerelease: false
|
125
119
|
type: :runtime
|
126
120
|
- !ruby/object:Gem::Dependency
|