Class: PatchFinder::Engine::MSU::Technet

Inherits:
Object
  • Object
show all
Includes:
Helper
Defined in:
lib/patch_finder/engine/msu/technet.rb

Instance Attribute Summary collapse

Attributes included from Helper

#verbose

Instance Method Summary collapse

Methods included from Helper

#download_file, #download_files, #print_error, #print_line, #print_status, #print_verbose, #print_verbose_error, #read_file, #send_http_get_request

Constructor Details

#initializevoid

Initializes the Technet client.



16
17
18
19
20
21
22
# File 'lib/patch_finder/engine/msu/technet.rb', line 16

def initialize
  @firstpage ||= lambda {
    uri = '/en-us/security/bulletin/dn602597.aspx'
    res = send_http_get_request("#{TECHNET}#{uri}")
    return res.body
  }.call
end

Instance Attribute Details

#firstpageObject (readonly)

Returns the value of attribute firstpage.



111
112
113
# File 'lib/patch_finder/engine/msu/technet.rb', line 111

def firstpage
  @firstpage
end

Instance Method Details

#find_msb_numbers(keyword) ⇒ Array

Returns the MSB (advisories) numbers for a search keyword.

Parameters:

  • keyword (String)

Returns:

  • (Array)


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/patch_finder/engine/msu/technet.rb', line 28

def find_msb_numbers(keyword)
  product_list_matches = get_product_dropdown_list.select { |p| Regexp.new(keyword) === p[:option_text] }
  if product_list_matches.empty?
    print_verbose('No match from the product list, attempting a generic search')
    search_by_keyword(keyword)
  else
    product_names = []
    ids = []
    product_list_matches.each do |e|
      ids << e[:option_value]
      product_names << e[:option_text]
    end
    print_verbose("Matches from the product list (#{product_names.length}): #{ product_names * ', ' }")
    search_by_product_ids(ids)
  end
end

#get_product_dropdown_listArray

Returns the Technet product list.

Returns:

  • (Array)


95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/patch_finder/engine/msu/technet.rb', line 95

def get_product_dropdown_list
  @product_dropdown_list ||= lambda {
    list = []

    page = ::Nokogiri::HTML(firstpage)
    page.search('//div[@class="sb-search"]//select[@id="productDropdown"]//option').each do |product|
      option_value = product.attributes['value'].value
      option_text  = product.text
      next if option_value == '-1' # This is the ALL option
      list << { option_value: option_value, option_text: option_text }
    end

    list
  }.call
end

#search(keyword) ⇒ Hash

Searches the Technet engine.

Parameters:

  • keyword (String)

Returns:

  • (Hash)

    JSON



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/patch_finder/engine/msu/technet.rb', line 49

def search(keyword)
  req_str = "#{TECHNET}/security/bulletin/services/GetBulletins?"
  req_str << "searchText=#{keyword}&"
  req_str << 'sortField=0&'
  req_str << 'sortOrder=1&'
  req_str << 'currentPage=1&'
  req_str << 'bulletinsPerPage=9999&'
  req_str << 'locale=en-us'

  res = send_http_get_request(req_str)
  begin
    return JSON.parse(res.body)
  rescue JSON::ParserError
  end

  {}
end

#search_by_keyword(keyword) ⇒ Hash

Searches for the MSBs (advisories) based on a keyword.

Parameters:

  • keyword (String)

Returns:

  • (Hash)


87
88
89
90
# File 'lib/patch_finder/engine/msu/technet.rb', line 87

def search_by_keyword(keyword)
  j = search(keyword)
  j['b'].collect { |e| e['Id'] }.map { |e| e.downcase }
end

#search_by_product_ids(ids) ⇒ Array

Searches for the MSBs (advisories) based on product IDs (as search keywords)

Parameters:

  • ids (Array)

Returns:

  • (Array)


71
72
73
74
75
76
77
78
79
80
81
# File 'lib/patch_finder/engine/msu/technet.rb', line 71

def search_by_product_ids(ids)
  msb_numbers = []

  ids.each do |id|
    j = search(id)
    msb = j['b'].collect { |e| e['Id'] }.map { |e| e.downcase }
    msb_numbers.concat(msb)
  end

  msb_numbers
end