metasploit_data_models 0.17.1 → 0.17.2.pre.metasploit.pre.data.pre.models.pre.search

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +4 -0
  3. data/Gemfile +2 -0
  4. data/app/models/mdm/host.rb +24 -0
  5. data/app/models/mdm/service.rb +9 -0
  6. data/app/models/metasploit_data_models/search/visitor/attribute.rb +13 -0
  7. data/app/models/metasploit_data_models/search/visitor/includes.rb +28 -0
  8. data/app/models/metasploit_data_models/search/visitor/joins.rb +47 -0
  9. data/app/models/metasploit_data_models/search/visitor/method.rb +13 -0
  10. data/app/models/metasploit_data_models/search/visitor/relation.rb +87 -0
  11. data/app/models/metasploit_data_models/search/visitor/where.rb +65 -0
  12. data/config/locales/en.yml +7 -0
  13. data/lib/metasploit_data_models.rb +1 -0
  14. data/lib/metasploit_data_models/search.rb +6 -0
  15. data/lib/metasploit_data_models/search/visitor.rb +8 -0
  16. data/lib/metasploit_data_models/version.rb +1 -1
  17. data/metasploit_data_models.gemspec +1 -0
  18. data/spec/app/models/metasploit_data_models/search/visitor/attribute_spec.rb +74 -0
  19. data/spec/app/models/metasploit_data_models/search/visitor/includes_spec.rb +124 -0
  20. data/spec/app/models/metasploit_data_models/search/visitor/joins_spec.rb +292 -0
  21. data/spec/app/models/metasploit_data_models/search/visitor/method_spec.rb +33 -0
  22. data/spec/app/models/metasploit_data_models/search/visitor/relation_spec.rb +253 -0
  23. data/spec/app/models/metasploit_data_models/search/visitor/where_spec.rb +147 -0
  24. data/spec/dummy/config/initializers/active_record_migrations.rb +4 -0
  25. data/spec/factories/mdm/services.rb +5 -0
  26. data/spec/support/shared/examples/metasploit_data_models/search/visitor/includes/visit/with_children.rb +38 -0
  27. data/spec/support/shared/examples/metasploit_data_models/search/visitor/includes/visit/with_metasploit_model_search_operation_base.rb +26 -0
  28. data/spec/support/shared/examples/metasploit_data_models/search/visitor/relation/visit/matching_record.rb +37 -0
  29. data/spec/support/shared/examples/metasploit_data_models/search/visitor/relation/visit/matching_record/with_metasploit_model_search_opeator_deprecated_platform.rb +31 -0
  30. data/spec/support/shared/examples/metasploit_data_models/search/visitor/relation/visit/matching_record/with_metasploit_model_search_operator_deprecated_authority.rb +78 -0
  31. data/spec/support/shared/examples/metasploit_data_models/search/visitor/where/visit/with_equality.rb +34 -0
  32. data/spec/support/shared/examples/metasploit_data_models/search/visitor/where/visit/with_metasploit_model_search_group_base.rb +50 -0
  33. metadata +61 -4
