nvd_feed_api 0.2.0 → 0.4.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
- 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: