Module: Nexpose::AJAX

Defined in:
lib/nexpose/ajax.rb

Overview

Accessor to the Nexpose AJAX API. These core methods should allow direct access to underlying controllers in order to test functionality that is not currently exposed through the XML API.

Defined Under Namespace

Modules: CONTENT_TYPE

Class Method Summary collapse

Class Method Details

.delete(nsc, uri, content_type = CONTENT_TYPE::XML) ⇒ Object

DELETE call to a Nexpose controller.

Parameters:

  • nsc (Connection)

    API connection to a Nexpose console.

  • uri (String)

    Controller address relative to host:port

  • content_type (String) (defaults to: CONTENT_TYPE::XML)

    Content type to use when issuing the DELETE.



106
107
108
109
110
# File 'lib/nexpose/ajax.rb', line 106

def delete(nsc, uri, content_type = CONTENT_TYPE::XML)
  delete = Net::HTTP::Delete.new(uri)
  delete.set_content_type(content_type)
  request(nsc, delete)
end

.form_post(nsc, uri, parameters, content_type = CONTENT_TYPE::FORM) ⇒ Hash

POST call to a Nexpose controller that uses a form-post model. This is here to support legacy use of POST in old controllers.

Parameters:

  • nsc (Connection)

    API connection to a Nexpose console.

  • uri (String)

    Controller address relative to host:port

  • parameters (Hash)

    Hash of attributes that need to be sent to the controller.

  • content_type (String) (defaults to: CONTENT_TYPE::FORM)

    Content type to use when issuing the POST.

Returns:

  • (Hash)

    The parsed JSON response from the call.



94
95
96
97
98
99
# File 'lib/nexpose/ajax.rb', line 94

def form_post(nsc, uri, parameters, content_type = CONTENT_TYPE::FORM)
  post = Net::HTTP::Post.new(uri)
  post.set_content_type(content_type)
  post.set_form_data(parameters)
  request(nsc, post)
end

.get(nsc, uri, content_type = CONTENT_TYPE::XML, options = {}) ⇒ String|REXML::Document|Hash

GET call to a Nexpose controller.

Parameters:

  • nsc (Connection)

    API connection to a Nexpose console.

  • uri (String)

    Controller address relative to host:port

  • content_type (String) (defaults to: CONTENT_TYPE::XML)

    Content type to use when issuing the GET.

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

    Parameter options to the call.

Returns:

  • (String|REXML::Document|Hash)

    The response from the call.



31
32
33
34
35
36
# File 'lib/nexpose/ajax.rb', line 31

def get(nsc, uri, content_type = CONTENT_TYPE::XML, options = {})
  parameterize_uri(uri, options)
  get = Net::HTTP::Get.new(uri)
  get.set_content_type(content_type)
  request(nsc, get)
end

.get_api_error(request, response) ⇒ Object



176
177
178
179
180
# File 'lib/nexpose/ajax.rb', line 176

def get_api_error(request, response)
  req_type = request.class.name.split('::').last.upcase
  error_message = get_error_message(request, response)
  Nexpose::APIError.new(response, "#{req_type} request to #{request.path} failed. #{error_message}", response.code)
end

.get_error_message(request, response) ⇒ Object

Get an error message from the response body if the request url api version is 2.1 or greater otherwise use the request body



194
195
196
197
198
199
# File 'lib/nexpose/ajax.rb', line 194

def get_error_message(request, response)
  version = get_request_api_version(request)
  data_request = use_response_error_message?(request, response)
  return_response = (version >= 2.1 || data_request)
  (return_response && response.body) ? "response body: #{response.body}" : "request body: #{request.body}"
end

.get_request_api_version(request) ⇒ Object

Get the version of the api target by request

Parameters:

  • request (HTTPRequest)


185
186
187
188
189
190
# File 'lib/nexpose/ajax.rb', line 185

def get_request_api_version(request)
  matches = request.path.match(API_PATTERN)
  matches[:version].to_f
rescue
  0.0
end

.get_rows(nsc, pref) ⇒ Object



253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/nexpose/ajax.rb', line 253

def get_rows(nsc, pref)
  uri = '/data/user/preferences/all'
  pref_key = "#{pref}.rows"
  resp = get(nsc, uri)
  json = JSON.parse(resp)
  if json.key?(pref_key)
    rows = json[pref_key].to_i
    rows > 0 ? rows : 10
  else
    10
  end
end

.headers(nsc, request) ⇒ Object

Attach necessary header fields.



149
150
151
152
# File 'lib/nexpose/ajax.rb', line 149

def headers(nsc, request)
  request.add_field('nexposeCCSessionID', nsc.session_id)
  request.add_field('Cookie', "nexposeCCSessionID=#{nsc.session_id}")
end

.https(nsc, timeout = nil) ⇒ Object

Use the Nexpose::Connection to establish a correct HTTPS object.



135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/nexpose/ajax.rb', line 135

def https(nsc, timeout = nil)
  http = Net::HTTP.new(nsc.host, nsc.port)
  http.read_timeout = (timeout || nsc.timeout)
  http.open_timeout = nsc.open_timeout
  http.use_ssl = true
  if nsc.trust_store.nil?
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  else
    http.cert_store = nsc.trust_store
  end
  http
end

.parameterize_uri(uri, parameters) ⇒ Hash

Append the query parameters to given URI.

Parameters:

  • uri (String)

    Controller address relative to host:port

  • parameters (Hash)

    Hash of attributes that need to be sent to the controller.

Returns:

  • (Hash)

    The parameterized URI.



126
127
128
129
130
131
132
# File 'lib/nexpose/ajax.rb', line 126

