omniauth-google-oauth2 1.0.1 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/README.md +3 -1
- data/examples/Gemfile +1 -1
- data/examples/config.ru +19 -9
- data/lib/omniauth/google_oauth2/version.rb +1 -1
- data/lib/omniauth/strategies/google_oauth2.rb +12 -5
- data/omniauth-google-oauth2.gemspec +2 -2
- data/spec/omniauth/strategies/google_oauth2_spec.rb +60 -15
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0532842d8362fc36a8797376dc54e09b1d11fa178d462114225eecbe87274785'
|
4
|
+
data.tar.gz: 63b1d0a5a3a6249b77b58cbfa4e696ae18748b59280cb73f36cb98f88abd98c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d6f34a8629057f1f89d613155567d0bb50917648794e64527976ba7ca4c372ed8806fd57bbe5cec55d2d60545ef2e9bd038da80e1101b96642018f1d8226951
|
7
|
+
data.tar.gz: b00da9be3e3f97af0cdfe9a15be3d99126176a26bc21337febb893be88949da0573b4f6a843fbedac3dc982a4fda29ca532b63d3a1272fc8544468b3a42d32aa
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,35 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## 1.1.1 - 2022-09-05
|
5
|
+
|
6
|
+
### Added
|
7
|
+
- Nothing.
|
8
|
+
|
9
|
+
### Deprecated
|
10
|
+
- Nothing.
|
11
|
+
|
12
|
+
### Removed
|
13
|
+
- Nothing.
|
14
|
+
|
15
|
+
### Fixed
|
16
|
+
- Fixed JWT decoding issue. (Invalid segment encoding) [#431](https://github.com/zquestz/omniauth-google-oauth2/pull/431)
|
17
|
+
|
18
|
+
## 1.1.0 - 2022-09-03
|
19
|
+
|
20
|
+
### Added
|
21
|
+
- `overridable_authorize_options` has been added to restrict overriding authorize_options by request params. [#423](https://github.com/zquestz/omniauth-google-oauth2/pull/423)
|
22
|
+
- Support for oauth2 2.0.x. [#429](https://github.com/zquestz/omniauth-google-oauth2/pull/429)
|
23
|
+
|
24
|
+
### Deprecated
|
25
|
+
- Nothing.
|
26
|
+
|
27
|
+
### Removed
|
28
|
+
- Nothing.
|
29
|
+
|
30
|
+
### Fixed
|
31
|
+
- Nothing.
|
32
|
+
|
4
33
|
## 1.0.1 - 2022-03-10
|
5
34
|
|
6
35
|
### Added
|
data/README.md
CHANGED
@@ -85,13 +85,15 @@ You can configure several options, which you pass in to the `provider` method vi
|
|
85
85
|
|
86
86
|
* `provider_ignores_state`: You will need to set this to `true` when using the `One-time Code Flow` below. In this flow there is no server side redirect that would set the state.
|
87
87
|
|
88
|
+
* `overridable_authorize_options`: By default, all `authorize_options` can be overridden with request parameters. You can restrict the behavior by using this option.
|
89
|
+
|
88
90
|
Here's an example of a possible configuration where the strategy name is changed, the user is asked for extra permissions, the user is always prompted to select their account when logging in and the user's profile picture is returned as a thumbnail:
|
89
91
|
|
90
92
|
```ruby
|
91
93
|
Rails.application.config.middleware.use OmniAuth::Builder do
|
92
94
|
provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'],
|
93
95
|
{
|
94
|
-
scope: '
|
96
|
+
scope: 'email, profile, http://gdata.youtube.com',
|
95
97
|
prompt: 'select_account',
|
96
98
|
image_aspect_ratio: 'square',
|
97
99
|
image_size: 50
|
data/examples/Gemfile
CHANGED
data/examples/config.ru
CHANGED
@@ -19,6 +19,19 @@ OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
|
|
19
19
|
|
20
20
|
# Main example app for omniauth-google-oauth2
|
21
21
|
class App < Sinatra::Base
|
22
|
+
configure do
|
23
|
+
set :sessions, true
|
24
|
+
set :inline_templates, true
|
25
|
+
end
|
26
|
+
|
27
|
+
use Rack::Session::Cookie, secret: ENV['RACK_COOKIE_SECRET']
|
28
|
+
|
29
|
+
use OmniAuth::Builder do
|
30
|
+
# For additional provider examples please look at 'omni_auth.rb'
|
31
|
+
# The key provider_ignores_state is only for AJAX flows. It is not recommended for normal logins.
|
32
|
+
provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], access_type: 'offline', prompt: 'consent', provider_ignores_state: true, scope: 'email,profile,calendar'
|
33
|
+
end
|
34
|
+
|
22
35
|
get '/' do
|
23
36
|
<<-HTML
|
24
37
|
<!DOCTYPE html>
|
@@ -73,7 +86,12 @@ class App < Sinatra::Base
|
|
73
86
|
</head>
|
74
87
|
<body>
|
75
88
|
<ul>
|
76
|
-
<li
|
89
|
+
<li>
|
90
|
+
<form method='post' action='/auth/google_oauth2'>
|
91
|
+
<input type="hidden" name="authenticity_token" value="#{request.env['rack.session']['csrf']}">
|
92
|
+
<button type='submit'>Login with Google</button>
|
93
|
+
</form>
|
94
|
+
</li>
|
77
95
|
<li><a href='#' class="googleplus-login">Sign in with Google via AJAX</a></li>
|
78
96
|
</ul>
|
79
97
|
</body>
|
@@ -109,12 +127,4 @@ class App < Sinatra::Base
|
|
109
127
|
end
|
110
128
|
end
|
111
129
|
|
112
|
-
use Rack::Session::Cookie, secret: ENV['RACK_COOKIE_SECRET']
|
113
|
-
|
114
|
-
use OmniAuth::Builder do
|
115
|
-
# For additional provider examples please look at 'omni_auth.rb'
|
116
|
-
# The key provider_ignores_state is only for AJAX flows. It is not recommended for normal logins.
|
117
|
-
provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], access_type: 'offline', prompt: 'consent', provider_ignores_state: true, scope: 'email,profile,calendar'
|
118
|
-
end
|
119
|
-
|
120
130
|
run App.new
|
@@ -15,13 +15,15 @@ module OmniAuth
|
|
15
15
|
DEFAULT_SCOPE = 'email,profile'
|
16
16
|
USER_INFO_URL = 'https://www.googleapis.com/oauth2/v3/userinfo'
|
17
17
|
IMAGE_SIZE_REGEXP = /(s\d+(-c)?)|(w\d+-h\d+(-c)?)|(w\d+(-c)?)|(h\d+(-c)?)|c/
|
18
|
+
AUTHORIZE_OPTIONS = %i[access_type hd login_hint prompt request_visible_actions scope state redirect_uri include_granted_scopes openid_realm device_id device_name]
|
18
19
|
|
19
20
|
option :name, 'google_oauth2'
|
20
21
|
option :skip_friends, true
|
21
22
|
option :skip_image_info, true
|
22
23
|
option :skip_jwt, false
|
23
24
|
option :jwt_leeway, 60
|
24
|
-
option :authorize_options,
|
25
|
+
option :authorize_options, AUTHORIZE_OPTIONS
|
26
|
+
option :overridable_authorize_options, AUTHORIZE_OPTIONS
|
25
27
|
option :authorized_client_ids, []
|
26
28
|
|
27
29
|
option :client_options,
|
@@ -31,7 +33,7 @@ module OmniAuth
|
|
31
33
|
|
32
34
|
def authorize_params
|
33
35
|
super.tap do |params|
|
34
|
-
options[:authorize_options].each do |k|
|
36
|
+
(options[:authorize_options] & options[:overridable_authorize_options]).each do |k|
|
35
37
|
params[k] = request.params[k.to_s] unless [nil, ''].include?(request.params[k.to_s])
|
36
38
|
end
|
37
39
|
|
@@ -67,9 +69,10 @@ module OmniAuth
|
|
67
69
|
|
68
70
|
extra do
|
69
71
|
hash = {}
|
70
|
-
|
71
|
-
|
72
|
-
|
72
|
+
token = nil_or_empty?(access_token['id_token']) ? access_token.token : access_token['id_token']
|
73
|
+
hash[:id_token] = token
|
74
|
+
if !options[:skip_jwt] && !nil_or_empty?(token)
|
75
|
+
decoded = ::JWT.decode(token, nil, false).first
|
73
76
|
|
74
77
|
# We have to manually verify the claims because the third parameter to
|
75
78
|
# JWT.decode is false since no verification key is provided.
|
@@ -106,6 +109,10 @@ module OmniAuth
|
|
106
109
|
|
107
110
|
private
|
108
111
|
|
112
|
+
def nil_or_empty?(obj)
|
113
|
+
obj.is_a?(String) ? obj.empty? : obj.nil?
|
114
|
+
end
|
115
|
+
|
109
116
|
def callback_url
|
110
117
|
options[:redirect_uri] || (full_host + callback_path)
|
111
118
|
end
|
@@ -21,9 +21,9 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.required_ruby_version = '>= 2.2'
|
22
22
|
|
23
23
|
gem.add_runtime_dependency 'jwt', '>= 2.0'
|
24
|
-
gem.add_runtime_dependency 'oauth2', '~>
|
24
|
+
gem.add_runtime_dependency 'oauth2', '~> 2.0.6'
|
25
25
|
gem.add_runtime_dependency 'omniauth', '~> 2.0'
|
26
|
-
gem.add_runtime_dependency 'omniauth-oauth2', '~> 1.
|
26
|
+
gem.add_runtime_dependency 'omniauth-oauth2', '~> 1.8.0'
|
27
27
|
|
28
28
|
gem.add_development_dependency 'rake', '~> 12.0'
|
29
29
|
gem.add_development_dependency 'rspec', '~> 3.6'
|
@@ -242,9 +242,18 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
242
242
|
context "authorize option #{k}" do
|
243
243
|
let(:request) { double('Request', params: { k.to_s => 'http://example.com' }, cookies: {}, env: {}) }
|
244
244
|
|
245
|
-
|
246
|
-
|
247
|
-
|
245
|
+
context 'when overridable_authorize_options is default' do
|
246
|
+
it "should set the #{k} authorize option dynamically in the request" do
|
247
|
+
@options = { k: '' }
|
248
|
+
expect(subject.authorize_params[k.to_s]).to eq('http://example.com')
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context 'when overridable_authorize_options is empty' do
|
253
|
+
it "should not set the #{k} authorize option dynamically in the request" do
|
254
|
+
@options = { k: '', overridable_authorize_options: [] }
|
255
|
+
expect(subject.authorize_params[k.to_s]).not_to eq('http://example.com')
|
256
|
+
end
|
248
257
|
end
|
249
258
|
end
|
250
259
|
end
|
@@ -252,9 +261,18 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
252
261
|
describe 'custom authorize_options' do
|
253
262
|
let(:request) { double('Request', params: { 'foo' => 'something' }, cookies: {}, env: {}) }
|
254
263
|
|
255
|
-
|
256
|
-
|
257
|
-
|
264
|
+
context 'when overridable_authorize_options is default' do
|
265
|
+
it 'should not support request overrides from custom authorize_options' do
|
266
|
+
@options = { authorize_options: [:foo], foo: '' }
|
267
|
+
expect(subject.authorize_params['foo']).not_to eq('something')
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
context 'when overridable_authorize_options is customized' do
|
272
|
+
it 'should support request overrides from custom authorize_options' do
|
273
|
+
@options = { authorize_options: [:foo], overridable_authorize_options: [:foo], foo: '' }
|
274
|
+
expect(subject.authorize_params['foo']).to eq('something')
|
275
|
+
end
|
258
276
|
end
|
259
277
|
end
|
260
278
|
end
|
@@ -321,7 +339,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
321
339
|
end
|
322
340
|
end
|
323
341
|
end
|
324
|
-
let(:access_token) { OAuth2::AccessToken.from_hash(client, {}) }
|
342
|
+
let(:access_token) { OAuth2::AccessToken.from_hash(client, { 'access_token' => 'a' }) }
|
325
343
|
before { allow(subject).to receive(:access_token).and_return(access_token) }
|
326
344
|
|
327
345
|
context 'with verified email' do
|
@@ -387,8 +405,6 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
387
405
|
end
|
388
406
|
end
|
389
407
|
end
|
390
|
-
let(:access_token) { OAuth2::AccessToken.from_hash(client, {}) }
|
391
|
-
|
392
408
|
before { allow(subject).to receive(:access_token).and_return(access_token) }
|
393
409
|
|
394
410
|
describe 'id_token' do
|
@@ -449,7 +465,10 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
449
465
|
end
|
450
466
|
end
|
451
467
|
|
452
|
-
context 'when the
|
468
|
+
context 'when the access token is empty or nil' do
|
469
|
+
let(:access_token) { OAuth2::AccessToken.new(client, nil, { 'refresh_token' => 'foo' }) }
|
470
|
+
before { allow(subject.extra).to receive(:access_token).and_return(access_token) }
|
471
|
+
|
453
472
|
it 'should not include id_token' do
|
454
473
|
expect(subject.extra).not_to have_key(:id_token)
|
455
474
|
end
|
@@ -461,6 +480,19 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
461
480
|
end
|
462
481
|
|
463
482
|
describe 'raw_info' do
|
483
|
+
let(:token_info) do
|
484
|
+
{
|
485
|
+
'abc' => 'xyz',
|
486
|
+
'exp' => Time.now.to_i + 3600,
|
487
|
+
'nbf' => Time.now.to_i - 60,
|
488
|
+
'iat' => Time.now.to_i,
|
489
|
+
'aud' => 'appid',
|
490
|
+
'iss' => 'accounts.google.com'
|
491
|
+
}
|
492
|
+
end
|
493
|
+
let(:id_token) { JWT.encode(token_info, 'secret') }
|
494
|
+
let(:access_token) { OAuth2::AccessToken.from_hash(client, 'id_token' => id_token) }
|
495
|
+
|
464
496
|
context 'when skip_info is true' do
|
465
497
|
before { subject.options[:skip_info] = true }
|
466
498
|
|
@@ -645,15 +677,22 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
645
677
|
end
|
646
678
|
|
647
679
|
it 'should read access_token from hash if this is not an AJAX request with a code parameter' do
|
680
|
+
client = OAuth2::Client.new('abc', 'def') do |builder|
|
681
|
+
builder.request :url_encoded
|
682
|
+
builder.adapter :test do |stub|
|
683
|
+
stub.get('/oauth2/v3/userinfo') { [200, { 'content-type' => 'application/json' }, '{"sub": "12345"}'] }
|
684
|
+
end
|
685
|
+
end
|
686
|
+
|
648
687
|
allow(request).to receive(:xhr?).and_return(false)
|
649
688
|
allow(request).to receive(:params).and_return('access_token' => 'valid_access_token')
|
650
689
|
expect(subject).to receive(:verify_token).with('valid_access_token').and_return true
|
651
|
-
expect(subject).to receive(:client).and_return(
|
690
|
+
expect(subject).to receive(:client).and_return(client)
|
652
691
|
|
653
692
|
token = subject.build_access_token
|
654
693
|
expect(token).to be_instance_of(::OAuth2::AccessToken)
|
655
694
|
expect(token.token).to eq('valid_access_token')
|
656
|
-
expect(token.client).to eq(
|
695
|
+
expect(token.client).to eq(client)
|
657
696
|
end
|
658
697
|
|
659
698
|
it 'reads the code from a json request body' do
|
@@ -690,18 +729,24 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
690
729
|
|
691
730
|
it 'reads the access token from a json request body' do
|
692
731
|
body = StringIO.new(%({"access_token":"valid_access_token"}))
|
732
|
+
client = OAuth2::Client.new('abc', 'def') do |builder|
|
733
|
+
builder.request :url_encoded
|
734
|
+
builder.adapter :test do |stub|
|
735
|
+
stub.get('/oauth2/v3/userinfo') { [200, { 'content-type' => 'application/json' }, '{"sub": "12345"}'] }
|
736
|
+
end
|
737
|
+
end
|
693
738
|
|
694
739
|
allow(request).to receive(:xhr?).and_return(false)
|
695
740
|
allow(request).to receive(:content_type).and_return('application/json')
|
696
741
|
allow(request).to receive(:body).and_return(body)
|
697
|
-
expect(subject).to receive(:client).and_return(
|
742
|
+
expect(subject).to receive(:client).and_return(client)
|
698
743
|
|
699
744
|
expect(subject).to receive(:verify_token).with('valid_access_token').and_return true
|
700
745
|
|
701
746
|
token = subject.build_access_token
|
702
747
|
expect(token).to be_instance_of(::OAuth2::AccessToken)
|
703
748
|
expect(token.token).to eq('valid_access_token')
|
704
|
-
expect(token.client).to eq(
|
749
|
+
expect(token.client).to eq(client)
|
705
750
|
end
|
706
751
|
|
707
752
|
it 'should use callback_url without query_string if this is not an AJAX request' do
|
@@ -777,7 +822,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
777
822
|
end
|
778
823
|
end
|
779
824
|
end
|
780
|
-
let(:access_token) { OAuth2::AccessToken.from_hash(client, {}) }
|
825
|
+
let(:access_token) { OAuth2::AccessToken.from_hash(client, { 'access_token' => 'foo' }) }
|
781
826
|
|
782
827
|
context 'when domain is nil' do
|
783
828
|
let(:client) do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omniauth-google-oauth2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Ellithorpe
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-09-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: jwt
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
34
|
+
version: 2.0.6
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
41
|
+
version: 2.0.6
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: omniauth
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,14 +59,14 @@ dependencies:
|
|
59
59
|
requirements:
|
60
60
|
- - "~>"
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: 1.
|
62
|
+
version: 1.8.0
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
67
|
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 1.
|
69
|
+
version: 1.8.0
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: rake
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -155,8 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
155
|
- !ruby/object:Gem::Version
|
156
156
|
version: '0'
|
157
157
|
requirements: []
|
158
|
-
|
159
|
-
rubygems_version: 2.7.9
|
158
|
+
rubygems_version: 3.0.9
|
160
159
|
signing_key:
|
161
160
|
specification_version: 4
|
162
161
|
summary: A Google OAuth2 strategy for OmniAuth 1.x
|