metasploit_data_models 0.15.2 → 0.16.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.
Files changed (74) hide show
  1. data/Gemfile +2 -0
  2. data/app/models/mdm/client.rb +0 -1
  3. data/app/models/mdm/cred.rb +1 -1
  4. data/app/models/mdm/exploited_host.rb +0 -1
  5. data/app/models/mdm/listener.rb +2 -1
  6. data/app/models/mdm/nexpose_console.rb +2 -2
  7. data/app/models/mdm/session.rb +5 -1
  8. data/app/models/mdm/workspace.rb +0 -1
  9. data/db/migrate/20130525015035_remove_campaign_id_from_clients.rb +9 -0
  10. data/db/migrate/20130525212420_drop_table_imported_creds.rb +14 -0
  11. data/db/migrate/20130531144949_making_host_tags_a_real_ar_model.rb +6 -0
  12. data/lib/mdm/host/operating_system_normalization.rb +4 -4
  13. data/lib/metasploit_data_models/version.rb +1 -1
  14. data/spec/app/models/mdm/client_spec.rb +43 -0
  15. data/spec/app/models/mdm/cred_spec.rb +211 -0
  16. data/spec/app/models/mdm/events_spec.rb +85 -0
  17. data/spec/app/models/mdm/exploit_attempt_spec.rb +60 -0
  18. data/spec/app/models/mdm/exploited_host_spec.rb +44 -0
  19. data/spec/app/models/mdm/host_detail_spec.rb +49 -0
  20. data/spec/app/models/mdm/host_spec.rb +468 -0
  21. data/spec/app/models/mdm/host_tag_spec.rb +26 -0
  22. data/spec/app/models/mdm/listener_spec.rb +108 -0
  23. data/spec/app/models/mdm/loot_spec.rb +77 -0
  24. data/spec/app/models/mdm/nexpose_console_spec.rb +128 -0
  25. data/spec/app/models/mdm/note_spec.rb +84 -0
  26. data/spec/app/models/mdm/ref_spec.rb +13 -0
  27. data/spec/app/models/mdm/report_spec.rb +104 -0
  28. data/spec/app/models/mdm/report_template_spec.rb +52 -0
  29. data/spec/app/models/mdm/route_spec.rb +36 -0
  30. data/spec/app/models/mdm/service_spec.rb +70 -15
  31. data/spec/app/models/mdm/session_event_spec.rb +42 -0
  32. data/spec/app/models/mdm/session_spec.rb +114 -0
  33. data/spec/app/models/mdm/tag_spec.rb +104 -0
  34. data/spec/app/models/mdm/task_creds_spec.rb +32 -0
  35. data/spec/app/models/mdm/task_host_spec.rb +33 -0
  36. data/spec/app/models/mdm/task_service_spec.rb +33 -0
  37. data/spec/app/models/mdm/task_spec.rb +59 -5
  38. data/spec/app/models/mdm/user_spec.rb +51 -0
  39. data/spec/app/models/mdm/vuln_attempt_spec.rb +54 -0
  40. data/spec/app/models/mdm/vuln_details_spec.rb +66 -0
  41. data/spec/app/models/mdm/vuln_ref_spec.rb +24 -0
  42. data/spec/app/models/mdm/vuln_spec.rb +25 -0
  43. data/spec/app/models/mdm/web_form_spec.rb +47 -0
  44. data/spec/app/models/mdm/web_page_spec.rb +55 -0
  45. data/spec/app/models/mdm/web_site_spec.rb +86 -0
  46. data/spec/app/models/mdm/web_vuln_spec.rb +12 -0
  47. data/spec/app/models/mdm/workspace_spec.rb +567 -0
  48. data/spec/dummy/db/schema.rb +5 -13
  49. data/spec/factories/mdm/addresses.rb +5 -0
  50. data/spec/factories/mdm/clients.rb +8 -0
  51. data/spec/factories/mdm/events.rb +15 -0
  52. data/spec/factories/mdm/exploit_attempts.rb +8 -0
  53. data/spec/factories/mdm/exploited_hosts.rb +7 -0
  54. data/spec/factories/mdm/fingerprints/nessus_fingerprints.rb +6 -0
  55. data/spec/factories/mdm/fingerprints/nexpose_fingerprints.rb +6 -0
  56. data/spec/factories/mdm/fingerprints/nmap_fingerprints.rb +6 -0
  57. data/spec/factories/mdm/fingerprints/retina_fingerprints.rb +6 -0
  58. data/spec/factories/mdm/fingerprints/session_fingerprints.rb +6 -0
  59. data/spec/factories/mdm/host_details.rb +8 -0
  60. data/spec/factories/mdm/listeners.rb +12 -0
  61. data/spec/factories/mdm/loots.rb +11 -0
  62. data/spec/factories/mdm/nexpose_consoles.rb +15 -0
  63. data/spec/factories/mdm/notes.rb +12 -0
  64. data/spec/factories/mdm/report_templates.rb +8 -0
  65. data/spec/factories/mdm/reports.rb +13 -0
  66. data/spec/factories/mdm/routes.rb +36 -0
  67. data/spec/factories/mdm/session_events.rb +8 -0
  68. data/spec/factories/mdm/sessions.rb +13 -0
  69. data/spec/factories/mdm/vuln_attempts.rb +8 -0
  70. data/spec/factories/mdm/vuln_details.rb +8 -0
  71. data/spec/factories/mdm/web_forms.rb +33 -0
  72. data/spec/factories/mdm/web_pages.rb +64 -0
  73. metadata +95 -5
  74. data/app/models/mdm/imported_cred.rb +0 -10