@@ -0,0 +1,253 @@
1
+ require 'spec_helper'
2
+
3
+ describe MetasploitDataModels::Search::Visitor::Relation do
4
+ subject(:visitor) do
5
+ described_class.new(
6
+ :query => query
7
+ )
8
+ end
9
+
10
+ let(:formatted) do
11
+ # needs to be a valid operation so that query is valid
12
+ "name:\"#{value}\""
13
+ end
14
+
15
+ let(:query) do
16
+ Metasploit::Model::Search::Query.new(
17
+ :formatted => formatted,
18
+ :klass => Mdm::Host
19
+ )
20
+ end
21
+
22
+ let(:value) {
23
+ FactoryGirl.generate :mdm_host_name
24
+ }
25
+
26
+ context 'validations' do
27
+ context 'query' do
28
+ it { should validate_presence_of(:query) }
29
+
30
+ context 'valid' do
31
+ let(:error) do
32
+ I18n.translate('errors.messages.invalid')
33
+ end
34
+
35
+ let(:errors) do
36
+ visitor.errors[:query]
37
+ end
38
+
39
+ context 'with query' do
40
+ let(:query) do
41
+ double('Query')
42
+ end
43
+
44
+ before(:each) do
45
+ query.stub(:valid? => query)
46
+
47
+ visitor.valid?
48
+ end
49
+
50
+ context 'with valid' do
51
+ let(:valid) do
52
+ true
53
+ end
54
+
55
+ it 'should not record error' do
56
+ errors.should_not include(error)
57
+ end
58
+ end
59
+
60
+ context 'without valid' do
61
+ let(:valid) do
62
+ false
63
+ end
64
+
65
+ it 'should record error' do
66
+ errors.should_not include(error)
67
+ end
68
+ end
69
+ end
70
+
71
+ context 'without query' do
72
+ let(:query) do
73
+ nil
74
+ end
75
+
76
+ it 'should not record error' do
77
+ errors.should_not include(error)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ context '#visit' do
85
+ subject(:visit) do
86
+ visitor.visit
87
+ end
88
+
89
+ context 'MetasploitDataModels::Search::Visitor::Includes' do
90
+ subject(:includes_visitor) do
91
+ visitor.visitor_by_relation_method[:includes]
92
+ end
93
+
94
+ it 'should visit Metasploit::Model::Search::Query#tree' do
95
+ includes_visitor.should_receive(:visit).with(query.tree)
96
+
97
+ visit
98
+ end
99
+
100
+ it 'should pass visited to ActiveRecord::Relation#includes' do
101
+ visited = double('Visited')
102
+ includes_visitor.stub(:visit).with(query.tree).and_return(visited)
103
+
104
+ ActiveRecord::Relation.any_instance.should_receive(:includes).with(visited).and_return(query.klass.scoped)
105
+
106
+ visit
107
+ end
108
+ end
109
+
110
+ context 'MetasploitDataModels::Search::Visitor::Joins' do
111
+ subject(:joins_visitor) do
112
+ visitor.visitor_by_relation_method[:joins]
113
+ end
114
+
115
+ it 'should visit Metasploit::Model::Search::Query#tree' do
116
+ joins_visitor.should_receive(:visit).with(query.tree)
117
+
118
+ visit
119
+ end
120
+
121
+ it 'should pass visited to ActiveRecord::Relation#joins' do
122
+ visited = double('Visited')
123
+ joins_visitor.stub(:visit).with(query.tree).and_return(visited)
124
+
125
+ ActiveRecord::Relation.any_instance.should_receive(:joins).with(visited).and_return(query.klass.scoped)
126
+
127
+ visit
128
+ end
129
+ end
130
+
131
+ context 'MetasploitDataModels::Search::Visitor::Where' do
132
+ subject(:where_visitor) do
133
+ visitor.visitor_by_relation_method[:where]
134
+ end
135
+
136
+ it 'should visit Metasploit::Model::Search::Query#tree' do
137
+ where_visitor.should_receive(:visit).with(query.tree)
138
+
139
+ visit
140
+ end
141
+
142
+ it 'should pass visited to ActiveRecord::Relation#includes' do
143
+ visited = double('Visited')
144
+ where_visitor.stub(:visit).with(query.tree).and_return(visited)
145
+
146
+ ActiveRecord::Relation.any_instance.should_receive(:where).with(visited).and_return(query.klass.scoped)
147
+
148
+ visit
149
+ end
150
+ end
151
+
152
+ context 'matching record' do
153
+ context 'with Mdm::Host' do
154
+ #
155
+ # lets
156
+ #
157
+ # Don't use factories to prevent prefix aliasing when sequences go from 1 to 10 or 10 to 100
158
+ #
159
+
160
+ let(:matching_record_name) {
161
+ 'mdm_host_name_a'
162
+ }
163
+
164
+ let(:matching_service_name) {
165
+ 'mdm_service_name_a'
166
+ }
167
+
168
+ let(:non_matching_record_name) {
169
+ 'mdm_host_name_b'
170
+ }
171
+
172
+ let(:non_matching_service_name) {
173
+ 'mdm_service_name_b'
174
+ }
175
+
176
+ #
177
+ # let!s
178
+ #
179
+
180
+ let!(:matching_record) do
181
+ FactoryGirl.build(
182
+ :mdm_host,
183
+ name: matching_record_name
184
+ )
185
+ end
186
+
187
+ let!(:matching_service) do
188
+ FactoryGirl.create(
189
+ :mdm_service,
190
+ host: matching_record,
191
+ name: matching_service_name
192
+ )
193
+ end
194
+
195
+ let!(:non_matching_record) do
196
+ FactoryGirl.build(
197
+ :mdm_host,
198
+ name: non_matching_record_name
199
+ )
200
+ end
201
+
202
+ let!(:non_matching_service) do
203
+ FactoryGirl.create(
204
+ :mdm_service,
205
+ host: non_matching_record,
206
+ name: non_matching_service_name
207
+ )
208
+ end
209
+
210
+ it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
211
+ :attribute => :name
212
+
213
+ it_should_behave_like 'MetasploitDataModels::Search::Visitor::Relation#visit matching record',
214
+ association: :services,
215
+ attribute: :name
216
+
217
+ context 'with all operators' do
218
+ let(:formatted) {
219
+ %Q{name:"#{matching_record_name}" services.name:"#{matching_service_name}"}
220
+ }
221
+
222
+ it 'should find only matching record' do
223
+ if visit.to_a != [matching_record]
224
+ true
225
+ end
226
+
227
+ expect(visit).to match_array([matching_record])
228
+ end
229
+ end
230
+ end
231
+ end
232
+ end
233
+
234
+ context '#visitor_by_relation_method' do
235
+ subject(:visitor_by_relation_method) do
236
+ visitor.visitor_by_relation_method
237
+ end
238
+
239
+ its([:joins]) { should be_a MetasploitDataModels::Search::Visitor::Joins }
240
+ its([:includes]) { should be_a MetasploitDataModels::Search::Visitor::Includes }
241
+ its([:where]) { should be_a MetasploitDataModels::Search::Visitor::Where }
242
+ end
243
+
244
+ context 'visitor_class_by_relation_method' do
245
+ subject(:visitor_class_by_relation_method) do
246
+ described_class.visitor_class_by_relation_method
247
+ end
248
+
249
+ its([:joins]) { should == MetasploitDataModels::Search::Visitor::Joins }
250
+ its([:includes]) { should == MetasploitDataModels::Search::Visitor::Includes }
251
+ its([:where]) { should == MetasploitDataModels::Search::Visitor::Where }
252
+ end
253
+ end
@@ -0,0 +1,147 @@
1
+ require 'spec_helper'
2
+
3
+ describe MetasploitDataModels::Search::Visitor::Where do
4
+ subject(:visitor) do
5
+ described_class.new
6
+ end
7
+
8
+ context '#attribute_visitor' do
9
+ subject(:attribute_visitor) do
10
+ visitor.attribute_visitor
11
+ end
12
+
13
+ it { should be_a MetasploitDataModels::Search::Visitor::Attribute }
14
+ end
15
+
16
+ context '#method_visitor' do
17
+ subject(:method_visitor) do
18
+ visitor.method_visitor
19
+ end
20
+
21
+ it { should be_a MetasploitDataModels::Search::Visitor::Method }
22
+ end
23
+
24
+ context '#visit' do
25
+ subject(:visit) do
26
+ visitor.visit(node)
27
+ end
28
+
29
+ arel_class_by_group_class = {
30
+ Metasploit::Model::Search::Group::Intersection => Arel::Nodes::And,
31
+ Metasploit::Model::Search::Group::Union => Arel::Nodes::Or
32
+ }
33
+
34
+ arel_class_by_group_class.each do |group_class, arel_class|
35
+ context "with #{group_class}" do
36
+ it_should_behave_like 'MetasploitDataModels::Search::Visitor::Where#visit with Metasploit::Model::Search::Group::Base',
37
+ :arel_class => arel_class do
38
+ let(:node_class) do
39
+ group_class
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ equality_operation_classes = [
46
+ Metasploit::Model::Search::Operation::Boolean,
47
+ Metasploit::Model::Search::Operation::Date,
48
+ Metasploit::Model::Search::Operation::Integer,
49
+ Metasploit::Model::Search::Operation::Set::Integer,
50
+ Metasploit::Model::Search::Operation::Set::String
51
+ ]
52
+
53
+ equality_operation_classes.each do |operation_class|
54
+ context "with #{operation_class}" do
55
+ it_should_behave_like 'MetasploitDataModels::Search::Visitor::Where#visit with equality operation' do
56
+ let(:node_class) do
57
+ operation_class
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'with Metasploit::Model::Search::Operation::String' do
64
+ let(:node) do
65
+ Metasploit::Model::Search::Operation::String.new(
66
+ :operator => operator,
67
+ :value => value
68
+ )
69
+ end
70
+
71
+ let(:operator) do
72
+ Metasploit::Model::Search::Operator::Attribute.new(
73
+ :klass => Mdm::Host,
74
+ :attribute => :name
75
+ )
76
+ end
77
+
78
+ let(:value) do
79
+ 'metasploitable'
80
+ end
81
+
82
+ it 'should visit operation.operator with attribute_visitor' do
83
+ visitor.attribute_visitor.should_receive(:visit).with(operator).and_call_original
84
+
85
+ visit
86
+ end
87
+
88
+ it 'should call matches on Arel::Attributes::Attribute from attribute_visitor' do
89
+ attribute = double('Visited Operator')
90
+ visitor.attribute_visitor.stub(:visit).with(operator).and_return(attribute)
91
+
92
+ attribute.should_receive(:matches).with("%#{value}%")
93
+
94
+ visit
95
+ end
96
+ end
97
+
98
+ context 'with Metasploit::Model::Search::Query#tree' do
99
+ let(:node) do
100
+ query.tree
101
+ end
102
+
103
+ let(:query) do
104
+ Metasploit::Model::Search::Query.new(
105
+ :formatted => formatted,
106
+ :klass => klass
107
+ )
108
+ end
109
+
110
+ context 'with Metasploit::model::Search::Query#klass' do
111
+ context 'with Mdm::Host' do
112
+ let(:klass) {
113
+ Mdm::Host
114
+ }
115
+
116
+ context 'with name' do
117
+ let(:name) do
118
+ FactoryGirl.generate :mdm_host_name
119
+ end
120
+
121
+ let(:formatted) do
122
+ "name:\"#{name}\""
123
+ end
124
+
125
+ it 'should match module_instances.name with ILIKE' do
126
+ visit.to_sql.should == "\"hosts\".\"name\" ILIKE '%#{name}%'"
127
+ end
128
+ end
129
+
130
+ context 'with services.name' do
131
+ let(:name) do
132
+ FactoryGirl.generate :mdm_service_name
133
+ end
134
+
135
+ let(:formatted) do
136
+ "services.name:\"#{name}\""
137
+ end
138
+
139
+ it 'should match module_actions.name with ILIKE' do
140
+ visit.to_sql.should == "\"services\".\"name\" ILIKE '%#{name}%'"
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,4 @@
1
+ # remove Dummy's db/migrate, which doesn't exists and replace it with gem's
2
+ ActiveRecord::Migrator.migrations_paths = [
3
+ MetasploitDataModels.root.join('db', 'migrate').to_path
4
+ ]
@@ -8,6 +8,7 @@ FactoryGirl.define do
8
8
  #
