nessana 0.2.0 → 0.3.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: ee396ef7c7de91a411465ca7cd27f2dd2ec0ae3ada00d65f2d7fd93bcf7231d1
4
- data.tar.gz: f53065e4cd980ea6ea2da9127a87bede09ceaca1a7607df7f53323b4d090aa73
3
+ metadata.gz: b385c40628994b9e7819e4a855084d81d9bf5a3c8d650e0999ec4e217ba038d6
4
+ data.tar.gz: c62f1308a920473dd891ddfa2057d2b2dabe4ae0d58b0922184ce7998ef19e65
5
5
  SHA512:
6
- metadata.gz: 68b6913aa147d06ef5e1336fd8f694f148e2f67e58cf28b1e1e3690d7761fadbcb0addcd94fa21eafd4f7bbf4bd27f8047702451e65f434d59a66141d2b604ba
7
- data.tar.gz: 0bcab82e1682510938fcaf5a69a4d3cffe2beba1af660c8417d81540dd464512dcaeaee0bf57d8e3918aba060f240a9e9c686fb190d82961ce1b9ff2cf94d808
6
+ metadata.gz: 5cb874ce7320573f4b19e0393a3d8a0af2a0851a9df0f7cebca345d3d3ffc9dfeb1cc6ae45fec6ce35ab855a75c71eb94abb22b53afeebfa55d82122ca1c4104
7
+ data.tar.gz: 9efc4f1a4f11b29db8b4b11da2800bfe5e0574219e3d0c87c8e45bfca6229d7224e190fba9e58ed23f50e1ecf0d23d3de13255dbeff3612667f72b782e2d4685
data/README.md CHANGED
@@ -11,3 +11,23 @@ $ nessana -c config.yml scan.csv
11
11
  ## Contributing
12
12
 
13
13
  See [CONTRIBUTING.md](CONTRIBUTING.md)
14
+
15
+ ## License
16
+
17
+ ```
18
+ <one line to give the program's name and a brief idea of what it does.>
19
+ Copyright (C) 2019 Kristofer Rye
20
+
21
+ This program is free software: you can redistribute it and/or modify
22
+ it under the terms of the GNU Affero General Public License as published
23
+ by the Free Software Foundation, either version 3 of the License, or
24
+ (at your option) any later version.
25
+
26
+ This program is distributed in the hope that it will be useful,
27
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
28
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29
+ GNU Affero General Public License for more details.
30
+
31
+ You should have received a copy of the GNU Affero General Public License
32
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
33
+ ```
data/bin/nessana CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'nessana/executor'
4
4
 
5
- Nessana::Executor.execute!
5
+ exit Nessana::Executor.execute!
@@ -25,7 +25,7 @@ module Nessana
25
25
  @status == other.status || false
26
26
  end
27
27
 
28
- alias eql? ==
28
+ alias :eql? :==
29
29
 
30
30
  protected
31
31
 
data/lib/nessana/dump.rb CHANGED
@@ -2,7 +2,6 @@ require 'time'
2
2
 
3
3
  require 'csv'
4
4
  require 'fastcsv'
5
- require 'tty-spinner'
6
5
 
7
6
  require 'nessana/detection'
8
7
  require 'nessana/vulnerability'
@@ -10,75 +9,32 @@ require 'nessana/vulnerability'
10
9
  module Nessana
11
10
  class Dump < Hash
12
11
  attr_reader :filters
13
- attr_reader :filename
14
12
 
15
- def initialize(filename = nil, filters = [])
16
- @filename, @filters = filename, filters
13
+ def self.read(file, filters = [])
14
+ data = read_csv(file)
17
15
 
18
- if @filename
19
- if File.readable?(@filename)
20
- spinner_options = {
21
- success_mark: "\u2713".encode('utf-8'),
22
- format: :dots_3
23
- }
24
- spinner = TTY::Spinner.new("[:spinner] Loading #{@filename}...", **spinner_options)
25
- spinner.auto_spin
16
+ self.new(data, filters)
17
+ end
26
18
 
27
- read_csv!
19
+ def initialize(vulnerabilities = {}, filters = [])
20
+ @filters = filters
28
21
 
29
- spinner.success('done!')
30
- else
31
- throw 'file not readable; sad face'
32
- end
22
+ filtered_data = vulnerabilities.select do |_, vulnerability|
23
+ !vulnerability.matches?(@filters)
33
24
  end
25
+
26
+ merge!(filtered_data)
34
27
  end
35
28
 
36
29
  def -(other)
37
- spinner_options = {
38
- success_mark: "\u2713".encode('utf-8'),
39
- format: :dots_3
40
- }
41
-
42
- spinner = TTY::Spinner.new('[:spinner] :action...', **spinner_options)
43
- spinner.update(action: 'Generating detections...')
44
-
45
30
  other_plugin_ids = other.keys
