session_test.rb 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. require 'test_helper'
  2. class SessionTest < Test::Unit::TestCase
  3. def setup
  4. ShopifyAPI::Session.secret = 'secret'
  5. end
  6. test "not be valid without a url" do
  7. session = ShopifyAPI::Session.new(nil, "any-token")
  8. assert_not session.valid?
  9. end
  10. test "not be valid without token" do
  11. session = ShopifyAPI::Session.new("testshop.myshopify.com")
  12. assert_not session.valid?
  13. end
  14. test "be valid with any token and any url" do
  15. session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token")
  16. assert session.valid?
  17. end
  18. test "not raise error without params" do
  19. assert_nothing_raised do
  20. session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token")
  21. end
  22. end
  23. test "ignore everything but the subdomain in the shop" do
  24. assert_equal "https://testshop.myshopify.com/admin", ShopifyAPI::Session.new("http://user:pass@testshop.notshopify.net/path", "any-token").site
  25. end
  26. test "append the myshopify domain if not given" do
  27. assert_equal "https://testshop.myshopify.com/admin", ShopifyAPI::Session.new("testshop", "any-token").site
  28. end
  29. test "not raise error without params" do
  30. assert_nothing_raised do
  31. session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token")
  32. end
  33. end
  34. test "raise error if params passed but signature omitted" do
  35. assert_raises(ShopifyAPI::ValidationException) do
  36. session = ShopifyAPI::Session.new("testshop.myshopify.com")
  37. session.request_token({'code' => 'any-code'})
  38. end
  39. end
  40. test "setup api_key and secret for all sessions" do
  41. ShopifyAPI::Session.setup(:api_key => "My test key", :secret => "My test secret")
  42. assert_equal "My test key", ShopifyAPI::Session.api_key
  43. assert_equal "My test secret", ShopifyAPI::Session.secret
  44. end
  45. test "use 'https' protocol by default for all sessions" do
  46. assert_equal 'https', ShopifyAPI::Session.protocol
  47. end
  48. test "#temp reset ShopifyAPI::Base.site to original value" do
  49. ShopifyAPI::Session.setup(:api_key => "key", :secret => "secret")
  50. session1 = ShopifyAPI::Session.new('fakeshop.myshopify.com', 'token1')
  51. ShopifyAPI::Base.activate_session(session1)
  52. ShopifyAPI::Session.temp("testshop.myshopify.com", "any-token") {
  53. @assigned_site = ShopifyAPI::Base.site
  54. }
  55. assert_equal 'https://testshop.myshopify.com/admin', @assigned_site.to_s
  56. assert_equal 'https://fakeshop.myshopify.com/admin', ShopifyAPI::Base.site.to_s
  57. end
  58. test "create_permission_url returns correct url with single scope no redirect uri" do
  59. ShopifyAPI::Session.setup(:api_key => "My_test_key", :secret => "My test secret")
  60. session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
  61. scope = ["write_products"]
  62. permission_url = session.create_permission_url(scope)
  63. assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=write_products", permission_url
  64. end
  65. test "create_permission_url returns correct url with single scope and redirect uri" do
  66. ShopifyAPI::Session.setup(:api_key => "My_test_key", :secret => "My test secret")
  67. session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
  68. scope = ["write_products"]
  69. permission_url = session.create_permission_url(scope, "http://my_redirect_uri.com")
  70. assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=write_products&redirect_uri=http://my_redirect_uri.com", permission_url
  71. end
  72. test "create_permission_url returns correct url with dual scope no redirect uri" do
  73. ShopifyAPI::Session.setup(:api_key => "My_test_key", :secret => "My test secret")
  74. session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
  75. scope = ["write_products","write_customers"]
  76. permission_url = session.create_permission_url(scope)
  77. assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=write_products,write_customers", permission_url
  78. end
  79. test "create_permission_url returns correct url with no scope no redirect uri" do
  80. ShopifyAPI::Session.setup(:api_key => "My_test_key", :secret => "My test secret")
  81. session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
  82. scope = []
  83. permission_url = session.create_permission_url(scope)
  84. assert_equal "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&scope=", permission_url
  85. end
  86. test "raise exception if code invalid in request token" do
  87. ShopifyAPI::Session.setup(:api_key => "My test key", :secret => "My test secret")
  88. session = ShopifyAPI::Session.new('http://localhost.myshopify.com')
  89. fake nil, :url => 'https://localhost.myshopify.com/admin/oauth/access_token',:method => :post, :status => 404, :body => '{"error" : "invalid_request"}'
  90. assert_raises(ShopifyAPI::ValidationException) do
  91. session.request_token(params={:code => "bad-code"})
  92. end
  93. assert_equal false, session.valid?
  94. end
  95. test "#temp reset ShopifyAPI::Base.site to original value when using a non-standard port" do
  96. ShopifyAPI::Session.setup(:api_key => "key", :secret => "secret")
  97. session1 = ShopifyAPI::Session.new('fakeshop.myshopify.com:3000', 'token1')
  98. ShopifyAPI::Base.activate_session(session1)
  99. end
  100. test "myshopify_domain supports non-standard ports" do
  101. begin
  102. ShopifyAPI::Session.setup(:api_key => "key", :secret => "secret", :myshopify_domain => 'localhost', port: '3000')
  103. session = ShopifyAPI::Session.new('fakeshop.localhost:3000', 'token1')
  104. ShopifyAPI::Base.activate_session(session)
  105. assert_equal 'https://fakeshop.localhost:3000/admin', ShopifyAPI::Base.site.to_s
  106. session = ShopifyAPI::Session.new('fakeshop', 'token1')
  107. ShopifyAPI::Base.activate_session(session)
  108. assert_equal 'https://fakeshop.localhost:3000/admin', ShopifyAPI::Base.site.to_s
  109. ensure
  110. ShopifyAPI::Session.myshopify_domain = "myshopify.com"
  111. ShopifyAPI::Session.port = nil
  112. end
  113. end
  114. test "return site for session" do
  115. session = ShopifyAPI::Session.new("testshop.myshopify.com", "any-token")
  116. assert_equal "https://testshop.myshopify.com/admin", session.site
  117. end
  118. test "return_token_if_signature_is_valid" do
  119. params = {:code => 'any-code', :timestamp => Time.now}
  120. sorted_params = make_sorted_params(params)
  121. signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new(), ShopifyAPI::Session.secret, sorted_params)
  122. fake nil, :url => 'https://testshop.myshopify.com/admin/oauth/access_token',:method => :post, :body => '{"access_token" : "any-token"}'
  123. session = ShopifyAPI::Session.new("testshop.myshopify.com")
  124. token = session.request_token(params.merge(:hmac => signature))
  125. assert_equal "any-token", token
  126. end
  127. test "raise error if signature does not match expected" do
  128. params = {:code => "any-code", :timestamp => Time.now}
  129. sorted_params = make_sorted_params(params)
  130. signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new(), ShopifyAPI::Session.secret, sorted_params)
  131. params[:foo] = 'world'
  132. assert_raises(ShopifyAPI::ValidationException) do
  133. session = ShopifyAPI::Session.new("testshop.myshopify.com")
  134. session.request_token(params.merge(:hmac => signature))
  135. end
  136. end
  137. test "raise error if timestamp is too old" do
  138. params = {:code => "any-code", :timestamp => Time.now - 2.days}
  139. sorted_params = make_sorted_params(params)
  140. signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new(), ShopifyAPI::Session.secret, sorted_params)
  141. params[:foo] = 'world'
  142. assert_raises(ShopifyAPI::ValidationException) do
  143. session = ShopifyAPI::Session.new("testshop.myshopify.com")
  144. session.request_token(params.merge(:hmac => signature))
  145. end
  146. end
  147. test "return true when the signature is valid and the keys of params are strings" do
  148. now = Time.now
  149. params = {"code" => "any-code", "timestamp" => now}
  150. sorted_params = make_sorted_params(params)
  151. signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new(), ShopifyAPI::Session.secret, sorted_params)
  152. params = {"code" => "any-code", "timestamp" => now, "hmac" => signature}
  153. end
  154. test "return true when validating signature of params with ampersand and equal sign characters" do
  155. ShopifyAPI::Session.secret = 'secret'
  156. params = {'a' => '1&b=2', 'c=3&d' => '4'}
  157. to_sign = "a=1%26b=2&c%3D3%26d=4"
  158. params['hmac'] = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), ShopifyAPI::Session.secret, to_sign)
  159. assert_equal true, ShopifyAPI::Session.validate_signature(params)
  160. end
  161. test "return true when validating signature of params with percent sign characters" do
  162. ShopifyAPI::Session.secret = 'secret'
  163. params = {'a%3D1%26b' => '2%26c%3D3'}
  164. to_sign = "a%253D1%2526b=2%2526c%253D3"
  165. params['hmac'] = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), ShopifyAPI::Session.secret, to_sign)
  166. assert_equal true, ShopifyAPI::Session.validate_signature(params)
  167. end
  168. private
  169. def make_sorted_params(params)
  170. sorted_params = params.with_indifferent_access.except(:signature, :hmac, :action, :controller).collect{|k,v|"#{k}=#{v}"}.sort.join('&')
  171. end
  172. end