9
9
  # Attributes
10
10
  #
11
+ name { generate :mdm_service_name }
11
12
  port 4567
12
13
  proto 'snmp'
13
14
  state 'open'
@@ -19,6 +20,10 @@ FactoryGirl.define do
19
20
  end
20
21
  end
21
22
 
23
+ sequence(:mdm_service_name) { |n|
24
+ "mdm_service_name#{n}"
25
+ }
26
+
22
27
  port_bits = 16
23
28
  port_limit = 1 << port_bits
24
29
 
@@ -0,0 +1,38 @@
1
+ shared_examples_for 'MetasploitDataModels::Search::Visitor::Includes#visit with #children' do
2
+ let(:children) do
3
+ 2.times.collect { |n|
4
+ double("Child #{n}")
5
+ }
6
+ end
7
+
8
+ let(:node) do
9
+ node_class.new(
10
+ :children => children
11
+ )
12
+ end
13
+
14
+ it 'should visit each child' do
15
+ # needed for call to visit subject
16
+ visitor.should_receive(:visit).with(node).and_call_original
17
+
18
+ children.each do |child|
19
+ visitor.should_receive(:visit).with(child).and_return([])
20
+ end
21
+
22
+ visit
23
+ end
24
+
25
+ it 'should return Array of all child visits' do
26
+ child_visits = []
27
+
28
+ visitor.should_receive(:visit).with(node).and_call_original
29
+
30
+ children.each_with_index do |child, i|
31
+ child_visit = ["Visited Child #{i}"]
32
+ visitor.stub(:visit).with(child).and_return(child_visit)
33
+ child_visits.concat(child_visit)
34
+ end
35
+
36
+ visit.should == child_visits
37
+ end
38
+ end