46
31
  self_plugin_ids = keys
47
32
 
48
- spinner.update(action: 'Finding L detections')
49
-
50
- other_detection_pairs = other.map do |plugin_id, vulnerability|
51
- spinner.update(action: "Finding L detections (#{plugin_id})")
52
- spinner.auto_spin
53
-
54
- vulnerability.detections.map do |detection|
55
- { plugin_id => detection }
56
- end
57
- end
58
-
59
- other_detections = Set.new(other_detection_pairs.flatten)
60
-
61
- spinner.update(action: 'Finding R detections')
62
-
63
- detection_pairs = map do |plugin_id, vulnerability|
64
- spinner.update(action: "Finding R detections (#{plugin_id})")
65
- spinner.auto_spin
66
-
67
- vulnerability.detections.map do |detection|
68
- { plugin_id => detection }
69
- end
70
- end
71
-
72
- self_detections = Set.new(detection_pairs.flatten)
73
-
74
- spinner.update(action: 'Joining detection sets')
75
- spinner.auto_spin
33
+ other_detections = other.detection_pairs
34
+ self_detections = detection_pairs
76
35
 
77
36
  detections = Set.new([other_detections, self_detections]).flatten
78
37
 
79
- spinner.update(action: 'Processing detections')
80
- spinner.auto_spin
81
-
82
38
  detections.each do |detection_entry|
83
39
  in_self = self_detections.include? detection_entry
84
40
  in_other = other_detections.include? detection_entry
@@ -96,8 +52,6 @@ module Nessana
96
52
  end
97
53
  end
98
54
 
99
- spinner.success('done!')
100
-
101
55
  added_plugin_ids = self_plugin_ids - other_plugin_ids
102
56
  deleted_plugin_ids = other_plugin_ids - self_plugin_ids
103
57
  all_plugin_ids = other_plugin_ids + added_plugin_ids
@@ -127,19 +81,19 @@ module Nessana
127
81
  all_vulnerabilities
128
82
  end
129
83
 
130
- def read_csv!
131
- data = read_csv(filename)
132
-
133
- filtered_data = data.select do |_, vulnerability|
134
- !vulnerability.matches?(@filters)
84
+ def detection_pairs
85
+ pairs = map do |plugin_id, vulnerability|
86
+ vulnerability.detections.map do |detection|
87
+ { plugin_id => detection }
88
+ end
135
89
  end
136
90
 
137
- merge!(filtered_data)
91
+ Set.new(pairs.flatten)
138
92
  end
139
93
 
140
94
  protected
141
95
 
142
- def read_csv(filename)
96
+ def self.read_csv(filename)
143
97
  dump_data = {}
144
98
 
145
99
  first_row = true
@@ -1,7 +1,6 @@
1
1
  require 'optparse'
2
2
  require 'pp'
3
- require 'ruby-prof'
4
- require 'ruby-prof-flamegraph'
3
+ require 'tty-spinner'
5
4
 
6
5
  require 'nessana/executor/execution_configuration'
7
6
  require 'nessana/filter'
@@ -16,26 +15,55 @@ module Nessana
16
15
  def self.execute!(argv = ARGV)
17
16
  parse!(*argv)
18
17
 
19
- RubyProf.start if !!@configuration['performance']
18
+ return @configuration unless @configuration.is_a?(Nessana::Executor::ExecutionConfiguration)
19
+
20
+ return @configuration['__exit-code__'] if @configuration['__stop__']
20
21
 
21
22
  unless @configuration['old_filename']
22
- $stderr.puts 'No old dump filename given; will assume no prior knowledge.'
23
+ warn 'No old dump filename given; assuming you want this.'
23
24
  end
24
25
 
25
26
  unless @configuration['new_filename']
26
- puts 'No new dump filename given; cannot do anything.'
27
- return
27
+ warn 'No new dump filename given; cannot do anything.'
28
+ return 1
28
29
  end
29
30
 
30
31
  filters = @configuration['filters'].map do |filter_hash|
31
32
  Filter.new(filter_hash)
32
33
  end
33
34
 
