Sha256: c71c253cde26664771d1bfeae1d6c38ecefe763414ba7bd0465627a2f829d0ee

Contents?: true

Size: 1.96 KB

Versions: 2

Compression:

Stored size: 1.96 KB

Contents

require 'httparty'
require 'cgi'

module Bluekai
  class Request
    attr_accessor :api_user_key, :api_private_key

    def initialize(method, path, query, body, domain)
      @method = method.upcase
      @path = path
      @query = query
      @body = body
      @domain = domain
    end

    def run
      response = http_request
      fail "HTTP Request Error: #{response.body}" unless response.code.start_with?('2')
      return :success if response.body.nil? || response.body.strip.empty?
      JSON.parse(response.body, symbolize_names: true)
    end

    private

    attr_reader :method, :path, :query, :body, :domain

    def http_request
      case method
      when 'GET'
        HTTParty.get(url)
      when 'POST'
        HTTParty.post(url, non_get_params)
      when 'PUT'
        HTTParty.put(url, non_get_params)
      when 'DELETE'
        HTTParty.delete(url, non_get_params)
      end.response
    end

    def non_get_params
      { body: body_sorted, headers: json_headers }
    end

    def url
      "#{domain}#{path}?#{query_url_formatted}"\
        "bkuid=#{api_user_key}&bksig=#{signature}"
    end

    def query_values
      return nil unless query
      query.values.join
    end

    def body_sorted
      # sort hash according to keys for correct signature computation
      body.sort_by { |key, _value| key.to_s }.to_h.to_json if body
    end

    def json_headers
      {
        'Accept' => 'application/json',
        'Content-type' => 'application/json'
      }
    end

    def query_url_formatted
      return nil unless query
      query.map { |k, v| "#{k}=#{v}" }.join('&') + '&'
    end

    def string_to_sign
      method + path + query_values.to_s + body_sorted.to_s
    end

    # HMAC-SHA256(Secret key, HTTP_METHOD + URI_PATH + QUERY_ARG_VALUES + POST_DATA)
    def signature
      digest = OpenSSL::Digest.new('sha256')
      hmac = OpenSSL::HMAC.digest(digest, api_private_key, string_to_sign)
      CGI.escape(Base64.strict_encode64(hmac))
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
bluekai-0.0.4 lib/bluekai/request.rb
bluekai-0.0.3 lib/bluekai/request.rb