Class: SecurityClient::Auth

Inherits:
Object
  • Object
show all
Defined in:
lib/security_client.rb

Class Method Summary collapse

Class Method Details

.build_headers(papi, sapi, endpoint, query, host, http_method) ⇒ Object



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/security_client.rb', line 259

def self.build_headers(papi, sapi, endpoint, query, host, http_method)

  # This function calculates the signature for the message, adding the Signature header
  # to contain the data. Certain HTTP headers are required for
  # signature calculation and will be added by this code as
  # necessary. The constructed headers object is returned

  # the '(request-target)' is part of the signed data.
  # it's value is 'http_method path?query'
  reqt = "#{http_method} #{endpoint}"

  # The time at which the signature was created expressed as the unix epoch
  created = Time.now.to_i

  # the Digest header is always included/overridden by
  # this code. it is a hash of the body of the http message
  # and is always present even if the body is empty
  hash_sha512 = OpenSSL::Digest::SHA512.new
  hash_sha512 << JSON.dump(query)
  digest = 'SHA-512='+Base64.strict_encode64(hash_sha512.digest)

  # Initialize the headers object to be returned via this method
  all_headers = {}
  # The content type of request
  all_headers['content-type'] = 'application/json'
  # The request target calculated above(reqt)
  all_headers['(request-target)'] = reqt
  # The date and time in GMT format
  all_headers['date'] = get_date
  # The host specified by the caller
  all_headers['host'] = get_host(host)
  all_headers['(created)'] = created
  all_headers['digest'] = digest
  headers = ['content-type', 'date', 'host', '(created)', '(request-target)', 'digest']

  # include the specified headers in the hmac calculation. each
  # header is of the form 'header_name: header value\n'
  # included headers are also added to an ordered list of headers
  # which is included in the message
  hmac = OpenSSL::HMAC.new(sapi, OpenSSL::Digest::SHA512.new)
  headers.each do |header|
    if all_headers.key?(header)
      hmac << "#{header}: #{all_headers[header]}\n"
    end
  end

  all_headers.delete('(created)')
  all_headers.delete('(request-target)')
  all_headers.delete('host')

  # Build the Signature header itself
  all_headers['signature']  = 'keyId="' + papi + '"'
  all_headers['signature'] += ', algorithm="hmac-sha512"'
  all_headers['signature'] += ', created=' + created.to_s
  all_headers['signature'] += ', headers="' + headers.join(" ") + '"'
  all_headers['signature'] += ', signature="'
  all_headers['signature'] += Base64.strict_encode64(hmac.digest)
  all_headers['signature'] += '"'

  return all_headers
end

.get_dateObject



326
327
328
# File 'lib/security_client.rb', line 326

def self.get_date
  DateTime.now.in_time_zone('GMT').strftime("%a, %d %b %Y") + " " + DateTime.now.in_time_zone('GMT').strftime("%H:%M:%S") + " GMT"
end

.get_host(host) ⇒ Object



321
322
323
324
# File 'lib/security_client.rb', line 321

def self.get_host(host)
  uri = URI(host)
  return "#{uri.hostname}:#{uri.port}"
end