scabox_sdk 1.0.0 → 1.0.1.pre.rc.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8c80dcf7f5f6a7347e69ce67fed3e010384b30eae97bf1dc4be4c3c10e799bf
4
- data.tar.gz: 506708f0c1f04c91f4d629cfbfc7bdc5cf08581cec840bcd8ef9e32e2067728f
3
+ metadata.gz: a5290735bdf05ded68ae369b9599e308390a6fdca9defd8f0fb03618dc3b3bb9
4
+ data.tar.gz: 99f6c2594b03415cdf1f44c688d00bbfc81d5b4d576fd9c06ae898ffdcd8004c
5
5
  SHA512:
6
- metadata.gz: e8452b4ea6ee804868721b994219fc51910359ef9c91c98579ab62737c2278e4d74ac5d09f6d48041c777a0dce8e8696cad65d5695d81e621d17b49b8c1cd085
7
- data.tar.gz: 53e2726f1f657d862c417fcc460937854cb3d5dee97483240730ade740a04f2e73c2ed5ac4a6a6ce32ed8226b3e43d467167271204b9f37ae65ebf755183400f
6
+ metadata.gz: 35e54954d882951c9dae143b096ed1ae0e5112326bb21913da6a581da5d52d9188dfd88446cea01450a4ae07750c01dacde6cc6541383c7c5b7b92e61b0e2896
7
+ data.tar.gz: 1d5e9dd00638ad27164c72343df57edb77373066646ba6bcc324f02b47a99c65110f14ec52fc4e2e454db556720873de61782ec0d779d833649cfccb53b4dc33
@@ -29,6 +29,7 @@ module ScaBox
29
29
  @opts.verbose = false
30
30
  @opts.info = false
31
31
  @opts.color = true
32
+ @opts.output_stdout = false
32
33
 
33
34
  opt_parser = OptionParser.new do |opts|
34
35
  opts.on('-c', '--codebase=CODEBASE', 'Codebase to be scanned') do |codebase|
@@ -43,6 +44,10 @@ module ScaBox
43
44
  @opts.output = output
44
45
  end
45
46
 
47
+ opts.on('--output-stdout', 'Print result to stdout') do
48
+ @opts.output_stdout = true
49
+ end
50
+
46
51
  opts.on("-v", '--[no-]verbose', 'Run verbosely') do |v|
47
52
  @opts.verbose = v
48
53
  end
@@ -31,6 +31,8 @@ module ScaBox
31
31
  @opts.verbose = false
32
32
  @opts.info = false
33
33
  @opts.color = true
34
+ @opts.output_stdout = false
35
+
34
36
 
35
37
  opt_parser = OptionParser.new do |opts|
36
38
  opts.on('-n', '--image-name=IMAGE_NAME', 'Name of image to be scanned') do |image_name|
@@ -49,6 +51,10 @@ module ScaBox
49
51
  @opts.output = output
50
52
  end
51
53
 
54
+ opts.on('--output-stdout', 'Print result to stdout') do
55
+ @opts.output_stdout = true
56
+ end
57
+
52
58
  opts.on("-v", '--[no-]verbose', 'Run verbosely') do |v|
53
59
  @opts.verbose = v
54
60
  end
@@ -8,7 +8,12 @@ module ScaBox
8
8
  @color = flag
9
9
  end
10
10
 
11
+ def suppress_output?
12
+ @opts.output_stdout
13
+ end
14
+
11
15
  def print_title(s, level = 0)
16
+ return if suppress_output?
12
17
  pad = " " * (level * 4)
13
18
  out_s = "#{pad}[*] #{s}"
14
19
  if @color
@@ -20,6 +25,7 @@ module ScaBox
20
25
  end
21
26
 
22
27
  def print_normal(s, level = 0)
28
+ return if suppress_output?
23
29
  pad = " " * (level * 4)
24
30
  out_s = "#{pad}#{s}"
25
31
  puts out_s
@@ -27,6 +33,7 @@ module ScaBox
27
33
  end
28
34
 
29
35
  def print_success(s, level = 0)
36
+ return if suppress_output?
30
37
  pad = " " * (level * 4)
31
38
  out_s = "#{pad}[SUCCESS] #{s}"
32
39
  if @color
@@ -38,6 +45,7 @@ module ScaBox
38
45
  end
39
46
 
40
47
  def print_error(s, level = 0)
