class ShippingEasy::Authenticator

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.

Constants

EXPIRATION_INTERVAL

Attributes

api_secret[R]
api_signature[R]
api_timestamp[R]
body[R]
expected_signature[R]
method[R]
params[R]
path[R]

Public Class Methods

authenticate(options = {}) click to toggle source

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.

# File lib/shipping_easy/authenticator.rb, line 47
def self.authenticate(options = {})
  new(options).authenticate
end
new(options = {}) click to toggle source

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.
# File lib/shipping_easy/authenticator.rb, line 26
def initialize(options = {})
  @api_secret = options.fetch(:api_secret, ShippingEasy.api_secret)
  @method = options.fetch(:method, :get)
  @path = options.fetch(:path)
  @body = options.fetch(:body, nil)
  @params = options.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

Public Instance Methods

authenticate() click to toggle source

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.

# 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() click to toggle source

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.

# File lib/shipping_easy/authenticator.rb, line 93
def parsed_timestamp
  raise ArgumentError if api_timestamp == 0
  Time.at(api_timestamp)
rescue ArgumentError, TypeError
  raise ShippingEasy::TimestampFormatError
end
request_expired?() click to toggle source

Returns true if the supplied API timestamp has expired.

# File lib/shipping_easy/authenticator.rb, line 78
def request_expired?
  parsed_timestamp < request_expires_at
end
request_expires_at() click to toggle source

Returns the time that the request expires, given the supplied API timestamp.

Returns a Time object.

# File lib/shipping_easy/authenticator.rb, line 85
def request_expires_at
  Time.now - EXPIRATION_INTERVAL
end
signatures_match?() click to toggle source

Returns true if the signature included in the request matches our calculated signature.

# File lib/shipping_easy/authenticator.rb, line 73
def signatures_match?
  expected_signature == api_signature
end