Class: ShippingEasy::Signature
- Inherits:
-
Object
- Object
- ShippingEasy::Signature
- Defined in:
- lib/shipping_easy/signature.rb
Overview
Used to generate ShippingEasy API signatures or to compare signature with one another.
Instance Attribute Summary collapse
-
#api_secret ⇒ Object
readonly
Returns the value of attribute api_secret.
-
#body ⇒ Object
readonly
Returns the value of attribute body.
-
#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.
Instance Method Summary collapse
-
#==(other_signature) ⇒ Object
Equality operator to determine if another signature object, or string, matches the current signature.
-
#encrypted ⇒ Object
Encrypts the plaintext signature with the supplied API secret.
-
#initialize(options = {}) ⇒ Signature
constructor
Creates a new API signature object.
-
#plaintext ⇒ Object
Concatenates the parts of the base signature into a plaintext string using the following order:.
-
#to_s ⇒ Object
Returns the encrypted form of the signature.
Constructor Details
#initialize(options = {}) ⇒ Signature
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.
21 22 23 24 25 26 27 28 29 |
# File 'lib/shipping_easy/signature.rb', line 21 def initialize( = {}) = .dup @api_secret = .delete(:api_secret) || "" @method = .fetch(:method, :get).to_s.upcase @path = .delete(:path) || "" @body = .delete(:body) || "" @params = [:params].nil? ? {} : .delete(:params).dup @params.delete(:api_signature) # remove for convenience end |
Instance Attribute Details
#api_secret ⇒ Object (readonly)
Returns the value of attribute api_secret.
6 7 8 |
# File 'lib/shipping_easy/signature.rb', line 6 def api_secret @api_secret end |
#body ⇒ Object (readonly)
Returns the value of attribute body.
6 7 8 |
# File 'lib/shipping_easy/signature.rb', line 6 def body @body end |
#method ⇒ Object (readonly)
Returns the value of attribute method.
6 7 8 |
# File 'lib/shipping_easy/signature.rb', line 6 def method @method end |
#params ⇒ Object (readonly)
Returns the value of attribute params.
6 7 8 |
# File 'lib/shipping_easy/signature.rb', line 6 def params @params end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
6 7 8 |
# File 'lib/shipping_easy/signature.rb', line 6 def path @path end |
Instance Method Details
#==(other_signature) ⇒ Object
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.
66 67 68 69 70 71 72 73 74 |
# 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 ⇒ Object
Encrypts the plaintext signature with the supplied API secret. This signature should be included when making a ShippingEasy API call.
Returns an encrypted signature.
56 57 58 |
# File 'lib/shipping_easy/signature.rb', line 56 def encrypted OpenSSL::HMAC::hexdigest("sha256", api_secret, plaintext) end |
#plaintext ⇒ Object
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&flops","cost":"10.00","shipping_cost":"2.00"}”
Returns a correctly contenated plaintext API signature.
43 44 45 46 47 48 49 50 |
# 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 ⇒ Object
Returns the encrypted form of the signature.
Returns an encrypted signature.
79 80 81 |
# File 'lib/shipping_easy/signature.rb', line 79 def to_s encrypted end |