48
+ return if suppress_output?
41
49
  pad = " " * (level * 4)
42
50
  out_s = "#{pad}[ ERROR ] #{s}"
43
51
  if @color
@@ -49,6 +57,7 @@ module ScaBox
49
57
  end
50
58
 
51
59
  def print_with_label(s, label, level = 0)
60
+ return if suppress_output?
52
61
  pad = " " * (level * 4)
53
62
  out_s = "#{pad}[#{label}] #{s}"
54
63
  puts out_s
@@ -56,6 +65,7 @@ module ScaBox
56
65
  end
57
66
 
58
67
  def print_debug(s, level = 0)
68
+ return if suppress_output?
59
69
  pad = " " * (level * 4)
60
70
  now = DateTime.now.strftime('%d/%m/%Y %H:%M:%S.%3N')
61
71
  out_s = "#{pad}DEBUG|#{now}| #{s}"
@@ -32,8 +32,8 @@ module ScaBox
32
32
  end
33
33
 
34
34
  def check_output_flag
35
- if @opts.output.nil?
36
- print_error("Output -o not passed")
35
+ if @opts.output.nil? and @opts.output_stdout == false
36
+ print_error("Neither -o nor --output-stdout passed")
37
37
  exit 1
38
38
  end
39
39
  end
@@ -98,16 +98,51 @@ module ScaBox
98
98
  title
99
99
  end
100
100
 
101
+ def get_code_version
102
+ code_version = []
103
+ Dir.chdir @opts.codebase do
104
+ # git show-ref --head --heads --tags | grep $(git rev-parse HEAD)
105
+ stdout_str, stderr_str, status = Open3.capture3('/usr/bin/git', 'rev-parse', 'HEAD')
106
+ return code_version if stderr_str.include? 'fatal' || status != 0
107
+
108
+ head_hash = stdout_str.chomp
109
+
110
+ stdout_str, status = Open3.capture2('/usr/bin/git', 'show-ref', '--head', '--heads', '--tags')
111
+ return code_version if status != 0
112
+
113
+ stdout_str.each_line do |line|
114
+ line = line.chomp
115
+
116
+ if line.include? head_hash
117
+ code_version << line
118
+ end
119
+ end
120
+ end
121
+ code_version
122
+ end
123
+
101
124
  def save_results
102
125
  print_normal("Issues found: #{@issues.length}")
103
126
  unless @issues.empty?
104
127
  if @opts.format == :json
105
- output = JSON.pretty_generate(@issues)
128
+ code_version = []
129
+ code_version = get_code_version unless @opts.codebase.nil?
130
+
131
+ json_output = {'type': 'sca', 'code_version': code_version, 'issues': @issues}
132
+ output = JSON.pretty_generate(json_output)
106
133
  else
107
134
  output = txt_output
108
135
  end
109
- File.open(@opts.output, 'wb') {|file| file.write(output) }
110
- print_normal("Output saved: #{@opts.output}")
136
+
137
+ if (!@opts.output.nil?)
138
+ File.open(@opts.output, 'wb') {|file| file.write(output) }
139
+ print_normal("Output saved: #{@opts.output}")
140
+ end
141
+
142
+ if (@opts.output_stdout)
143
+ puts output
144
+ end
145
+
111
146
  end
112
147
  end
113
148
 
