lib/ey-hmac/adapter.rb in ey-hmac-2.3.0 vs lib/ey-hmac/adapter.rb in ey-hmac-2.3.1
- old
+ new
@@ -1,24 +1,27 @@
+# frozen_string_literal: true
+
# This class is responsible for forming the canonical string to used to sign requests
# @abstract override methods {#method}, {#path}, {#body}, {#content_type} and {#content_digest}
class Ey::Hmac::Adapter
- AUTHORIZATION_REGEXP = /\w+ ([^:]+):(.+)$/
+ AUTHORIZATION_REGEXP = /\w+ ([^:]+):(.+)$/.freeze
- autoload :Rack, "ey-hmac/adapter/rack"
- autoload :Faraday, "ey-hmac/adapter/faraday"
+ autoload :Rack, 'ey-hmac/adapter/rack'
+ autoload :Faraday, 'ey-hmac/adapter/faraday'
attr_reader :request, :options, :authorization_header, :service, :sign_with, :accept_digests
# @param [Object] request signer-specific request implementation
# @option options [Integer] :version signature version
# @option options [Integer] :ttl (nil) duration during which HMAC is valid after signed date
# @option options [String] :authorization_header ('Authorization') Authorization header key.
# @option options [String] :server ('EyHmac') service name prefixed to {#authorization}. set to {#service}
# @option options [Symbol] :sign_with (:sha_256) outgoing signature digest algorithm. See {OpenSSL::Digest#new}
# @option options [Array] :accepted_digests ([:sha_256]) accepted incoming signature digest algorithm. See {OpenSSL::Digest#new}
- def initialize(request, options={})
- @request, @options = request, options
+ def initialize(request, options = {})
+ @request = request
+ @options = options
@ttl = options[:ttl]
@authorization_header = options[:authorization_header] || 'Authorization'
@service = options[:service] || 'EyHmac'
@sign_with = options[:sign_with] || :sha256
@@ -34,14 +37,16 @@
end
# @param [String] key_secret private HMAC key
# @param [String] signature digest hash function. Defaults to #sign_with
# @return [String] HMAC signature of {#request}
- def signature(key_secret, digest = self.sign_with)
+ def signature(key_secret, digest = sign_with)
Base64.strict_encode64(
OpenSSL::HMAC.digest(
- OpenSSL::Digest.new(digest.to_s), key_secret, canonicalize)).strip
+ OpenSSL::Digest.new(digest.to_s), key_secret, canonicalize
+ )
+ ).strip
end
# @param [String] key_id public HMAC key
# @param [String] key_secret private HMAC key
# @return [String] HMAC header value of {#request}
@@ -104,11 +109,11 @@
# Check {#authorization_signature} against calculated {#signature}
# @yieldparam key_id [String] public HMAC key
# @return [Boolean] true if block yields matching private key and signature matches, else false
# @see #authenticated!
- def authenticated?(options={}, &block)
+ def authenticated?(_options = {}, &block)
authenticated!(&block)
rescue Ey::Hmac::Error
false
end
@@ -117,22 +122,19 @@
key_id, signature_value = check_signature!
key_secret = block.call(key_id)
unless key_secret
raise Ey::Hmac::MissingSecret,
- "Failed to find secret matching #{key_id.inspect}"
+ "Failed to find secret matching #{key_id.inspect}"
end
check_ttl!
calculated_signatures = accept_digests.map { |ad| signature(key_secret, ad) }
matching_signature = calculated_signatures.any? { |cs| secure_compare(signature_value, cs) }
- unless matching_signature
- raise Ey::Hmac::SignatureMismatch,
- "Calculated signature #{signature_value} does not match #{calculated_signatures.inspect} using #{canonicalize.inspect}"
- end
+ raise Ey::Hmac::SignatureMismatch unless matching_signature
true
end
alias authenticate! authenticated!
@@ -141,34 +143,35 @@
# Constant time string comparison.
# pulled from https://github.com/rack/rack/blob/master/lib/rack/utils.rb#L399
def secure_compare(a, b)
return false unless a.bytesize == b.bytesize
- l = a.unpack("C*")
+ l = a.unpack('C*')
- r, i = 0, -1
- b.each_byte { |v| r |= v ^ l[i+=1] }
- r == 0
+ r = 0
+ i = -1
+ b.each_byte { |v| r |= v ^ l[i += 1] }
+ r.zero?
end
def check_ttl!
if @ttl && date
expiry = Time.parse(date).to_i + @ttl
current_time = Time.now.to_i
unless expiry > current_time
raise Ey::Hmac::ExpiredHmac,
- "Signature has expired passed #{expiry}. Current time is #{current_time}"
+ "Signature has expired passed #{expiry}. Current time is #{current_time}"
end
end
end
def check_signature!
authorization_match = AUTHORIZATION_REGEXP.match(authorization_signature)
unless authorization_match
raise Ey::Hmac::MissingAuthorization,
- "Failed to parse authorization_signature #{authorization_signature}"
+ "Failed to parse authorization_signature #{authorization_signature}"
end
[authorization_match[1], authorization_match[2]]
end
end