lib/holepicker/vulnerability.rb
require 'rubygems'
require 'time'
module HolePicker
class Vulnerability
NEW_VULNERABILITY_DAYS = 7
NEW_VULNERABILITY_TIME = NEW_VULNERABILITY_DAYS * 86400
attr_reader :id, :date, :url, :note, :gems
def self.next_id
@@count ||= 0
@@count += 1
end
def initialize(json)
@gems = {}
json['gems'].each do |name, versions|
@gems[name] = versions.map { |v| ::Gem::Version.new(v) }
end
@id = self.class.next_id
@url = json['url']
@note = json['note']
@date = Time.parse(json['date'])
end
def day
@date.strftime("%Y-%m-%d")
end
def recent?
date > Time.now - NEW_VULNERABILITY_TIME
end
def tag
"##{@id}"
end
def gem_names
@gems.keys
end
def gem_vulnerable?(gem)
!gem_safe?(gem)
end
def gem_safe?(gem)
fixes = @gems[gem.name]
!fixes || fixes.any? { |fix| fix_included?(fix, gem) } || fixes.all? { |fix| gem.version > fix }
end
private
def fix_included?(fix, gem)
gem.version == fix || (gem.version > fix && same_level?(fix, gem))
end
def same_level?(fix, gem)
segments_count = fix.segments.length
fix.segments[0...segments_count-1] == gem.version.segments[0...segments_count-1]
end
end
end