@@ -18,5 +18,29 @@ describe Mdm::VulnRef do
18
18
  it { should have_db_column(:vuln_id).of_type(:integer) }
19
19
  end
20
20
  end
21
+
22
+ context 'associations' do
23
+ it { should belong_to(:vuln).class_name('Mdm::Vuln') }
24
+ it { should belong_to(:ref).class_name('Mdm::Ref') }
25
+ end
26
+
27
+ context 'factory' do
28
+ it 'should be valid' do
29
+ vuln_ref = FactoryGirl.build(:mdm_vuln_ref)
30
+ vuln_ref.should be_valid
31
+ end
32
+ end
33
+
34
+ context '#destroy' do
35
+ it 'should successfully destroy the object' do
36
+ vuln_ref = FactoryGirl.create(:mdm_vuln_ref)
37
+ expect {
38
+ vuln_ref.destroy
39
+ }.to_not raise_error
40
+ expect {
41
+ vuln_ref.reload
42
+ }.to raise_error(ActiveRecord::RecordNotFound)
43
+ end
44
+ end
21
45
 
22
46
  end
@@ -5,6 +5,31 @@ describe Mdm::Vuln do
5
5
  FactoryGirl.build(:mdm_vuln)
6
6
  end
7
7
 
8
+ context '#destroy' do
9
+ it 'should successfully destroy the object and dependent objects' do
10
+ vuln = FactoryGirl.create(:mdm_vuln)
11
+ vuln_attempt = FactoryGirl.create(:mdm_vuln_attempt, :vuln => vuln)
12
+ vuln_detail = FactoryGirl.create(:mdm_vuln_detail, :vuln => vuln)
13
+ vuln_ref = FactoryGirl.create(:mdm_vuln_ref, :vuln => vuln)
14
+ expect {
15
+ vuln.destroy
16
+ }.to_not raise_error
17
+ expect {
18
+ vuln.reload
19
+ }.to raise_error(ActiveRecord::RecordNotFound)
20
+ expect {
21
+ vuln_attempt.reload
22
+ }.to raise_error(ActiveRecord::RecordNotFound)
23
+ expect {
24
+ vuln_detail.reload
25
+ }.to raise_error(ActiveRecord::RecordNotFound)
26
+ expect {
27
+ vuln_ref.reload
28
+ }.to raise_error(ActiveRecord::RecordNotFound)
29
+ end
30
+ end
31
+
32
+
8
33
  context 'associations' do
9
34
  it { should belong_to(:host).class_name('Mdm::Host') }
