Class: Bundler::Audit::Database

Inherits:
Object
  • Object
show all
Defined in:
lib/bundler/audit/database.rb

Overview

Represents the directory of advisories, grouped by gem name and CVE number.

Constant Summary collapse

URL =

Git URL of the ruby-advisory-db

'https://github.com/rubysec/ruby-advisory-db.git'
VENDORED_PATH =

Default path to the ruby-advisory-db

File.expand_path(File.join(File.dirname(__FILE__),'..','..','..','data','ruby-advisory-db'))
VENDORED_TIMESTAMP =

Timestamp for when the database was last updated

Time.parse(File.read("#{VENDORED_PATH}.ts")).utc
USER_PATH =

Path to the user's copy of the ruby-advisory-db

File.expand_path(File.join(ENV['HOME'],'.local','share','ruby-advisory-db'))

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path = self.class.path) ⇒ Database

Initializes the Advisory Database.

Parameters:

  • path (String) (defaults to: self.class.path)

    The path to the advisory database.

Raises:

  • (ArgumentError)

    The path was not a directory.


55
56
57
58
59
60
61
# File 'lib/bundler/audit/database.rb', line 55

def initialize(path=self.class.path)
  unless File.directory?(path)
    raise(ArgumentError,"#{path.dump} is not a directory")
  end

  @path = path
end

Instance Attribute Details

#pathObject (readonly)

The path to the advisory database


44
45
46
# File 'lib/bundler/audit/database.rb', line 44

def path
  @path
end

Class Method Details

.pathString

The default path for the database.

Returns:

  • (String)

    The path to the database directory.


69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/bundler/audit/database.rb', line 69

def self.path
  if File.directory?(USER_PATH)
    t1 = Dir.chdir(USER_PATH) { Time.parse(`git log --date=iso8601 --pretty="%cd" -1`).utc }
    t2 = VENDORED_TIMESTAMP

    if t1 >= t2 then USER_PATH
    else             VENDORED_PATH
    end
  else
    VENDORED_PATH
  end
end

.update!(options = {}) ⇒ Boolean?

Note:

Requires network access.

Updates the ruby-advisory-db.

Parameters:

  • options (Hash) (defaults to: {})

    Additional options.

Options Hash (options):

  • :quiet (Boolean)

    Specify whether git should be --quiet.

Returns:

  • (Boolean, nil)

    Specifies whether the update was successful. A nil indicates no update was performed.

Raises:

  • (ArgumentError)

    Invalid options were given.

Since:

  • 0.3.0


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/bundler/audit/database.rb', line 103

def self.update!(options={})
  unless (options.keys - [:quiet]).empty?
    raise(ArgumentError,"Invalid option(s)")
  end

  if File.directory?(USER_PATH)
    if File.directory?(File.join(USER_PATH, ".git"))
      Dir.chdir(USER_PATH) do
        command = %w(git pull --no-rebase)
        command << '--quiet' if options[:quiet]
        command << 'origin' << 'master'
        system *command
      end
    end
  else
    command = %w(git clone)
    command << '--quiet' if options[:quiet]
    command << URL << USER_PATH
    system *command
  end
end

Instance Method Details

#advisories {|advisory| ... } ⇒ Enumerator

Enumerates over every advisory in the database.

Yields:

  • (advisory)

    If a block is given, it will be passed each advisory.

Yield Parameters:

  • advisory (Advisory)

    An advisory from the database.

Returns:

  • (Enumerator)

    If no block is given, an Enumerator will be returned.


137
138
139
140
141
142
143
# File 'lib/bundler/audit/database.rb', line 137

def advisories(&block)
  return enum_for(__method__) unless block_given?

  each_advisory_path do |path|
    yield Advisory.load(path)
  end
end

#advisories_for(name) {|advisory| ... } ⇒ Enumerator

Enumerates over advisories for the given gem.

Parameters:

  • name (String)

    The gem name to lookup.

Yields:

  • (advisory)

    If a block is given, each advisory for the given gem will be yielded.

Yield Parameters:

  • advisory (Advisory)

    An advisory for the given gem.

Returns:

  • (Enumerator)

    If no block is given, an Enumerator will be returned.


160
161
162
163
164
165
166
# File 'lib/bundler/audit/database.rb', line 160

def advisories_for(name)
  return enum_for(__method__,name) unless block_given?

  each_advisory_path_for(name) do |path|
    yield Advisory.load(path)
  end
end

#check_gem(gem) {|advisory| ... } ⇒ Enumerator

Verifies whether the gem is effected by any advisories.

Parameters:

  • gem (Gem::Specification)

    The gem to verify.

Yields:

  • (advisory)

    If a block is given, it will be passed advisories that effect the gem.

Yield Parameters:

  • advisory (Advisory)

    An advisory that effects the specific version of the gem.

Returns:

  • (Enumerator)

    If no block is given, an Enumerator will be returned.


184
185
186
187
188
189
190
191
192
# File 'lib/bundler/audit/database.rb', line 184

def check_gem(gem)
  return enum_for(__method__,gem) unless block_given?

  advisories_for(gem.name) do |advisory|
    if advisory.vulnerable?(gem.version)
      yield advisory
    end
  end
end

#each_advisory_path {|path| ... } ⇒ Object (protected)

Enumerates over every advisory path in the database.

Yields:

  • (path)

    The given block will be passed each advisory path.

Yield Parameters:

  • path (String)

    A path to an advisory .yml file.


235
236
237
# File 'lib/bundler/audit/database.rb', line 235

def each_advisory_path(&block)
  Dir.glob(File.join(@path,'gems','*','*.yml'),&block)
end

#each_advisory_path_for(name) {|path| ... } ⇒ Object (protected)

Enumerates over the advisories for the given gem.

Parameters:

  • name (String)

    The gem of the gem.

Yields:

  • (path)

    The given block will be passed each advisory path.

Yield Parameters:

  • path (String)

    A path to an advisory .yml file.


251
252
253
# File 'lib/bundler/audit/database.rb', line 251

def each_advisory_path_for(name,&block)
  Dir.glob(File.join(@path,'gems',name,'*.yml'),&block)
end

#inspectString

Inspects the database.

Returns:

  • (String)

    The inspected database.


220
221
222
# File 'lib/bundler/audit/database.rb', line 220

def inspect
  "#<#{self.class}:#{self}>"
end

#sizeInteger

The number of advisories within the database.

Returns:

  • (Integer)

    The number of advisories.


200
201
202
# File 'lib/bundler/audit/database.rb', line 200

def size
  each_advisory_path.count
end

#to_sString

Converts the database to a String.

Returns:

  • (String)

    The path to the database.


210
211
212
# File 'lib/bundler/audit/database.rb', line 210

def to_s
  @path
end