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 +4 -4
- data/.travis.yml +1 -1
- data/lib/omniauth/shopify/version.rb +1 -1
- data/lib/omniauth/strategies/shopify.rb +22 -2
- data/test/integration_test.rb +71 -11
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 753ea51893552576c2eebc375147568613694af8
|
4
|
+
data.tar.gz: a2c1d077db0e9f08bba5a4626247467ce41d0145
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b9f5917e02733e066f6f83a253ffc45bf2ad48b0b77c1ee1645451d171cdcb4cf1f7ec546030042690259411e04d406208a398bf58b733a2d37244a80edf616
|
7
|
+
data.tar.gz: 76c7448c74383acb722f98759f9a0762f3b3955f4eb91bbf610ae4c2da2a2b128065faaafa1e004ce5a06f5864c171594e58147478bb64c4ff27ee1f2609daaf
|
data/.travis.yml
CHANGED
@@ -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
|
data/test/integration_test.rb
CHANGED
@@ -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
|
-
|
75
|
-
|
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
|
-
|
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.
|
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:
|
11
|
+
date: 2016-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: omniauth-oauth2
|