10
35
  it { should belong_to(:service).class_name('Mdm::Service') }
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mdm::WebForm do
4
+
5
+ context 'associations' do
6
+ it { should belong_to(:web_site).class_name('Mdm::WebSite') }
7
+ end
8
+
9
+ context 'database' do
10
+
11
+ context 'timestamps'do
12
+ it { should have_db_column(:created_at).of_type(:datetime).with_options(:null => false) }
13
+ it { should have_db_column(:updated_at).of_type(:datetime).with_options(:null => false) }
14
+ end
15
+
16
+ context 'columns' do
17
+ it { should have_db_column(:web_site_id).of_type(:integer).with_options(:null => false) }
18
+ it { should have_db_column(:path).of_type(:text) }
19
+ it { should have_db_column(:method).of_type(:string) }
20
+ it { should have_db_column(:params).of_type(:text) }
21
+ it { should have_db_column(:query).of_type(:text) }
22
+ end
23
+
24
+ context 'indices' do
25
+ it { should have_db_index(:path) }
26
+ end
27
+ end
28
+
29
+ context 'factory' do
30
+ it 'should be valid' do
31
+ web_form = FactoryGirl.build(:mdm_web_form)
32
+ web_form.should be_valid
33
+ end
34
+ end
35
+
36
+ context '#destroy' do
37
+ it 'should successfully destroy the object' do
38
+ web_form = FactoryGirl.create(:mdm_web_form)
39
+ expect {
40
+ web_form.destroy
41
+ }.to_not raise_error
42
+ expect {
43
+ web_form.reload
44
+ }.to raise_error(ActiveRecord::RecordNotFound)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mdm::WebPage do
4
+
5
+ context 'associations' do
6
+ it { should belong_to(:web_site).class_name('Mdm::WebSite') }
7
+ end
8
+
9
+ context 'database' do
10
+
11
+ context 'timestamps'do
12
+ it { should have_db_column(:created_at).of_type(:datetime).with_options(:null => false) }
13
+ it { should have_db_column(:updated_at).of_type(:datetime).with_options(:null => false) }
14
+ it { should have_db_column(:mtime).of_type(:datetime) }
15
+ end
16
+
17
+ context 'columns' do
18
+ it { should have_db_column(:web_site_id).of_type(:integer).with_options(:null => false) }
19
+ it { should have_db_column(:path).of_type(:text) }
20
+ it { should have_db_column(:query).of_type(:text) }
21
+ it { should have_db_column(:code).of_type(:integer).with_options(:null => false) }
22
+ it { should have_db_column(:cookie).of_type(:text) }
23
+ it { should have_db_column(:auth).of_type(:text) }
24
+ it { should have_db_column(:ctype).of_type(:text) }
25
+ it { should have_db_column(:location).of_type(:text) }
26
+ it { should have_db_column(:headers).of_type(:text) }
27
+ it { should have_db_column(:body).of_type(:binary) }
28
+ it { should have_db_column(:request).of_type(:binary) }
29
+ end
30
+
31
+ context 'indices' do
32
+ it { should have_db_index(:path) }
33
+ it { should have_db_index(:query) }
34
+ end
35
+ end
36
+
37
+ context 'factory' do
38
+ it 'should be valid' do
39
+ web_page = FactoryGirl.build(:mdm_web_page)
40
+ web_page.should be_valid
41
+ end
42
+ end
43
+
44
+ context '#destroy' do
45
+ it 'should successfully destroy the object' do
46
+ web_page = FactoryGirl.create(:mdm_web_page)
47
+ expect {
48
+ web_page.destroy
49
+ }.to_not raise_error
50
+ expect {
51
+ web_page.reload
52
+ }.to raise_error(ActiveRecord::RecordNotFound)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mdm::WebSite do
4
+
5
+ context 'factory' do
6
+ it 'should be valid' do
7
+ web_site = FactoryGirl.build(:mdm_web_site)
8
+ web_site.should be_valid
9
+ end
10
+ end
11
+
12
+ context 'database' do
13
+
14
+ context 'timestamps'do
15
+ it { should have_db_column(:created_at).of_type(:datetime).with_options(:null => false) }
16
+ it { should have_db_column(:updated_at).of_type(:datetime).with_options(:null => false) }
17
+ end
18
+
19
+ context 'columns' do
20
+ it { should have_db_column(:service_id).of_type(:integer).with_options(:null => false) }
21
+ it { should have_db_column(:vhost).of_type(:string) }
22
+ it { should have_db_column(:comments).of_type(:text) }
23
+ it { should have_db_column(:options).of_type(:text) }
24
+ end
25
+
26
+ context 'indices' do
27
+ it { should have_db_index(:comments) }
28
+ it { should have_db_index(:options) }
29
+ it { should have_db_index(:vhost) }
30
+ end
31
+ end
32
+
33
+ context '#destroy' do
34
+ it 'should successfully destroy the object' do
35
+ web_site = FactoryGirl.create(:mdm_web_site)
36
+ expect {
37
+ web_site.destroy
38
+ }.to_not raise_error
39
+ expect {
40
+ web_site.reload
41
+ }.to raise_error(ActiveRecord::RecordNotFound)
42
+ end
43
+ end
44
+
45
+ context 'associations' do
46
+ it { should belong_to(:service).class_name('Mdm::Service') }
47
+ it { should have_many(:web_forms).class_name('Mdm::WebForm').dependent(:destroy) }
48
+ it { should have_many(:web_pages).class_name('Mdm::WebPage').dependent(:destroy) }
49
+ it { should have_many(:web_vulns).class_name('Mdm::WebVuln').dependent(:destroy) }
50
+ end
51
+
52
+ context 'methods' do
53
+ context '#form_count' do
54
+ it 'should return an accurate count of associated Webforms' do
55
+ mysite = FactoryGirl.create(:mdm_web_site)
56
+ FactoryGirl.create(:mdm_web_form, :web_site => mysite)
57
+ FactoryGirl.create(:mdm_web_form, :web_site => mysite)
58
+ mysite.form_count.should == 2
59
+ FactoryGirl.create(:mdm_web_form, :web_site => mysite)
60
+ mysite.form_count.should == 3
61
+ end
62
+ end
63
+
64
+ context '#page_count' do
65
+ it 'should return an accurate count of associated Webpages' do
66
+ mysite = FactoryGirl.create(:mdm_web_site)
67
+ FactoryGirl.create(:mdm_web_page, :web_site => mysite)
68
+ FactoryGirl.create(:mdm_web_page, :web_site => mysite)
69
+ mysite.page_count.should == 2
70
+ FactoryGirl.create(:mdm_web_page, :web_site => mysite)
71
+ mysite.page_count.should == 3
72
+ end
73
+ end
74
+
75
+ context '#vuln_count' do
76
+ it 'should return an accurate count of associated Webvulns' do
77
+ mysite = FactoryGirl.create(:mdm_web_site)
78
+ FactoryGirl.create(:mdm_web_vuln, :web_site => mysite)
79
+ FactoryGirl.create(:mdm_web_vuln, :web_site => mysite)
80
+ mysite.vuln_count.should == 2
81
+ FactoryGirl.create(:mdm_web_vuln, :web_site => mysite)
82
+ mysite.vuln_count.should == 3
83
+ end
84
+ end
85
+ end
86
+ end
@@ -44,6 +44,18 @@ describe Mdm::WebVuln do
44
44
  end
