class ShippingEasy::Signature
Used to generate ShippingEasy
API signatures or to compare signature with one another.
Attributes
Public Class Methods
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
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
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
Concatenates the parts of the base signature into a plaintext string using the following order:
-
Capitilized method of the request. E.g. “POST”
-
The URI path
-
The query parameters sorted alphabetically and concatenated together into a URL friendly format: param1=ABC¶m2=XYZ
-
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¶m1=ABC¶m2=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
Returns the encrypted form of the signature.
Returns an encrypted signature.
# File lib/shipping_easy/signature.rb, line 79 def to_s encrypted end