nvd-json_feeds 0.1.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 (67) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.github/workflows/ruby.yml +29 -0
  4. data/.gitignore +9 -0
  5. data/.rspec +1 -0
  6. data/.yardopts +1 -0
  7. data/ChangeLog.md +25 -0
  8. data/Gemfile +13 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +136 -0
  11. data/Rakefile +31 -0
  12. data/gemspec.yml +22 -0
  13. data/lib/nvd/json_feeds.rb +25 -0
  14. data/lib/nvd/json_feeds/exceptions.rb +15 -0
  15. data/lib/nvd/json_feeds/feed.rb +50 -0
  16. data/lib/nvd/json_feeds/feed_file.rb +95 -0
  17. data/lib/nvd/json_feeds/feed_uri.rb +131 -0
  18. data/lib/nvd/json_feeds/gz_feed_file.rb +60 -0
  19. data/lib/nvd/json_feeds/gz_feed_uri.rb +25 -0
  20. data/lib/nvd/json_feeds/json_feed_file.rb +21 -0
  21. data/lib/nvd/json_feeds/meta.rb +122 -0
  22. data/lib/nvd/json_feeds/meta_feed_uri.rb +22 -0
  23. data/lib/nvd/json_feeds/schema/configurations.rb +61 -0
  24. data/lib/nvd/json_feeds/schema/configurations/node.rb +98 -0
  25. data/lib/nvd/json_feeds/schema/cpe/has_uri.rb +66 -0
  26. data/lib/nvd/json_feeds/schema/cpe/match.rb +117 -0
  27. data/lib/nvd/json_feeds/schema/cpe/name.rb +67 -0
  28. data/lib/nvd/json_feeds/schema/cve_feed.rb +142 -0
  29. data/lib/nvd/json_feeds/schema/cve_item.rb +94 -0
  30. data/lib/nvd/json_feeds/schema/cvss_v2.rb +298 -0
  31. data/lib/nvd/json_feeds/schema/cvss_v3.rb +332 -0
  32. data/lib/nvd/json_feeds/schema/has_data_version.rb +54 -0
  33. data/lib/nvd/json_feeds/schema/impact.rb +73 -0
  34. data/lib/nvd/json_feeds/schema/impact/base_metric_v2.rb +132 -0
  35. data/lib/nvd/json_feeds/schema/impact/base_metric_v3.rb +79 -0
  36. data/lib/nvd/json_feeds/schema/timestamp.rb +9 -0
  37. data/lib/nvd/json_feeds/version.rb +6 -0
  38. data/lib/nvd/json_feeds/zip_feed_file.rb +64 -0
  39. data/lib/nvd/json_feeds/zip_feed_uri.rb +25 -0
  40. data/nvd-json_feeds.gemspec +61 -0
  41. data/spec/feed_file_examples.rb +27 -0
  42. data/spec/feed_file_spec.rb +42 -0
  43. data/spec/feed_spec.rb +56 -0
  44. data/spec/feed_uri_spec.rb +81 -0
  45. data/spec/fixtures/gz_feed_file/nvdcve-1.1-recent.json.gz +0 -0
  46. data/spec/fixtures/nvdcve-1.1-recent.json +180 -0
  47. data/spec/fixtures/zip_feed_file/nvdcve-1.1-recent.json.zip +0 -0
  48. data/spec/gz_feed_file_spec.rb +66 -0
  49. data/spec/gz_feed_uri_spec.rb +35 -0
  50. data/spec/json_feed_file_spec.rb +18 -0
  51. data/spec/json_feeds_spec.rb +8 -0
  52. data/spec/meta_spec.rb +141 -0
  53. data/spec/schema/configurations/node_spec.rb +87 -0
  54. data/spec/schema/configurations_spec.rb +57 -0
  55. data/spec/schema/cpe/match_spec.rb +188 -0
  56. data/spec/schema/cpe/name_spec.rb +54 -0
  57. data/spec/schema/cve_feed_spec.rb +162 -0
  58. data/spec/schema/cve_item_spec.rb +116 -0
  59. data/spec/schema/impact/base_metric_v2_spec.rb +183 -0
  60. data/spec/schema/impact/base_metric_v3_spec.rb +80 -0
  61. data/spec/schema/impact_spec.rb +53 -0
  62. data/spec/schema/shared_examples.rb +136 -0
  63. data/spec/schema/timestamp_spec.rb +8 -0
  64. data/spec/spec_helper.rb +8 -0
  65. data/spec/zip_feed_file_spec.rb +66 -0
  66. data/spec/zip_feed_uri_spec.rb +35 -0
  67. metadata +156 -0
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+ require 'schema/shared_examples'
3
+ require 'nvd/json_feeds/schema/impact/base_metric_v3'
4
+
5
+ describe Schema::Impact::BaseMetricV3 do
6
+ describe "#initialize" do
7
+ context "when cvss_v3: is given" do
8
+ let(:cvss_v3) { double(:CVSSv3) }
9
+
10
+ subject { described_class.new(cvss_v3: cvss_v3) }
11
+
12
+ it "must set #cvss_v3" do
13
+ expect(subject.cvss_v3).to eq(cvss_v3)
14
+ end
15
+
16
+ context "and when exploitability_score: is given" do
17
+ let(:exploitability_score) { 5.0 }
18
+
19
+ subject do
20
+ described_class.new(
21
+ cvss_v3: cvss_v3,
22
+ exploitability_score: exploitability_score
23
+ )
24
+ end
25
+
26
+ it "must set #exploitability_score" do
27
+ expect(subject.exploitability_score).to eq(exploitability_score)
28
+ end
29
+ end
30
+
31
+ context "but when exploitability_score: is not given" do
32
+ it { expect(subject.exploitability_score).to be(nil) }
33
+ end
34
+
35
+ context "and when impact_score: is given" do
36
+ let(:impact_score) { 5.0 }
37
+
38
+ subject do
39
+ described_class.new(
40
+ cvss_v3: cvss_v3,
41
+ impact_score: impact_score
42
+ )
43
+ end
44
+
45
+ it "must set #impact_score" do
46
+ expect(subject.impact_score).to eq(impact_score)
47
+ end
48
+ end
49
+
50
+ context "but when impact_score: is not given" do
51
+ it { expect(subject.impact_score).to be(nil) }
52
+ end
53
+ end
54
+
55
+ context "when cvss_v3: is not given" do
56
+ it do
57
+ expect {
58
+ described_class.new
59
+ }.to raise_error(ArgumentError)
60
+ end
61
+ end
62
+ end
63
+
64
+ describe ".load" do
65
+ include_examples ".load"
66
+
67
+ let(:json_node) { json_tree['CVE_Items'][0]['impact']['baseMetricV3'] }
68
+
69
+ include_examples "JSON Object field", json_key: 'cvssV3',
70
+ required: true,
71
+ method: :cvss_v3,
72
+ object_class: Schema::CVSSv3
73
+
74
+ include_examples "JSON field", json_key: 'exploitabilityScore',
75
+ method: :exploitability_score
76
+
77
+ include_examples "JSON field", json_key: 'impactScore',
78
+ method: :impact_score
79
+ end
80
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+ require 'schema/shared_examples'
3
+ require 'nvd/json_feeds/schema/impact'
4
+
5
+ describe Schema::Impact do
6
+ describe "#initialize" do
7
+ context "when user_interaction_required: is given" do
8
+ let(:base_metric_v3) { double(:BaseMetricV2) }
9
+
10
+ subject do
11
+ described_class.new(base_metric_v3: base_metric_v3)
12
+ end
13
+
14
+ it "must set #base_metric_v3" do
15
+ expect(subject.base_metric_v3).to eq(base_metric_v3)
16
+ end
17
+ end
18
+
19
+ context "when base_metric_v3: is not given" do
20
+ it { expect(subject.base_metric_v3).to be(nil) }
21
+ end
22
+
23
+ context "when user_interaction_required: is given" do
24
+ let(:base_metric_v2) { double(:BaseMetricV2) }
25
+
26
+ subject do
27
+ described_class.new(base_metric_v2: base_metric_v2)
28
+ end
29
+
30
+ it "must set #base_metric_v2" do
31
+ expect(subject.base_metric_v2).to eq(base_metric_v2)
32
+ end
33
+ end
34
+
35
+ context "when base_metric_v2: is not given" do
36
+ it { expect(subject.base_metric_v2).to be(nil) }
37
+ end
38
+ end
39
+
40
+ describe ".load" do
41
+ include_examples ".load"
42
+
43
+ let(:json_node) { json_tree['CVE_Items'][0]['impact'] }
44
+
45
+ include_examples "JSON Object field", json_key: 'baseMetricV3',
46
+ method: :base_metric_v3,
47
+ object_class: described_class::BaseMetricV3
48
+
49
+ include_examples "JSON Object field", json_key: 'baseMetricV2',
50
+ method: :base_metric_v2,
51
+ object_class: described_class::BaseMetricV2
52
+ end
53
+ end
@@ -0,0 +1,136 @@
1
+ require 'rspec'
2
+ require 'json'
3
+
4
+ RSpec.shared_examples ".from_json" do
5
+ let(:fixtures_dir) { File.expand_path('../../fixtures',__FILE__) }
6
+ let(:json_filename) { 'nvdcve-1.1-recent.json' }
7
+ let(:json_file) { File.join(fixtures_dir,json_filename) }
8
+
9
+ let(:json_tree) { JSON.parse(File.read(json_file)) }
10
+ let(:json_node) { json_tree }
11
+
12
+ subject { described_class.from_json(json_node) }
13
+ end
14
+
15
+ RSpec.shared_examples ".load" do
16
+ include_examples ".from_json"
17
+
18
+ subject { described_class.load(json_node) }
19
+
20
+ it { expect(subject).to be_kind_of(described_class) }
21
+ end
22
+
23
+ RSpec.shared_examples "JSON field" do |method: , json_key: , required: false, value: nil, map: nil|
24
+ context "\"#{json_key}\"" do
25
+ let(:json_value) { json_node[json_key] }
26
+
27
+ if value then let(:expected,&value)
28
+ else
29
+ if map then let(:expected) { map[json_value] }
30
+ else let(:expected) { json_value }
31
+ end
32
+ end
33
+
34
+ if required
35
+ it "must set ##{method}" do
36
+ expect(subject.send(method)).to eq(expected)
37
+ end
38
+
39
+ context "when the \"#{json_key}\" key is missing" do
40
+ before { json_node.delete(json_key) }
41
+
42
+ it do
43
+ expect {
44
+ described_class.load(json_node)
45
+ }.to raise_error(KeyError)
46
+ end
47
+ end
48
+ else
49
+ context "when the \"#{json_key}\" key is present" do
50
+ it "must set ##{method}" do
51
+ expect(subject.send(method)).to eq(expected)
52
+ end
53
+ end
54
+
55
+ context "when the \"#{json_key}\" key is missing" do
56
+ before { json_node.delete(json_key) }
57
+
58
+ it do
59
+ expect(subject.send(method)).to be(nil)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ RSpec.shared_examples "JSON Object field" do |method: , json_key: , required: false, object_class: |
67
+ context "\"#{json_key}\"" do
68
+ let(:json_value) { json_node[json_key] }
69
+
70
+ if required
71
+ it { expect(subject.send(method)).to be_kind_of(object_class) }
72
+
73
+ context "when the \"#{json_key}\" key is missing" do
74
+ before { json_node.delete(json_key) }
75
+
76
+ it do
77
+ expect {
78
+ described_class.load(json_node)
79
+ }.to raise_error(KeyError)
80
+ end
81
+ end
82
+ else
83
+ context "when the \"#{json_key}\" key is present" do
84
+ it { expect(subject.send(method)).to be_kind_of(object_class) }
85
+ end
86
+
87
+ context "when the \"#{json_key}\" key is missing" do
88
+ before { json_node.delete(json_key) }
89
+
90
+ it do
91
+ expect(subject.send(method)).to be(nil)
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ RSpec.shared_examples "JSON Array field" do |method: , json_key: , required: false, element_class: |
99
+ context "\"#{json_key}\"" do
100
+ let(:json_value) { json_node[json_key] }
101
+
102
+ if required
103
+ it { expect(subject.send(method)).to be_kind_of(Array) }
104
+ it { expect(subject.send(method)).to_not be_empty }
105
+ it { expect(subject.send(method)).to all(be_kind_of(element_class)) }
106
+
107
+ it "must parse every element of \"#{json_key}\"" do
108
+ expect(subject.send(method).length).to eq(json_value.length)
109
+ end
110
+
111
+ context "when the \"#{json_key}\" key is missing" do
112
+ before { json_node.delete(json_key) }
113
+
114
+ it do
115
+ expect {
116
+ described_class.load(json_node)
117
+ }.to raise_error(KeyError)
118
+ end
119
+ end
120
+ else
121
+ context "when the \"#{json_key}\" key is present" do
122
+ it { expect(subject.send(method)).to be_kind_of(Array) }
123
+ it { expect(subject.send(method)).to_not be_empty }
124
+ it { expect(subject.send(method)).to all(be_kind_of(element_class)) }
125
+ end
126
+
127
+ context "when the \"#{json_key}\" key is missing" do
128
+ before { json_node.delete(json_key) }
129
+
130
+ it do
131
+ expect(subject.send(method)).to eq([])
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'nvd/json_feeds/schema/timestamp'
3
+
4
+ describe "NVD::JSONFeeds::Schema::Timestamp" do
5
+ subject { Schema::Timestamp }
6
+
7
+ it { expect(subject).to be(CVESchema::CVE::Timestamp) }
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'rspec'
2
+ require 'nvd/json_feeds/version'
3
+
4
+ include NVD::JSONFeeds
5
+
6
+ RSpec.configure do |specs|
7
+ specs.filter_run_excluding :integration
8
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'feed_file_examples'
3
+ require 'nvd/json_feeds/zip_feed_file'
4
+
5
+ require 'fileutils'
6
+ require 'shellwords'
7
+
8
+ describe NVD::JSONFeeds::ZipFeedFile do
9
+ let(:fixtures_dir) { File.expand_path('../fixtures',__FILE__) }
10
+ let(:json_filename) { 'nvdcve-1.1-recent.json' }
11
+ let(:json_file) { File.join(fixtures_dir,json_filename) }
12
+
13
+ let(:zip_filename) { "#{json_filename}.zip" }
14
+ let(:dir) { File.join(fixtures_dir,'zip_feed_file') }
15
+ let(:path) { File.join(dir,zip_filename) }
16
+
17
+ subject { described_class.new(path) }
18
+
19
+ include_examples "FeedFile"
20
+
21
+ describe "#json_filename" do
22
+ it "must return the '.json' filename without the '.zip' extension" do
23
+ expect(subject.json_filename).to eq(json_filename)
24
+ end
25
+ end
26
+
27
+ describe "#read" do
28
+ it "must read the unziped contents" do
29
+ expect(subject.read).to be == File.read(json_file)
30
+ end
31
+
32
+ context "when unzip is not installed" do
33
+ before do
34
+ expect(subject).to receive(:`).and_raise(Errno::ENOENT)
35
+ end
36
+
37
+ it do
38
+ expect { subject.read }.to raise_error(ReadFailed)
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "#extract" do
44
+ let(:extracted_json_file) { File.join(dir,json_filename) }
45
+
46
+ it "must unzip the '.zip' file and return a JSONFeedfile" do
47
+ feed_file = subject.extract
48
+
49
+ expect(feed_file).to be_kind_of(JSONFeedFile)
50
+ expect(feed_file.path).to eq(extracted_json_file)
51
+ expect(File.file?(extracted_json_file)).to be(true)
52
+ end
53
+
54
+ context "when unzip fails" do
55
+ before do
56
+ allow(subject).to receive(:system).and_return(false)
57
+ end
58
+
59
+ it do
60
+ expect { subject.extract }.to raise_error(ExtractFailed)
61
+ end
62
+ end
63
+
64
+ after { FileUtils.rm_f(extracted_json_file) }
65
+ end
66
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'nvd/json_feeds/zip_feed_uri'
3
+
4
+ require 'fileutils'
5
+
6
+ describe NVD::JSONFeeds::ZipFeedURI do
7
+ let(:fixtures_dir) { File.expand_path('../fixtures',__FILE__) }
8
+
9
+ let(:name) { :recent }
10
+ let(:ext) { '.json.zip' }
11
+
12
+ subject { described_class.new(name,ext) }
13
+
14
+ describe "#download", :integration do
15
+ let(:download_dir) { File.join(fixtures_dir,'download') }
16
+ let(:dest) { File.join(download_dir,subject.filename) }
17
+
18
+ before do
19
+ FileUtils.mkdir_p(download_dir)
20
+ FileUtils.rm_f(dest)
21
+ end
22
+
23
+ it "must return a ZipFeedFile object for the newly downloaded file" do
24
+ feed_file = subject.download(dest)
25
+
26
+ expect(feed_file).to be_kind_of(ZipFeedFile)
27
+ expect(feed_file.path).to eq(dest)
28
+ expect(File.file?(dest)).to be(true)
29
+ end
30
+
31
+ after do
32
+ FileUtils.rm_f(dest)
33
+ end
34
+ end
35
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nvd-json_feeds
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Postmodern
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: multi_json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: cve_schema
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ description: Provides a Ruby API to NVD JSON Feeds.
56
+ email: postmodern.mod3@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files:
60
+ - ChangeLog.md
61
+ - LICENSE.txt
62
+ - README.md
63
+ files:
64
+ - ".document"
65
+ - ".github/workflows/ruby.yml"
66
+ - ".gitignore"
67
+ - ".rspec"
68
+ - ".yardopts"
69
+ - ChangeLog.md
70
+ - Gemfile
71
+ - LICENSE.txt
72
+ - README.md
73
+ - Rakefile
74
+ - gemspec.yml
75
+ - lib/nvd/json_feeds.rb
76
+ - lib/nvd/json_feeds/exceptions.rb
77
+ - lib/nvd/json_feeds/feed.rb
78
+ - lib/nvd/json_feeds/feed_file.rb
79
+ - lib/nvd/json_feeds/feed_uri.rb
80
+ - lib/nvd/json_feeds/gz_feed_file.rb
81
+ - lib/nvd/json_feeds/gz_feed_uri.rb
82
+ - lib/nvd/json_feeds/json_feed_file.rb
83
+ - lib/nvd/json_feeds/meta.rb
84
+ - lib/nvd/json_feeds/meta_feed_uri.rb
85
+ - lib/nvd/json_feeds/schema/configurations.rb
86
+ - lib/nvd/json_feeds/schema/configurations/node.rb
87
+ - lib/nvd/json_feeds/schema/cpe/has_uri.rb
88
+ - lib/nvd/json_feeds/schema/cpe/match.rb
89
+ - lib/nvd/json_feeds/schema/cpe/name.rb
90
+ - lib/nvd/json_feeds/schema/cve_feed.rb
91
+ - lib/nvd/json_feeds/schema/cve_item.rb
92
+ - lib/nvd/json_feeds/schema/cvss_v2.rb
93
+ - lib/nvd/json_feeds/schema/cvss_v3.rb
94
+ - lib/nvd/json_feeds/schema/has_data_version.rb
95
+ - lib/nvd/json_feeds/schema/impact.rb
96
+ - lib/nvd/json_feeds/schema/impact/base_metric_v2.rb
97
+ - lib/nvd/json_feeds/schema/impact/base_metric_v3.rb
98
+ - lib/nvd/json_feeds/schema/timestamp.rb
99
+ - lib/nvd/json_feeds/version.rb
100
+ - lib/nvd/json_feeds/zip_feed_file.rb
101
+ - lib/nvd/json_feeds/zip_feed_uri.rb
102
+ - nvd-json_feeds.gemspec
103
+ - spec/feed_file_examples.rb
104
+ - spec/feed_file_spec.rb
105
+ - spec/feed_spec.rb
106
+ - spec/feed_uri_spec.rb
107
+ - spec/fixtures/gz_feed_file/nvdcve-1.1-recent.json.gz
108
+ - spec/fixtures/nvdcve-1.1-recent.json
109
+ - spec/fixtures/zip_feed_file/nvdcve-1.1-recent.json.zip
110
+ - spec/gz_feed_file_spec.rb
111
+ - spec/gz_feed_uri_spec.rb
112
+ - spec/json_feed_file_spec.rb
113
+ - spec/json_feeds_spec.rb
114
+ - spec/meta_spec.rb
115
+ - spec/schema/configurations/node_spec.rb
116
+ - spec/schema/configurations_spec.rb
117
+ - spec/schema/cpe/match_spec.rb
118
+ - spec/schema/cpe/name_spec.rb
119
+ - spec/schema/cve_feed_spec.rb
120
+ - spec/schema/cve_item_spec.rb
121
+ - spec/schema/impact/base_metric_v2_spec.rb
122
+ - spec/schema/impact/base_metric_v3_spec.rb
123
+ - spec/schema/impact_spec.rb
124
+ - spec/schema/shared_examples.rb
125
+ - spec/schema/timestamp_spec.rb
126
+ - spec/spec_helper.rb
127
+ - spec/zip_feed_file_spec.rb
128
+ - spec/zip_feed_uri_spec.rb
129
+ homepage: https://github.com/postmodern/nvd-json_feeds#readme
130
+ licenses:
131
+ - MIT
132
+ metadata:
133
+ documentation_uri: https://rubydoc.info/gems/nvd-json_feeds
134
+ source_code_uri: https://github.com/postmodern/nvd-json_feeds.rb
135
+ bug_tracker_uri: https://github.com/postmodern/nvd-json_feeds.rb/issues
136
+ changelog_uri: https://github.com/postmodern/nvd-json_feeds.rb/blob/main/ChangeLog.md
137
+ post_install_message:
138
+ rdoc_options: []
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: 2.7.0
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ requirements: []
152
+ rubygems_version: 3.1.4
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: A Ruby API to NVD JSON Feeds
156
+ test_files: []