omniauth-shopify-oauth2 1.1.11 → 1.1.12

Sign up to get free protection for your applications and to get access to all the features.
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