Class: BellaBaxter::HmacAuthProvider

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

Overview

Kiota AuthenticationProvider that signs every request with HMAC-SHA256.

Reads the bax-keyId-signingSecret API key and adds:

X-Bella-Key-Id, X-Bella-Timestamp, X-Bella-Signature

Instance Method Summary collapse

Constructor Details

#initialize(api_key, bella_client: 'bella-ruby-sdk', app_client: nil) ⇒ HmacAuthProvider

Returns a new instance of HmacAuthProvider.



14
15
16
17
18
19
20
21
22
23
24
# File 'lib/bella_baxter/hmac_auth_provider.rb', line 14

def initialize(api_key, bella_client: 'bella-ruby-sdk', app_client: nil)
  parts = api_key.split("-", 3)
  unless parts.length == 3 && parts[0] == "bax"
    raise InvalidApiKeyError, "api_key must be in format bax-{keyId}-{signingSecret}"
  end

  @key_id         = parts[1]
  @signing_secret = [parts[2]].pack("H*")
  @bella_client   = bella_client
  @app_client     = app_client || ENV['BELLA_BAXTER_APP_CLIENT']
end

Instance Method Details

#authenticate_request(request, _additional_context = {}) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/bella_baxter/hmac_auth_provider.rb', line 26

def authenticate_request(request, _additional_context = {})
  Fiber.new do
    method    = request.http_method.to_s.upcase
    uri       = URI.parse(request.uri.to_s)
    path      = uri.path
    query     = sorted_query(uri.query)
    body      = request.content.to_s
    timestamp = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
    body_hash = Digest::SHA256.hexdigest(body)
    sts       = "#{method}\n#{path}\n#{query}\n#{timestamp}\n#{body_hash}"
    signature = OpenSSL::HMAC.hexdigest("SHA256", @signing_secret, sts)

    request.headers.try_add("X-Bella-Key-Id",    @key_id)
    request.headers.try_add("X-Bella-Timestamp", timestamp)
    request.headers.try_add("X-Bella-Signature", signature)
    request.headers.try_add("X-Bella-Client",    @bella_client)
    request.headers.try_add("X-App-Client",      @app_client) if @app_client
  end
end