nvd_feed_api 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 38ab69d805d125729995fc9ea26d79e0b324414f
4
- data.tar.gz: 7c9838e134a5f503d21979a5915db3cd9d9e823b
2
+ SHA256:
3
+ metadata.gz: d03fa81fd296a62aba7a9356b3c41135851febb254af4db13758c5b76475739f
4
+ data.tar.gz: c0d716121dccaeaee6944ccd3e0d85cf59854084ae68d0f7347fb678dc4760bf
5
5
  SHA512:
6
- metadata.gz: eda8d75faf07c0189cf6fdf9bbea8296fce70f0aaf380e8af2a3af83d1216f6ae360319cd01e727659f4cac527cd284ac9e9555dfb1dc79f1982f93309940129
7
- data.tar.gz: eb9eb999eee1ef44b3b64de314f3fb37b0cc857df67a7ae580ed6f71ef51e827f3ec93de5b5fdfdd0205a0f280f6825e673a858e67248c9a684dc77a1342adea
6
+ metadata.gz: b5bef50a5709e8bd53a138110e80f6a5ee34d02f5849e1a3d9add0c9573e963926adbdf6eeb610b75d04d25d285b4450b8e99aa724582d382ed072ef46c89a8a
7
+ data.tar.gz: 7be0a9191d6efb0e7a80e7a868d8d019186268008473e3e731fe9e4e3e1d21b85b7cc6189c912d5315495dbb12dbaaa688ca077823ba844a01d91b11696ae954
@@ -0,0 +1,3 @@
1
+ github: noraj
2
+ issuehunt: noraj
3
+ ko_fi: noraj
data/.gitignore CHANGED
@@ -50,4 +50,4 @@ build-iPhoneSimulator/
50
50
  .rvmrc
51
51
 
52
52
  # do not check Gemfile.lock fror gems
53
- Gemfile.lock
53
+ #Gemfile.lock
data/.gitlab-ci.yml CHANGED
@@ -1,36 +1,43 @@
1
1
  # Official language image. Look for the different tagged releases at:
2
2
  # https://hub.docker.com/r/library/ruby/tags/
3
- image: ruby:2.4-alpine
4
3
 
4
+ # Caching: https://docs.gitlab.com/ee/ci/caching/#caching-ruby-dependencies
5
5
  cache:
6
+ key: ${CI_COMMIT_REF_SLUG}
6
7
  paths:
7
8
  - vendor/ruby # cache gems in between builds
8
9
 
9
10
  before_script:
10
11
  - ruby -v # Print out ruby version for debugging
11
- - gem install bundler --no-ri --no-rdoc # Bundler is not installed with the image
12
+ - gem install bundler --no-document # Bundler is not installed with the image
12
13
  # install nproc (coreutils) for bundle -j
13
14
  # install git for building the gemspec
14
15
  # install make, gcc for building gem native extension (commonmarker)
15
16
  # libc-dev for musl-dev dependency (stdlib.h) needed by gcc
16
17
  - apk --no-cache add coreutils git make gcc libc-dev
17
18
  - bundle install -j $(nproc) --path vendor # Install dependencies into ./vendor/ruby
18
- - rake install # install the gem
19
+ - bundle exec rake install # install the gem
19
20
 
20
- rubocop:
21
+ # Anchors: https://docs.gitlab.com/ee/ci/yaml/README.html#anchors
22
+ .test_template: &job_definition
21
23
  stage: test
22
24
  script:
23
- - rubocop
25
+ - bundle exec rubocop
26
+ - bundle exec rake test
24
27
 
25
- test:
26
- stage: test
27
- script:
28
- - rake test
28
+ #test:2.4:
29
+ # <<: *job_definition
30
+ # image: ruby:2.4-alpine
31
+
32
+ test:3.1:
33
+ <<: *job_definition
34
+ image: ruby:3.1-alpine
29
35
 
30
36
  pages:
31
37
  stage: deploy
38
+ image: ruby:3.1-alpine
32
39
  script:
33
- - yard doc
40
+ - bundle exec yard doc
34
41
  - mkdir public
