omniauth-shopify-oauth2 1.1.11 → 1.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4983dd45c4c7df37fa58540d63025ae4843b67b0
4
- data.tar.gz: 109aa26f248b774657725c8908aeb6c4b224c998
3
+ metadata.gz: 753ea51893552576c2eebc375147568613694af8
4
+ data.tar.gz: a2c1d077db0e9f08bba5a4626247467ce41d0145
5
5
  SHA512:
6
- metadata.gz: 7d19445d82627ba563846393c24f55cd4b26e63d940ef468ea178b1afa24d180bc3b2e6054fee2d037429ec10ac895b7e64270af900dd60ccd445648c41ec406
7
- data.tar.gz: 9bbc58ac9a92c621fb6859d133a0ac16b12b86f2fc633ce36600a9480d21434cb2bd4e04aafaee0ccd5906e155800fe769eda5ce9b0cef3ab9f24d41e8a9f778
6
+ metadata.gz: 3b9f5917e02733e066f6f83a253ffc45bf2ad48b0b77c1ee1645451d171cdcb4cf1f7ec546030042690259411e04d406208a398bf58b733a2d37244a80edf616
7
+ data.tar.gz: 76c7448c74383acb722f98759f9a0762f3b3955f4eb91bbf610ae4c2da2a2b128065faaafa1e004ce5a06f5864c171594e58147478bb64c4ff27ee1f2609daaf
data/.travis.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
3
  - 2.1.0
4
+ - 2.2.2
@@ -1,5 +1,5 @@
1
1
  module OmniAuth
2
2
  module Shopify
3
- VERSION = "1.1.11"
3
+ VERSION = "1.1.12"
4
4
  end
5
5
  end
@@ -17,6 +17,10 @@ module OmniAuth
17
17
  option :callback_url
18
18
  option :myshopify_domain, 'myshopify.com'
19
19
 
