metasploit_data_models 0.18.1 → 0.19.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -3,6 +3,28 @@ require 'spec_helper'
|
|
3
3
|
describe Mdm::Service do
|
4
4
|
it_should_behave_like 'Metasploit::Concern.run'
|
5
5
|
|
6
|
+
context 'CONSTANTS' do
|
7
|
+
context 'PROTOS' do
|
8
|
+
subject(:protos) {
|
9
|
+
described_class::PROTOS
|
10
|
+
}
|
11
|
+
|
12
|
+
it { should include 'tcp' }
|
13
|
+
it { should include 'udp' }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'STATES' do
|
17
|
+
subject(:states) {
|
18
|
+
described_class::STATES
|
19
|
+
}
|
20
|
+
|
21
|
+
it { should include 'closed' }
|
22
|
+
it { should include 'filtered' }
|
23
|
+
it { should include 'open' }
|
24
|
+
it { should include 'unknown' }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
6
28
|
context "Associations" do
|
7
29
|
|
8
30
|
it { should have_many(:task_services).class_name('Mdm::TaskService').dependent(:destroy) }
|
@@ -33,13 +55,13 @@ describe Mdm::Service do
|
|
33
55
|
end
|
34
56
|
end
|
35
57
|
|
36
|
-
context "search for '
|
58
|
+
context "search for 'tcp'" do
|
37
59
|
it "should find only services that match" do
|
38
|
-
|
39
|
-
|
40
|
-
search_results = Mdm::Service.search('
|
41
|
-
search_results.should include(
|
42
|
-
search_results.should_not include(
|
60
|
+
tcp_service = FactoryGirl.create(:mdm_service, proto: 'tcp')
|
61
|
+
udp_service = FactoryGirl.create(:mdm_service, proto: 'udp')
|
62
|
+
search_results = Mdm::Service.search('tcp')
|
63
|
+
search_results.should include(tcp_service)
|
64
|
+
search_results.should_not include(udp_service)
|
43
65
|
end
|
44
66
|
end
|
45
67
|
end
|
@@ -98,44 +120,11 @@ describe Mdm::Service do
|
|
98
120
|
end
|
99
121
|
|
100
122
|
context "validations" do
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
mdm_service
|
105
|
-
end
|
106
|
-
|
107
|
-
context "invalid" do
|
108
|
-
it "should validate presence of :port" do
|
109
|
-
mdm_service.port = nil
|
110
|
-
mdm_service.valid?
|
111
|
-
mdm_service.errors[:port][0].should include "is not a number"
|
112
|
-
end
|
123
|
+
subject(:mdm_service) {
|
124
|
+
FactoryGirl.build(:mdm_service)
|
125
|
+
}
|
113
126
|
|
114
|
-
|
115
|
-
|
116
|
-
mdm_service.valid?
|
117
|
-
mdm_service.errors[:proto][0].should include "can't be blank"
|
118
|
-
end
|
119
|
-
|
120
|
-
it "should not allow non-numeric value for port" do
|
121
|
-
mdm_service.port = Faker::Lorem.characters(4)
|
122
|
-
mdm_service.valid?
|
123
|
-
mdm_service.errors[:port][0].should include "is not a number"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
context "valid" do
|
128
|
-
it "should allow numeric value for port" do
|
129
|
-
mdm_service.port = Faker::Number.number(4)
|
130
|
-
mdm_service.valid?
|
131
|
-
mdm_service.should have(0).errors_on(:port)
|
132
|
-
end
|
133
|
-
|
134
|
-
it "should allow proto" do
|
135
|
-
mdm_service.proto = "tcp"
|
136
|
-
mdm_service.valid?
|
137
|
-
mdm_service.should have(0).errors_on(:proto)
|
138
|
-
end
|
139
|
-
end
|
127
|
+
it { should validate_numericality_of(:port).only_integer }
|
128
|
+
it { should ensure_inclusion_of(:proto).in_array(described_class::PROTOS) }
|
140
129
|
end
|
141
130
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::IPAddress::V4::CIDR do
|
4
|
+
subject(:cidr) {
|
5
|
+
described_class.new(
|
6
|
+
value: formatted_value
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
let(:formatted_value) {
|
11
|
+
nil
|
12
|
+
}
|
13
|
+
|
14
|
+
it { should be_a MetasploitDataModels::IPAddress::CIDR }
|
15
|
+
|
16
|
+
context 'address_class' do
|
17
|
+
subject(:address_class) {
|
18
|
+
described_class.address_class
|
19
|
+
}
|
20
|
+
|
21
|
+
it { should == MetasploitDataModels::IPAddress::V4::Single }
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'validations' do
|
25
|
+
let(:formatted_address) {
|
26
|
+
'1.2.3.4'
|
27
|
+
}
|
28
|
+
|
29
|
+
context 'with IPv4 CIDR notation' do
|
30
|
+
let(:formatted_prefix_length) {
|
31
|
+
'8'
|
32
|
+
}
|
33
|
+
|
34
|
+
let(:formatted_value) {
|
35
|
+
"#{formatted_address}/#{formatted_prefix_length}"
|
36
|
+
}
|
37
|
+
|
38
|
+
it { should be_valid }
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with IPv4 address' do
|
42
|
+
let(:formatted_value) {
|
43
|
+
formatted_address
|
44
|
+
}
|
45
|
+
|
46
|
+
it { should_not be_valid }
|
47
|
+
|
48
|
+
context 'errors' do
|
49
|
+
before(:each) do
|
50
|
+
cidr.valid?
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'on #address' do
|
54
|
+
subject(:address_errors) {
|
55
|
+
cidr.errors[:address]
|
56
|
+
}
|
57
|
+
|
58
|
+
it { should be_empty }
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'on #prefix_length' do
|
62
|
+
subject(:prefix_length_errors) {
|
63
|
+
cidr.errors[:prefix_length]
|
64
|
+
}
|
65
|
+
|
66
|
+
let(:blank_error) {
|
67
|
+
I18n.translate!('errors.messages.not_a_number')
|
68
|
+
}
|
69
|
+
|
70
|
+
it { should include(blank_error) }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'with IPv6 CIDR notation' do
|
76
|
+
let(:formatted_value) {
|
77
|
+
"#{formatted_address}/#{formatted_prefix_length}"
|
78
|
+
}
|
79
|
+
|
80
|
+
let(:formatted_address) {
|
81
|
+
'::1'
|
82
|
+
}
|
83
|
+
|
84
|
+
let(:formatted_prefix_length) {
|
85
|
+
'48'
|
86
|
+
}
|
87
|
+
|
88
|
+
it { should_not be_valid }
|
89
|
+
|
90
|
+
context 'errors' do
|
91
|
+
before(:each) do
|
92
|
+
cidr.valid?
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'on #address' do
|
96
|
+
subject(:address_errors) {
|
97
|
+
cidr.errors[:address]
|
98
|
+
}
|
99
|
+
|
100
|
+
let(:invalid_error) {
|
101
|
+
I18n.translate!('errors.messages.invalid')
|
102
|
+
}
|
103
|
+
|
104
|
+
it { should include(invalid_error) }
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'on #prefix_length' do
|
108
|
+
subject(:prefix_length_errors) {
|
109
|
+
cidr.errors[:prefix_length]
|
110
|
+
}
|
111
|
+
|
112
|
+
let(:too_big_error) {
|
113
|
+
I18n.translate!('errors.messages.less_than_or_equal_to', count: 32)
|
114
|
+
}
|
115
|
+
|
116
|
+
it { should include(too_big_error) }
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::IPAddress::V4::Nmap do
|
4
|
+
subject(:nmap) {
|
5
|
+
described_class.new(
|
6
|
+
value: formatted_value
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
context 'validation' do
|
11
|
+
before(:each) do
|
12
|
+
nmap.valid?
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'errors on #segments' do
|
16
|
+
subject(:segments_errors) {
|
17
|
+
nmap.errors[:segments]
|
18
|
+
}
|
19
|
+
|
20
|
+
context 'with segments' do
|
21
|
+
context 'with invalid segment' do
|
22
|
+
let(:error) {
|
23
|
+
I18n.translate!(
|
24
|
+
'metasploit.model.errors.models.metasploit_data_models/ip_address/v4/segmented.attributes.segments.segment_invalid',
|
25
|
+
index: 0,
|
26
|
+
segment: '5-4'
|
27
|
+
)
|
28
|
+
}
|
29
|
+
|
30
|
+
let(:formatted_value) {
|
31
|
+
'5-4.3.2.1'
|
32
|
+
}
|
33
|
+
|
34
|
+
it 'should include index of segment and segment value in the error' do
|
35
|
+
expect(segments_errors).to include(error)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with valid segments' do
|
40
|
+
let(:formatted_value) {
|
41
|
+
'1.2.3.4'
|
42
|
+
}
|
43
|
+
|
44
|
+
it { should be_empty }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'without segments' do
|
49
|
+
let(:formatted_value) {
|
50
|
+
'::1'
|
51
|
+
}
|
52
|
+
|
53
|
+
let(:length_error) {
|
54
|
+
I18n.translate!(
|
55
|
+
'metasploit.model.errors.models.metasploit_data_models/ip_address/v4/segmented.attributes.segments.wrong_length',
|
56
|
+
count: 4
|
57
|
+
)
|
58
|
+
}
|
59
|
+
|
60
|
+
it { should include length_error }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'regexp' do
|
66
|
+
subject(:regexp) {
|
67
|
+
described_class.regexp
|
68
|
+
}
|
69
|
+
|
70
|
+
it 'matches a normal IPv4 address because they are a generate form of Nmap format' do
|
71
|
+
expect(regexp).to match_string_exactly('1.2.3.4')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'matches an IPv4 Nmap address with comma separated list of numbers and ranges for each segment' do
|
75
|
+
expect(regexp).to match_string_exactly('1,2-3.4-5,6.7,8.9-10,11-12')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context '#value' do
|
80
|
+
subject(:value) {
|
81
|
+
nmap.value
|
82
|
+
}
|
83
|
+
|
84
|
+
context 'with nil' do
|
85
|
+
let(:formatted_value) {
|
86
|
+
nil
|
87
|
+
}
|
88
|
+
|
89
|
+
it { should be_nil }
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'with matching formatted value' do
|
93
|
+
let(:formatted_value) {
|
94
|
+
'1.2-3.4,5-6.7-8,9'
|
95
|
+
}
|
96
|
+
|
97
|
+
it 'has 4 segments' do
|
98
|
+
expect(value.length).to eq(4)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'has MetasploitDataModels::IPAddress::V4::Segment::Nmap::List for segments' do
|
102
|
+
expect(
|
103
|
+
value.all? { |segment|
|
104
|
+
segment.is_a? MetasploitDataModels::IPAddress::V4::Segment::Nmap::List
|
105
|
+
}
|
106
|
+
).to eq(true)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'has segments ordered from high to low' do
|
110
|
+
highest_segment = value[0]
|
111
|
+
|
112
|
+
expect(highest_segment.value[0]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Single
|
113
|
+
expect(highest_segment.value[0].value).to eq(1)
|
114
|
+
|
115
|
+
high_middle_segment = value[1]
|
116
|
+
|
117
|
+
expect(high_middle_segment.value[0]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Nmap::Range
|
118
|
+
expect(high_middle_segment.value[0].begin.value).to eq(2)
|
119
|
+
expect(high_middle_segment.value[0].end.value).to eq(3)
|
120
|
+
|
121
|
+
low_middle_segment = value[2]
|
122
|
+
|
123
|
+
expect(low_middle_segment.value[0]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Single
|
124
|
+
expect(low_middle_segment.value[0].value).to eq(4)
|
125
|
+
|
126
|
+
expect(low_middle_segment.value[1]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Nmap::Range
|
127
|
+
expect(low_middle_segment.value[1].begin.value).to eq(5)
|
128
|
+
expect(low_middle_segment.value[1].end.value).to eq(6)
|
129
|
+
|
130
|
+
low_segment = value[3]
|
131
|
+
|
132
|
+
expect(low_segment.value[0]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Nmap::Range
|
133
|
+
expect(low_segment.value[0].begin.value).to eq(7)
|
134
|
+
expect(low_segment.value[0].end.value).to eq(8)
|
135
|
+
|
136
|
+
expect(low_segment.value[1]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Single
|
137
|
+
expect(low_segment.value[1].value).to eq(9)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'without matching formatted value' do
|
142
|
+
let(:formatted_value) {
|
143
|
+
'::1'
|
144
|
+
}
|
145
|
+
|
146
|
+
it 'is the formated value' do
|
147
|
+
expect(value).to eq(formatted_value)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,300 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::IPAddress::V4::Range do
|
4
|
+
subject(:range) {
|
5
|
+
described_class.new(
|
6
|
+
value: formatted_value
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
#
|
11
|
+
# lets
|
12
|
+
#
|
13
|
+
|
14
|
+
let(:formatted_value) {
|
15
|
+
nil
|
16
|
+
}
|
17
|
+
|
18
|
+
context 'validations' do
|
19
|
+
#
|
20
|
+
# lets
|
21
|
+
#
|
22
|
+
|
23
|
+
let(:presence_error) {
|
24
|
+
I18n.translate!('errors.messages.blank')
|
25
|
+
}
|
26
|
+
|
27
|
+
let(:invalid_error) {
|
28
|
+
I18n.translate!('errors.messages.invalid')
|
29
|
+
}
|
30
|
+
|
31
|
+
#
|
32
|
+
# Callbacks
|
33
|
+
#
|
34
|
+
|
35
|
+
before(:each) do
|
36
|
+
range.valid?
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'errors on #begin' do
|
40
|
+
subject(:begin_errors) {
|
41
|
+
range.errors[:begin]
|
42
|
+
}
|
43
|
+
|
44
|
+
context '#begin' do
|
45
|
+
context 'with nil' do
|
46
|
+
let(:formatted_value) {
|
47
|
+
nil
|
48
|
+
}
|
49
|
+
|
50
|
+
it { should include presence_error }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'with MetasploitDataModels::IPAddress::V4::Single' do
|
54
|
+
context 'with valid' do
|
55
|
+
let(:formatted_value) {
|
56
|
+
'1.1.1.1-256.256.256.256'
|
57
|
+
}
|
58
|
+
|
59
|
+
it { should_not include invalid_error }
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'without valid' do
|
63
|
+
let(:formatted_value) {
|
64
|
+
'256.256.256.256-257.257.257.257'
|
65
|
+
}
|
66
|
+
|
67
|
+
it { should include invalid_error }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'errors on #end' do
|
74
|
+
subject(:end_errors) {
|
75
|
+
range.errors[:end]
|
76
|
+
}
|
77
|
+
|
78
|
+
context '#end' do
|
79
|
+
context 'with nil' do
|
80
|
+
let(:formatted_value) {
|
81
|
+
nil
|
82
|
+
}
|
83
|
+
|
84
|
+
it { should include presence_error }
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'with MetasploitDataModels::IPAddress::V4::Single' do
|
88
|
+
context 'with valid' do
|
89
|
+
let(:formatted_value) {
|
90
|
+
'256.256.256.256-1.1.1.1'
|
91
|
+
}
|
92
|
+
|
93
|
+
it { should_not include invalid_error }
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'without valid' do
|
97
|
+
let(:formatted_value) {
|
98
|
+
'257.257.257.257-256.256.256.256'
|
99
|
+
}
|
100
|
+
|
101
|
+
it { should include invalid_error }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'errors on #value' do
|
108
|
+
subject(:value_errors) {
|
109
|
+
range.errors[:value]
|
110
|
+
}
|
111
|
+
|
112
|
+
let(:error) {
|
113
|
+
I18n.translate!(
|
114
|
+
'metasploit.model.errors.models.metasploit_data_models/ip_address/range.attributes.value.order',
|
115
|
+
begin: range.begin,
|
116
|
+
end: range.end
|
117
|
+
)
|
118
|
+
}
|
119
|
+
|
120
|
+
context 'with nil' do
|
121
|
+
let(:formatted_value) {
|
122
|
+
nil
|
123
|
+
}
|
124
|
+
|
125
|
+
it { should_not include error }
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'with incomparables' do
|
129
|
+
let(:formatted_value) {
|
130
|
+
'a-1'
|
131
|
+
}
|
132
|
+
|
133
|
+
it { should_not include error }
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'with numbers' do
|
137
|
+
context 'in order' do
|
138
|
+
let(:formatted_value) {
|
139
|
+
'1.1.1.1-2.2.2.2'
|
140
|
+
}
|
141
|
+
|
142
|
+
it { should_not include error }
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'out of order' do
|
146
|
+
let(:formatted_value) {
|
147
|
+
'2.2.2.2-1.1.1.1'
|
148
|
+
}
|
149
|
+
|
150
|
+
it { should include error }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'match_regexp' do
|
157
|
+
subject(:match_regexp) do
|
158
|
+
described_class::match_regexp
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'matches range exactly' do
|
162
|
+
expect(match_regexp).to match_string_exactly('1.1.1.1-255.255.255.255')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'regexp' do
|
167
|
+
subject(:regexp) {
|
168
|
+
described_class::regexp
|
169
|
+
}
|
170
|
+
|
171
|
+
it 'does not match a single IPv4 address' do
|
172
|
+
expect(regexp).not_to match('255.255.255.255')
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'does not match separator by itself' do
|
176
|
+
expect(regexp).not_to match('-')
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'does not match range with only one extreme' do
|
180
|
+
expect(regexp).not_to match('1.1.1.1-')
|
181
|
+
expect(regexp).not_to match('-255.255.255.255')
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'matches range' do
|
185
|
+
expect(regexp).to match_string_exactly('1.1.1.1-255.255.255.255')
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context '#to_s' do
|
190
|
+
subject(:to_s) {
|
191
|
+
range.to_s
|
192
|
+
}
|
193
|
+
|
194
|
+
context 'with Range' do
|
195
|
+
let(:formatted_value) {
|
196
|
+
'1.1.1.1-2.2.2.2'
|
197
|
+
}
|
198
|
+
|
199
|
+
it 'equals the original formatted value' do
|
200
|
+
expect(to_s).to eq(formatted_value)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'without Range' do
|
205
|
+
let(:formatted_value) {
|
206
|
+
'1..2'
|
207
|
+
}
|
208
|
+
|
209
|
+
it { should == '-' }
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context '#value' do
|
214
|
+
subject(:value) {
|
215
|
+
range.value
|
216
|
+
}
|
217
|
+
|
218
|
+
context 'with -' do
|
219
|
+
context 'with extremes' do
|
220
|
+
let(:formatted_value) {
|
221
|
+
'1.1.1.1-2.2.2.2'
|
222
|
+
}
|
223
|
+
|
224
|
+
it { should be_a Range }
|
225
|
+
|
226
|
+
context 'Range#begin' do
|
227
|
+
subject(:range_begin) {
|
228
|
+
value.begin
|
229
|
+
}
|
230
|
+
|
231
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Single }
|
232
|
+
|
233
|
+
it "is value before '-'" do
|
234
|
+
expect(range_begin).to eq(MetasploitDataModels::IPAddress::V4::Single.new(value: '1.1.1.1'))
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context 'Range#end' do
|
239
|
+
subject(:range_end) {
|
240
|
+
value.end
|
241
|
+
}
|
242
|
+
|
243
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Single }
|
244
|
+
|
245
|
+
it "is value after '-'" do
|
246
|
+
expect(range_end).to eq(MetasploitDataModels::IPAddress::V4::Single.new(value: '2.2.2.2'))
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context 'without extremes' do
|
252
|
+
let(:formatted_value) {
|
253
|
+
'-'
|
254
|
+
}
|
255
|
+
|
256
|
+
it { should be_a Range }
|
257
|
+
|
258
|
+
context 'Range#begin' do
|
259
|
+
subject(:range_begin) {
|
260
|
+
value.begin
|
261
|
+
}
|
262
|
+
|
263
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Single }
|
264
|
+
|
265
|
+
context 'MetasploitDataModels::IPAddress::V4::Single#value' do
|
266
|
+
subject(:begin_value) {
|
267
|
+
range_begin.value
|
268
|
+
}
|
269
|
+
|
270
|
+
it { should == '' }
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
context 'Range#end' do
|
275
|
+
subject(:range_end) {
|
276
|
+
value.end
|
277
|
+
}
|
278
|
+
|
279
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Single }
|
280
|
+
|
281
|
+
context 'MetasploitDataModels::IPAddress::V4::Single#value' do
|
282
|
+
subject(:end_value) {
|
283
|
+
range_end.value
|
284
|
+
}
|
285
|
+
|
286
|
+
it { should == '' }
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
context 'without -' do
|
293
|
+
let(:formatted_value) do
|
294
|
+
'1'
|
295
|
+
end
|
296
|
+
|
297
|
+
it { should_not be_a Range }
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|