module Roqua module CoreApi module Sessions # Make a single hmac signed request. # HmacAuthRequest.new(consumer_key: 'mykey', consumer_secret: '...') # HmacAuthRequest.new(consumer_key: 'mykey', hmac: '...', nonce: '...', timestamp: 1467704698) class HmacAuthRequest < AuthSession attr_reader :consumer_key, :consumer_secret, :timestamp, :nonce def initialize(consumer_key: ENV.fetch('CORE_CONSUMER_KEY'), consumer_secret: ENV.fetch('CORE_CONSUMER_SECRET'), timestamp: Time.now.to_i, nonce: SecureRandom.urlsafe_base64(32), hmac: nil, **additional_arguments) @consumer_key = consumer_key @consumer_secret = consumer_secret @timestamp = timestamp @nonce = nonce @hmac = hmac super(**additional_arguments) end def headers(request_method, path, params) {'Authorization' => "HMAC #{consumer_key}:#{hmac(request_method, path, params)}:#{nonce}:#{timestamp}"} end # handle 401 response. def access_denied(response) fail Unauthorized, response end private def hmac(request_method, path, params) @hmac || calculate_hmac(request_method, path, params) end def calculate_hmac(request_method, path, params) checker = Authmac::HmacChecker.new(consumer_secret, digest_function: 'sha256', message_format: :json) params_to_sign = params.merge \ 'request_method' => request_method, 'request_path' => "/api/v1#{path}", 'timestamp' => timestamp.to_s, 'nonce' => nonce, 'consumer_key' => consumer_key checker.sign(params_to_sign.with_indifferent_access) end end end end end