@@ -0,0 +1,74 @@
1
+ require_relative '../spec_helper'
2
+ require_relative '../../lib/scabox_sdk'
3
+
4
+ RSpec.describe 'Codebase' do
5
+ describe 'parse_opts' do
6
+ context 'should parse all the provided options' do
7
+ let(:scanner) { ScaBox::CodebaseScanner.new(name: 'test', description: 'test', support: []) }
8
+ subject { scanner.parse_opts(['-c', 'codebase', '-f', 'json', '-o', 'outputfile', '-v']) }
9
+
10
+ it 'codebase - is expected to eq "codebase"' do
11
+ expect(subject.codebase).to eq 'codebase'
12
+ end
13
+
14
+ it "format - is expected to eq :json" do
15
+ expect(subject.format).to eq :json
16
+ end
17
+
18
+ it "output - is expected to eq outputfile" do
19
+ expect(subject.output).to eq 'outputfile'
20
+ end
21
+
22
+ it "verbose - is expected to equal true" do
23
+ expect(subject.verbose).to be true
24
+ end
25
+
26
+ it "info - is expected to eq false" do
27
+ expect(subject.info).to be false
28
+ end
29
+
30
+ it "color - is expected to equal true" do
31
+ expect(subject.color).to be true
32
+ end
33
+ end
34
+ end
35
+
36
+ describe 'run' do
37
+ context 'should fail when codebase is not provided' do
38
+ let(:scanner) { ScaBox::CodebaseScanner.new(name: 'test', description: 'test', support: []) }
39
+ before do
40
+ scanner.parse_opts([])
41
+ end
42
+
43
+ it do
44
+ expect { scanner.run }.to raise_error(SystemExit) do |error|
45
+ expect( error.status ).to eq(1)
46
+ end
47
+ end
48
+ it do
49
+ expect { scanner.run }.to raise_error(SystemExit) do |error|
50
+ expect( error.message ).to eq('exit')
51
+ end
52
+ end
53
+ end
54
+
55
+ context 'should raise name error for prepare_command method when correct options are provided' do
56
+ let(:scanner) { ScaBox::CodebaseScanner.new(name: 'test', description: 'test', support: []) }
57
+ let(:report) { '/tmp/codebasescanner_output.json' }
58
+
59
+ before do
60
+ File.delete(report) if File.exist?(report)
61
+
62
+ $VERBOSE = nil
63
+ ARGV = ['-c', 'codebase', '-f', 'json', '-o', report, '-v']
64
+ end
65
+
66
+ it "should raise name error for prepare_command method when correct options are provided" do
67
+ expect { scanner.run }.to raise_error(NameError) do |error| # #<NameError: undefined local variable or method `prepare_command' for #<ScaBox::CodebaseScanner:0x00005616ee3fab00>>
68
+ expect( error.message ).to match(/undefined.*prepare_command/)
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,79 @@
1
+ require_relative '../spec_helper'
2
+ require_relative '../../lib/scabox_sdk'
3
+
4
+ RSpec.describe 'Container' do
5
+ describe 'parse_opts' do
6
+ context 'should parse all the provided options' do
7
+ let(:scanner) { ScaBox::ContainerScanner.new(name: 'test', description: 'test', support: []) }
8
+ subject { scanner.parse_opts(['-n', 'imagename', '-p', 'imagefile', '-f', 'json', '-o', 'outputfile', '-v']) }
9
+
10
+ it "image_name - is expected to equal imagename" do
11
+ expect(subject.image_name).to eq 'imagename'
12
+ end
13
+
14
+ it "image_file - is expected to equal imagefile" do
15
+ expect(subject.image_file).to eq 'imagefile'
16
+ end
17
+
18
+ it "format - is expected to eq :json" do
19
+ expect(subject.format).to eq :json
20
+ end
21
+
22
+ it "output - is expected to eq outputfile" do
23
+ expect(subject.output).to eq 'outputfile'
24
+ end
25
+
26
+ it "verbose - is expected to equal true" do
27
+ expect(subject.verbose).to be true
28
+ end
29
+
30
+ it "info - is expected to eq false" do
31
+ expect(subject.info).to be false
32
+ end
33
+
34
+ it "color - is expected to equal true" do
35
+ expect(subject.color).to be true
36
+ end
37
+ end
38
+ end
39
+
40
+ describe 'run' do
41
+ context 'should fail when image name and image file are not provided' do
42
+ let(:scanner) { ScaBox::ContainerScanner.new(name: 'test', description: 'test', support: []) }
43
+
44
+ before do
45
+ scanner.parse_opts([])
46
+ end
47
+
48
+ it do
49
+ expect { scanner.run }.to raise_error(SystemExit) do |error|
50
+ expect( error.status ).to eq(1)
51
+ end
52
+ end
53
+ it do
54
+ expect { scanner.run }.to raise_error(SystemExit) do |error|
55
+ expect( error.message ).to eq('exit')
56
+ end
57
+ end
58
+ end
59
+
60
+ context 'should raise name error for prepare_command method when correct options are provided' do
61
+ let(:scanner) { ScaBox::ContainerScanner.new(name: 'test', description: 'test', support: []) }
62
+ let(:report) { '/tmp/containerscanner_output.json' }
63
+
64
+ before do
65
+ File.delete(report) if File.exist?(report)
66
+
67
+ $VERBOSE = nil
68
+ ARGV = ['-n', 'python:3.4-alpine', '-f', 'json', '-o', report, '-v']
69
+ end
70
+
71
+ it "should raise name error for prepare_command method when correct options are provided" do
72
+ expect { scanner.run }.to raise_error(NameError) do |error| # #<NameError: undefined local variable or method `prepare_command' for #<ScaBox::ContainerScanner:0x00005616ee3fab00>>
73
+ expect( error.message ).to match(/undefined.*prepare_command/)
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ end
@@ -0,0 +1,46 @@
1
+ require_relative '../spec_helper'
2
+ require_relative '../../lib/scabox_sdk'
3
+
4
+ RSpec.describe 'Printer' do
5
+ let(:runner) { ScaBox::CodebaseScanner.new(name: 'test', description: 'test', support: []) }
6
+
7
+ before do
8
+ runner.parse_opts(['--no-color'])
9
+ end
10
+
11
+ describe 'print_title' do
12
+ context 'should print with title format' do
13
+ it {expect { runner.print_title('abc') }.to output("[*] abc\n").to_stdout }
14
+ end
15
+ end
16
+
17
+ describe 'print_normal' do
18
+ context 'should print with normal format' do
19
+ it {expect { runner.print_normal('abc') }.to output("abc\n").to_stdout }
20
+ end
21
+ end
22
+
23
+ describe 'print_success' do
24
+ context 'should print with success format' do
25
+ it {expect { runner.print_success('abc') }.to output("[SUCCESS] abc\n").to_stdout }
26
+ end
27
+ end
28
+
29
+ describe 'print_error' do
30
+ context 'should print with error format' do
31
+ it {expect { runner.print_error('abc') }.to output("[ ERROR ] abc\n").to_stdout }
32
+ end
33
+ end
34
+
35
+ describe 'print_with_label' do
36
+ context 'should print with label format' do
37
+ it {expect { runner.print_with_label('abc', 'def') }.to output("[def] abc\n").to_stdout }
38
+ end
39
+ end
40
+
41
+ describe 'print_debug' do
42
+ context 'should print with debug format' do
43
+ it {expect { runner.print_debug('abc') }.to output(/DEBUG\|.*\| abc/).to_stdout }
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,75 @@
1
+ require_relative '../spec_helper'
2
+ require_relative '../../lib/scabox_sdk'
3
+
4
+ RSpec.describe 'Runner' do
5
+ let(:runner) { ScaBox::CodebaseScanner.new(name: 'test', description: 'test', support: []) }
6
+ let(:runner_timeout_10_sec) { ScaBox::CodebaseScanner.new(name: 'test', description: 'test', support: []) }
7
+
8
+ before do
9
+ runner.parse_opts([])
10
+
11
+ runner_timeout_10_sec.parse_opts([])
12
+ runner_timeout_10_sec.instance_variable_set(:@timeout, 10)
13
+
14
+ Thread.report_on_exception = false
15
+ end
16
+
17
+ describe '#command?' do
18
+ context 'should return true if binary exists' do
19
+ it { expect(runner.command?('ls')).to eq true }
20
+ end
21
+
22
+ context 'should return false if binary not exists' do
23
+ it { expect(runner.command?('xxx')).to eq false }
24
+ end
25
+ end
26
+
27
+ describe '#run_cmd' do
28
+ context 'should run a valid command and return results' do
29
+ subject { runner.run_cmd(['uname']) }
30
+
31
+ it { expect(subject).to be_an(Array) }
32
+ it { expect(subject.length).to be(2) }
33
+ it { expect(subject[0]).to eq "Linux\n" }
34
+ it { expect(subject[1]).to eq(nil).or be_an(Process::Status) }
35
+ end
36
+
37
+ context 'should exit with an invalid command' do
38
+ it do
39
+ expect { runner.run_cmd(['xxx'])}.to raise_error(SystemExit) do |error|
40
+ expect( error.status ).to eq(1)
41
+ end
42
+ end
43
+ it do
44
+ expect { runner.run_cmd(['xxx'])}.to raise_error(SystemExit) do |error|
45
+ expect( error.message ).to eq('exit')
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ describe '#run_cmd_with_timeout' do
52
+ context 'should not fail when not exceeded timeout' do
53
+ subject { runner_timeout_10_sec.run_cmd_with_timeout(['uname']) }
54
+
55
+ it { expect(subject).to be_an(Array) }
56
+ it { expect(subject.length).to be(2) }
57
+ it { expect(subject[0]).to eq "Linux\n" }
58
+ it { expect(subject[1]).to eq(nil).or be_an(Process::Status) }
59
+ end
60
+
61
+ context 'should fail when exceeded timeout' do
62
+ it do
63
+ expect { runner_timeout_10_sec.run_cmd_with_timeout(['sleep', '20'])}.to raise_error(SystemExit) do |error|
64
+ expect( error.status ).to eq(1)
65
+ end
66
+ end
67
+ it do
68
+ expect { runner_timeout_10_sec.run_cmd_with_timeout(['sleep', '20'])}.to raise_error(SystemExit) do |error|
69
+ expect( error.message ).to eq('exit')
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+
@@ -0,0 +1,295 @@
1
+ require_relative '../spec_helper'
2
+ require_relative '../../lib/scabox_sdk'
3
+
4
+ RSpec.describe 'Scanner' do
5
+ describe 'check_info_flag' do
6
+ context 'should print info and exit when info flag is true' do
7
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
8
+
9
+ before do
10
+ scanner.instance_variable_set(:@opts, OpenStruct.new(info: true))
11
+ end
12
+
13
+ it do
14
+ expect { scanner.check_info_flag}.to raise_error(SystemExit) do |error|
15
+ expect( error.status ).to eq(0)
16
+ end
17
+ end
18
+
19
+ it do
20
+ expect { scanner.check_info_flag}.to raise_error(SystemExit) do |error|
21
+ expect( error.message ).to eq('exit')
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ describe 'check_output_flag' do
28
+ context 'should print error and exit when no output flag is provided' do
29
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
30
+
31
+ before do
32
+ scanner.instance_variable_set(:@opts, OpenStruct.new(output_stdout: false))
33
+ end
34
+
35
+ it do
36
+ expect { scanner.check_output_flag }.to raise_error(SystemExit) do |error|
37
+ expect( error.status ).to eq(1)
38
+ end
39
+ end
40
+
41
+ it do
42
+ expect { scanner.check_output_flag}.to raise_error(SystemExit) do |error|
43
+ expect( error.message ).to eq('exit')
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ describe 'start_scan' do
50
+ context 'should raise name error for prepare_command method' do
51
+
52
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
53
+
54
+ before do
55
+ scanner.instance_variable_set(:@opts, OpenStruct.new())
56
+ end
57
+
58
+ it "should raise name error for prepare_command" do
59
+ expect { scanner.run }.to raise_error(NameError) # #<NameError: undefined local variable or method `prepare_command' ...
60
+ end
61
+ end
62
+ end
63
+
64
+
65
+ describe 'add_issue' do
66
+ context 'should add issue to instance array @issues' do
67
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
68
+
69
+ before do
70
+
71
+ scanner.add_issue(
72
+ cve: 'CVE-XXXX-YYYY',
73
+ references: ['http://localhost'],
74
+ title: 'title',
75
+ discovery_method: 'discovery_method',
76
+ description: 'description',
77
+ severity: 'undefined',
78
+ solution: 'solution'
79
+ )
80
+ end
81
+
82
+ it "@issues.length == 1" do
83
+ expect(scanner.issues.length).to eq 1
84
+ end
85
+
86
+ it "@issues[0][:plugin] == 'test'" do
87
+ expect(scanner.issues[0][:plugin]).to eq 'test'
88
+ end
89
+
90
+ it "@issues[0][:cve] == 'CVE-XXXX-YYYY'" do
91
+ expect(scanner.issues[0][:cve][0]).to eq 'CVE-XXXX-YYYY'
92
+ end
93
+
94
+ it "@issues[0][:references].length == 1" do
95
+ expect(scanner.issues[0][:references].length).to eq 1
96
+ end
97
+
98
+ it "@issues[0][:title] == 'title'" do
99
+ expect(scanner.issues[0][:title]).to eq 'title'
100
+ end
101
+
102
+ it "@issues[0][:discovery_method] == 'discovery_method'" do
103
+ expect(scanner.issues[0][:discovery_method]).to eq 'discovery_method'
104
+ end
105
+
106
+ it "@issues[0][:description] == 'description'" do
107
+ expect(scanner.issues[0][:description]).to eq 'description'
108
+ end
109
+
110
+ it "@issues[0][:severity] == 'undefined'" do
111
+ expect(scanner.issues[0][:severity]).to eq 'undefined'
112
+ end
113
+
114
+ it "@issues[0][:solution] == 'solution'" do
115
+ expect(scanner.issues[0][:solution]).to eq 'solution'
116
+ end
117
+
118
+ it "@issues[0][:hash] == 'e4634c7ab84ffe3a5ea189729f9b5a1763d527bf540d0512e87e5871045f7b4f'" do
119
+ expect(scanner.issues[0][:hash]).to eq 'e4634c7ab84ffe3a5ea189729f9b5a1763d527bf540d0512e87e5871045f7b4f'
120
+ end
121
+
122
+ end
123
+ end
124
+
125
+ describe 'build_title' do
126
+ context 'should build title without CVE IDs' do
127
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
128
+
129
+ before do
130
+ scanner.instance_variable_set(:@opts, OpenStruct.new())
131
+ end
132
+
133
+ it "should build title without CVE IDs" do
134
+ expect(scanner.build_title(cve: []) ).to eq 'Vulnerability'
135
+ end
136
+ end
137
+
138
+ context 'should build title with CVE IDs' do
139
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
140
+
141
+ before do
142
+ scanner.instance_variable_set(:@opts, OpenStruct.new())
143
+ end
144
+
145
+ it "should build title with CVE IDs" do
146
+ expect(scanner.build_title(cve: [4, 3, 2, 1]) ).to eq '1,2,3,4'
147
+ end
148
+ end
149
+ end
150
+
151
+ describe 'save_results' do
152
+ context 'should save results to file' do
153
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
154
+ let(:report) { '/tmp/save_results.json' }
155
+
156
+ before do
157
+ File.delete(report) if File.exist?(report)
158
+
159
+ issue = {
160
+ cve: ['CVE-XXXX-YYYY'],
161
+ references: ['http://localhost'],
162
+ title: 'title',
163
+ discovery_method: 'discovery_method',
164
+ description: 'description',
165
+ severity: 'undefined',
166
+ solution: 'solution'
167
+ }
168
+
169
+ scanner.instance_variable_set(:@issues, [issue])
170
+ scanner.instance_variable_set(:@opts, OpenStruct.new(output: report))
171
+ scanner.save_results
172
+ end
173
+
174
+ it "should save results to file" do
175
+ expect(File.exist?(report)).to be true
176
+ end
177
+ end
178
+ end
179
+
180
+ describe 'txt_output' do
181
+ context 'should format issue for txt output' do
182
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
183
+
184
+ before do
185
+ issue = {
186
+ hash: 'aaaaaaaaaaaaaaaaaaaaaa',
187
+ plugin: 'plugin',
188
+ path: 'lololol',
189
+ component: 'xxx',
190
+ version: '123',
191
+ cve: ['CVE-XXXX-YYYY'],
192
+ references: ['http://localhost'],
193
+ title: 'title',
194
+ discovery_method: 'discovery_method',
195
+ description: 'description',
196
+ severity: 'undefined',
197
+ solution: 'solution'
198
+ }
199
+
200
+ scanner.instance_variable_set(:@issues, [issue])
201
+ end
202
+
203
+ it "should format issue for txt output" do
204
+ sep = "=" * 100
205
+ output = ''
206
+
207
+ output << "Hash: aaaaaaaaaaaaaaaaaaaaaa\n"
208
+ output << "Plugin: plugin\n"
209
+ output << "Path: lololol\n"
210
+ output << "Component: xxx\n"
211
+ output << "Version: 123\n"
212
+ output << "Discovery Method discovery_method\n"
213
+ output << "Title: title\n"
214
+ output << "Description: description\n"
215
+ output << "Solution: solution\n"
216
+ output << "Severity: undefined\n"
217
+ output << "CVE: CVE-XXXX-YYYY\n"
218
+ output << "References:\nhttp://localhost\n"
219
+ output << "#{sep}\n\n"
220
+
221
+ expect(scanner.txt_output ).to eq output
222
+ end
223
+ end
224
+ end
225
+
226
+ describe 'filename_for_plugin' do
227
+ context 'should format filename for plugin' do
228
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
229
+
230
+ it "should format filename for plugin" do
231
+ expect(scanner.filename_for_plugin ).to match /test_.*\.json/
232
+ end
233
+ end
234
+ end
235
+
236
+ describe 'parse_json_from_str' do
237
+ context 'should parse json from string' do
238
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
239
+
240
+ it "should parse json from string" do
241
+ expect(scanner.parse_json_from_str('{"abc": "123"}') ).to be_an Hash
242
+ expect(scanner.parse_json_from_str('{"abc": "123"}') ).to have_key("abc")
243
+ expect(scanner.parse_json_from_str('{"abc": "123"}')["abc"] ).to eq "123"
244
+ end
245
+
246
+ it "should return nil when json is invalid" do
247
+ expect(scanner.parse_json_from_str('xxxxx') ).to eq nil
248
+ end
249
+ end
250
+ end
251
+
252
+ describe 'parse_json_from_file' do
253
+ context 'should parse json from file' do
254
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
255
+ let(:filename_valid) { '/tmp/json_input_valid_test.json' }
256
+ let(:filename_invalid) { '/tmp/json_input_invalid_test.json' }
257
+
258
+ before do
259
+ File.write(filename_valid, '{"abc": "123"}')
260
+ File.write(filename_invalid, 'xxxxx')
261
+ end
262
+
263
+ it "should parse json from file" do
264
+ expect(scanner.parse_json_from_file(filename_valid) ).to be_an Hash
265
+ expect(scanner.parse_json_from_file(filename_valid) ).to have_key("abc")
266
+ expect(scanner.parse_json_from_file(filename_valid)["abc"] ).to eq "123"
267
+ end
268
+
269
+ it "should return nil when json is invalid" do
270
+ expect(scanner.parse_json_from_file(filename_invalid) ).to eq nil
271
+ end
272
+ end
273
+ end
274
+
275
+ describe 'gen_random_tmp_filename' do
276
+ context 'should generate random filename' do
277
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
278
+
279
+ it "should generate random filename" do
280
+ expect(scanner.gen_random_tmp_filename('.xxxyyy')).to match /\/tmp\/.*\.xxxyyy/
281
+ end
282
+ end
283
+ end
284
+
285
+ describe 'gen_random_tmp_filename_json' do
286
+ context 'should generate random json filename' do
287
+ let(:scanner) { ScaBox::Scanner.new(name: 'test', description: 'test', support: []) }
288
+
289
+ it "should generate random json filename" do
290
+ expect(scanner.gen_random_tmp_filename_json).to match /\/tmp\/.*\.json/
291
+ end
292
+ end
293
+ end
294
+
295
+ end
@@ -0,0 +1,8 @@
1
+ require_relative 'spec_helper'
2
+ require_relative '../lib/scabox_sdk'
3
+
4
+
5
+ RSpec.describe 'Scabox_Sdk' do
6
+
7
+ end
8
+
@@ -0,0 +1,108 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
4
+ # this file to always be loaded, without a need to explicitly require it in any
5
+ # files.
6
+ #
7
+ # Given that it is always loaded, you are encouraged to keep this file as
8
+ # light-weight as possible. Requiring heavyweight dependencies from this file
9
+ # will add to the boot time of your test suite on EVERY test run, even for an
10
+ # individual file that may not need all of that loaded. Instead, consider making
11
+ # a separate helper file that requires the additional dependencies and performs
12
+ # the additional setup, and require it from the spec files that actually need
13
+ # it.
14
+ #
15
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
16
+ require 'simplecov'
17
+ SimpleCov.start
18
+
19
+ RSpec.configure do |config|
20
+ # rspec-expectations config goes here. You can use an alternate
21
+ # assertion/expectation library such as wrong or the stdlib/minitest
22
+ # assertions if you prefer.
23
+ config.before(:each) do
24
+ allow($stdout).to receive(:puts)
25
+ allow($stdout).to receive(:write)
26
+ end
27
+
28
+ config.expect_with :rspec do |expectations|
29
+ # This option will default to `true` in RSpec 4. It makes the `description`
30
+ # and `failure_message` of custom matchers include text for helper methods
31
+ # defined using `chain`, e.g.:
32
+ # be_bigger_than(2).and_smaller_than(4).description
33
+ # # => "be bigger than 2 and smaller than 4"
34
+ # ...rather than:
35
+ # # => "be bigger than 2"
36
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
37
+ end
38
+
39
+ # rspec-mocks config goes here. You can use an alternate test double
40
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
41
+ config.mock_with :rspec do |mocks|
42
+ # Prevents you from mocking or stubbing a method that does not exist on
43
+ # a real object. This is generally recommended, and will default to
44
+ # `true` in RSpec 4.
45
+ mocks.verify_partial_doubles = true
46
+ end
47
+
48
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
49
+ # have no way to turn it off -- the option exists only for backwards
50
+ # compatibility in RSpec 3). It causes shared context metadata to be
51
+ # inherited by the metadata hash of host groups and examples, rather than
52
+ # triggering implicit auto-inclusion in groups with matching metadata.
53
+ config.shared_context_metadata_behavior = :apply_to_host_groups
54
+
55
+ # The settings below are suggested to provide a good initial experience
56
+ # with RSpec, but feel free to customize to your heart's content.
57
+ =begin
58
+ # This allows you to limit a spec run to individual examples or groups
59
+ # you care about by tagging them with `:focus` metadata. When nothing
60
+ # is tagged with `:focus`, all examples get run. RSpec also provides
61
+ # aliases for `it`, `describe`, and `context` that include `:focus`
62
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
63
+ config.filter_run_when_matching :focus
64
+
65
+ # Allows RSpec to persist some state between runs in order to support
66
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
67
+ # you configure your source control system to ignore this file.
68
+ config.example_status_persistence_file_path = "spec/examples.txt"
69
+
70
+ # Limits the available syntax to the non-monkey patched syntax that is
71
+ # recommended. For more details, see:
72
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
73
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
74
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
75
+ config.disable_monkey_patching!
76
+
77
+ # This setting enables warnings. It's recommended, but in some cases may
78
+ # be too noisy due to issues in dependencies.
79
+ config.warnings = true
80
+
81
+ # Many RSpec users commonly either run the entire suite or an individual
82
+ # file, and it's useful to allow more verbose output when running an
83
+ # individual spec file.
84
+ if config.files_to_run.one?
85
+ # Use the documentation formatter for detailed output,
86
+ # unless a formatter has already been configured
87
+ # (e.g. via a command-line flag).
88
+ config.default_formatter = "doc"
89
+ end
90
+
91
+ # Print the 10 slowest examples and example groups at the
92
+ # end of the spec run, to help surface which specs are running
93
+ # particularly slow.
94
+ config.profile_examples = 10
95
+
96
+ # Run specs in random order to surface order dependencies. If you find an
97
+ # order dependency and want to debug it, you can fix the order by providing
98
+ # the seed, which is printed after each run.
99
+ # --seed 1234
100
+ config.order = :random
101
+
102
+ # Seed global randomization in this process using the `--seed` CLI option.
103
+ # Setting this allows you to use `--seed` to deterministically reproduce
104
+ # test failures related to randomization by passing the same `--seed` value
105
+ # as the one that triggered the failure.
106
+ Kernel.srand config.seed
107
+ =end
108
+ end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scabox_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1.pre.rc.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - rd
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2020-09-16 00:00:00.000000000 Z
@@ -51,11 +51,18 @@ files:
51
51
  - lib/scabox_sdk/printer.rb
