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



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

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



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

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)


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

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



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

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
153
# 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}")
  request.add_field('X-Requested-With', 'XMLHttpRequest')
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.



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

def preserving_preference(nsc, pref)
  orig = get_rows(nsc, pref)
  yield
ensure
  set_rows(nsc, pref, orig)
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



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

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.



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

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



265
266
267
268
269
# File 'lib/nexpose/ajax.rb', line 265

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)


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

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