Class: Ubiq::Auth
- Inherits:
-
Object
- Object
- Ubiq::Auth
- Defined in:
- lib/ubiq/auth.rb
Overview
This module implements HTTP authentication for the Ubiq platform via message signing as described by the IETF httpbis-message-signatures draft specification.
Class Method Summary collapse
- .build_headers(papi, sapi, endpoint, query, host, http_method) ⇒ Object
- .get_date ⇒ Object
-
.get_host(host) ⇒ Object
Only want to return port in the URI if the host contained one, otherwise let gateway resolve it.
Class Method Details
.build_headers(papi, sapi, endpoint, query, host, http_method) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/ubiq/auth.rb', line 12 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 = {} all_headers['user-agent'] = 'ubiq-ruby/' + Ubiq::VERSION # 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_date ⇒ Object
84 85 86 87 |
# File 'lib/ubiq/auth.rb', line 84 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
Only want to return port in the URI if the host contained one, otherwise let gateway resolve it
77 78 79 80 81 82 |
# File 'lib/ubiq/auth.rb', line 77 def self.get_host(host) uri = URI(host) ret = uri.hostname.to_s ret += ":#{uri.port}" if host.match(/:[0-9]+/) ret end |