35
42
  - mv doc/* public/
36
43
  artifacts:
data/.rubocop.yml CHANGED
@@ -1,5 +1,12 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.4
2
+ TargetRubyVersion: 2.7
3
+ NewCops: enable
4
+
5
+ Layout/HashAlignment:
6
+ EnforcedHashRocketStyle: table
7
+
8
+ Layout/LineLength:
9
+ Enabled: false
3
10
 
4
11
  # Rubocop is too stupid too see that the variable is used
5
12
  Lint/UselessAssignment:
@@ -18,10 +25,7 @@ Metrics/ClassLength:
18
25
  Enabled: false
19
26
 
20
27
  Metrics/CyclomaticComplexity:
21
- Max: 20
22
-
23
- Metrics/LineLength:
24
- Enabled: false
28
+ Max: 25
25
29
 
26
30
  Metrics/MethodLength:
27
31
  Max: 100
@@ -35,6 +39,9 @@ Naming/VariableName:
35
39
  Security/JSONLoad:
36
40
  Enabled: false
37
41
 
42
+ Style/CaseLikeIf:
43
+ Enabled: true
44
+
38
45
  Style/FrozenStringLiteralComment:
39
46
  EnforcedStyle: never
40
47
 
@@ -44,3 +51,6 @@ Style/PerlBackrefs:
44
51
  # Allow explicit return
45
52
  Style/RedundantReturn:
46
53
  Enabled: false
54
+
55
+ Style/WordArray:
56
+ EnforcedStyle: brackets
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 3.1.0
data/.yardopts CHANGED
@@ -1,6 +1,8 @@
1
1
  --protected
2
2
  --private
3
3
  --output-dir doc/
4
+ --markup markdown
5
+ --markup-provider commonmarker
4
6
  -
5
7
  --main README.md
6
8
  LICENSE.txt
data/Gemfile CHANGED
@@ -1,4 +1,27 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in .gemspec
4
3
  gemspec
4
+
5
+ group :runtime, :cli do
6
+ gem 'archive-zip', '~> 0.11'
7
+ gem 'nokogiri', '~> 1.11'
8
+ gem 'oj', '>= 3.7.8', '<4'
9
+ end
10
+
11
+ group :development, :install do
12
+ gem 'bundler', '~> 2.1'
13
+ end
14
+
15
+ group :development, :test do
16
+ gem 'minitest', '~> 5.12'
17
+ gem 'rake', '~> 13.0'
18
+ end
19
+
20
+ group :development, :lint do
21
+ gem 'rubocop', '~> 1.23'
22
+ end
23
+
24
+ group :development, :docs do
25
+ gem 'commonmarker', '~> 0.21' # for markdown support in YARD
26
+ gem 'yard', ['>= 0.9.27', '< 0.10']
27
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,64 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ nvd_feed_api (0.4.0)
5
+ archive-zip (~> 0.11)
6
+ nokogiri (~> 1.11)
7
+ oj (>= 3.7.8, < 4)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ archive-zip (0.12.0)
13
+ io-like (~> 0.3.0)
14
+ ast (2.4.2)
15
+ commonmarker (0.23.2)
16
+ io-like (0.3.1)
17
+ mini_portile2 (2.7.1)
18
+ minitest (5.15.0)
19
+ nokogiri (1.13.1)
20
+ mini_portile2 (~> 2.7.0)
21
+ racc (~> 1.4)
22
+ oj (3.13.10)
23
+ parallel (1.21.0)
24
+ parser (3.0.3.2)
25
+ ast (~> 2.4.1)
26
+ racc (1.6.0)
27
+ rainbow (3.0.0)
28
+ rake (13.0.6)
29
+ regexp_parser (2.2.0)
30
+ rexml (3.2.5)
31
+ rubocop (1.24.1)
32
+ parallel (~> 1.10)
33
+ parser (>= 3.0.0.0)
34
+ rainbow (>= 2.2.2, < 4.0)
35
+ regexp_parser (>= 1.8, < 3.0)
36
+ rexml
37
+ rubocop-ast (>= 1.15.1, < 2.0)
38
+ ruby-progressbar (~> 1.7)
39
+ unicode-display_width (>= 1.4.0, < 3.0)
40
+ rubocop-ast (1.15.1)
41
+ parser (>= 3.0.1.1)
42
+ ruby-progressbar (1.11.0)
43
+ unicode-display_width (2.1.0)
44
+ webrick (1.7.0)
45
+ yard (0.9.27)
46
+ webrick (~> 1.7.0)
47
+
48
+ PLATFORMS
49
+ ruby
50
+
51
+ DEPENDENCIES
52
+ archive-zip (~> 0.11)
53
+ bundler (~> 2.1)
54
+ commonmarker (~> 0.21)
55
+ minitest (~> 5.12)
56
+ nokogiri (~> 1.11)
57
+ nvd_feed_api!
58
+ oj (>= 3.7.8, < 4)
59
+ rake (~> 13.0)
60
+ rubocop (~> 1.23)
61
+ yard (>= 0.9.27, < 0.10)
62
+
63
+ BUNDLED WITH
64
+ 2.3.6
data/README.md CHANGED
@@ -5,6 +5,7 @@
5
5
  [![Gem stable](https://img.shields.io/gem/dv/nvd_feed_api/stable.svg)][rubygems]
6
6
  [![Gem latest](https://img.shields.io/gem/dtv/nvd_feed_api.svg)][rubygems]
7
7
  [![Gem total download](https://img.shields.io/gem/dt/nvd_feed_api.svg)][rubygems]
8
+ [![Rawsec's CyberSecurity Inventory](https://inventory.rawsec.ml/img/badges/Rawsec-inventoried-FF5050_flat.svg)](https://inventory.rawsec.ml/tools.html#nvd_feed_api)
8
9
 
9
10
  [rubygems]:https://rubygems.org/gems/nvd_feed_api/
10
11
 
@@ -12,7 +13,7 @@
12
13
 
13
14
  **nvd_feed_api** is a simple ruby API for NVD CVE feeds.
14
15
 
15
- The API will help you to download and manage NVD Data Feeds, search for CVEs, build your vulerability assesment platform or vulnerability database.
16
+ The API will help you to download and manage NVD Data Feeds, search for CVEs, build your vulnerability assessment platform or vulnerability database.
16
17
 
17
18
  Name | Link
18
19
  --- | ---
@@ -13,7 +13,7 @@ class NVDFeedScraper
13
13
  class Feed
14
14
  class << self
15
15
  # Get / set default feed storage location, where will be stored JSON feeds and archives by default.
16
- # @return [String] default feed storage location. Default to +/tmp/+.
16
+ # @return [String] default feed storage location. Default to `/tmp/`.
17
17
  # @example
18
18
  # NVDFeedScraper::Feed.default_storage_location = '/srv/downloads/'
19
19
  attr_accessor :default_storage_location
@@ -69,11 +69,11 @@ class NVDFeedScraper
69
69
  # f.json_file # => "/tmp/nvdcve-1.0-2014.json"
70
70
  attr_reader :json_file
71
71
 
72
- # @return [String] the type of the feed, should always be +CVE+.
72
+ # @return [String] the type of the feed, should always be `CVE`.
73
73
  # @note Return nil if not previously loaded by {#json_pull}.
74
74
  attr_reader :data_type
75
75
 
76
- # @return [String] the format of the feed, should always be +MITRE+.
76
+ # @return [String] the format of the feed, should always be `MITRE`.
77
77
  # @note Return nil if not previously loaded by {#json_pull}.
78
78
  attr_reader :data_format
79
79
 
@@ -96,7 +96,7 @@ class NVDFeedScraper
96
96
  # @param gz_url [String] see {#gz_url}.
97
97
  # @param zip_url [String] see {#zip_url}.
98
98
  def initialize(name, updated, meta_url, gz_url, zip_url)
99
- # Frome meta file
99
+ # From meta file
100
100
  @name = name
101
101
  @updated = updated
102
102
  @meta_url = meta_url
@@ -146,7 +146,7 @@ class NVDFeedScraper
146
146
  # Download the JSON feed and fill the attribute.
147
147
  # @param opts [Hash] see {#download_file}.
148
148
  # @return [String] the path of the saved JSON file. Default use {Feed#default_storage_location}.
149
- # @note Will downlaod and save the zip of the JSON file, unzip and save it. This massively consume time.
149
+ # @note Will download and save the zip of the JSON file, unzip and save it. This massively consume time.
150
150
  # @see #json_file
151
151
  def json_pull(opts = {})
152
152
  opts[:destination_path] ||= Feed.default_storage_location
@@ -184,6 +184,7 @@ class NVDFeedScraper
184
184
  # Verify hash integrity
185
185
  computed_h = Digest::SHA256.file(@json_file)
186
186
  raise "File corruption: #{@json_file}" unless meta.sha256.casecmp(computed_h.hexdigest).zero?
187
+
187
188
  # update data
188
189
  doc = Oj::Doc.open(File.read(@json_file))
189
190
  @data_type = doc.fetch('/CVE_data_type')
@@ -223,11 +224,15 @@ class NVDFeedScraper
223
224
  def cve(*arg_cve)
224
225
  raise 'json_file is nil, it needs to be populated with json_pull' if @json_file.nil?
225
226
  raise "json_file (#{@json_file}) doesn't exist" unless File.file?(@json_file)
227
+
226
228
  return_value = nil
227
229
  raise 'no argument provided, 1 or more expected' if arg_cve.empty?
230
+
228
231
  if arg_cve.length == 1
229
- if arg_cve[0].is_a?(String)
232
+ case arg_cve[0]
233
+ when String
230
234
  raise "bad CVE name (#{arg_cve[0]})" unless /^CVE-[0-9]{4}-[0-9]{4,}$/i.match?(arg_cve[0])
235
+
231
236
  doc = Oj::Doc.open(File.read(@json_file))
232
237
  # Quicker than doc.fetch('/CVE_Items').size
233
238
  (1..@data_number_of_cves).each do |i|
@@ -237,13 +242,14 @@ class NVDFeedScraper
237
242
  end
238
243
  end
239
244
  doc.close
240
- elsif arg_cve[0].is_a?(Array)
245
+ when Array
241
246
  return_value = []
242
247
  # Sorting CVE can allow us to parse quicker
243
248
  # Upcase to be sure include? works
244
249
  cves_to_find = arg_cve[0].map(&:upcase).sort
245
250
  raise 'one of the provided arguments is not a String' unless cves_to_find.all? { |x| x.is_a?(String) }
246
251
  raise 'bad CVE name' unless cves_to_find.all? { |x| /^CVE-[0-9]{4}-[0-9]{4,}$/i.match?(x) }
252
+
247
253
  doc = Oj::Doc.open(File.read(@json_file))
248
254
  # Quicker than doc.fetch('/CVE_Items').size
249
255
  (1..@data_number_of_cves).each do |i|
@@ -273,6 +279,7 @@ class NVDFeedScraper
273
279
  def available_cves
274
280
  raise 'json_file is nil, it needs to be populated with json_pull' if @json_file.nil?
275
281
  raise "json_file (#{@json_file}) doesn't exist" unless File.file?(@json_file)
282
+
276
283
  doc = Oj::Doc.open(File.read(@json_file))
277
284
  # Quicker than doc.fetch('/CVE_Items').size
278
285
  cve_names = []
@@ -290,6 +297,7 @@ class NVDFeedScraper
290
297
  # 'CVE-2007'
291
298
  def name=(arg_name)
292
299
  raise "name (#{arg_name}) is not a string" unless arg_name.is_a?(String)
300
+
293
301
  @name = arg_name
294
302
  end
295
303
 
@@ -299,6 +307,7 @@ class NVDFeedScraper
299
307
  # '10/19/2017 3:27:02 AM -04:00'
300
308
  def updated=(arg_updated)
301
309
  raise "updated date (#{arg_updated}) is not a string" unless arg_updated.is_a?(String)
310
+
302
311
  @updated = arg_updated
303
312
  end
304
313
 
@@ -308,6 +317,7 @@ class NVDFeedScraper
308
317
  # 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2007.meta'
309
318
  def meta_url=(arg_meta_url)
310
319
  raise "meta_url (#{arg_meta_url}) is not a string" unless arg_meta_url.is_a?(String)
320
+
311
321
  @meta_url = arg_meta_url
312
322
  end
313
323
 
@@ -317,6 +327,7 @@ class NVDFeedScraper
317
327
  # 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2007.json.gz'
318
328
  def gz_url=(arg_gz_url)
319
329
  raise "gz_url (#{arg_gz_url}) is not a string" unless arg_gz_url.is_a?(String)
330
+
320
331
  @gz_url = arg_gz_url
321
332
  end
322
333
 
@@ -326,6 +337,7 @@ class NVDFeedScraper
326
337
  # 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2007.json.zip'
327
338
  def zip_url=(arg_zip_url)
328
339
  raise "zip_url (#{arg_zip_url}) is not a string" unless arg_zip_url.is_a?(String)
340
+
329
341
  @zip_url = arg_zip_url
330
342
  end
331
343
 
@@ -352,30 +364,28 @@ class NVDFeedScraper
352
364
  uri = URI(file_url)
353
365
  filename = uri.path.split('/').last
354
366
  destination_file = destination_path + filename
355
- unless opts[:sha256].nil?
356
- if File.file?(destination_file)
357
- # Verify hash to see if it is the latest
358
- computed_h = Digest::SHA256.file(destination_file)
359
- skip_download = true if opts[:sha256].casecmp(computed_h.hexdigest).zero?
360
- end
367
+ if !opts[:sha256].nil? && File.file?(destination_file)
368
+ # Verify hash to see if it is the latest
369
+ computed_h = Digest::SHA256.file(destination_file)
370
+ skip_download = true if opts[:sha256].casecmp(computed_h.hexdigest).zero?
361
371
  end
362
372
  unless skip_download
363
373
  res = Net::HTTP.get_response(uri)
364
374
  raise "#{file_url} ended with #{res.code} #{res.message}" unless res.is_a?(Net::HTTPSuccess)
365
- open(destination_file, 'wb') do |file|
366
- file.write(res.body)
367
- end
375
+
376
+ File.binwrite(destination_file, res.body)
368
377
  end
369
378
  return destination_file
370
379
  end
371
380
 
372
381
  # Update the feed
373
382
  # @param fresh_feed [Feed] the fresh feed from which the feed will be updated.
374
- # @return [Boolean] +true+ if the feed was updated, +false+ if it wasn't.
383
+ # @return [Boolean] `true` if the feed was updated, `false` if it wasn't.
375
384
  # @note Is not intended to be used directly, use {NVDFeedScraper#update_feeds} instead.
376
385
  def update!(fresh_feed)
377
386
  return_value = false
378
387
  raise "#{fresh_feed} is not a Feed" unless fresh_feed.is_a?(Feed)
388
+
379
389
  # update attributes
380
390
  if updated != fresh_feed.updated
381
391
  self.name = fresh_feed.name
@@ -76,26 +76,26 @@ class NVDFeedScraper
76
76
  # Parse the meta file from the URL and set the attributes.
77
77
  # @overload parse
78
78
  # Parse the meta file from the URL and set the attributes.
79
- # @return [Integer] Returns +0+ when there is no error.
79
+ # @return [Integer] Returns `0` when there is no error.
80
80
  # @overload parse(url)
81
81
  # Set the URL of the meta file of the feed and
82
82
  # parse the meta file from the URL and set the attributes.
83
83
  # @param url [String] see {Feed.meta_url}
84
- # @return [Integer] Returns +0+ when there is no error.
84
+ # @return [Integer] Returns `0` when there is no error.
85
85
  def parse(*arg)
86
- if arg.empty?
87
- elsif arg.length == 1 # arg = url
86
+ if arg.length == 1 # arg = url
88
87
  self.url = arg[0]
89
- else
88
+ elsif arg.length > 1
90
89
  raise 'Too much arguments'
91
90
  end
92
91
 
93
92
  raise "Can't parse if the URL is empty" if @url.nil?
93
+
94
94
  uri = URI(@url)
95
95
 
96
96
  meta = Net::HTTP.get(uri)
97
97
 
98
- meta = Hash[meta.split.map { |x| x.split(':', 2) }]
98
+ meta = meta.split.to_h { |x| x.split(':', 2) }
99
99
 
100
100
  raise 'no lastModifiedDate attribute found' unless meta['lastModifiedDate']
101
101
  raise 'no valid size attribute found' unless /[0-9]+/.match?(meta['size'])
@@ -1,3 +1,3 @@
1
1
  module NvdFeedApi
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.4.0'.freeze
3
3
  end
data/lib/nvd_feed_api.rb CHANGED
@@ -18,8 +18,9 @@ require 'nvd_feed_api/feed'
18
18
  # scraper.feeds("CVE-2007")
19
19
  # cve2007, cve2015 = scraper.feeds("CVE-2007", "CVE-2015")
20
20
  class NVDFeedScraper
21
+ BASE = 'https://nvd.nist.gov'.freeze
21
22
  # The NVD url where is located the data feeds.
22
- URL = 'https://nvd.nist.gov/vuln/data-feeds'.freeze
23
+ URL = "#{BASE}/vuln/data-feeds".freeze
23
24
  # Load constants
24
25
  include NvdFeedApi
25
26
 
@@ -31,21 +32,34 @@ class NVDFeedScraper
31
32
 
32
33
  # Scrap / parse the website to get the feeds and fill the {#feeds} attribute.
33
34
  # @note {#scrap} need to be called only once but can be called again to update if the NVD feed page changed.
34
- # @return [Integer] +0+ when there is no error.
35
+ # @return [Integer] Number of scrapped feeds.
35
36
  def scrap
36
37
  uri = URI(@url)
37
38
  html = Net::HTTP.get(uri)
38
39
 
39
40
  doc = Nokogiri::HTML(html)
40
41
  @feeds = []
41
- doc.css('h3#JSON_FEED ~ div.row:first-of-type table.xml-feed-table > tbody > tr[data-testid*=desc]').each do |tr|
42
- name = tr.css('td')[0].text
43
- updated = tr.css('td')[1].text
44
- meta = tr.css('td')[2].css('> a').attr('href').value
45
- gz = tr.css('+ tr > td > a').attr('href').value
46
- zip = tr.css('+ tr + tr > td > a').attr('href').value
47
- @feeds.push(Feed.new(name, updated, meta, gz, zip))
42
+ tmp_feeds = {}
43
+ doc.css('#vuln-feed-table table.xml-feed-table tr[data-testid]').each do |tr|
44
+ num, type = tr.attr('data-testid')[13..].split('-')
45
+ case type
46
+ when 'meta'
47
+ tmp_feeds[num] = {}
48
+ tmp_feeds[num][:name] = tr.css('td')[0].text
49
+ tmp_feeds[num][:updated] = tr.css('td')[1].text
50
+ tmp_feeds[num][:meta] = BASE + tr.css('td')[2].css('> a').attr('href').value
51
+ when 'gz'
52
+ tmp_feeds[num][:gz] = BASE + tr.css('td > a').attr('href').value
53
+ when 'zip'
54
+ tmp_feeds[num][:zip] = BASE + tr.css('td > a').attr('href').value
55
+ @feeds.push(Feed.new(tmp_feeds[num][:name],
56
+ tmp_feeds[num][:updated],
57
+ tmp_feeds[num][:meta],
58
+ tmp_feeds[num][:gz],
59
+ tmp_feeds[num][:zip]))
60
+ end
48
61
  end
62
+ return @feeds.size
49
63
  end
50
64
 
51
65
  # Return feeds. Can only be called after {#scrap}.
@@ -72,17 +86,20 @@ class NVDFeedScraper
72
86
  # @see https://nvd.nist.gov/vuln/data-feeds
73
87
  def feeds(*arg_feeds)
74
88
  raise 'call scrap method before using feeds method' if @feeds.nil?
89
+
75
90
  return_value = nil
76
91
  if arg_feeds.empty?
77
92
  return_value = @feeds
78
93
  elsif arg_feeds.length == 1
79
- if arg_feeds[0].is_a?(String)
94
+ case arg_feeds[0]
95
+ when String
80
96
  @feeds.each do |feed| # feed is an object
81
97
  return_value = feed if arg_feeds.include?(feed.name)
82
98
  end
83
99
  # if nothing found return nil
84
- elsif arg_feeds[0].is_a?(Array)
100
+ when Array
85
101
  raise 'one of the provided arguments is not a String' unless arg_feeds[0].all? { |x| x.is_a?(String) }
102
+
86
103
  # Sorting CVE can allow us to parse quicker
87
104
  # Upcase to be sure include? works
88
105
  # Does not use map(&:upcase) to preserve CVE-Recent and CVE-Modified
@@ -114,6 +131,7 @@ class NVDFeedScraper
114
131
  # scraper.available_feeds => ["CVE-Modified", "CVE-Recent", "CVE-2017", "CVE-2016", "CVE-2015", "CVE-2014", "CVE-2013", "CVE-2012", "CVE-2011", "CVE-2010", "CVE-2009", "CVE-2008", "CVE-2007", "CVE-2006", "CVE-2005", "CVE-2004", "CVE-2003", "CVE-2002"]
115
132
  def available_feeds
116
133
  raise 'call scrap method before using available_feeds method' if @feeds.nil?
134
+
117
135
  feed_names = []
118
136
  @feeds.each do |feed| # feed is an objet
119
137
  feed_names.push(feed.name)
@@ -146,9 +164,12 @@ class NVDFeedScraper
146
164
  def cve(*arg_cve)
147
165
  return_value = nil
148
166
  raise 'no argument provided, 1 or more expected' if arg_cve.empty?
167
+
149
168
  if arg_cve.length == 1
150
- if arg_cve[0].is_a?(String)
169
+ case arg_cve[0]
170
+ when String
151
171
  raise 'bad CVE name' unless /^CVE-[0-9]{4}-[0-9]{4,}$/i.match?(arg_cve[0])
172
+
152
173
  year = /^CVE-([0-9]{4})-[0-9]{4,}$/i.match(arg_cve[0]).captures[0]
153
174
  matched_feed = nil
154
175
  feed_names = available_feeds
@@ -163,12 +184,14 @@ class NVDFeedScraper
163
184
  # CVE-2002 feed (the 1st one) contains CVE from 1999 to 2002
164
185
  matched_feed = 'CVE-2002' if matched_feed.nil? && ('1999'..'2001').to_a.include?(year)
165
186
  raise "bad CVE year in #{arg_cve}" if matched_feed.nil?
187
+
166
188
  f = feeds(matched_feed)
167
189
  f.json_pull
168
190
  return_value = f.cve(arg_cve[0])
169
- elsif arg_cve[0].is_a?(Array)
191
+ when Array
170
192
  raise 'one of the provided arguments is not a String' unless arg_cve[0].all? { |x| x.is_a?(String) }
171
193
  raise 'bad CVE name' unless arg_cve[0].all? { |x| /^CVE-[0-9]{4}-[0-9]{4,}$/i.match?(x) }
194
+
172
195
  return_value = []
173
196
  # Sorting CVE can allow us to parse quicker
174
197
  # Upcase to be sure include? works
@@ -185,6 +208,7 @@ class NVDFeedScraper
185
208
  # So virtually add those feed...
186
209
  feed_names.merge(virtual_feeds)
187
210
  raise 'unexisting CVE year was provided in some CVE' unless feeds_to_match.subset?(feed_names)
211
+
188
212
  matched_feeds = feeds_to_match.intersection(feed_names)
189
213
  # and now that the intersection is done remove those virtual feeds and add CVE-2002 instead if needed
190
214
  unless matched_feeds.intersection(virtual_feeds.to_set).empty?
@@ -195,9 +219,10 @@ class NVDFeedScraper
195
219
  feeds_arr.each do |feed|
196
220
  feed.json_pull
197
221
  cves_obj = feed.cve(cves_to_find.select { |cve| cve.include?(feed.name) })
198
- if cves_obj.is_a?(Hash)
222
+ case cves_obj
223
+ when Hash
199
224
  return_value.push(cves_obj)
200
- elsif cves_obj.is_a?(Array)
225
+ when Array
201
226
  return_value.push(*cves_obj)
202
227
  else
203
228
  raise 'cve() method of the feed instance returns wrong value'
@@ -217,16 +242,16 @@ class NVDFeedScraper
217
242
  # @overload update_feeds(feed)
218
243
  # One feed.
219
244
  # @param feed [Feed] feed object to update.
220
- # @return [Boolean] +true+ if the feed was updated, +false+ if it wasn't.
245
+ # @return [Boolean] `true` if the feed was updated, `false` if it wasn't.
221
246
  # @overload update_feeds(feed_arr)
222
247
  # An array of feed.
223
248
  # @param feed_arr [Array<Feed>] array of feed objects to update.
224
- # @return [Array<Boolean>] +true+ if the feed was updated, +false+ if it wasn't.
249
+ # @return [Array<Boolean>] `true` if the feed was updated, `false` if it wasn't.
225
250
  # @overload update_feeds(feed, *)
226
251
  # Multiple feeds.
227
252
  # @param feed [Feed] feed object to update.
228
253
  # @param * [Feed] As many feed objects as you want.
229
- # @return [Array<Boolean>] +true+ if the feed was updated, +false+ if it wasn't.
254
+ # @return [Array<Boolean>] `true` if the feed was updated, `false` if it wasn't.
230
255
  # @example
231
256
  # s = NVDFeedScraper.new
232
257
  # s.scrap
@@ -235,13 +260,15 @@ class NVDFeedScraper
235
260
  def update_feeds(*arg_feed)
236
261
  return_value = false
237
262
  raise 'no argument provided, 1 or more expected' if arg_feed.empty?
263
+
238
264
  scrap
239
265
  if arg_feed.length == 1
240
- if arg_feed[0].is_a?(Feed)
266
+ case arg_feed[0]
267
+ when Feed
241
268
  new_feed = feeds(arg_feed[0].name)
242
269
  # update attributes
243
270
  return_value = arg_feed[0].update!(new_feed)
244
- elsif arg_feed[0].is_a?(Array)
271
+ when Array
245
272
  return_value = []
246
273
  arg_feed[0].each do |f|
247
274
  res = update_feeds(f)
data/nvd_feed_api.gemspec CHANGED
@@ -1,12 +1,9 @@
1
- lib = File.expand_path('../lib', __FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'nvd_feed_api/version'
1
+ require_relative 'lib/nvd_feed_api/version'
4
2
 
5
3
  Gem::Specification.new do |s|
6
4
  s.name = 'nvd_feed_api'
7
5
  s.version = NvdFeedApi::VERSION
8
6
  s.platform = Gem::Platform::RUBY
9
- s.date = '2018-01-06'
10
7
  s.summary = 'API for NVD CVE feeds'
11
8
  s.description = 'A simple API for NVD CVE feeds'
12
9
  s.authors = ['Alexandre ZANNI']
@@ -20,27 +17,19 @@ Gem::Specification.new do |s|
20
17
  s.require_paths = ['lib']
21
18
 
22
19
  s.metadata = {
23
- 'yard.run' => 'yard',
24
- 'bug_tracker_uri' => 'https://gitlab.com/noraj/nvd_api/issues',
25
- 'changelog_uri' => 'https://noraj.gitlab.io/nvd_api/file.CHANGELOG.html',
26
- 'documentation_uri' => 'https://noraj.gitlab.io/nvd_api/',
27
- 'homepage_uri' => 'https://noraj.gitlab.io/nvd_api/',
28
- 'source_code_uri' => 'https://gitlab.com/noraj/nvd_api/tree/master',
29
- 'wiki_uri' => 'https://gitlab.com/noraj/nvd_api/wikis/home'
20
+ 'yard.run' => 'yard',
21
+ 'bug_tracker_uri' => 'https://gitlab.com/noraj/nvd_api/issues',
22
+ 'changelog_uri' => 'https://noraj.gitlab.io/nvd_api/file.CHANGELOG.html',
23
+ 'documentation_uri' => 'https://noraj.gitlab.io/nvd_api/',
24
+ 'homepage_uri' => 'https://noraj.gitlab.io/nvd_api/',
25
+ 'source_code_uri' => 'https://gitlab.com/noraj/nvd_api/tree/master',
26
+ 'wiki_uri' => 'https://gitlab.com/noraj/nvd_api/wikis/home',
27
+ 'rubygems_mfa_required' => 'true'
30
28
  }
31
29
 
32
- s.required_ruby_version = '~> 2.4'
30
+ s.required_ruby_version = ['>= 2.7.0', '< 3.2']
33
31
 
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('redcarpet', '~> 3.4') # for GMF support in YARD
44
- s.add_development_dependency('rubocop', '~> 0.51')
45
- s.add_development_dependency('yard', '~> 0.9')
32
+ s.add_dependency('archive-zip', '~> 0.11')
33
+ s.add_dependency('nokogiri', '~> 1.11')
34
+ s.add_dependency('oj', '>= 3.7.8', '<4')
46
35
  end
data/pages/CHANGELOG.md CHANGED
@@ -1,3 +1,43 @@
1
+ # [unreleased]
2
+
3
+ # [0.4.0] - 31 January 2021
4
+
5
+ - Dependencies:
6
+ - Update to yard [v0.9.27](https://github.com/lsegal/yard/releases/tag/v0.9.27)
7
+ - Move from Redcarpet to CommonMarker markdown provider
8
+ - Move doc syntax from Rdoc to markdown
9
+ - Move dev dependencies from gemspec to gemfile
10
+ - Chore:
11
+ - Add support for Ruby 3.1
12
+ - Update rubocop rules
13
+
14
+ # [0.3.1] - 13 October 2020
15
+
16
+ [0.3.1]: https://gitlab.com/noraj/nvd_api/tags/v0.3.1
17
+
18
+ - fix scrap method to reflect NVD feeds page changes
19
+ - update dependencies
20
+ - update rubocop rules
21
+
22
+ # [0.3.0] - 22 January 2019
23
+
24
+ [0.3.0]: https://gitlab.com/noraj/nvd_api/tags/v0.3.0
25
+
26
+ - update dependencies: updated gemspec, ruby 2.6 support, fix gem doc flag, fix oj crash (seg fault)
27
+ - Gemfile.lock: now Gemfile.lock is not ignored anymore
28
+ - gitlab-ci: add ruby 2.6 test, add caching key, and anchors for better reuse, always use bundle
29
+ - NVDFeedScraper `scrap` method: change return value
30
+ - rubocop: fix lint
31
+
32
+ # [0.2.1] - 2 May 2018
33
+
34
+ [0.2.1]: https://gitlab.com/noraj/nvd_api/tags/v0.2.1
35
+
36
+ - Gitlab-CI: test with ruby 2.4.x and 2.5.x
37
+ - style: fix Style/ExpandPathArguments cop
38
+ - security: fix Security/Open cop, protect from pipe command injection
39
+ - test: fix NVD URL after NVD changed it
40
+
1
41
  # [0.2.0] - 20 January 2018
2
42
 
3
43
  [0.2.0]: https://gitlab.com/noraj/nvd_api/tags/v0.2.0
data/pages/INSTALL.md CHANGED
@@ -10,14 +10,7 @@ $ gem install nvd_feed_api
10
10
 
11
11
  ## Development
12
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
- ```
13
+ It's better to use [rbenv](https://github.com/rbenv/rbenv) to have latests version of ruby and to avoid trashing your system ruby.
21
14
 
22
15
  ### Install from rubygems.org
23
16
 
@@ -53,7 +46,7 @@ Note: if an automatic install is needed you can get the version with `$ gem buil
53
46
 
54
47
  ### Run the API in irb without installing the gem
55
48
 
56
- Usefull when you want to try your changes without building the gem and re-installing it each time.
49
+ Useful when you want to try your changes without building the gem and re-installing it each time.
57
50
 
58
51
  ```
59
52
  $ git clone https://gitlab.com/noraj/nvd_api.git nvd_feed_api
data/renovate.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "extends": [
3
+ "config:base"
4
+ ],
5
+ "bundler": {
6
+ "enabled": true
7
+ },
8
+ "assignees": [
9
+ "noraj"
10
+ ],
11
+ "enabledManagers": [
12
+ "bundler",
13
+ "gitlabci"
14
+ ]
15
+ }
@@ -9,7 +9,7 @@ class NVDAPITest < Minitest::Test
9
9
  end
10
10
 
11
11
  def test_scraper_scrap
12
- assert_equal(0, @s.scrap, 'scrap method return nothing')
12
+ assert_operator(0, :<, @s.scrap, 'scrap method returns nothing')
13
13
  end
14
14
 
15
15
  def test_scraper_feeds_noarg
@@ -78,7 +78,7 @@ class NVDAPITest < Minitest::Test
78
78
  f2017, f2016, f_modified = @s.feeds('CVE-2017', 'CVE-2016', 'CVE-Modified')
79
79
  # one arg
80
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")
81
+ assert(['TrueClass', 'FalseClass'].include?(@s.update_feeds(f2017).class.to_s), "update_feeds doesn't return a boolean")
82
82
  # two args
83
83
  assert_instance_of(Array, @s.update_feeds(f2017, f2016), "update_feeds doesn't return an array")
84
84
  refute_empty(@s.update_feeds(f2017, f2016), 'update_feeds returns an empty array')
@@ -109,9 +109,9 @@ class NVDAPITest < Minitest::Test
109
109
 
110
110
  def test_feed_attributes
111
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'
112
+ meta_url = 'https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2010.meta'
113
+ gz_url = 'https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2010.json.gz'
114
+ zip_url = 'https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2010.json.zip'
115
115
  f = @s.feeds('CVE-2010')
116
116
  # Test name
117
117
  assert_instance_of(String, f.name, "name doesn't return a string")
@@ -231,7 +231,7 @@ class NVDAPITest < Minitest::Test
231
231
  f_new = @s.feeds('CVE-2006')
232
232
  # Right arg
233
233
  # can't use assert_instance_of because there is no boolean class
234
- assert(%w[TrueClass FalseClass].include?(f.update!(f_new).class.to_s), "update! doesn't return a boolean")
234
+ assert(['TrueClass', 'FalseClass'].include?(f.update!(f_new).class.to_s), "update! doesn't return a boolean")
235
235
  # Bad arg
236
236
  err = assert_raises(RuntimeError) do
237
237
  f.update!('bad_arg')
@@ -240,25 +240,25 @@ class NVDAPITest < Minitest::Test
240
240
  end
241
241
 
242
242
  def test_meta_parse_noarg
243
- m = NVDFeedScraper::Meta.new('https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2015.meta')
243
+ m = NVDFeedScraper::Meta.new('https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2015.meta')
244
244
  assert_equal(0, m.parse, 'parse method return nothing')
245
245
  end
246
246
 
247
247
  def test_meta_parse_witharg
248
248
  m = NVDFeedScraper::Meta.new
249
- meta_url = 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2015.meta'
249
+ meta_url = 'https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2015.meta'
250
250
  assert_equal(0, m.parse(meta_url), 'parse method return nothing')
251
251
  end
252
252
 
253
253
  def test_meta_url_setter
254
254
  m = NVDFeedScraper::Meta.new
255
- meta_url = 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2015.meta'
255
+ meta_url = 'https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2015.meta'
256
256
  assert_equal(meta_url, m.url = meta_url, 'the meta URL is not set correctly')
257
257
  end
258
258
 
259
259
  def test_meta_attributes
260
260
  m = NVDFeedScraper::Meta.new
261
- meta_url = 'https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2015.meta'
261
+ meta_url = 'https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2015.meta'
262
262
  m.url = meta_url
263
263
  m.parse
264
264
  # Test gz_size
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nvd_feed_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre ZANNI
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-06 00:00:00.000000000 Z
11
+ date: 2022-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: archive-zip
@@ -16,154 +16,48 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.10'
19
+ version: '0.11'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.10'
26
+ version: '0.11'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: nokogiri
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.8'
33
+ version: '1.11'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.8'
40
+ version: '1.11'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: oj
43
43
  requirement: !ruby/object:Gem::Requirement
44
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
- - - "~>"
45
+ - - ">="
102
46
  - !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: redcarpet
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '3.4'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
47
+ version: 3.7.8
48
+ - - "<"
137
49
  - !ruby/object:Gem::Version
138
- version: '3.4'
139
- - !ruby/object:Gem::Dependency
140
- name: rubocop
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '0.51'
146
- type: :development
50
+ version: '4'
51
+ type: :runtime
147
52
  prerelease: false
148
53
  version_requirements: !ruby/object:Gem::Requirement
149
54
  requirements:
150
- - - "~>"
55
+ - - ">="
151
56
  - !ruby/object:Gem::Version
152
- version: '0.51'
153
- - !ruby/object:Gem::Dependency
154
- name: yard
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - "~>"
158
- - !ruby/object:Gem::Version
159
- version: '0.9'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
57
+ version: 3.7.8
58
+ - - "<"
165
59
  - !ruby/object:Gem::Version
166
- version: '0.9'
60
+ version: '4'
167
61
  description: A simple API for NVD CVE feeds
168
62
  email: alexandre.zanni@europe.com
169
63
  executables:
@@ -173,6 +67,7 @@ executables:
173
67
  extensions: []
174
68
  extra_rdoc_files: []
175
69
  files:
70
+ - ".github/FUNDING.yml"
176
71
  - ".gitignore"
177
72
  - ".gitlab-ci.yml"
178
73
  - ".gitlab/CONTRIBUTING.md"
@@ -180,8 +75,10 @@ files:
180
75
  - ".gitlab/issue_templates/Feature_proposal.md"
181
76
  - ".gitlab/merge_request_templates/MR.md"
182
77
  - ".rubocop.yml"
78
+ - ".tool-versions"
183
79
  - ".yardopts"
184
80
  - Gemfile
81
+ - Gemfile.lock
185
82
  - LICENSE.txt
186
83
  - README.md
187
84
  - Rakefile
@@ -197,6 +94,7 @@ files:
197
94
  - pages/EXAMPLES.md
198
95
  - pages/FEATURES.md
199
96
  - pages/INSTALL.md
97
+ - renovate.json
200
98
  - test/test_nvd_feed_api.rb
201
99
  homepage: https://noraj.gitlab.io/nvd_api/
202
100
  licenses:
@@ -209,24 +107,27 @@ metadata:
209
107
  homepage_uri: https://noraj.gitlab.io/nvd_api/
210
108
  source_code_uri: https://gitlab.com/noraj/nvd_api/tree/master
211
109
  wiki_uri: https://gitlab.com/noraj/nvd_api/wikis/home
212
- post_install_message:
110
+ rubygems_mfa_required: 'true'
111
+ post_install_message:
213
112
  rdoc_options: []
214
113
  require_paths:
215
114
  - lib
216
115
  required_ruby_version: !ruby/object:Gem::Requirement
217
116
  requirements:
218
- - - "~>"
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: 2.7.0
120
+ - - "<"
219
121
  - !ruby/object:Gem::Version
220
- version: '2.4'
122
+ version: '3.2'
221
123
  required_rubygems_version: !ruby/object:Gem::Requirement
222
124
  requirements:
223
125
  - - ">="
224
126
  - !ruby/object:Gem::Version
225
127
  version: '0'
226
128
  requirements: []
227
- rubyforge_project:
228
- rubygems_version: 2.6.14
229
- signing_key:
129
+ rubygems_version: 3.3.3
130
+ signing_key:
230
131
  specification_version: 4
231
132
  summary: API for NVD CVE feeds
232
133
  test_files: