class ShippingEasy::Signature

Used to generate ShippingEasy API signatures or to compare signature with one another.

Attributes

api_secret[R]
body[R]
method[R]
params[R]
path[R]

Public Class Methods

new(options = {}) click to toggle source

Creates a new API signature object.

options - The Hash options used to create a signature:

: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/signature.rb, line 21
def initialize(options = {})
  options = options.dup
  @api_secret = options.delete(:api_secret) || ""
  @method = options.fetch(:method, :get).to_s.upcase
  @path = options.delete(:path) || ""
  @body = options.delete(:body) || ""
  @params = options[:params].nil? ? {} : options.delete(:params).dup
  @params.delete(:api_signature) # remove for convenience
end

Public Instance Methods

==(other_signature) click to toggle source

Equality operator to determine if another signature object, or string, matches the current signature. If a string is passed in, it should represent the encrypted form of the API signature, not the plaintext version.

It uses a constant time string comparison function to limit the vulnerability of timing attacks.

Returns true if the supplied string or signature object matches the current object.

# File lib/shipping_easy/signature.rb, line 66
def ==(other_signature)
  expected_signature, supplied_signature = self.to_s, other_signature.to_s
  return false if expected_signature.nil? || supplied_signature.nil? || expected_signature.empty? || supplied_signature.empty?
  return false if expected_signature.bytesize != supplied_signature.bytesize
  l = expected_signature.unpack "C#{expected_signature.bytesize}"
  res = 0
  supplied_signature.each_byte { |byte| res |= byte ^ l.shift }
  res == 0
end
encrypted() click to toggle source

Encrypts the plaintext signature with the supplied API secret. This signature should be included when making a ShippingEasy API call.

Returns an encrypted signature.

# File lib/shipping_easy/signature.rb, line 56
def encrypted
  OpenSSL::HMAC::hexdigest("sha256", api_secret, plaintext)
end
plaintext() click to toggle source

Concatenates the parts of the base signature into a plaintext string using the following order:

  1. Capitilized method of the request. E.g. “POST”

  2. The URI path

  3. The query parameters sorted alphabetically and concatenated together into a URL friendly format: param1=ABC&param2=XYZ

  4. The request body as a string if one exists

All parts are then concatenated together with an ampersand. The result resembles something like this:

“POST&/api/orders&param1=ABC&param2=XYZ&{"orders":{"name":"Flip flops","cost":"10.00","shipping_cost":"2.00"}}”

Returns a correctly contenated plaintext API signature.

# File lib/shipping_easy/signature.rb, line 43
def plaintext
  parts = []
  parts << method
  parts << path
  parts << Rack::Utils.build_query(params.sort)
  parts << body.to_s unless body.nil? || body == ""
  parts.join("&")
end
to_s() click to toggle source

Returns the encrypted form of the signature.

Returns an encrypted signature.

# File lib/shipping_easy/signature.rb, line 79
def to_s
  encrypted
end