class ApiSigv2::Validator

Validate a request

request = {
  http_method: 'PUT',
  url: 'https://domain.com',
  headers: {
    'Authorization' => 'API-HMAC-SHA256 Credential=access_key/20191227/api_request...',
    'Host' => 'example.com,
    'X-Content-Sha256' => '...',
    'X-Datetime' => '2019-12-27T09:13:14.873+0000'
  },
  body: 'body'
}
validator = ApiSigv2::Validator.new(request, uri_escape_path: true)
validator.access_key # get key from request headers
validator.valid?('secret_key')

Attributes

request[R]

Public Class Methods

new(request, options = {}) click to toggle source
# File lib/api_sigv2/validator.rb, line 24
def initialize(request, options = {})
  @request = request
  @options = options
end

Public Instance Methods

access_key() click to toggle source
# File lib/api_sigv2/validator.rb, line 29
def access_key
  return unless valid_credential?

  @access_key ||= auth_header.credential.split('/')[0]
end
signed_headers() click to toggle source
# File lib/api_sigv2/validator.rb, line 35
def signed_headers
  @signed_headers ||= headers.slice(*auth_header.signed_headers)
end
valid?(secret_key) click to toggle source

Validate a signature. Returns boolean

validator.valid?('secret_key_here')

@param [String] secret key

# File lib/api_sigv2/validator.rb, line 45
def valid?(secret_key)
  valid_authorization? && valid_timestamp? && valid_signature?(secret_key)
end
valid_authorization?() click to toggle source
# File lib/api_sigv2/validator.rb, line 49
def valid_authorization?
  valid_credential? && !auth_header.signature.nil?
end
valid_credential?() click to toggle source
# File lib/api_sigv2/validator.rb, line 53
def valid_credential?
  !auth_header.credential.nil?
end
valid_signature?(secret_key) click to toggle source
# File lib/api_sigv2/validator.rb, line 61
def valid_signature?(secret_key)
  return false unless secret_key

  signer = Signer.new(access_key, secret_key, @options)
  data = signer.sign_request(request)

  Utils.secure_compare(
    auth_header.signature,
    data.signature
  )
end
valid_timestamp?() click to toggle source
# File lib/api_sigv2/validator.rb, line 57
def valid_timestamp?
  timestamp && ttl_range.cover?(timestamp.to_time)
end

Private Instance Methods

auth_header() click to toggle source
# File lib/api_sigv2/validator.rb, line 75
def auth_header
  @auth_header ||= AuthHeader.new(headers[signature_header_name])
end
headers() click to toggle source
# File lib/api_sigv2/validator.rb, line 87
def headers
  @headers ||= Utils.normalize_keys(request[:headers])
end
signature_header_name() click to toggle source
# File lib/api_sigv2/validator.rb, line 79
def signature_header_name
  @options[:signature_header] || ApiSigv2.configuration.signature_header
end
timestamp() click to toggle source
# File lib/api_sigv2/validator.rb, line 83
def timestamp
  @timestamp ||= Utils.safe_parse_datetime(headers['x-datetime'])
end
ttl_range() click to toggle source
# File lib/api_sigv2/validator.rb, line 91
def ttl_range
  to = Time.now.utc
  from = to - ApiSigv2.configuration.signature_ttl

  from..to
end