def parameterize_uri(uri, parameters)
  params = Hash.try_convert(parameters)
  unless params.nil? || params.empty?
    uri = uri.concat(('?').concat(parameters.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&')))
  end
  uri
end

.patch(nsc, uri, payload = nil, content_type = CONTENT_TYPE::XML) ⇒ String

PATCH call to a Nexpose controller.

Parameters:

  • nsc (Connection)

    API connection to a Nexpose console.

  • uri (String)

    Controller address relative to host:port

  • payload (String|REXML::Document) (defaults to: nil)

    XML document required by the call.

  • content_type (String) (defaults to: CONTENT_TYPE::XML)

    Content type to use when issuing the PATCH.

Returns:

  • (String)

    The response from the call.



77
78
79
80
81
82
# File 'lib/nexpose/ajax.rb', line 77

def patch(nsc, uri, payload = nil, content_type = CONTENT_TYPE::XML)
  patch = Net::HTTP::Patch.new(uri)
  patch.set_content_type(content_type)
  patch.body = payload.to_s if payload
  request(nsc, patch)
end

.post(nsc, uri, payload = nil, content_type = CONTENT_TYPE::XML, timeout = nil) ⇒ String|REXML::Document|Hash

POST call to a Nexpose controller.

Parameters:

  • nsc (Connection)

    API connection to a Nexpose console.

  • uri (String)

    Controller address relative to host:port

  • payload (String|REXML::Document) (defaults to: nil)

    XML document required by the call.

  • content_type (String) (defaults to: CONTENT_TYPE::XML)

    Content type to use when issuing the POST.

  • timeout (Fixnum) (defaults to: nil)

    Set an explicit timeout for the HTTP request.

Returns:

  • (String|REXML::Document|Hash)

    The response from the call.



62
63
64
65
66
67
# File 'lib/nexpose/ajax.rb', line 62

def post(nsc, uri, payload = nil, content_type = CONTENT_TYPE::XML, timeout = nil)
  post = Net::HTTP::Post.new(uri)
  post.set_content_type(content_type)
  post.body = payload.to_s if payload
  request(nsc, post, timeout)
end

.preserving_preference(nsc, pref) ⇒ Object

Execute a block of code while presenving the preferences for any underlying table being accessed. Use this method when accessing data tables which are present in the UI to prevent existing row preferences from being set to 500.

This is an internal utility method, not subject to backward compatibility concerns.

Parameters:

  • nsc (Connection)

    Live connection to a Nepose console.

  • pref (String)

    Preference key value to preserve.



222
223
224
225
226
227
228
229
# File 'lib/nexpose/ajax.rb', line 222

def preserving_preference(nsc, pref)
  begin
    orig = get_rows(nsc, pref)
    yield
  ensure
    set_rows(nsc, pref, orig)
  end
end

.put(nsc, uri, payload = nil, content_type = CONTENT_TYPE::XML) ⇒ String

PUT call to a Nexpose controller.

Parameters:

  • nsc (Connection)

    API connection to a Nexpose console.

  • uri (String)

    Controller address relative to host:port

  • payload (String|REXML::Document) (defaults to: nil)

    XML document required by the call.

  • content_type (String) (defaults to: CONTENT_TYPE::XML)

    Content type to use when issuing the PUT.

Returns:

  • (String)

    The response from the call.



46
47
48
49
50
51
# File 'lib/nexpose/ajax.rb', line 46

def put(nsc, uri, payload = nil, content_type = CONTENT_TYPE::XML)
  put = Net::HTTP::Put.new(uri)
  put.set_content_type(content_type)
  put.body = payload.to_s if payload
  request(nsc, put)
end

.request(nsc, request, timeout = nil) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/nexpose/ajax.rb', line 154

def request(nsc, request, timeout = nil)
  http = https(nsc, timeout)
  headers(nsc, request)

  # Return response body if request is successful. Brittle.
  response = http.request(request)
  case response
  when Net::HTTPOK, Net::HTTPCreated, Net::HTTPNoContent
    response.body
  when Net::HTTPForbidden
    raise Nexpose::PermissionError.new(response)
  when Net::HTTPFound
    if response.header['location'] =~ /login/
      raise Nexpose::AuthenticationFailed.new(response)
    else
      raise get_api_error(request, response)
    end
  else
    raise get_api_error(request, response)
  end
end

.row_pref_of(val) ⇒ Fixnum

Get a valid row preference value.

This is an internal utility method, not subject to backward compatibility concerns.

Parameters:

  • val (Fixnum)

    Value to get inclusive row preference for.

Returns:

  • (Fixnum)

    Valid row preference.



239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/nexpose/ajax.rb', line 239

def row_pref_of(val)
  if val.nil? || val > 100
    500
  elsif val > 50
    100
  elsif val > 25
    50
  elsif val > 10
    25
  else
    10
  end
end

.set_rows(nsc, pref, value) ⇒ Object



266
267
268
269
270
271
272
# File 'lib/nexpose/ajax.rb', line 266

def set_rows(nsc, pref, value)
  uri = '/data/user/preference'
  params = { 'name'  => "#{pref}.rows",
             'value' => value }

  form_post(nsc, uri, params)
end

.use_response_error_message?(request, response) ⇒ Boolean

Code cleanup to allow for cleaner get_error_message method

Returns:

  • (Boolean)


203
204
205
206
207
208
209
# File 'lib/nexpose/ajax.rb', line 203

def use_response_error_message?(request, response)
  if (request.path.include?('/data/') && !response.content_type.nil?)
    response.content_type.include? 'text/plain'
  else
    false
  end
end