Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions lib/omniauth/strategies/google_oauth2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ def authorize_params

extra do
hash = {}
hash[:id_token] = access_token['id_token']
if !options[:skip_jwt] && !access_token['id_token'].nil?
decoded = ::JWT.decode(access_token['id_token'], nil, false).first
hash[:id_token] = access_token.token
if !options[:skip_jwt] && !nil_or_empty(access_token.token)
decoded = ::JWT.decode(access_token.token, nil, false).first

# We have to manually verify the claims because the third parameter to
# JWT.decode is false since no verification key is provided.
Expand Down Expand Up @@ -106,6 +106,10 @@ def custom_build_access_token

private

def nil_or_empty(obj)
obj.is_a?(String) ? obj.empty? : obj.nil?
end

def callback_url
options[:redirect_uri] || (full_host + callback_path)
end
Expand Down
4 changes: 2 additions & 2 deletions omniauth-google-oauth2.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ Gem::Specification.new do |gem|
gem.required_ruby_version = '>= 2.2'

gem.add_runtime_dependency 'jwt', '>= 2.0'
gem.add_runtime_dependency 'oauth2', '~> 1.1'
gem.add_runtime_dependency 'oauth2', '~> 2.0.6'
gem.add_runtime_dependency 'omniauth', '~> 2.0'
gem.add_runtime_dependency 'omniauth-oauth2', '~> 1.7.1'
gem.add_runtime_dependency 'omniauth-oauth2', '~> 1.8.0'

gem.add_development_dependency 'rake', '~> 12.0'
gem.add_development_dependency 'rspec', '~> 3.6'
Expand Down
45 changes: 36 additions & 9 deletions spec/omniauth/strategies/google_oauth2_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@
end
end
end
let(:access_token) { OAuth2::AccessToken.from_hash(client, {}) }
let(:access_token) { OAuth2::AccessToken.from_hash(client, { 'access_token' => 'a' }) }
before { allow(subject).to receive(:access_token).and_return(access_token) }

context 'with verified email' do
Expand Down Expand Up @@ -387,8 +387,6 @@
end
end
end
let(:access_token) { OAuth2::AccessToken.from_hash(client, {}) }

before { allow(subject).to receive(:access_token).and_return(access_token) }

describe 'id_token' do
Expand Down Expand Up @@ -449,7 +447,10 @@
end
end

context 'when the id_token is missing' do
context 'when the access token is empty or nil' do
let(:access_token) { OAuth2::AccessToken.new(client, nil, { 'refresh_token' => 'foo' }) }
before { allow(subject.extra).to receive(:access_token).and_return(access_token) }

it 'should not include id_token' do
expect(subject.extra).not_to have_key(:id_token)
end
Expand All @@ -461,6 +462,19 @@
end

describe 'raw_info' do
let(:token_info) do
{
'abc' => 'xyz',
'exp' => Time.now.to_i + 3600,
'nbf' => Time.now.to_i - 60,
'iat' => Time.now.to_i,
'aud' => 'appid',
'iss' => 'accounts.google.com'
}
end
let(:id_token) { JWT.encode(token_info, 'secret') }
let(:access_token) { OAuth2::AccessToken.from_hash(client, 'id_token' => id_token) }

context 'when skip_info is true' do
before { subject.options[:skip_info] = true }

Expand Down Expand Up @@ -645,15 +659,22 @@
end

it 'should read access_token from hash if this is not an AJAX request with a code parameter' do
client = OAuth2::Client.new('abc', 'def') do |builder|
builder.request :url_encoded
builder.adapter :test do |stub|
stub.get('/oauth2/v3/userinfo') { [200, { 'content-type' => 'application/json' }, '{"sub": "12345"}'] }
end
end

allow(request).to receive(:xhr?).and_return(false)
allow(request).to receive(:params).and_return('access_token' => 'valid_access_token')
expect(subject).to receive(:verify_token).with('valid_access_token').and_return true
expect(subject).to receive(:client).and_return(:client)
expect(subject).to receive(:client).and_return(client)

token = subject.build_access_token
expect(token).to be_instance_of(::OAuth2::AccessToken)
expect(token.token).to eq('valid_access_token')
expect(token.client).to eq(:client)
expect(token.client).to eq(client)
end

it 'reads the code from a json request body' do
Expand Down Expand Up @@ -690,18 +711,24 @@

it 'reads the access token from a json request body' do
body = StringIO.new(%({"access_token":"valid_access_token"}))
client = OAuth2::Client.new('abc', 'def') do |builder|
builder.request :url_encoded
builder.adapter :test do |stub|
stub.get('/oauth2/v3/userinfo') { [200, { 'content-type' => 'application/json' }, '{"sub": "12345"}'] }
end
end

allow(request).to receive(:xhr?).and_return(false)
allow(request).to receive(:content_type).and_return('application/json')
allow(request).to receive(:body).and_return(body)
expect(subject).to receive(:client).and_return(:client)
expect(subject).to receive(:client).and_return(client)

expect(subject).to receive(:verify_token).with('valid_access_token').and_return true

token = subject.build_access_token
expect(token).to be_instance_of(::OAuth2::AccessToken)
expect(token.token).to eq('valid_access_token')
expect(token.client).to eq(:client)
expect(token.client).to eq(client)
end

it 'should use callback_url without query_string if this is not an AJAX request' do
Expand Down Expand Up @@ -777,7 +804,7 @@
end
end
end
let(:access_token) { OAuth2::AccessToken.from_hash(client, {}) }
let(:access_token) { OAuth2::AccessToken.from_hash(client, { 'access_token' => 'foo' }) }

context 'when domain is nil' do
let(:client) do
Expand Down