metasploit-credential 0.14.7 → 0.14.8
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/CONTRIBUTING.md +41 -9
- data/lib/metasploit/credential/exporter/core.rb +2 -2
- data/lib/metasploit/credential/exporter/pwdump.rb +2 -2
- data/lib/metasploit/credential/migrator.rb +1 -1
- data/lib/metasploit/credential/version.rb +12 -21
- data/spec/dummy/db/structure.sql +0 -1
- data/spec/lib/metasploit/credential/creation_spec.rb +8 -6
- data/spec/lib/metasploit/credential/exporter/core_spec.rb +85 -100
- data/spec/lib/metasploit/credential/exporter/pwdump_spec.rb +16 -14
- data/spec/lib/metasploit/credential/importer/core_spec.rb +12 -10
- data/spec/lib/metasploit/credential/importer/multi_spec.rb +6 -4
- data/spec/lib/metasploit/credential/importer/pwdump_spec.rb +13 -11
- data/spec/lib/metasploit/credential/importer/zip_spec.rb +7 -5
- data/spec/lib/metasploit/credential/migrator_spec.rb +13 -13
- data/spec/lib/metasploit/credential/version_spec.rb +141 -3
- data/spec/lib/metasploit/credential_spec.rb +15 -4
- data/spec/models/mdm/service_spec.rb +5 -3
- data/spec/models/mdm/session_spec.rb +4 -2
- data/spec/models/mdm/task_spec.rb +6 -4
- data/spec/models/mdm/user_spec.rb +4 -2
- data/spec/models/mdm/workspace_spec.rb +4 -2
- data/spec/models/metasploit/credential/blank_username_spec.rb +7 -5
- data/spec/models/metasploit/credential/core_spec.rb +45 -43
- data/spec/models/metasploit/credential/login/status_spec.rb +21 -19
- data/spec/models/metasploit/credential/login_spec.rb +38 -36
- data/spec/models/metasploit/credential/nonreplayable_hash_spec.rb +5 -3
- data/spec/models/metasploit/credential/ntlm_hash_spec.rb +15 -13
- data/spec/models/metasploit/credential/origin/cracked_password_spec.rb +7 -5
- data/spec/models/metasploit/credential/origin/import_spec.rb +10 -8
- data/spec/models/metasploit/credential/origin/manual_spec.rb +9 -7
- data/spec/models/metasploit/credential/origin/service_spec.rb +12 -10
- data/spec/models/metasploit/credential/origin/session_spec.rb +13 -11
- data/spec/models/metasploit/credential/password_hash_spec.rb +6 -4
- data/spec/models/metasploit/credential/password_spec.rb +5 -3
- data/spec/models/metasploit/credential/postgres_md5_spec.rb +6 -4
- data/spec/models/metasploit/credential/private_spec.rb +10 -8
- data/spec/models/metasploit/credential/public_spec.rb +7 -5
- data/spec/models/metasploit/credential/realm_spec.rb +16 -14
- data/spec/models/metasploit/credential/replayable_hash_spec.rb +5 -3
- data/spec/models/metasploit/credential/ssh_key_spec.rb +17 -15
- data/spec/models/metasploit/credential/username_spec.rb +8 -6
- data/spec/models/metasploit_data_models/search/visitor/relation_spec.rb +3 -1
- data/spec/spec_helper.rb +25 -95
- data/spec/support/shared/contexts/mdm/workspace.rb +1 -1
- data/spec/support/shared/examples/core_validations.rb +42 -117
- data/spec/support/shared/examples/single_table_inheritance_database_columns.rb +2 -2
- data/spec/support/shared/examples/timestamp_database_column.rb +2 -2
- metadata +8 -22
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Metasploit::Credential::Exporter::Pwdump do
|
2
4
|
include_context 'Mdm::Workspace'
|
3
5
|
|
4
6
|
subject(:exporter){ Metasploit::Credential::Exporter::Pwdump.new}
|
@@ -11,7 +13,7 @@ RSpec.describe Metasploit::Credential::Exporter::Pwdump do
|
|
11
13
|
describe "associated Mdm::Service objects" do
|
12
14
|
it 'should properly format the service information' do
|
13
15
|
service = login.service
|
14
|
-
|
16
|
+
exporter.format_service_for_login(login).should == "#{service.host.address}:#{service.port}/#{service.proto} (#{service.name})"
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
@@ -23,17 +25,17 @@ RSpec.describe Metasploit::Credential::Exporter::Pwdump do
|
|
23
25
|
end
|
24
26
|
|
25
27
|
it 'should have the proper formatting with extant data' do
|
26
|
-
|
28
|
+
exporter.format_password(login).should == "#{login.core.public.username} #{login.core.private.data}"
|
27
29
|
end
|
28
30
|
|
29
31
|
it 'should have the proper formatting with a missing public' do
|
30
32
|
login.core.public.username = ""
|
31
|
-
|
33
|
+
exporter.format_password(login).should == "#{Metasploit::Credential::Exporter::Pwdump::BLANK_CRED_STRING} #{login.core.private.data}"
|
32
34
|
end
|
33
35
|
|
34
36
|
it 'should have the proper formatting with a missing private' do
|
35
37
|
login.core.private.data = ""
|
36
|
-
|
38
|
+
exporter.format_password(login).should == "#{login.core.public.username} #{Metasploit::Credential::Exporter::Pwdump::BLANK_CRED_STRING}"
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
@@ -45,17 +47,17 @@ RSpec.describe Metasploit::Credential::Exporter::Pwdump do
|
|
45
47
|
end
|
46
48
|
|
47
49
|
it 'should have the proper formatting with extant data' do
|
48
|
-
|
50
|
+
exporter.format_nonreplayable_hash(login).should == "#{login.core.public.username}:#{login.core.private.data}:::"
|
49
51
|
end
|
50
52
|
|
51
53
|
it 'should have the proper formatting with a missing public' do
|
52
54
|
login.core.public.username = ""
|
53
|
-
|
55
|
+
exporter.format_nonreplayable_hash(login).should == "#{Metasploit::Credential::Exporter::Pwdump::BLANK_CRED_STRING}:#{login.core.private.data}:::"
|
54
56
|
end
|
55
57
|
|
56
58
|
it 'should have the proper formatting with a missing private' do
|
57
59
|
login.core.private.data = ""
|
58
|
-
|
60
|
+
exporter.format_nonreplayable_hash(login).should == "#{login.core.public.username}:#{Metasploit::Credential::Exporter::Pwdump::BLANK_CRED_STRING}:::"
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
@@ -67,17 +69,17 @@ RSpec.describe Metasploit::Credential::Exporter::Pwdump do
|
|
67
69
|
end
|
68
70
|
|
69
71
|
it 'should have the proper formatting with extant data' do
|
70
|
-
|
72
|
+
exporter.format_ntlm_hash(login).should == "#{login.core.public.username}:#{login.id}:#{login.core.private.data}:::"
|
71
73
|
end
|
72
74
|
|
73
75
|
it 'should have the proper formatting with a missing public' do
|
74
76
|
login.core.public.username = ""
|
75
|
-
|
77
|
+
exporter.format_ntlm_hash(login).should == "#{Metasploit::Credential::Exporter::Pwdump::BLANK_CRED_STRING}:#{login.id}:#{login.core.private.data}:::"
|
76
78
|
end
|
77
79
|
|
78
80
|
it 'should have the proper formatting with a missing private' do
|
79
81
|
login.core.private.data = ""
|
80
|
-
|
82
|
+
exporter.format_ntlm_hash(login).should == "#{login.core.public.username}:#{login.id}:#{Metasploit::Credential::Exporter::Pwdump::BLANK_CRED_STRING}:::"
|
81
83
|
end
|
82
84
|
end
|
83
85
|
|
@@ -89,17 +91,17 @@ RSpec.describe Metasploit::Credential::Exporter::Pwdump do
|
|
89
91
|
end
|
90
92
|
|
91
93
|
it 'should have the proper formatting with extant data' do
|
92
|
-
|
94
|
+
exporter.format_postgres_md5(login).should == "#{login.core.public.username}:#{login.core.private.data}"
|
93
95
|
end
|
94
96
|
|
95
97
|
it 'should have the proper formatting with a missing public' do
|
96
98
|
login.core.public.username = ""
|
97
|
-
|
99
|
+
exporter.format_postgres_md5(login).should == "#{Metasploit::Credential::Exporter::Pwdump::BLANK_CRED_STRING}:#{login.core.private.data}"
|
98
100
|
end
|
99
101
|
|
100
102
|
it 'should have the proper formatting with a missing private' do
|
101
103
|
login.core.private.data = ""
|
102
|
-
|
104
|
+
exporter.format_postgres_md5(login).should == "#{login.core.public.username}:#{Metasploit::Credential::Exporter::Pwdump::BLANK_CRED_STRING}"
|
103
105
|
end
|
104
106
|
|
105
107
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Metasploit::Credential::Importer::Core do
|
2
4
|
include_context 'Mdm::Workspace'
|
3
5
|
let(:workspace){FactoryGirl.create(:mdm_workspace)}
|
4
6
|
|
@@ -17,7 +19,7 @@ RSpec.describe Metasploit::Credential::Importer::Core do
|
|
17
19
|
core_csv_importer.private_credential_type = "Metasploit::Credential::Password"
|
18
20
|
end
|
19
21
|
|
20
|
-
it {
|
22
|
+
it { should be_valid }
|
21
23
|
end
|
22
24
|
|
23
25
|
describe "with a non-supported credential type" do
|
@@ -34,7 +36,7 @@ RSpec.describe Metasploit::Credential::Importer::Core do
|
|
34
36
|
|
35
37
|
it 'should report the error being invalid private type' do
|
36
38
|
core_csv_importer.valid?
|
37
|
-
|
39
|
+
core_csv_importer.errors[:private_credential_type].should include error
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
@@ -52,7 +54,7 @@ RSpec.describe Metasploit::Credential::Importer::Core do
|
|
52
54
|
|
53
55
|
it 'should report the error being invalid headers' do
|
54
56
|
core_csv_importer.valid?
|
55
|
-
|
57
|
+
core_csv_importer.errors[:input].should include error
|
56
58
|
end
|
57
59
|
end
|
58
60
|
end
|
@@ -60,7 +62,7 @@ RSpec.describe Metasploit::Credential::Importer::Core do
|
|
60
62
|
describe "long-form imports" do
|
61
63
|
describe "with well-formed CSV data" do
|
62
64
|
describe "with a compliant header" do
|
63
|
-
it {
|
65
|
+
it { should be_valid }
|
64
66
|
end
|
65
67
|
|
66
68
|
describe "with data that includes a missing Public (username)" do
|
@@ -125,7 +127,7 @@ RSpec.describe Metasploit::Credential::Importer::Core do
|
|
125
127
|
|
126
128
|
it 'should report the error being incorrect headers' do
|
127
129
|
core_csv_importer.valid?
|
128
|
-
|
130
|
+
core_csv_importer.errors[:input].should include error
|
129
131
|
end
|
130
132
|
end
|
131
133
|
|
@@ -138,11 +140,11 @@ RSpec.describe Metasploit::Credential::Importer::Core do
|
|
138
140
|
core_csv_importer.input = FactoryGirl.generate(:malformed_csv)
|
139
141
|
end
|
140
142
|
|
141
|
-
it {
|
143
|
+
it { should be_invalid }
|
142
144
|
|
143
145
|
it 'should report the error being malformed CSV' do
|
144
146
|
core_csv_importer.valid?
|
145
|
-
|
147
|
+
core_csv_importer.errors[:input].should include error
|
146
148
|
end
|
147
149
|
end
|
148
150
|
|
@@ -155,11 +157,11 @@ RSpec.describe Metasploit::Credential::Importer::Core do
|
|
155
157
|
core_csv_importer.input = FactoryGirl.generate(:empty_core_csv)
|
156
158
|
end
|
157
159
|
|
158
|
-
it {
|
160
|
+
it { should be_invalid }
|
159
161
|
|
160
162
|
it 'should show the proper error message' do
|
161
163
|
core_csv_importer.valid?
|
162
|
-
|
164
|
+
core_csv_importer.errors[:input].should include error
|
163
165
|
end
|
164
166
|
end
|
165
167
|
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Metasploit::Credential::Importer::Multi do
|
2
4
|
include_context 'Mdm::Workspace'
|
3
5
|
include_context 'metasploit_credential_importer_zip_file'
|
4
6
|
|
@@ -29,7 +31,7 @@ RSpec.describe Metasploit::Credential::Importer::Multi do
|
|
29
31
|
context "when given zip file" do
|
30
32
|
subject(:multi_importer){ Metasploit::Credential::Importer::Multi.new(input: File.open(supported_file), origin: import_origin)}
|
31
33
|
|
32
|
-
it {
|
34
|
+
it { should be_valid }
|
33
35
|
end
|
34
36
|
|
35
37
|
describe "#csv?" do
|
@@ -37,7 +39,7 @@ RSpec.describe Metasploit::Credential::Importer::Multi do
|
|
37
39
|
subject(:multi_importer){ Metasploit::Credential::Importer::Multi.new(input: File.open(valid_csv_file), origin: import_origin)}
|
38
40
|
|
39
41
|
it 'should return true' do
|
40
|
-
|
42
|
+
multi_importer.csv?.should be_true
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -45,7 +47,7 @@ RSpec.describe Metasploit::Credential::Importer::Multi do
|
|
45
47
|
subject(:multi_importer){ Metasploit::Credential::Importer::Multi.new(input: File.open(unsupported_file), origin: import_origin)}
|
46
48
|
|
47
49
|
it 'should return true' do
|
48
|
-
|
50
|
+
multi_importer.csv?.should be_false
|
49
51
|
end
|
50
52
|
end
|
51
53
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Metasploit::Credential::Importer::Pwdump do
|
2
4
|
include_context 'Mdm::Workspace'
|
3
5
|
|
4
6
|
let(:workspace) {FactoryGirl.create(:mdm_workspace)}
|
@@ -9,12 +11,12 @@ RSpec.describe Metasploit::Credential::Importer::Pwdump do
|
|
9
11
|
origin: origin)}
|
10
12
|
|
11
13
|
describe "validation" do
|
12
|
-
it {
|
14
|
+
it { should be_valid }
|
13
15
|
|
14
16
|
describe "without a filename" do
|
15
17
|
it 'should not be valid' do
|
16
18
|
pwdump_importer.filename = nil
|
17
|
-
|
19
|
+
pwdump_importer.should_not be_valid
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
@@ -22,32 +24,32 @@ RSpec.describe Metasploit::Credential::Importer::Pwdump do
|
|
22
24
|
describe "#blank_or_string" do
|
23
25
|
context "with a blank string" do
|
24
26
|
it 'should return empty string' do
|
25
|
-
|
27
|
+
pwdump_importer.blank_or_string("").should == ""
|
26
28
|
end
|
27
29
|
end
|
28
30
|
context "with a BLANK_CRED_STRING" do
|
29
31
|
it 'should return empty string' do
|
30
|
-
|
32
|
+
pwdump_importer.blank_or_string(Metasploit::Credential::Exporter::Pwdump::BLANK_CRED_STRING).should == ""
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
34
36
|
context "with a JTR_NO_PASSWORD_STRING" do
|
35
37
|
it 'should return empty string' do
|
36
|
-
|
38
|
+
pwdump_importer.blank_or_string(Metasploit::Credential::Importer::Pwdump::JTR_NO_PASSWORD_STRING).should == ""
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
40
42
|
context "with a present string" do
|
41
43
|
it 'should return the string' do
|
42
44
|
string = "mah-hard-passwerd"
|
43
|
-
|
45
|
+
pwdump_importer.blank_or_string(string).should == string
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
47
49
|
context "with the dehex flag" do
|
48
50
|
it 'should dehex the string with the Metasploit::Credential::Text#dehex method' do
|
49
51
|
string = "mah-hard-passwerd"
|
50
|
-
|
52
|
+
Metasploit::Credential::Text.should_receive(:dehex).with string
|
51
53
|
pwdump_importer.blank_or_string(string, true)
|
52
54
|
end
|
53
55
|
end
|
@@ -62,8 +64,8 @@ RSpec.describe Metasploit::Credential::Importer::Pwdump do
|
|
62
64
|
it 'should create Cores with the same Origin' do
|
63
65
|
pwdump_importer.import!
|
64
66
|
origins = Metasploit::Credential::Core.all.collect(&:origin).uniq
|
65
|
-
|
66
|
-
|
67
|
+
origins.size.should be(1)
|
68
|
+
origins.first.id.should be(origin.id)
|
67
69
|
end
|
68
70
|
|
69
71
|
it 'should create the proper number of Logins' do
|
@@ -94,7 +96,7 @@ RSpec.describe Metasploit::Credential::Importer::Pwdump do
|
|
94
96
|
# Legacy files may have these lines when missing SSH key files
|
95
97
|
it 'should not create a Private from a "Warning" line' do
|
96
98
|
pwdump_importer.import!
|
97
|
-
|
99
|
+
Metasploit::Credential::Private.where(data:'missing').should be_blank
|
98
100
|
end
|
99
101
|
end
|
100
102
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Metasploit::Credential::Importer::Zip do
|
2
4
|
include_context 'Mdm::Workspace'
|
3
5
|
include_context 'metasploit_credential_importer_zip_file'
|
4
6
|
|
@@ -9,7 +11,7 @@ RSpec.describe Metasploit::Credential::Importer::Zip do
|
|
9
11
|
DUMMY_ZIP_PATH = "/tmp/import-test-dummy.zip"
|
10
12
|
|
11
13
|
context "when the zip file contains a keys directory and a manifest CSV" do
|
12
|
-
it {
|
14
|
+
it { should be_valid }
|
13
15
|
end
|
14
16
|
|
15
17
|
context "when the zip file is not actually an archive" do
|
@@ -30,7 +32,7 @@ RSpec.describe Metasploit::Credential::Importer::Zip do
|
|
30
32
|
|
31
33
|
it 'should show the proper error message' do
|
32
34
|
zip_importer.valid?
|
33
|
-
|
35
|
+
zip_importer.errors[:input].should include error
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
@@ -47,7 +49,7 @@ RSpec.describe Metasploit::Credential::Importer::Zip do
|
|
47
49
|
|
48
50
|
it 'should show the proper error message' do
|
49
51
|
zip_importer.valid?
|
50
|
-
|
52
|
+
zip_importer.errors[:input].should include error
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
@@ -61,7 +63,7 @@ RSpec.describe Metasploit::Credential::Importer::Zip do
|
|
61
63
|
|
62
64
|
describe "zip constants" do
|
63
65
|
it 'should have ZIP_HEADER_IDENTIFIER whose length corresponds to ZIP_HEADER_BYTE_LENGTH' do
|
64
|
-
|
66
|
+
Metasploit::Credential::Importer::Zip::ZIP_HEADER_IDENTIFIER.size.should == Metasploit::Credential::Importer::Zip::ZIP_HEADER_BYTE_LENGTH
|
65
67
|
end
|
66
68
|
end
|
67
69
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'tempfile'
|
3
3
|
|
4
|
-
|
4
|
+
describe Metasploit::Credential::Migrator do
|
5
5
|
include_context 'Mdm::Workspace'
|
6
6
|
|
7
7
|
let(:workspace){ FactoryGirl.create(:mdm_workspace) }
|
@@ -62,9 +62,9 @@ RSpec.describe Metasploit::Credential::Migrator do
|
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should be created for each Mdm::Cred" do
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
Metasploit::Credential::Public.where(username: cred1.user).should_not be_blank
|
66
|
+
Metasploit::Credential::Public.where(username: cred2.user).should_not be_blank
|
67
|
+
Metasploit::Credential::Public.where(username: cred3.user).should_not be_blank
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -75,9 +75,9 @@ RSpec.describe Metasploit::Credential::Migrator do
|
|
75
75
|
|
76
76
|
it "should be created for each Mdm::Cred" do
|
77
77
|
migrator.convert_creds_in_workspace(workspace)
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
Metasploit::Credential::Password.where(data: cred1.pass).should_not be_blank
|
79
|
+
Metasploit::Credential::Password.where(data: cred2.pass).should_not be_blank
|
80
|
+
Metasploit::Credential::Password.where(data: cred3.pass).should_not be_blank
|
81
81
|
end
|
82
82
|
end
|
83
83
|
end
|
@@ -97,7 +97,7 @@ RSpec.describe Metasploit::Credential::Migrator do
|
|
97
97
|
end
|
98
98
|
|
99
99
|
it 'should create a new NTLMHash in the database' do
|
100
|
-
|
100
|
+
Metasploit::Credential::NTLMHash.where(data: cred.pass).should_not be_blank
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
@@ -126,7 +126,7 @@ RSpec.describe Metasploit::Credential::Migrator do
|
|
126
126
|
end
|
127
127
|
|
128
128
|
it 'should create a new SSHKey in the database' do
|
129
|
-
|
129
|
+
Metasploit::Credential::SSHKey.where(data: ssh_key_content).should_not be_blank
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
@@ -144,7 +144,7 @@ RSpec.describe Metasploit::Credential::Migrator do
|
|
144
144
|
end
|
145
145
|
|
146
146
|
it 'should create a new SSHKey in the database' do
|
147
|
-
|
147
|
+
Metasploit::Credential::SSHKey.where(data: ssh_key_content).should_not be_blank
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
@@ -162,7 +162,7 @@ RSpec.describe Metasploit::Credential::Migrator do
|
|
162
162
|
end
|
163
163
|
|
164
164
|
it 'should not create a new SSHKey in the database' do
|
165
|
-
|
165
|
+
Metasploit::Credential::SSHKey.count.should be_zero
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
@@ -182,7 +182,7 @@ RSpec.describe Metasploit::Credential::Migrator do
|
|
182
182
|
end
|
183
183
|
|
184
184
|
it 'should create a new Password in the database' do
|
185
|
-
|
185
|
+
Metasploit::Credential::Password.where(data: cred.pass).should_not be_blank
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
@@ -200,7 +200,7 @@ RSpec.describe Metasploit::Credential::Migrator do
|
|
200
200
|
end
|
201
201
|
|
202
202
|
it 'should create a new NonreplayableHash in the database' do
|
203
|
-
|
203
|
+
Metasploit::Credential::NonreplayableHash.where(data: cred.pass).should_not be_blank
|
204
204
|
end
|
205
205
|
end
|
206
206
|
end
|
@@ -1,3 +1,141 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Metasploit::Credential::Version do
|
4
|
+
context 'CONSTANTS' do
|
5
|
+
context 'MAJOR' do
|
6
|
+
subject(:major) do
|
7
|
+
described_class::MAJOR
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'is 0 because the API is not locked yet' do
|
11
|
+
expect(major).to eq(0)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'MINOR' do
|
16
|
+
subject(:minor) do
|
17
|
+
described_class::MINOR
|
18
|
+
end
|
19
|
+
|
20
|
+
it { should be_a Integer }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'PATCH' do
|
24
|
+
subject(:patch) do
|
25
|
+
described_class::PATCH
|
26
|
+
end
|
27
|
+
|
28
|
+
it { should be_a Integer }
|
29
|
+
end
|
30
|
+
|
31
|
+
pull_request = ENV['TRAVIS_PULL_REQUEST']
|
32
|
+
|
33
|
+
# a pull request cannot check PRERELEASE because it will be tested in the target branch, but the source itself
|
34
|
+
# is from the source branch and so has the source branch PRERELEASE.
|
35
|
+
#
|
36
|
+
# PRERELEASE can only be set appropriately for a merge by merging to the target branch and then updating PRERELEASE
|
37
|
+
# on the target branch before committing and/or pushing to github and travis-ci.
|
38
|
+
if pull_request.nil? || pull_request == 'false'
|
39
|
+
context 'PREPRELEASE' do
|
40
|
+
subject(:prerelease) do
|
41
|
+
described_class::PRERELEASE
|
42
|
+
end
|
43
|
+
|
44
|
+
branch = ENV['TRAVIS_BRANCH']
|
45
|
+
|
46
|
+
if branch.blank?
|
47
|
+
branch = `git rev-parse --abbrev-ref HEAD`.strip
|
48
|
+
end
|
49
|
+
|
50
|
+
if branch == 'master'
|
51
|
+
it 'does not have a PRERELEASE' do
|
52
|
+
expect(defined? described_class::PRERELEASE).to be_nil
|
53
|
+
end
|
54
|
+
else
|
55
|
+
branch_regex = %r{\A(?:refs/remotes/)?(?<type>bug|chore|feature|staging)(/(?<story>[^/]+))?/(?<prerelease>[^\/]+)\z}
|
56
|
+
match = branch.match(branch_regex)
|
57
|
+
|
58
|
+
if match
|
59
|
+
it 'matches the branch relative name' do
|
60
|
+
expect(prerelease).to eq(match[:prerelease])
|
61
|
+
end
|
62
|
+
else
|
63
|
+
tag_regex = /\Av(?<major>\d+).(?<minor>\d+).(?<patch>\d+)(\.pre\.(?<prerelease>.*))?\z/
|
64
|
+
# travis-ci sets TRAVIS_BRANCH to the tag name for tag builds
|
65
|
+
match = branch.match(tag_regex)
|
66
|
+
|
67
|
+
if match
|
68
|
+
tag_prerelease = match[:prerelease]
|
69
|
+
|
70
|
+
if tag_prerelease
|
71
|
+
it 'matches the tag prerelease converted from a gem version to a VERSION' do
|
72
|
+
expect(prerelease).to eq(tag_prerelease.gsub('.pre.', '-'))
|
73
|
+
end
|
74
|
+
else
|
75
|
+
it 'does not have a PRERELEASE' do
|
76
|
+
expect(defined? described_class::PRERELEASE).to be_nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
else
|
80
|
+
it 'has a abbreviated reference that can be parsed for prerelease' do
|
81
|
+
fail "Do not know how to parse #{branch.inspect} for PRERELEASE"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'full' do
|
91
|
+
subject(:full) do
|
92
|
+
described_class.full
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# lets
|
97
|
+
#
|
98
|
+
|
99
|
+
let(:major) do
|
100
|
+
1
|
101
|
+
end
|
102
|
+
|
103
|
+
let(:minor) do
|
104
|
+
2
|
105
|
+
end
|
106
|
+
|
107
|
+
let(:patch) do
|
108
|
+
3
|
109
|
+
end
|
110
|
+
|
111
|
+
before(:each) do
|
112
|
+
stub_const("#{described_class}::MAJOR", major)
|
113
|
+
stub_const("#{described_class}::MINOR", minor)
|
114
|
+
stub_const("#{described_class}::PATCH", patch)
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'with PRERELEASE' do
|
118
|
+
let(:prerelease) do
|
119
|
+
'prerelease'
|
120
|
+
end
|
121
|
+
|
122
|
+
before(:each) do
|
123
|
+
stub_const("#{described_class}::PRERELEASE", prerelease)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'is <major>.<minor>.<patch>-<prerelease>' do
|
127
|
+
expect(full).to eq("#{major}.#{minor}.#{patch}-#{prerelease}")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'without PRERELEASE' do
|
132
|
+
before(:each) do
|
133
|
+
hide_const("#{described_class}::PRERELEASE")
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'is <major>.<minor>.<patch>' do
|
137
|
+
expect(full).to eq("#{major}.#{minor}.#{patch}")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|