|
@@ -1,4 +1,5 @@
|
|
require 'test_helper'
|
|
require 'test_helper'
|
|
|
|
+require 'timecop'
|
|
|
|
|
|
class SessionTest < Test::Unit::TestCase
|
|
class SessionTest < Test::Unit::TestCase
|
|
|
|
|
|
@@ -141,19 +142,59 @@ class SessionTest < Test::Unit::TestCase
|
|
end
|
|
end
|
|
|
|
|
|
test "return_token_if_signature_is_valid" do
|
|
test "return_token_if_signature_is_valid" do
|
|
- params = {:code => 'any-code', :timestamp => Time.now}
|
|
|
|
- sorted_params = make_sorted_params(params)
|
|
|
|
- signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new(), ShopifyAPI::Session.secret, sorted_params)
|
|
|
|
- fake nil, :url => 'https://testshop.myshopify.com/admin/oauth/access_token',:method => :post, :body => '{"access_token" : "any-token"}'
|
|
|
|
|
|
+ fake nil,
|
|
|
|
+ url: 'https://testshop.myshopify.com/admin/oauth/access_token',
|
|
|
|
+ method: :post,
|
|
|
|
+ body: '{"access_token":"any-token"}'
|
|
session = ShopifyAPI::Session.new("testshop.myshopify.com")
|
|
session = ShopifyAPI::Session.new("testshop.myshopify.com")
|
|
- token = session.request_token(params.merge(:hmac => signature))
|
|
|
|
|
|
+
|
|
|
|
+ params = { code: 'any-code', timestamp: Time.now }
|
|
|
|
+ token = session.request_token(params.merge(hmac: generate_signature(params)))
|
|
|
|
+
|
|
assert_equal "any-token", token
|
|
assert_equal "any-token", token
|
|
|
|
+ assert_equal "any-token", session.token
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ test "extra parameters are stored in session" do
|
|
|
|
+ fake nil,
|
|
|
|
+ url: 'https://testshop.myshopify.com/admin/oauth/access_token',
|
|
|
|
+ method: :post,
|
|
|
|
+ body: '{"access_token":"any-token","foo":"example"}'
|
|
|
|
+ session = ShopifyAPI::Session.new("testshop.myshopify.com")
|
|
|
|
+
|
|
|
|
+ params = { code: 'any-code', timestamp: Time.now }
|
|
|
|
+ assert session.request_token(params.merge(hmac: generate_signature(params)))
|
|
|
|
+
|
|
|
|
+ assert_equal ({ "foo" => "example" }), session.extra
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ test "expires_in is automatically converted in expires_at" do
|
|
|
|
+ fake nil,
|
|
|
|
+ url: 'https://testshop.myshopify.com/admin/oauth/access_token',
|
|
|
|
+ method: :post,
|
|
|
|
+ body: '{"access_token":"any-token","expires_in":86393}'
|
|
|
|
+ session = ShopifyAPI::Session.new("testshop.myshopify.com")
|
|
|
|
+
|
|
|
|
+ Timecop.freeze do
|
|
|
|
+ params = { code: 'any-code', timestamp: Time.now }
|
|
|
|
+ assert session.request_token(params.merge(hmac: generate_signature(params)))
|
|
|
|
+
|
|
|
|
+ expires_at = Time.now.utc + 86393
|
|
|
|
+ assert_equal ({ "expires_at" => expires_at.to_i }), session.extra
|
|
|
|
+ assert session.expires_at.is_a?(Time)
|
|
|
|
+ assert_equal expires_at.to_i, session.expires_at.to_i
|
|
|
|
+ assert_equal 86393, session.expires_in
|
|
|
|
+ assert_equal false, session.expired?
|
|
|
|
+
|
|
|
|
+ Timecop.travel(session.expires_at) do
|
|
|
|
+ assert_equal true, session.expired?
|
|
|
|
+ end
|
|
|
|
+ end
|
|
end
|
|
end
|
|
|
|
|
|
test "raise error if signature does not match expected" do
|
|
test "raise error if signature does not match expected" do
|
|
params = {:code => "any-code", :timestamp => Time.now}
|
|
params = {:code => "any-code", :timestamp => Time.now}
|
|
- sorted_params = make_sorted_params(params)
|
|
|
|
- signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new(), ShopifyAPI::Session.secret, sorted_params)
|
|
|
|
|
|
+ signature = generate_signature(params)
|
|
params[:foo] = 'world'
|
|
params[:foo] = 'world'
|
|
assert_raises(ShopifyAPI::ValidationException) do
|
|
assert_raises(ShopifyAPI::ValidationException) do
|
|
session = ShopifyAPI::Session.new("testshop.myshopify.com")
|
|
session = ShopifyAPI::Session.new("testshop.myshopify.com")
|
|
@@ -163,8 +204,7 @@ class SessionTest < Test::Unit::TestCase
|
|
|
|
|
|
test "raise error if timestamp is too old" do
|
|
test "raise error if timestamp is too old" do
|
|
params = {:code => "any-code", :timestamp => Time.now - 2.days}
|
|
params = {:code => "any-code", :timestamp => Time.now - 2.days}
|
|
- sorted_params = make_sorted_params(params)
|
|
|
|
- signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new(), ShopifyAPI::Session.secret, sorted_params)
|
|
|
|
|
|
+ signature = generate_signature(params)
|
|
params[:foo] = 'world'
|
|
params[:foo] = 'world'
|
|
assert_raises(ShopifyAPI::ValidationException) do
|
|
assert_raises(ShopifyAPI::ValidationException) do
|
|
session = ShopifyAPI::Session.new("testshop.myshopify.com")
|
|
session = ShopifyAPI::Session.new("testshop.myshopify.com")
|
|
@@ -173,18 +213,16 @@ class SessionTest < Test::Unit::TestCase
|
|
end
|
|
end
|
|
|
|
|
|
test "return true when the signature is valid and the keys of params are strings" do
|
|
test "return true when the signature is valid and the keys of params are strings" do
|
|
- now = Time.now
|
|
|
|
- params = {"code" => "any-code", "timestamp" => now}
|
|
|
|
- sorted_params = make_sorted_params(params)
|
|
|
|
- signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new(), ShopifyAPI::Session.secret, sorted_params)
|
|
|
|
- params = {"code" => "any-code", "timestamp" => now, "hmac" => signature}
|
|
|
|
|
|
+ params = {"code" => "any-code", "timestamp" => Time.now}
|
|
|
|
+ params["hmac"] = generate_signature(params)
|
|
|
|
+ assert_equal true, ShopifyAPI::Session.validate_signature(params)
|
|
end
|
|
end
|
|
|
|
|
|
test "return true when validating signature of params with ampersand and equal sign characters" do
|
|
test "return true when validating signature of params with ampersand and equal sign characters" do
|
|
ShopifyAPI::Session.secret = 'secret'
|
|
ShopifyAPI::Session.secret = 'secret'
|
|
params = {'a' => '1&b=2', 'c=3&d' => '4'}
|
|
params = {'a' => '1&b=2', 'c=3&d' => '4'}
|
|
to_sign = "a=1%26b=2&c%3D3%26d=4"
|
|
to_sign = "a=1%26b=2&c%3D3%26d=4"
|
|
- params['hmac'] = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), ShopifyAPI::Session.secret, to_sign)
|
|
|
|
|
|
+ params['hmac'] = generate_signature(to_sign)
|
|
|
|
|
|
assert_equal true, ShopifyAPI::Session.validate_signature(params)
|
|
assert_equal true, ShopifyAPI::Session.validate_signature(params)
|
|
end
|
|
end
|
|
@@ -193,7 +231,7 @@ class SessionTest < Test::Unit::TestCase
|
|
ShopifyAPI::Session.secret = 'secret'
|
|
ShopifyAPI::Session.secret = 'secret'
|
|
params = {'a%3D1%26b' => '2%26c%3D3'}
|
|
params = {'a%3D1%26b' => '2%26c%3D3'}
|
|
to_sign = "a%253D1%2526b=2%2526c%253D3"
|
|
to_sign = "a%253D1%2526b=2%2526c%253D3"
|
|
- params['hmac'] = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), ShopifyAPI::Session.secret, to_sign)
|
|
|
|
|
|
+ params['hmac'] = generate_signature(to_sign)
|
|
|
|
|
|
assert_equal true, ShopifyAPI::Session.validate_signature(params)
|
|
assert_equal true, ShopifyAPI::Session.validate_signature(params)
|
|
end
|
|
end
|
|
@@ -203,4 +241,9 @@ class SessionTest < Test::Unit::TestCase
|
|
def make_sorted_params(params)
|
|
def make_sorted_params(params)
|
|
sorted_params = params.with_indifferent_access.except(:signature, :hmac, :action, :controller).collect{|k,v|"#{k}=#{v}"}.sort.join('&')
|
|
sorted_params = params.with_indifferent_access.except(:signature, :hmac, :action, :controller).collect{|k,v|"#{k}=#{v}"}.sort.join('&')
|
|
end
|
|
end
|
|
|
|
+
|
|
|
|
+ def generate_signature(params)
|
|
|
|
+ params = make_sorted_params(params) if params.is_a?(Hash)
|
|
|
|
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, ShopifyAPI::Session.secret, params)
|
|
|
|
+ end
|
|
end
|
|
end
|