Class: Ey::Hmac::Adapter Abstract
- Inherits:
-
Object
- Object
- Ey::Hmac::Adapter
- Defined in:
- lib/ey-hmac/adapter.rb
Overview
override methods #method, #path, #body, #content_type and #content_digest
This class is responsible for forming the canonical string to used to sign requests
Defined Under Namespace
Constant Summary collapse
- AUTHORIZATION_REGEXP =
/\w+ ([^:]+):(.+)$/.freeze
- DEFAULT_CANONICALIZE_WITH =
%i[method content_type content_digest date path].freeze
Instance Attribute Summary collapse
-
#accept_digests ⇒ Object
readonly
Returns the value of attribute accept_digests.
-
#authorization_header ⇒ Object
readonly
Returns the value of attribute authorization_header.
-
#canonicalize_with ⇒ Object
readonly
Returns the value of attribute canonicalize_with.
-
#include_query_string ⇒ Object
readonly
Returns the value of attribute include_query_string.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#request ⇒ Object
readonly
Returns the value of attribute request.
-
#service ⇒ Object
readonly
Returns the value of attribute service.
-
#sign_with ⇒ Object
readonly
Returns the value of attribute sign_with.
Instance Method Summary collapse
- #authenticated!(&block) ⇒ Object (also: #authenticate!)
-
#authenticated?(_options = {}) {|key_id| ... } ⇒ Boolean
Check #authorization_signature against calculated #signature.
-
#authorization(key_id, key_secret) ⇒ String
HMAC header value of #request.
-
#authorization_signature ⇒ String
abstract
Value of the #authorization_header.
- #body ⇒ String, NilClass abstract
-
#canonicalize ⇒ String
In order for the server to correctly authorize the request, the client and server MUST AGREE on this format.
-
#content_digest ⇒ String
abstract
Digest of body.
-
#content_type ⇒ String
abstract
Value of the Content-Type header in #request.
-
#date ⇒ String
abstract
Value of the Date header in #request.
-
#initialize(request, options = {}) ⇒ Adapter
constructor
A new instance of Adapter.
-
#method ⇒ String
abstract
Upcased request verb.
-
#path ⇒ String
abstract
Request path.
-
#sign!(key_id, key_secret) ⇒ String
abstract
Add #signature header to request.
-
#signature(key_secret, digest = sign_with) ⇒ String
HMAC signature of #request.
Constructor Details
#initialize(request, options = {}) ⇒ Adapter
Returns a new instance of Adapter.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/ey-hmac/adapter.rb', line 29 def initialize(request, = {}) @request = request @options = @ttl = [:ttl] @authorization_header = [:authorization_header] || 'Authorization' @service = [:service] || 'EyHmac' @sign_with = [:sign_with] || :sha256 @include_query_string = .fetch(:include_query_string, false) @accept_digests = Array([:accept_digests] || :sha256) @canonicalize_with = DEFAULT_CANONICALIZE_WITH @canonicalize_with += :query_string if include_query_string end |
Instance Attribute Details
#accept_digests ⇒ Object (readonly)
Returns the value of attribute accept_digests.
12 13 14 |
# File 'lib/ey-hmac/adapter.rb', line 12 def accept_digests @accept_digests end |
#authorization_header ⇒ Object (readonly)
Returns the value of attribute authorization_header.
12 13 14 |
# File 'lib/ey-hmac/adapter.rb', line 12 def @authorization_header end |
#canonicalize_with ⇒ Object (readonly)
Returns the value of attribute canonicalize_with.
12 13 14 |
# File 'lib/ey-hmac/adapter.rb', line 12 def canonicalize_with @canonicalize_with end |
#include_query_string ⇒ Object (readonly)
Returns the value of attribute include_query_string.
12 13 14 |
# File 'lib/ey-hmac/adapter.rb', line 12 def include_query_string @include_query_string end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
12 13 14 |
# File 'lib/ey-hmac/adapter.rb', line 12 def @options end |
#request ⇒ Object (readonly)
Returns the value of attribute request.
12 13 14 |
# File 'lib/ey-hmac/adapter.rb', line 12 def request @request end |
#service ⇒ Object (readonly)
Returns the value of attribute service.
12 13 14 |
# File 'lib/ey-hmac/adapter.rb', line 12 def service @service end |
#sign_with ⇒ Object (readonly)
Returns the value of attribute sign_with.
12 13 14 |
# File 'lib/ey-hmac/adapter.rb', line 12 def sign_with @sign_with end |
Instance Method Details
#authenticated!(&block) ⇒ Object Also known as: authenticate!
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/ey-hmac/adapter.rb', line 134 def authenticated!(&block) 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}" end check_ttl! matching_signature = accept_digests .lazy .map { |ad| signature(key_secret, ad) } .any? { |cs| secure_compare(signature_value, cs) } raise Ey::Hmac::SignatureMismatch unless matching_signature true end |
#authenticated?(_options = {}) {|key_id| ... } ⇒ Boolean
Check #authorization_signature against calculated #signature
127 128 129 130 131 |
# File 'lib/ey-hmac/adapter.rb', line 127 def authenticated?( = {}, &block) authenticated!(&block) rescue Ey::Hmac::Error false end |
#authorization(key_id, key_secret) ⇒ String
Returns HMAC header value of #request.
66 67 68 |
# File 'lib/ey-hmac/adapter.rb', line 66 def (key_id, key_secret) "#{service} #{key_id}:#{signature(key_secret, sign_with)}" end |
#authorization_signature ⇒ String
used when verifying a signed request
Returns value of the #authorization_header.
111 112 113 |
# File 'lib/ey-hmac/adapter.rb', line 111 def raise NotImplementedError end |
#body ⇒ String, NilClass
92 93 94 |
# File 'lib/ey-hmac/adapter.rb', line 92 def body raise NotImplementedError end |
#canonicalize ⇒ String
In order for the server to correctly authorize the request, the client and server MUST AGREE on this format
default canonical string formation is ‘#method\n#content_type\n#content_digest\n#date\n#path’
48 49 50 |
# File 'lib/ey-hmac/adapter.rb', line 48 def canonicalize canonicalize_with.map { || public_send() }.join("\n") end |
#content_digest ⇒ String
Digest of body. Default is MD5.
85 86 87 |
# File 'lib/ey-hmac/adapter.rb', line 85 def content_digest raise NotImplementedError end |
#content_type ⇒ String
Returns value of the Content-Type header in #request.
98 99 100 |
# File 'lib/ey-hmac/adapter.rb', line 98 def content_type raise NotImplementedError end |
#date ⇒ String
Returns value of the Date header in #request.
105 106 107 |
# File 'lib/ey-hmac/adapter.rb', line 105 def date raise NotImplementedError end |
#method ⇒ String
Returns upcased request verb. i.e. ‘GET’.
72 73 74 |
# File 'lib/ey-hmac/adapter.rb', line 72 def method raise NotImplementedError end |
#path ⇒ String
Returns request path. i.e. ‘/blogs/1’.
78 79 80 |
# File 'lib/ey-hmac/adapter.rb', line 78 def path raise NotImplementedError end |
#sign!(key_id, key_secret) ⇒ String
Add #signature header to request. Typically this is ‘Authorization’ or ‘WWW-Authorization’
119 120 121 |
# File 'lib/ey-hmac/adapter.rb', line 119 def sign!(key_id, key_secret) raise NotImplementedError end |
#signature(key_secret, digest = sign_with) ⇒ String
Returns HMAC signature of #request.
55 56 57 58 59 60 61 |
# File 'lib/ey-hmac/adapter.rb', line 55 def signature(key_secret, digest = sign_with) Base64.strict_encode64( OpenSSL::HMAC.digest( OpenSSL::Digest.new(digest.to_s), key_secret, canonicalize ) ).strip end |