Module: Msf::WebServices::ServletHelper

Includes:
ResponseDataHelper
Defined in:
lib/msf/core/web_services/servlet_helper.rb

Constant Summary collapse

@@console_printer =
Rex::Ui::Text::Output::Stdio.new

Instance Method Summary collapse

Methods included from ResponseDataHelper

#json_to_hash, #json_to_mdm_object, #process_file, #to_ar

Instance Method Details

#create_error_response(error:, message:, code:) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/msf/core/web_services/servlet_helper.rb', line 60

def create_error_response(error:, message:, code:)
  error_response = {
    code: code,
    message: "#{message} #{error.message}"
  }
  set_json_error_response(response: error_response, code: code)
end

#encode_loot_data(data) ⇒ Object



135
136
137
138
139
140
# File 'lib/msf/core/web_services/servlet_helper.rb', line 135

def encode_loot_data(data)
  Array.wrap(data).each do |loot|
    loot.data = Base64.urlsafe_encode64(loot.data) if loot.data && !loot.data.empty?
  end
  data
end

#exec_report_job(request, includes = nil, &job) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/msf/core/web_services/servlet_helper.rb', line 68

def exec_report_job(request, includes = nil, &job)
  begin

    # report jobs always need data
    opts = parse_json_request(request, true)

    exec_async = opts.delete(:exec_async)
    if (exec_async)
      Msf::WebServices::JobProcessor.instance.submit_job(opts, &job)
      return set_empty_response
    else
      data = job.call(opts)
      return set_json_data_response(response: data, includes: includes)
    end

  rescue => e
    print_error_and_create_response(error: e, message: 'There was an error creating the record:', code: 500)
  end
end

#format_cred_json(data) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/msf/core/web_services/servlet_helper.rb', line 121

def format_cred_json(data)
  includes = [:logins, :public, :private, :realm, :origin]

  response = []
  Array.wrap(data).each do |cred|
    json = cred.as_json(include: includes)
    json['origin'] = json['origin'].merge('type' => cred.origin.class.to_s) if cred.origin
    json['public'] = json['public'].merge('type' => cred.public.type) if cred.public
    json['private'] = json['private'].merge('type' => cred.private.type) if cred.private
    response << json
  end
  response
end

#get_dbObject



88
89
90
# File 'lib/msf/core/web_services/servlet_helper.rb', line 88

def get_db
  Msf::WebServices::DBManagerProxy.instance.db
end

#is_single_object?(data, params) ⇒ Bool

Determines if this data set should be output as a single object instead of an array.

Parameters:

  • data (Array)

    Array containing the data to be returned to the user.

  • params (Hash)

    The parameters included in the request.

Returns:

  • (Bool)

    true if the data should be printed as a single object, false otherwise



114
115
116
117
118
119
# File 'lib/msf/core/web_services/servlet_helper.rb', line 114

def is_single_object?(data, params)
  # Check to see if the ID parameter was present. If so, print as a single object.
  # Note that ID is not valid as a query parameter, so we assume that the user
  # used <resource>/{ID} notation if ID is present in params.
  !params[:id].nil? && data.count == 1
end

#parse_json_request(request, strict = false) ⇒ Object



44
45
46
47
48
49
50
51
52
53
# File 'lib/msf/core/web_services/servlet_helper.rb', line 44

def parse_json_request(request, strict = false)
  body = request.body.read
  if (body.nil? || body.empty?)
    raise 'Invalid body, expected data' if strict
    return {}
  end

  hash = JSON.parse(body)
  hash.deep_symbolize_keys
end


166
167
168
169
170
171
172
173
174
175
176
# File 'lib/msf/core/web_services/servlet_helper.rb', line 166

def print_error(msg, exception = nil)
  unless exception.nil?
    msg += "\n    Call Stack:"
    exception.backtrace.each {|line|
      msg += "\n"
      msg += "\t #{line}"
    }
  end

  @@console_printer.print_error(msg)
end


55
56
57
58
# File 'lib/msf/core/web_services/servlet_helper.rb', line 55

