nvd_feed_api 0.0.1.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ module NvdFeedApi
2
+ VERSION = '0.0.1.rc1'.freeze
3
+ end
@@ -0,0 +1,45 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'nvd_feed_api/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'nvd_feed_api'
7
+ s.version = NvdFeedApi::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.date = '2017-09-10'
10
+ s.summary = 'API for NVD CVE feeds'
11
+ s.description = 'A simple API for NVD CVE feeds'
12
+ s.authors = ['Alexandre ZANNI']
13
+ s.email = 'alexandre.zanni@europe.com'
14
+ s.homepage = 'http://rubygems.org/gems/nvd_feed_api'
15
+ s.license = 'MIT'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
19
+ s.test_files = s.files.grep(%r{^(test)/})
20
+ s.require_paths = ['lib']
21
+
22
+ s.metadata = {
23
+ 'yard.run' => 'yard',
24
+ 'bug_tracker_uri' => 'https://gitlab.com/noraj/nvd_api/issues',
25
+ 'changelog_uri' => '',
26
+ 'documentation_uri' => '',
27
+ 'homepage_uri' => '',
28
+ 'source_code_uri' => 'https://gitlab.com/noraj/nvd_api/tree/master',
29
+ 'wiki_uri' => 'https://gitlab.com/noraj/nvd_api/wikis/home'
30
+ }
31
+
32
+ s.required_ruby_version = '~> 2.4'
33
+
34
+ s.add_dependency('archive-zip', '~> 0.10')
35
+ s.add_dependency('nokogiri', '~> 1.8')
36
+ s.add_dependency('oj', '~> 3.3')
37
+
38
+ s.add_development_dependency('bundler', '~> 1.15')
39
+ s.add_development_dependency('commonmarker', '~> 0.17') # for GMF support in YARD
40
+ s.add_development_dependency('github-markup', '~> 1.6') # for GMF support in YARD
41
+ s.add_development_dependency('minitest', '~> 5.10')
42
+ s.add_development_dependency('rake', '~> 12.3')
43
+ s.add_development_dependency('rubocop', '~> 0.51')
44
+ s.add_development_dependency('yard', '~> 0.9')
45
+ end
data/pages/EXAMPLES.md ADDED
@@ -0,0 +1,21 @@
1
+ # Examples
2
+
3
+ For all examples don't forget to add `require 'nvd_feed_api'`.
4
+
5
+ ## Download all feeds on disk
6
+
7
+ ```ruby
8
+ # Initialize the scraper.
9
+ s = NVDFeedScraper.new
10
+ # Scrap the NVD website to get the feeds attributes.
11
+ s.scrap
12
+ # Change the default feed storage location beacause default value is '/tmp/'.
13
+ # '/tmp/' is mounted as tmpFS and is cleaned at every start.
14
+ # This will considerably speed up your performance is you have to reboot.
15
+ NVDFeedScraper::Feed.default_storage_location = "/home/shark/Dev/cve_feeds"
16
+ # Create a {Feed} object for all available feeds
17
+ s.feeds(s.available_feeds).each do |f|
18
+ # and for each one download the JSON file and fill the attributes.
19
+ f.json_pull
20
+ end
21
+ ```
data/pages/FEATURES.md ADDED
@@ -0,0 +1,9 @@
1
+ # Features
2
+
3
+ More than data feed file management and downloading `nvd_feed_api` let you search for CVEs and automate a lot of tasks.
4
+
5
+ + **Deamon**: the scraper can run 24/7 without being restarted thanks to update methods
6
+ + **Documentation**: an API documentation with example is provided
7
+ + **Offline loading**: JSON feed files can be manually downloaded from the NVD website and put in the `destination_path` so:
8
+ - you can safely restart the scraper without having to re-download all feeds
9
+ - you can re-use already downloaded files in case of several scraper deployment
data/pages/INSTALL.md ADDED
@@ -0,0 +1,64 @@
1
+ # Installation
2
+
3
+ ## Production
4
+
5
+ ### Install from rubygems.org
6
+
7
+ ```
8
+ $ gem install nvd_feed_api
9
+ ```
10
+
11
+ ## Development
12
+
13
+ It's better to use [RVM](https://rvm.io/) to have latests version of ruby and to avoid trashing your system ruby.
14
+
15
+ To keep clean gem dependencies create a gemset with rvm:
16
+
17
+ ```
18
+ $ rvm gemset create nvd_feed_api
19
+ $ rvm gemset use nvd_feed_api
20
+ ```
21
+
22
+ ### Install from rubygems.org
23
+
24
+ ```
25
+ $ gem install --development nvd_feed_api
26
+ ```
27
+
28
+ ### Build from git
29
+
30
+ Just replace `x.x.x` with the gem version you see after `gem build`.
31
+
32
+ ```
33
+ $ git clone https://gitlab.com/noraj/nvd_api.git nvd_feed_api
34
+ $ cd nvd_feed_api
35
+ $ gem install bundle
36
+ $ ./bin/nvd_feed_api_setup
37
+ $ rake install
38
+ ```
39
+
40
+ You can use `nvd_feed_api_console` to launch `irb` with the API required.
41
+
42
+ Alternatively to build you can use:
43
+
44
+ ```
45
+ $ git clone https://gitlab.com/noraj/nvd_api.git nvd_feed_api
46
+ $ cd nvd_feed_api
47
+ $ gem install bundle
48
+ $ gem build nvd_feed_api.gemspec
49
+ $ gem install --development nvd_feed_api-x.x.x.gem
50
+ ```
51
+
52
+ Note: if an automatic install is needed you can get the version with `$ gem build nvd_feed_api.gemspec | grep Version | cut -d' ' -f4`.
53
+
54
+ ### Run the API in irb without installing the gem
55
+
56
+ Usefull when you want to try your changes without building the gem and re-installing it each time.
57
+
58
+ ```
59
+ $ git clone https://gitlab.com/noraj/nvd_api.git nvd_feed_api
60
+ $ cd nvd_feed_api
61
+ $ gem install bundle
62
+ $ ./bin/nvd_feed_api_setup
63
+ $ irb -Ilib -rnvd_feed_api
64
+ ```
@@ -0,0 +1,251 @@
1
+ require 'minitest/autorun'
2
+ require 'nvd_feed_api'
3
+ require 'date'
4
+
5
+ class NVDAPITest < Minitest::Test
6
+ def setup
7
+ @s = NVDFeedScraper.new
8
+ @s.scrap # needed for feeds method
9
+ end
10
+
11
+ def test_scraper_scrap
12
+ assert_equal(@s.scrap, 0, 'scrap method return nothing')
13
+ end
14
+
15
+ def test_scraper_feeds_noarg
16
+ assert_instance_of(Array, @s.feeds, "feeds doesn't return an array") # same as #assert(@s.feeds.instance_of?(Array), 'error')
17
+ refute_empty(@s.feeds, 'feeds returns an empty array')
18
+ end
19
+
20
+ def test_scraper_feeds_witharg
21
+ # one arg
22
+ assert_instance_of(NVDFeedScraper::Feed, @s.feeds('CVE-2017'), "feeds doesn't return a Feed object")
23
+ # two args
24
+ assert_instance_of(Array, @s.feeds('CVE-2017', 'CVE-Modified'), "feeds doesn't return an array")
25
+ refute_empty(@s.feeds('CVE-2017', 'CVE-Modified'), 'feeds returns an empty array')
26
+ # array arg
27
+ assert_instance_of(Array, @s.feeds(['CVE-2016', 'CVE-Recent']), "feeds doesn't return an array")
28
+ refute_empty(@s.feeds(['CVE-2016', 'CVE-Recent']), 'feeds returns an empty array')
29
+ # bad arg
30
+ assert_nil(@s.feeds('wrong'), 'feeds')
31
+ end
32
+
33
+ def test_scraper_available_feeds
34
+ assert_instance_of(Array, @s.available_feeds, "available_feeds doesn't return an array")
35
+ refute_empty(@s.available_feeds, 'available_feeds returns an empty array')
36
+ end
37
+
38
+ def test_scraper_available_cves
39
+ assert_instance_of(Array, @s.available_cves, "available_cves doesn't return an array")
40
+ refute_empty(@s.available_cves, 'available_cves returns an empty array')
41
+ end
42
+
43
+ def test_scraper_cve
44
+ # one arg
45
+ assert_instance_of(Hash, @s.cve('CVE-2015-0235'), "cve doesn't return a hash")
46
+ # two args
47
+ assert_instance_of(Array, @s.cve('CVE-2015-0235', 'CVE-2013-3893'), "cve doesn't return an array")
48
+ refute_empty(@s.cve('CVE-2015-0235', 'CVE-2013-3893'), 'cve returns an empty array')
49
+ # array arg
50
+ assert_instance_of(Array, @s.cve(['CVE-2014-0160', 'cve-2009-3555']), "cve doesn't return an array")
51
+ refute_empty(@s.cve(['CVE-2014-0160', 'cve-2009-3555']), 'cve returns an empty array')
52
+ # bad arg
53
+ ## string but not a CVE ID
54
+ assert_raises(RuntimeError) do
55
+ err = @s.cve('e')
56
+ assert_equal(err.message, 'bad CVE name')
57
+ end
58
+ ## correct CVE ID but bad year
59
+ assert_raises(RuntimeError) do
60
+ err = @s.cve('CVE-2001-31337')
61
+ assert_equal(err.message, 'bad CVE year in ["CVE-2001-31337"]')
62
+ end
63
+ ## correct CVE ID and year but unexisting CVE
64
+ assert_nil(@s.cve('CVE-2004-31337'))
65
+ ## correct CVE ID and year but unexisting CVE with array arg
66
+ assert_raises(RuntimeError) do
67
+ err = @s.cve(['CVE-2004-31337', 'CVE-2005-31337'])
68
+ assert_equal(err.message, 'CVE-2005-31337 are unexisting CVEs in this feed')
69
+ end
70
+ ## wrong arg type
71
+ assert_raises(RuntimeError) do
72
+ err = @s.cve(1)
73
+ assert_equal(err.message, 'the provided argument (1) is nor a String or an Array')
74
+ end
75
+ end
76
+
77
+ def test_scraper_update_feeds
78
+ f2017, f2016, f_modified = @s.feeds('CVE-2017', 'CVE-2016', 'CVE-Modified')
79
+ # one arg
80
+ # can't use assert_instance_of because there is no boolean class
81
+ assert(%w[TrueClass FalseClass].include?(@s.update_feeds(f2017).class.to_s), "update_feeds doesn't return a boolean")
82
+ # two args
83
+ assert_instance_of(Array, @s.update_feeds(f2017, f2016), "update_feeds doesn't return an array")
84
+ refute_empty(@s.update_feeds(f2017, f2016), 'update_feeds returns an empty array')
85
+ # array arg
86
+ assert_instance_of(Array, @s.update_feeds([f2017, f_modified]), "update_feeds doesn't return an array")
87
+ refute_empty(@s.update_feeds([f2017, f_modified]), 'update_feeds returns an empty array')
88
+ # bad arg
89
+ ## wrong arg type
90
+ assert_raises(RuntimeError) do
91
+ err = @s.update_feeds(1)
92
+ assert_equal(err.message, 'the provided argument 1 is not a Feed or an Array')
93
+ end
94
+ ## empty array
95
+ assert_empty(@s.update_feeds([]))
96
+ end
97
+
98
+ def test_feed_default_storage_location
99
+ # save default value / save context
100
+ default_val = NVDFeedScraper::Feed.default_storage_location
101
+ # check type
102
+ assert_instance_of(String, default_val, "default_storage_location doesn't return a string")
103
+ # check new value
104
+ new_val = '/srv/downloads/'
105
+ assert_equal(NVDFeedScraper::Feed.default_storage_location = new_val, new_val, 'the new value was not set properly')
106
+ # put the default value back / restore context
107
+ NVDFeedScraper::Feed.default_storage_location = default_val
108
+ end
109
+
110
+ def test_feed_attributes
111
+ name = 'CVE-2010'
112
+ meta_url = 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2010.meta'
113
+ gz_url = 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2010.json.gz'
114
+ zip_url = 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2010.json.zip'
115
+ f = @s.feeds('CVE-2010')
116
+ # Test name
117
+ assert_instance_of(String, f.name, "name doesn't return a string")
118
+ refute_empty(f.name, 'name is empty')
119
+ assert_equal(f.name, name, 'The name of the feed was modified')
120
+ # Test updated
121
+ assert_instance_of(String, f.updated, "updated doesn't return a string")
122
+ refute_empty(f.updated, 'updated is empty')
123
+ # Test meta
124
+ assert_nil(f.meta)
125
+ # Test json_file
126
+ assert_nil(f.json_file)
127
+ # Test gz_url
128
+ assert_instance_of(String, f.gz_url, "gz_url doesn't return a string")
129
+ refute_empty(f.gz_url, 'gz_url is empty')
130
+ assert_equal(f.gz_url, gz_url, 'The gz_url of the feed was modified')
131
+ # Test zip_url
132
+ assert_instance_of(String, f.zip_url, "zip_url doesn't return a string")
133
+ refute_empty(f.zip_url, 'zip_url is empty')
134
+ assert_equal(f.zip_url, zip_url, 'The zip_url url of the feed was modified')
135
+ # Test meta_url
136
+ assert_instance_of(String, f.meta_url, "meta_url doesn't return a string")
137
+ refute_empty(f.meta_url, 'meta_url is empty')
138
+ assert_equal(f.meta_url, meta_url, 'The meta_url url of the feed was modified')
139
+ end
140
+
141
+ def test_feed_available_cves
142
+ f = @s.feeds('CVE-2011')
143
+ f.json_pull
144
+ assert_instance_of(Array, f.available_cves, "available_cves doesn't return an array")
145
+ refute_empty(f.available_cves, 'available_cves returns an empty array')
146
+ end
147
+
148
+ def test_feed_cve
149
+ f = @s.feeds('CVE-2012')
150
+ f.json_pull
151
+ # one arg
152
+ assert_instance_of(Hash, @s.cve('CVE-2012-4969'), "cve doesn't return a hash")
153
+ # two args
154
+ assert_instance_of(Array, @s.cve('CVE-2012-4969', 'cve-2012-1889'), "cve doesn't return an array")
155
+ refute_empty(@s.cve('CVE-2012-4969', 'cve-2012-1889'), 'cve returns an empty array')
156
+ # array arg
157
+ assert_instance_of(Array, @s.cve(['CVE-2012-4969', 'cve-2012-1889']), "cve doesn't return an array")
158
+ refute_empty(@s.cve(['CVE-2012-4969', 'cve-2012-1889']), 'cve returns an empty array')
159
+ # bad arg
160
+ ## string but not a CVE ID
161
+ assert_raises(RuntimeError) do
162
+ err = @s.cve('e')
163
+ assert_equal(err.message, 'bad CVE name')
164
+ end
165
+ ## correct CVE ID but bad year
166
+ assert_nil(@s.cve('CVE-2004-31337'))
167
+ ## correct CVE ID and but year not in the feed with array arg
168
+ assert_raises(RuntimeError) do
169
+ err = @s.cve(['CVE-2004-31337', 'CVE-2005-31337'])
170
+ assert_equal(err.message, 'CVE-2004-31337, CVE-2005-31337 are unexisting CVEs in this feed')
171
+ end
172
+ ## wrong arg type
173
+ assert_raises(RuntimeError) do
174
+ err = @s.cve(1)
175
+ assert_equal(err.message, 'the provided argument (1) is nor a String or an Array')
176
+ end
177
+ end
178
+
179
+ def test_feed_download_gz
180
+ f = @s.feeds('CVE-2013')
181
+ return_value = f.download_gz
182
+ assert_instance_of(String, return_value, "download_gz doesn't return a string")
183
+ refute_empty(return_value, 'download_gz returns an empty string')
184
+ assert(File.file?(return_value), 'download_gz returns an unexisting file')
185
+ end
186
+
187
+ def test_feed_download_zip
188
+ f = @s.feeds('CVE-2003')
189
+ return_value = f.download_zip
190
+ assert_instance_of(String, return_value, "download_zip doesn't return a string")
191
+ refute_empty(return_value, 'download_zip returns an empty string')
192
+ assert(File.file?(return_value), 'download_zip returns an unexisting file')
193
+ end
194
+
195
+ def test_feed_json_pull
196
+ f = @s.feeds('CVE-2004')
197
+ return_value = f.json_pull
198
+ assert_instance_of(String, return_value, "json_pull doesn't return a string")
199
+ refute_empty(return_value, 'json_pull returns an empty string')
200
+ assert(File.file?(return_value), 'json_pull returns an unexisting file')
201
+ end
202
+
203
+ def test_feed_meta_pull
204
+ f = @s.feeds('CVE-2005')
205
+ return_value = f.meta_pull
206
+ assert_instance_of(NVDFeedScraper::Meta, return_value, "meta_pull doesn't return a Meta object")
207
+ end
208
+
209
+ def test_meta_parse_noarg
210
+ m = NVDFeedScraper::Meta.new('https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2015.meta')
211
+ assert_equal(m.parse, 0, 'parse method return nothing')
212
+ end
213
+
214
+ def test_meta_parse_witharg
215
+ m = NVDFeedScraper::Meta.new
216
+ meta_url = 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2015.meta'
217
+ assert_equal(m.parse(meta_url), 0, 'parse method return nothing')
218
+ end
219
+
220
+ def test_meta_url_setter
221
+ m = NVDFeedScraper::Meta.new
222
+ meta_url = 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2015.meta'
223
+ assert_equal(m.url = meta_url, meta_url, 'the meta URL is not set correctly')
224
+ end
225
+
226
+ def test_meta_attributes
227
+ m = NVDFeedScraper::Meta.new
228
+ meta_url = 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2015.meta'
229
+ m.url = meta_url
230
+ m.parse
231
+ # Test gz_size
232
+ assert_instance_of(String, m.gz_size, "Meta gz_size method doesn't return a string")
233
+ assert(m.gz_size.match?(/[0-9]+/), 'Meta gz_size is not an integer')
234
+ # Test last_modified_date
235
+ assert_instance_of(String, m.last_modified_date, "Meta last_modified_date method doesn't return a string")
236
+ ## Date and time of day for calendar date (extended) '%FT%T%:z'
237
+ assert(Date.rfc3339(m.last_modified_date), 'Meta last_modified_date is not a rfc3339 date')
238
+ # Test sha256
239
+ assert_instance_of(String, m.sha256, "Meta sha256 method doesn't return a string")
240
+ assert(m.sha256.match?(/[0-9A-F]{64}/), 'Meta sha256 is not a sha256 string matching /[0-9A-F]{64}/')
241
+ # Test size
242
+ assert_instance_of(String, m.size, "Meta size method doesn't return a string")
243
+ assert(m.size.match?(/[0-9]+/), 'Meta size is not an integer')
244
+ # Test url
245
+ assert_instance_of(String, m.url, "Meta url method doesn't return a string")
246
+ assert_equal(m.url, meta_url, 'The Meta url was modified')
247
+ # Test zip_size
248
+ assert_instance_of(String, m.zip_size, "Meta zip_size method doesn't return a string")
249
+ assert(m.zip_size.match?(/[0-9]+/), 'Meta zip_size is not an integer')
250
+ end
251
+ end
metadata ADDED
@@ -0,0 +1,211 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nvd_feed_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.rc1
5
+ platform: ruby
6
+ authors:
7
+ - Alexandre ZANNI
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: archive-zip
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: oj
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.15'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.15'
69
+ - !ruby/object:Gem::Dependency
70
+ name: commonmarker
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.17'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.17'
83
+ - !ruby/object:Gem::Dependency
84
+ name: github-markup
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.6'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '5.10'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '5.10'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '12.3'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '12.3'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.51'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.51'
139
+ - !ruby/object:Gem::Dependency
140
+ name: yard
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.9'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.9'
153
+ description: A simple API for NVD CVE feeds
154
+ email: alexandre.zanni@europe.com
155
+ executables:
156
+ - nvd_feed_api
157
+ - nvd_feed_api_console
158
+ - nvd_feed_api_setup
159
+ extensions: []
160
+ extra_rdoc_files: []
161
+ files:
162
+ - ".gitignore"
163
+ - ".rubocop.yml"
164
+ - ".yardopts"
165
+ - Gemfile
166
+ - LICENSE.txt
167
+ - README.md
168
+ - Rakefile
169
+ - bin/nvd_feed_api
170
+ - bin/nvd_feed_api_console
171
+ - bin/nvd_feed_api_setup
172
+ - lib/nvd_feed_api.rb
173
+ - lib/nvd_feed_api/version.rb
174
+ - nvd_feed_api.gemspec
175
+ - pages/EXAMPLES.md
176
+ - pages/FEATURES.md
177
+ - pages/INSTALL.md
178
+ - test/test_nvd_feed_api.rb
179
+ homepage: http://rubygems.org/gems/nvd_feed_api
180
+ licenses:
181
+ - MIT
182
+ metadata:
183
+ yard.run: yard
184
+ bug_tracker_uri: https://gitlab.com/noraj/nvd_api/issues
185
+ changelog_uri: ''
186
+ documentation_uri: ''
187
+ homepage_uri: ''
188
+ source_code_uri: https://gitlab.com/noraj/nvd_api/tree/master
189
+ wiki_uri: https://gitlab.com/noraj/nvd_api/wikis/home
190
+ post_install_message:
191
+ rdoc_options: []
192
+ require_paths:
193
+ - lib
194
+ required_ruby_version: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - "~>"
197
+ - !ruby/object:Gem::Version
198
+ version: '2.4'
199
+ required_rubygems_version: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - ">"
202
+ - !ruby/object:Gem::Version
203
+ version: 1.3.1
204
+ requirements: []
205
+ rubyforge_project:
206
+ rubygems_version: 2.6.13
207
+ signing_key:
208
+ specification_version: 4
209
+ summary: API for NVD CVE feeds
210
+ test_files:
211
+ - test/test_nvd_feed_api.rb