Class: ShippingEasy::Authenticator
- Inherits:
-
Object
- Object
- ShippingEasy::Authenticator
- Defined in:
- lib/shipping_easy/authenticator.rb
Overview
Authenticates a signed ShippingEasy API request by matching the supplied signature with a freshly calculated one using the API shared secret. Requests may not be more than 10 minutes old in order to prevent playback attacks.
Constant Summary collapse
- EXPIRATION_INTERVAL =
60 * 60
Instance Attribute Summary collapse
-
#api_secret ⇒ Object
readonly
Returns the value of attribute api_secret.
-
#api_signature ⇒ Object
readonly
Returns the value of attribute api_signature.
-
#api_timestamp ⇒ Object
readonly
Returns the value of attribute api_timestamp.
-
#body ⇒ Object
readonly
Returns the value of attribute body.
-
#expected_signature ⇒ Object
readonly
Returns the value of attribute expected_signature.
-
#method ⇒ Object
readonly
Returns the value of attribute method.
-
#params ⇒ Object
readonly
Returns the value of attribute params.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Class Method Summary collapse
-
.authenticate(options = {}) ⇒ Object
Convenience method to instantiate an authenticator and authenticate a signed request.
Instance Method Summary collapse
-
#authenticate ⇒ Object
Authenticates the signed request.
-
#initialize(options = {}) ⇒ Authenticator
constructor
Creates a new API authenticator object.
-
#parsed_timestamp ⇒ Object
Parses the supplied API timestamp string into a Time object.
-
#request_expired? ⇒ Boolean
Returns true if the supplied API timestamp has expired.
-
#request_expires_at ⇒ Object
Returns the time that the request expires, given the supplied API timestamp.
-
#signatures_match? ⇒ Boolean
Returns true if the signature included in the request matches our calculated signature.
Constructor Details
#initialize(options = {}) ⇒ Authenticator
Creates a new API authenticator object.
options - The Hash options used to authenticate the request:
:api_secret - A ShippingEasy-supplied API secret
:method - The HTTP method used in the request. Either :get or :post. Default is :get.
:path - The URI path of the request. E.g. "/api/orders"
:params - The query params passed in as part of the request.
:body - The body of the request which should normally be a JSON payload.
26 27 28 29 30 31 32 33 34 35 |
# File 'lib/shipping_easy/authenticator.rb', line 26 def initialize( = {}) @api_secret = .fetch(:api_secret, ShippingEasy.api_secret) @method = .fetch(:method, :get) @path = .fetch(:path) @body = .fetch(:body, nil) @params = .fetch(:params, {}) @api_signature = params.delete(:api_signature) @api_timestamp = params.fetch(:api_timestamp, nil).to_i @expected_signature = ShippingEasy::Signature.new(api_secret: @api_secret, method: @method, path: @path, params: @params, body: @body) end |
Instance Attribute Details
#api_secret ⇒ Object (readonly)
Returns the value of attribute api_secret.
9 10 11 |
# File 'lib/shipping_easy/authenticator.rb', line 9 def api_secret @api_secret end |
#api_signature ⇒ Object (readonly)
Returns the value of attribute api_signature.
9 10 11 |
# File 'lib/shipping_easy/authenticator.rb', line 9 def api_signature @api_signature end |
#api_timestamp ⇒ Object (readonly)
Returns the value of attribute api_timestamp.
9 10 11 |
# File 'lib/shipping_easy/authenticator.rb', line 9 def @api_timestamp end |
#body ⇒ Object (readonly)
Returns the value of attribute body.
9 10 11 |
# File 'lib/shipping_easy/authenticator.rb', line 9 def body @body end |
#expected_signature ⇒ Object (readonly)
Returns the value of attribute expected_signature.
9 10 11 |
# File 'lib/shipping_easy/authenticator.rb', line 9 def expected_signature @expected_signature end |
#method ⇒ Object (readonly)
Returns the value of attribute method.
9 10 11 |
# File 'lib/shipping_easy/authenticator.rb', line 9 def method @method end |
#params ⇒ Object (readonly)
Returns the value of attribute params.
9 10 11 |
# File 'lib/shipping_easy/authenticator.rb', line 9 def params @params end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
9 10 11 |
# File 'lib/shipping_easy/authenticator.rb', line 9 def path @path end |
Class Method Details
.authenticate(options = {}) ⇒ Object
Convenience method to instantiate an authenticator and authenticate a signed request.
options - The Hash options used to authenticate the request:
:api_secret - A ShippingEasy-supplied API secret
:method - The HTTP method used in the request. Either :get or :post. Default is :get.
:path - The URI path of the request. E.g. "/api/orders"
:params - The query params passed in as part of the request.
:body - The body of the request which should normally be a JSON payload.
See #authenticate for more detail.
47 48 49 |
# File 'lib/shipping_easy/authenticator.rb', line 47 def self.authenticate( = {}) new().authenticate end |
Instance Method Details
#authenticate ⇒ Object
Authenticates the signed request.
Example:
authenticator = ShippingEasyShippingEasy::Authenticator.new(api_secret: “XXX”,
method: :post,
path: "/api/orders",
params: { test_param: "ABCDE", api_key: "123", api_timestamp: "2014-01-03 10:41:21 -0600" },
body: "{\"orders\":{\"name\":\"Flip flops\",\"cost\":\"10.00\",\"shipping_cost\":\"2.00\"}}")
Throws ShippingEasyShippingEasy::RequestExpiredError if the API timestamp is expired. Throws ShippingEasyShippingEasy::AccessDeniedError if the signature cannot be verified. Throws ShippingEasyShippingEasy::TimestampFormatError if the timestamp format is invalid
Returns true if authentication passes.
66 67 68 69 70 |
# File 'lib/shipping_easy/authenticator.rb', line 66 def authenticate raise ShippingEasy::RequestExpiredError if request_expired? raise ShippingEasy::AccessDeniedError unless signatures_match? true end |
#parsed_timestamp ⇒ Object
Parses the supplied API timestamp string into a Time object.
Raises ShippingEasyShippingEasy::TimestampFormatError if the string cannot be converted into a Time object. Returns a Time object.
93 94 95 96 97 98 |
# File 'lib/shipping_easy/authenticator.rb', line 93 def raise ArgumentError if == 0 Time.at() rescue ArgumentError, TypeError raise ShippingEasy::TimestampFormatError end |
#request_expired? ⇒ Boolean
Returns true if the supplied API timestamp has expired.
78 79 80 |
# File 'lib/shipping_easy/authenticator.rb', line 78 def request_expired? < request_expires_at end |
#request_expires_at ⇒ Object
Returns the time that the request expires, given the supplied API timestamp.
Returns a Time object.
85 86 87 |
# File 'lib/shipping_easy/authenticator.rb', line 85 def request_expires_at Time.now - EXPIRATION_INTERVAL end |
#signatures_match? ⇒ Boolean
Returns true if the signature included in the request matches our calculated signature.
73 74 75 |
# File 'lib/shipping_easy/authenticator.rb', line 73 def signatures_match? expected_signature == api_signature end |