def print_error_and_create_response(error: , message:, code:)
  print_error "Error handling request: #{error.message}.", error
  create_error_response(error: error, message: message, code: code)
end


162
163
164
# File 'lib/msf/core/web_services/servlet_helper.rb', line 162

def print_good(msg)
  @@console_printer.print_good(msg)
end


154
155
156
# File 'lib/msf/core/web_services/servlet_helper.rb', line 154

def print_line(msg)
  @@console_printer.print_line(msg)
end


158
159
160
# File 'lib/msf/core/web_services/servlet_helper.rb', line 158

def print_warning(msg)
  @@console_printer.print_warning(msg)
end

#sanitize_params(params, query_hash = {}) ⇒ Hash

Sinatra injects extra parameters for some reason: github.com/sinatra/sinatra/issues/453 This method cleans those up so we don’t have any unexpected values before passing on. It also inspects the query string for any invalid parameters.

Parameters:

  • params (Hash)

    Hash containing the parameters for the request.

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

    The query_hash variable from the rack request.

Returns:

  • (Hash)

    Returns params with symbolized keys and the injected parameters removed.



99
100
101
102
103
104
105
106
# File 'lib/msf/core/web_services/servlet_helper.rb', line 99

def sanitize_params(params, query_hash = {})
  # Reject id passed as a query parameter for GET requests.
  # API standards say path ID should be used for single records.
  if query_hash.key?('id')
    raise ArgumentError, ("'id' is not a valid query parameter. Please use /api/v1/<resource>/{ID} instead.")
  end
  params.symbolize_keys.except(:captures, :splat).to_h.symbolize_keys
end

#set_empty_responseObject



15
16
17
# File 'lib/msf/core/web_services/servlet_helper.rb', line 15

def set_empty_response
  set_json_data_response(response: '')
end

#set_error_on_response(error) ⇒ Object



9
10
11
12
13
# File 'lib/msf/core/web_services/servlet_helper.rb', line 9

def set_error_on_response(error)
  print_error "Error handling request: #{error.message}", error
  headers = {'Content-Type' => 'text/plain'}
  [500, headers, error.message]
end

#set_html_response(data) ⇒ Object



39
40
41
42
# File 'lib/msf/core/web_services/servlet_helper.rb', line 39

def set_html_response(data)
  headers = {'Content-Type' => 'text/html'}
  [200, headers, data]
end

#set_json_data_response(response:, includes: nil, code: 200) ⇒ Object



29
30
31
32
# File 'lib/msf/core/web_services/servlet_helper.rb', line 29

def set_json_data_response(response:, includes: nil, code: 200)
  data_response = { data: response }
  set_json_response(data_response, includes = includes, code = code)
end

#set_json_error_response(response:, code:) ⇒ Object



34
35
36
37
# File 'lib/msf/core/web_services/servlet_helper.rb', line 34

def set_json_error_response(response:, code:)
  error_response = { error: response }
  set_json_response(error_response, nil, code = code)
end

#set_json_response(data, includes = nil, code = 200) ⇒ Object



24
25
26
27
# File 'lib/msf/core/web_services/servlet_helper.rb', line 24

def set_json_response(data, includes = nil, code = 200)
  headers = { 'Content-Type' => 'application/json' }
  [code, headers, to_json(data, includes)]
end

#set_raw_response(data, code: 200) ⇒ Object



19
20
21
22
# File 'lib/msf/core/web_services/servlet_helper.rb', line 19

def set_raw_response(data, code: 200)
  headers = { 'Content-Type' => 'application/json' }
  [code, headers, data]
end

#wardenWarden::Proxy

Get Warden::Proxy object from the Rack environment.

Returns:

  • (Warden::Proxy)

    The Warden::Proxy object from the Rack environment.



144
145
146
# File 'lib/msf/core/web_services/servlet_helper.rb', line 144

def warden
  env['warden']
end

#warden_optionsHash

Get Warden options hash from the Rack environment.

Returns:

  • (Hash)

    The Warden options hash from the Rack environment.



150
151
152
# File 'lib/msf/core/web_services/servlet_helper.rb', line 150

def warden_options
  env['warden.options']
end