52
52
  - lib/scabox_sdk/runner.rb
53
53
  - lib/scabox_sdk/scanner.rb
54
+ - spec/scabox_sdk/codebase_spec.rb
55
+ - spec/scabox_sdk/container_spec.rb
56
+ - spec/scabox_sdk/printer_spec.rb
57
+ - spec/scabox_sdk/runner_spec.rb
58
+ - spec/scabox_sdk/scanner_spec.rb
59
+ - spec/scabox_sdk_spec.rb
60
+ - spec/spec_helper.rb
54
61
  homepage: ''
55
62
  licenses:
56
63
  - MIT
57
64
  metadata: {}
58
- post_install_message:
65
+ post_install_message:
59
66
  rdoc_options: []
60
67
  require_paths:
61
68
  - lib
@@ -66,12 +73,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
66
73
  version: '2.4'
67
74
  required_rubygems_version: !ruby/object:Gem::Requirement
68
75
  requirements:
69
- - - ">="
76
+ - - ">"
70
77
  - !ruby/object:Gem::Version
71
- version: '0'
78
+ version: 1.3.1
72
79
  requirements: []
73
- rubygems_version: 3.2.3
74
- signing_key:
80
+ rubygems_version: 3.0.3
81
+ signing_key:
75
82
  specification_version: 4
76
83
  summary: SCABox SDK
77
84
  test_files: []