20
+ # When `true`, the authorization phase will fail if the granted scopes
21
+ # mismatch the requested scopes.
22
+ option :validate_granted_scopes, true
23
+
20
24
  option :setup, proc { |env|
21
25
  request = Rack::Request.new(env)
22
26
  env['omniauth.strategy'].options[:client_options][:site] = "https://#{request.GET['shop']}"
@@ -42,6 +46,12 @@ module OmniAuth
42
46
  Rack::Utils.secure_compare(calculated_signature, signature)
43
47
  end
44
48
 
49
+ def valid_scope?(token)
50
+ params = options.authorize_params.merge(options_for("authorize"))
51
+ return false unless token && params[:scope] && token['scope']
52
+ (params[:scope].split(',').sort == token['scope'].split(',').sort)
53
+ end
54
+
45
55
  def self.encoded_params_for_signature(params)
46
56
  params = params.dup
47
57
  params.delete('hmac')
@@ -71,11 +81,21 @@ module OmniAuth
71
81
  end
72
82
 
73
83
  def callback_phase
74
- return fail!(:invalid_site) unless valid_site?
75
- return fail!(:invalid_signature) unless valid_signature?
84
+ return fail!(:invalid_site, CallbackError.new(:invalid_site, "OAuth endpoint is not a myshopify site.")) unless valid_site?
85
+ return fail!(:invalid_signature, CallbackError.new(:invalid_signature, "Signature does not match, it may have been tampered with.")) unless valid_signature?
86
+
87
+ token = build_access_token
88
+ unless valid_scope?(token)
89
+ return fail!(:invalid_scope, CallbackError.new(:invalid_scope, "Scope does not match, it may have been tampered with."))
90
+ end
91
+
76
92
  super
77
93
  end
78
94
 
95
+ def build_access_token
96
+ @built_access_token ||= super
97
+ end
98
+
79
99
  def authorize_params
80
100
  super.tap do |params|
81
101
  params[:scope] ||= DEFAULT_SCOPE
@@ -2,7 +2,7 @@ require_relative 'test_helper'
2
2
 
3
3
  class IntegrationTest < Minitest::Test
4
4
  def setup
5
- build_app
5
+ build_app(scope: OmniAuth::Strategies::Shopify::DEFAULT_SCOPE)
6
6
  end
7
7
 
8
8
  def teardown
@@ -51,7 +51,7 @@ class IntegrationTest < Minitest::Test
51
51
  def test_callback
52
52
  access_token = SecureRandom.hex(16)
53
53
  code = SecureRandom.hex(16)
54
- expect_access_token_request(access_token)
54
+ expect_access_token_request(access_token, OmniAuth::Strategies::Shopify::DEFAULT_SCOPE)
55
55
 
56
56
  response = callback(sign_params(shop: 'snowdevil.myshopify.com', code: code, state: opts["rack.session"]["omniauth.state"]))
57
57
 
@@ -59,9 +59,10 @@ class IntegrationTest < Minitest::Test
59
59
  end
60
60
 
61
61
  def test_callback_with_legacy_signature
62
+ build_app scope: OmniAuth::Strategies::Shopify::DEFAULT_SCOPE
62
63
  access_token = SecureRandom.hex(16)
63
64
  code = SecureRandom.hex(16)
64
- expect_access_token_request(access_token)
65
+ expect_access_token_request(access_token, OmniAuth::Strategies::Shopify::DEFAULT_SCOPE)
65
66
 
66
67
  response = callback(sign_params(shop: 'snowdevil.myshopify.com', code: code, state: opts["rack.session"]["omniauth.state"]).merge(signature: 'ignored'))
67
68
 
@@ -71,9 +72,8 @@ class IntegrationTest < Minitest::Test
71
72
  def test_callback_custom_params
72
73
  access_token = SecureRandom.hex(16)
73
74
  code = SecureRandom.hex(16)
74
- FakeWeb.register_uri(:post, "https://snowdevil.myshopify.com/admin/oauth/access_token",
75
- body: JSON.dump(access_token: access_token),
76
- content_type: 'application/json')
75
+
76
+ expect_access_token_request(access_token, OmniAuth::Strategies::Shopify::DEFAULT_SCOPE)
77
77
 
78
78
  now = Time.now.to_i
79
79
  params = { shop: 'snowdevil.myshopify.com', code: code, timestamp: now, next: '/products?page=2&q=red%20shirt', state: opts["rack.session"]["omniauth.state"] }
@@ -136,18 +136,78 @@ class IntegrationTest < Minitest::Test
136
136
  assert_equal 'read_products,read_orders,write_content', redirect_params['scope']
137
137
  assert_equal 'https://app.example.com/admin/auth/legacy/callback', redirect_params['redirect_uri']
138
138
  end
139
+
139
140
  def test_callback_with_invalid_state_fails
140
141
  access_token = SecureRandom.hex(16)
141
142
  code = SecureRandom.hex(16)
142
- FakeWeb.register_uri(:post, "https://snowdevil.myshopify.com/admin/oauth/access_token",
143
- body: JSON.dump(access_token: access_token),
144
- content_type: 'application/json')
143
+ expect_access_token_request(access_token, OmniAuth::Strategies::Shopify::DEFAULT_SCOPE)
145
144
 
146
145
  response = callback(sign_params(shop: 'snowdevil.myshopify.com', code: code, state: 'invalid'))
147
146
 
148
147
  assert_equal 302, response.status
149
148
  assert_equal '/auth/failure?message=csrf_detected&strategy=shopify', response.location
150
149
  end
150
+
151
+ def test_callback_with_mismatching_scope_fails
152
+ access_token = SecureRandom.hex(16)
153
+ code = SecureRandom.hex(16)
154
+ expect_access_token_request(access_token, 'some_invalid_scope')
155
+
156
+ response = callback(sign_params(shop: 'snowdevil.myshopify.com', code: code, state: opts["rack.session"]["omniauth.state"]))
157
+
158
+ assert_equal 302, response.status
159
+ assert_equal '/auth/failure?message=invalid_scope&strategy=shopify', response.location
160
+ end
161
+
162
+ def test_callback_with_no_scope_fails
163
+ access_token = SecureRandom.hex(16)
164
+ code = SecureRandom.hex(16)
165
+ expect_access_token_request(access_token, nil)
166
+
167
+ response = callback(sign_params(shop: 'snowdevil.myshopify.com', code: code, state: opts["rack.session"]["omniauth.state"]))
168
+
169
+ assert_equal 302, response.status
170
+ assert_equal '/auth/failure?message=invalid_scope&strategy=shopify', response.location
171
+ end
172
+
173
+ def test_callback_with_missing_access_scope_fails
174
+ build_app scope: 'first_scope,second_scope'
175
+
176
+ access_token = SecureRandom.hex(16)
177
+ code = SecureRandom.hex(16)
178
+ expect_access_token_request(access_token, 'first_scope')
179
+
180
+ response = callback(sign_params(shop: 'snowdevil.myshopify.com', code: code, state: opts["rack.session"]["omniauth.state"]))
181
+
182
+ assert_equal 302, response.status
183
+ assert_equal '/auth/failure?message=invalid_scope&strategy=shopify', response.location
184
+ end
185
+
186
+ def test_callback_with_extra_access_scope_fails
187
+ build_app scope: 'first_scope,second_scope'
188
+
189
+ access_token = SecureRandom.hex(16)
190
+ code = SecureRandom.hex(16)
191
+ expect_access_token_request(access_token, 'second_scope,first_scope,third_scope')
192
+
193
+ response = callback(sign_params(shop: 'snowdevil.myshopify.com', code: code, state: opts["rack.session"]["omniauth.state"]))
194
+
195
+ assert_equal 302, response.status
196
+ assert_equal '/auth/failure?message=invalid_scope&strategy=shopify', response.location
197
+ end
198
+
199
+ def test_callback_with_scopes_out_of_order_works
200
+ build_app scope: 'first_scope,second_scope'
201
+
202
+ access_token = SecureRandom.hex(16)
203
+ code = SecureRandom.hex(16)
204
+ expect_access_token_request(access_token, 'second_scope,first_scope')
205
+
206
+ response = callback(sign_params(shop: 'snowdevil.myshopify.com', code: code, state: opts["rack.session"]["omniauth.state"]))
207
+
208
+ assert_callback_success(response, access_token, code)
209
+ end
210
+
151
211
  private
152
212
 
153
213
  def sign_params(params)
@@ -160,9 +220,9 @@ class IntegrationTest < Minitest::Test
160
220
  params
161
221
  end
162
222
 
163
- def expect_access_token_request(access_token)
223
+ def expect_access_token_request(access_token, scope)
164
224
  FakeWeb.register_uri(:post, "https://snowdevil.myshopify.com/admin/oauth/access_token",
165
- body: JSON.dump(access_token: access_token),
225
+ body: JSON.dump(access_token: access_token, scope: scope),
166
226
  content_type: 'application/json')
167
227
  end
168
228
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-shopify-oauth2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.11
4
+ version: 1.1.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Odorcic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-16 00:00:00.000000000 Z
11
+ date: 2016-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: omniauth-oauth2