45
45
  end
46
46
 
47
+ context '#destroy' do
48
+ it 'should successfully destroy the object' do
49
+ web_vuln = FactoryGirl.create(:mdm_web_vuln)
50
+ expect {
51
+ web_vuln.destroy
52
+ }.to_not raise_error
53
+ expect {
54
+ web_vuln.reload
55
+ }.to raise_error(ActiveRecord::RecordNotFound)
56
+ end
57
+ end
58
+
47
59
  context 'database' do
48
60
  context 'columns' do
49
61
  it { should have_db_column(:blame).of_type(:text) }
@@ -0,0 +1,567 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mdm::Workspace do
4
+ subject(:workspace) do
5
+ FactoryGirl.build(:mdm_workspace)
6
+ end
7
+
8
+ let(:default) do
9
+ 'default'
10
+ end
11
+
12
+ context 'factory' do
13
+ it 'should be valid' do
14
+ workspace = FactoryGirl.build(:mdm_workspace)
15
+ workspace.should be_valid
16
+ end
17
+ end
18
+
19
+ context '#destroy' do
20
+ it 'should successfully destroy the object and dependent objects' do
21
+ workspace = FactoryGirl.create(:mdm_workspace)
22
+ listener = FactoryGirl.create(:mdm_listener, :workspace => workspace)
23
+ report_template = FactoryGirl.create(:mdm_report_template, :workspace => workspace)
24
+ report = FactoryGirl.create(:mdm_report, :workspace => workspace)
25
+ task = FactoryGirl.create(:mdm_task, :workspace => workspace)
26
+
27
+ expect {
28
+ workspace.destroy
29
+ }.to_not raise_error
30
+ expect {
31
+ workspace.reload
32
+ }.to raise_error(ActiveRecord::RecordNotFound)
33
+ expect {
34
+ listener.reload
35
+ }.to raise_error(ActiveRecord::RecordNotFound)
36
+ expect {
37
+ report_template.reload
38
+ }.to raise_error(ActiveRecord::RecordNotFound)
39
+ expect {
40
+ report.reload
41
+ }.to raise_error(ActiveRecord::RecordNotFound)
42
+ expect {
43
+ task.reload
44
+ }.to raise_error(ActiveRecord::RecordNotFound)
45
+ end
46
+ end
47
+
48
+ context 'associations' do
49
+ it { should have_many(:clients).class_name('Mdm::Client').through(:hosts) }
50
+ it { should have_many(:creds).class_name('Mdm::Cred').through(:services) }
51
+ it { should have_many(:events).class_name('Mdm::Event') }
52
+ it { should have_many(:exploited_hosts).class_name('Mdm::ExploitedHost').through(:hosts) }
53
+ it { should have_many(:hosts).class_name('Mdm::Host') }
54
+ it { should have_many(:listeners).class_name('Mdm::Listener').dependent(:destroy) }
55
+ it { should have_many(:loots).class_name('Mdm::Loot').through(:hosts) }
56
+ it { should have_many(:notes).class_name('Mdm::Note') }
57
+ it { should belong_to(:owner).class_name('Mdm::User').with_foreign_key('owner_id') }
58
+ it { should have_many(:report_templates).class_name('Mdm::ReportTemplate').dependent(:destroy) }
59
+ it { should have_many(:reports).class_name('Mdm::Report').dependent(:destroy) }
60
+ it { should have_many(:services).class_name('Mdm::Service').through(:hosts).with_foreign_key('service_id') }
61
+ it { should have_many(:sessions).class_name('Mdm::Session').through(:hosts) }
62
+ it { should have_many(:tasks).class_name('Mdm::Task').dependent(:destroy).order('created_at DESC') }
63
+ it { should have_and_belong_to_many(:users).class_name('Mdm::User') }
64
+ it { should have_many(:vulns).class_name('Mdm::Vuln').through(:hosts) }
65
+ end
66
+
67
+ context 'callbacks' do
68
+ context 'before_save' do
69
+ context '#normalize' do
70
+ it 'should be called' do
71
+ workspace.should_receive(:normalize)
72
+ workspace.run_callbacks(:save, false)
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ context 'columns' do
79
+ it { should have_db_column(:boundary).of_type(:string).with_options(:limit => 4 * (2 ** 10)) }
80
+ it { should have_db_column(:description).of_type(:string).with_options(:limit => 4 * (2 ** 10)) }
81
+ it { should have_db_column(:limit_to_network).of_type(:boolean).with_options(:default => false, :null => false) }
82
+ it { should have_db_column(:name).of_type(:string) }
83
+ it { should have_db_column(:owner_id).of_type(:integer) }
84
+
85
+ context 'timestamps' do
86
+ it { should have_db_column(:created_at).of_type(:datetime).with_options(:null => false) }
87
+ it { should have_db_column(:updated_at).of_type(:datetime).with_options(:null => false) }
88
+ end
89
+ end
90
+
91
+ context 'CONSTANTS' do
92
+ it 'should define the DEFAULT name' do
93
+ described_class::DEFAULT.should == default
94
+ end
95
+ end
96
+
97
+ context 'validations' do
98
+ context 'boundary' do
99
+ let(:boundary) do
100
+ nil
101
+ end
102
+
103
+ let(:error) do
104
+ 'must be a valid IP range'
105
+ end
106
+
107
+ before(:each) do
108
+ workspace.boundary = boundary
109
+ workspace.valid?
110
+ end
111
+
112
+ it 'should validate using #valid_ip_or_range?', :pending => 'https://www.pivotaltracker.com/story/show/43244445' do
113
+ workspace.should_receive(:valid_ip_or_range?).with(boundary).and_return(false)
114
+
115
+ workspace.valid?
116
+ end
117
+
118
+ context 'with valid IP' do
119
+ let(:boundary) do
120
+ '192.168.0.1'
121
+ end
122
+
123
+ it 'should not record an error' do
124
+ workspace.errors[:boundary].should_not include(error)
125
+ end
126
+ end
127
+
128
+ context 'with valid range' do
129
+ let(:boundary) do
130
+ '192.168.0.1/24'
131
+ end
132
+
133
+ it 'should not record an error' do
134
+ workspace.errors[:boundary].should_not include(error)
135
+ end
136
+ end
137
+
138
+ context 'with invalid IP or range' do
139
+ let(:boundary) do
140
+ '192.168'
141
+ end
142
+
143
+ it 'should record error that boundary must be a valid IP range', :pending => 'https://www.pivotaltracker.com/story/show/43171927' do
144
+ workspace.should_not be_valid
145
+ workkspace.errors[:boundary].should include(error)
146
+ end
147
+ end
148
+ end
149
+
150
+ context 'description' do
151
+ it { should ensure_length_of(:description).is_at_most(4 * (2 ** 10)) }
152
+ end
153
+
154
+ context 'name' do
155
+ it { should ensure_length_of(:name).is_at_most(2**8 - 1) }
156
+ it { should validate_presence_of :name }
157
+ it { should validate_uniqueness_of :name }
158
+ end
159
+ end
160
+
161
+ context 'methods' do
162
+ let(:hosts) do
163
+ FactoryGirl.create_list(:mdm_host, 2, :workspace => workspace)
164
+ end
165
+
166
+ let(:other_hosts) do
167
+ FactoryGirl.create_list(:mdm_host, 2, :workspace => other_workspace)
168
+ end
169
+
170
+ let(:other_services) do
171
+ other_hosts.collect do |host|
172
+ FactoryGirl.create(:mdm_service, :host => host)
173
+ end
174
+ end
175
+
176
+ let(:other_web_sites) do
177
+ other_services.collect { |service|
178
+ FactoryGirl.create(:mdm_web_site, :service => service)
179
+ }
180
+ end
181
+
182
+ let(:other_workspace) do
183
+ FactoryGirl.create(:mdm_workspace)
184
+ end
185
+
186
+ let(:services) do
187
+ hosts.collect do |host|
188
+ FactoryGirl.create(:mdm_service, :host => host)
189
+ end
190
+ end
191
+
192
+ let(:web_sites) do
193
+ services.collect { |service|
194
+ FactoryGirl.create(:mdm_web_site, :service => service)
195
+ }
196
+ end
197
+
198
+ context '#creds' do
199
+ #
200
+ # Let!s (let + before(:each))
201
+ #
202
+
203
+ let!(:creds) do
204
+ services.collect do |service|
205
+ FactoryGirl.create(:mdm_cred, :service => service)
206
+ end
207
+ end
208
+
209
+ let!(:other_creds) do
210
+ other_services.collect do |service|
211
+ FactoryGirl.create(:mdm_cred, :service => service)
212
+ end
213
+ end
214
+
215
+ it 'should be an ActiveRecord::Relation', :pending => 'https://www.pivotaltracker.com/story/show/43219917' do
216
+ should be_a ActiveRecord::Relation
217
+ end
218
+
219
+ it 'should include services' do
220
+ # to_a to make query return instances
221
+ found_creds = workspace.creds.to_a
222
+
223
+ found_creds.length.should > 0
224
+ found_cred = found_creds.first
225
+
226
+ end
227
+
228
+ it 'should include hosts' do
229
+ found_creds = workspace.creds.to_a
230
+
231
+ found_creds.length.should > 0
232
+ found_cred = found_creds.first
233
+ service = found_cred.service
234
+ end
235
+
236
+ it 'should return only Mdm::Creds from hosts in workspace' do
237
+ found_creds = workspace.creds
238
+
239
+ found_creds.length.should == creds.length
240
+
241
+ found_creds.all? { |cred|
242
+ cred.service.host.workspace == workspace
243
+ }.should be_true
244
+ end
245
+ end
246
+
247
+ context 'default' do
248
+ context 'with default workspace' do
249
+ before(:each) do
250
+ FactoryGirl.create(
251
+ :mdm_workspace,
252
+ :name => default
253
+ )
254
+ end
255
+
256
+ it 'should not create workspace' do
257
+ workspace = nil
258
+
259
+ expect {
260
+ workspace = described_class.default
261
+ }.to change(Mdm::Workspace, :count).by(0)
262
+
263
+ workspace.should be_default
264
+ end
265
+ end
266
+
267
+ context 'without default workspace' do
268
+ it 'should create workspace' do
269
+ workspace = nil
270
+
271
+ expect {
272
+ workspace = described_class.default
273
+ }.to change(Mdm::Workspace, :count).by(1)
274
+
275
+ workspace.should be_default
276
+ end
277
+ end
278
+ end
279
+
280
+ context '#default?' do
281
+ subject do
282
+ workspace.default?
283
+ end
284
+
285
+ context 'with DEFAULT name' do
286
+ before(:each) do
287
+ workspace.name = default
288
+ end
289
+
290
+ it {
291
+ should be_true
292
+ }
293
+ end
294
+
295
+ context 'without DEFAULT name' do
296
+ it { should be_false }
297
+ end
298
+ end
299
+
300
+ context '#each_cred' do
301
+ it 'should pass each of the #creds to the block' do
302
+ creds = FactoryGirl.create_list(:mdm_cred, 2)
303
+ workspace.stub(:creds => creds)
304
+
305
+ expect { |block|
306
+ workspace.each_cred(&block)
307
+ }.to yield_successive_args(*creds)
308
+ end
309
+ end
310
+
311
+ context '#each_host_tag' do
312
+ it 'should pass each of the #host_tags to the block' do
313
+ tags = FactoryGirl.create_list(:mdm_tag, 2)
314
+ workspace.stub(:host_tags => tags)
315
+
316
+ expect { |block|
317
+ workspace.each_host_tag(&block)
318
+ }.to yield_successive_args(*tags)
319
+ end
320
+ end
321
+
322
+ context '#host_tags' do
323
+ let(:other_tags) do
324
+ FactoryGirl.create_list(
325
+ :mdm_tag,
326
+ 2
327
+ )
328
+ end
329
+
330
+ let(:tags) do
331
+ FactoryGirl.create_list(
332
+ :mdm_tag,
333
+ 2
334
+ )
335
+ end
336
+
337
+ subject(:host_tags) do
338
+ workspace.host_tags
339
+ end
340
+
341
+ #
342
+ # Let!s (let + before(:each))
343
+ #
344
+
345
+ let!(:host_tags) do
346
+ host_tags = []
347
+
348
+ hosts.zip(tags) do |host, tag|
349
+ host_tag = FactoryGirl.create(:mdm_host_tag, :host => host, :tag => tag)
350
+
351
+ host_tags << host_tag
352
+ end
353
+
354
+ host_tags
355
+ end
356
+
357
+ let!(:other_host_tags) do
358
+ host_tags = []
359
+
360
+ other_hosts.zip(other_tags) do |host, tag|
361
+ host_tag = FactoryGirl.create(:mdm_host_tag, :host => host, :tag => tag)
362
+
363
+ host_tags << host_tag
364
+ end
365
+
366
+ host_tags
367
+ end
368
+
369
+ it 'should return an ActiveRecord::Relation', :pending => 'https://www.pivotaltracker.com/story/show/43219917' do
370
+ should be_a ActiveRecord::Relation
371
+ end
372
+
373
+ it 'should include hosts' do
374
+ found_tags = workspace.host_tags.to_a
375
+
376
+ found_tags.length.should > 0
377
+
378
+ tag = found_tags.first
379
+ end
380
+
381
+ it 'should return only Mdm::Tags from hosts in the workspace' do
382
+ found_tags = workspace.host_tags
383
+
384
+ found_tags.length.should == tags.length
385
+
386
+ found_tags.all? { |tag|
387
+ tag.hosts.any? { |host|
388
+ host.workspace == workspace
389
+ }
390
+ }.should be_true
391
+ end
392
+ end
393
+
394
+ context '#normalize' do
395
+ let(:normalize) do
396
+ workspace.send(:normalize)
397
+ end
398
+
399
+ before(:each) do
400
+ workspace.boundary = boundary
401
+ end
402
+
403
+ context 'with boundary' do
404
+ let(:boundary) do
405
+ " #{stripped_boundary} "
406
+ end
407
+
408
+ let(:stripped_boundary) do
409
+ '192.168.0.1'
410
+ end
411
+
412
+ it "should remove spaces" do
413
+ normalize
414
+
415
+ workspace.boundary.should == stripped_boundary
416
+ end
417
+ end
418
+
419
+ context 'without boundary' do
420
+ let(:boundary) do
421
+ nil
422
+ end
423
+
424
+ it 'should not raise error' do
425
+ expect {
426
+ normalize
427
+ }.to_not raise_error
428
+ end
429
+ end
430
+ end
431
+
432
+ context '#web_forms' do
433
+
434
+ subject do
435
+ workspace.web_forms
436
+ end
437
+
438
+ #
439
+ # Let!s (let + before(:each))
440
+ #
441
+
442
+ let!(:other_web_forms) do
443
+ other_web_sites.collect { |web_site|
444
+ FactoryGirl.create(:web_form, :web_site => web_site)
445
+ }
446
+ end
447
+
448
+ let!(:web_forms) do
449
+ web_sites.collect { |web_site|
450
+ FactoryGirl.create(:web_form, :web_site => web_site)
451
+ }
452
+ end
453
+
454
+ it 'should return an ActiveRecord:Relation',
455
+ :pending => 'https://www.pivotaltracker.com/story/show/43219917' do
456
+ should be_a ActiveRecord::Relation
457
+ end
458
+
459
+ it 'should return only Mdm::WebPages from hosts in the workspace' do
460
+ found_web_forms = workspace.web_forms
461
+
462
+ found_web_forms.length.should == web_forms.length
463
+
464
+ found_web_forms.all? { |web_form|
465
+ web_form.web_site.service.host.workspace == workspace
466
+ }.should be_true
467
+ end
468
+ end
469
+
470
+ context '#web_sites' do
471
+ subject do
472
+ workspace.web_sites
473
+ end
474
+
475
+ #
476
+ # Let!s (let + before(:each))
477
+ #
478
+
479
+ before(:each) do
480
+ other_web_sites
481
+ web_sites
482
+ end
483
+
484
+ it 'should return an ActiveRecord:Relation',
485
+ :pending => 'https://www.pivotaltracker.com/story/show/43219917' do
486
+ should be_a ActiveRecord::Relation
487
+ end
488
+
489
+ it 'should return only Mdm::WebVulns from hosts in the workspace' do
490
+ # there are more web sites than those in the workspace
491
+ Mdm::WebSite.count.should > web_sites.count
492
+
493
+ found_web_sites = workspace.web_sites
494
+
495
+ found_web_sites.length.should == web_sites.count
496
+
497
+ found_web_sites.all? { |web_site|
498
+ web_site.service.host.workspace == workspace
499
+ }.should be_true
500
+ end
501
+ end
502
+
503
+ context '#web_vulns' do
504
+ subject do
505
+ workspace.web_vulns
506
+ end
507
+
508
+ #
509
+ # Let!s (let + before(:each))
510
+ #
511
+
512
+ let!(:other_web_vulns) do
513
+ other_web_sites.collect { |web_site|
514
+ FactoryGirl.create(:mdm_web_vuln, :web_site => web_site)
515
+ }
516
+ end
517
+
518
+ let!(:web_vulns) do
519
+ web_sites.collect { |web_site|
520
+ FactoryGirl.create(:mdm_web_vuln, :web_site => web_site)
521
+ }
522
+ end
523
+
524
+ it 'should return an ActiveRecord:Relation',
525
+ :pending => 'https://www.pivotaltracker.com/story/show/43219917' do
526
+ should be_a ActiveRecord::Relation
527
+ end
528
+
529
+ it 'should return only Mdm::WebVulns from hosts in the workspace' do
530
+ Mdm::WebVuln.count.should > web_vulns.length
531
+
532
+ found_web_vulns = workspace.web_vulns
533
+
534
+ found_web_vulns.length.should == web_vulns.length
535
+
536
+ found_web_vulns.all? { |web_vuln|
537
+ web_vuln.web_site.service.host.workspace == workspace
538
+ }.should be_true
539
+
540
+ end
541
+ end
542
+
543
+ context '#web_unique_forms' do
544
+ let(:rejected_address) do
545
+ hosts[1].address
546
+ end
547
+
548
+ let(:selected_address) do
549
+ hosts[0].address
550
+ end
551
+
552
+ it 'should return an ActiveRecord:Relation',
553
+ :pending => 'https://www.pivotaltracker.com/story/show/43219917' do
554
+ should be_a ActiveRecord::Relation
555
+ end
556
+
557
+ it "should reject #unique_web_forms from host addresses that aren't in addresses" do
558
+ web_forms = workspace.web_unique_forms([selected_address])
559
+
560
+ web_forms.all? { |web_form|
561
+ web_form.web_site.service.host.address.should == selected_address
562
+ }.should be_true
563
+ end
564
+ end
565
+ end
566
+
567
+ end