34
- old_dump = @configuration['old_filename'] ? Dump.new(@configuration['old_filename'], filters) : Dump.new
35
- new_dump = Dump.new(@configuration['new_filename'], filters)
35
+ spinner_options = {
36
+ success_mark: "\u2713".encode('utf-8'),
37
+ format: :dots_3
38
+ }
39
+
40
+ old_dump = nil
41
+
42
+ if @configuration['old_filename']
43
+ spinner = TTY::Spinner.new("[:spinner] Loading #{@configuration['old_filename']}...", **spinner_options)
44
+ spinner.auto_spin
45
+
46
+ old_dump = Dump.read(@configuration['old_filename'], filters)
47
+
48
+ spinner.success('done!')
49
+ else
50
+ old_dump = Dump.new
51
+ end
52
+
53
+ spinner = TTY::Spinner.new("[:spinner] Loading #{@configuration['old_filename']}...", **spinner_options)
54
+ spinner.auto_spin
55
+
56
+ new_dump = Dump.read(@configuration['new_filename'], filters)
57
+
58
+ spinner.success('done!')
59
+
60
+ spinner = TTY::Spinner.new('[:spinner] Comparing dumps...', **spinner_options)
61
+ spinner.auto_spin
36
62
 
37
63
  diff = new_dump - old_dump
38
64
 
65
+ spinner.success('done!')
66
+
39
67
  diff.sort do |vulnerability_a, vulnerability_b|
40
68
  vulnerability_a.plugin_id.to_i <=> vulnerability_b.plugin_id.to_i
41
69
  end.sort do |vulnerability_a, vulnerability_b|
@@ -52,12 +80,7 @@ DISCOVERIES"
52
80
  puts "\n" * 2
53
81
  end
54
82
 
55
- if !!@configuration['performance']
56
- result = RubyProf.stop
57
- printer = RubyProf::FlameGraphPrinter.new(result)
58
- io = open(@configuration['performance'], 'wb')
59
- printer.print(io, {})
60
- end
83
+ 0
61
84
  end
62
85
 
63
86
  def self.parse(*argv)
@@ -68,10 +91,8 @@ DISCOVERIES"
68
91
 
69
92
  if argv.count == 0
70
93
  puts parser
71
- exit 1
94
+ return 1
72
95
  end
73
-
74
- parser.parse(*argv)
75
96
  end
76
97
 
77
98
  remaining_arguments = option_parser.order!(argv)
@@ -95,6 +116,5 @@ DISCOVERIES"
95
116
  def self.parse!(*argv)
96
117
  @configuration = parse(*argv)
97
118
  end
98
-
99
119
  end
100
120
  end
@@ -3,6 +3,8 @@ require 'mime-types'
3
3
  require 'nessana/version'
4
4
 
5
5
  module Nessana::Executor
6
+ # TODO: Replace __stop__ and __exit-code__ with exits again, and
7
+ # use a rescue SystemExit => e instead.
6
8
  class ExecutionConfiguration < ::Hash
7
9
  def initialize
8
10
  self['verbosity'] = 'info'
@@ -25,14 +27,10 @@ module Nessana::Executor
25
27
  add_usage_option(parser)
26
28
  add_verbosity_option(parser)
27
29
 
28
- parser.on_tail('-h', '--help', 'Show this message') do
29
- puts parser
30
- exit
31
- end
32
-
33
- parser.on_tail('--version', 'Show version') do
30
+ parser.on_tail('-V', '--version', 'Show version') do
34
31
  puts Nessana::VERSION
35
- exit
32
+ self['__stop__'] = true
33
+ self['__exit-code__'] = 0
36
34
  end
37
35
  end
38
36
 
@@ -52,7 +50,8 @@ module Nessana::Executor
52
50
  def add_usage_option(parser)
53
51
  parser.on('-h', '--help', 'Print usage summary.') do
54
52
  puts parser
55
- exit 0
53
+ self['__stop__'] = true
54
+ self['__exit-code__'] = 0
56
55
  end
57
56
  end
58
57
 
@@ -1,3 +1,3 @@
1
1
  module Nessana
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nessana
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristofer Rye <kristofer.rye@gmail.com>
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-22 00:00:00.000000000 Z
11
+ date: 2019-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fastcsv
@@ -136,34 +136,6 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0.57'
139
- - !ruby/object:Gem::Dependency
140
- name: ruby-prof
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: 0.17.0
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: 0.17.0
153
- - !ruby/object:Gem::Dependency
154
- name: ruby-prof-flamegraph
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - "~>"
158
- - !ruby/object:Gem::Version
159
- version: 0.3.0
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: 0.3.0
167
139
  - !ruby/object:Gem::Dependency
168
140
  name: simplecov
169
141
  requirement: !ruby/object:Gem::Requirement
@@ -199,7 +171,7 @@ files:
199
171
  - lib/nessana/vulnerability.rb
200
172
  homepage: https://github.com/rye/nessana
201
173
  licenses:
202
- - MIT
174
+ - AGPL-3.0-only
203
175
  metadata: {}
204
176
  post_install_message:
205
177
  rdoc_options: []