Skip to content
Snippets Groups Projects
Commit af6885fd authored by Mohammed  Bilal's avatar Mohammed Bilal 💬
Browse files

New upstream version 1.1.1

parent dab966d2
No related branches found
No related tags found
No related merge requests found
# Changelog
All notable changes to this project will be documented in this file.
## 1.1.1 - 2022-09-05
### Added
- Nothing.
### Deprecated
- Nothing.
### Removed
- Nothing.
### Fixed
- Fixed JWT decoding issue. (Invalid segment encoding) [#431](https://github.com/zquestz/omniauth-google-oauth2/pull/431)
## 1.1.0 - 2022-09-03
### Added
- `overridable_authorize_options` has been added to restrict overriding authorize_options by request params. [#423](https://github.com/zquestz/omniauth-google-oauth2/pull/423)
- Support for oauth2 2.0.x. [#429](https://github.com/zquestz/omniauth-google-oauth2/pull/429)
### Deprecated
- Nothing.
### Removed
- Nothing.
### Fixed
- Nothing.
## 1.0.1 - 2022-03-10
### Added
......
......@@ -85,13 +85,15 @@ You can configure several options, which you pass in to the `provider` method vi
* `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.
* `overridable_authorize_options`: By default, all `authorize_options` can be overridden with request parameters. You can restrict the behavior by using this option.
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:
```ruby
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'],
{
scope: 'userinfo.email, userinfo.profile, http://gdata.youtube.com',
scope: 'email, profile, http://gdata.youtube.com',
prompt: 'select_account',
image_aspect_ratio: 'square',
image_size: 50
......
......@@ -2,7 +2,7 @@
source 'https://rubygems.org'
gem 'omniauth-google-oauth2', '~> 0.8.1'
gem 'omniauth-google-oauth2', '~> 1.1.1'
gem 'rubocop'
gem 'sinatra', '~> 1.4'
gem 'webrick'
......@@ -19,6 +19,19 @@ OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
# Main example app for omniauth-google-oauth2
class App < Sinatra::Base
configure do
set :sessions, true
set :inline_templates, true
end
use Rack::Session::Cookie, secret: ENV['RACK_COOKIE_SECRET']
use OmniAuth::Builder do
# For additional provider examples please look at 'omni_auth.rb'
# The key provider_ignores_state is only for AJAX flows. It is not recommended for normal logins.
provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], access_type: 'offline', prompt: 'consent', provider_ignores_state: true, scope: 'email,profile,calendar'
end
get '/' do
<<-HTML
<!DOCTYPE html>
......@@ -73,7 +86,12 @@ class App < Sinatra::Base
</head>
<body>
<ul>
<li><a href='/auth/google_oauth2'>Sign in with Google</a></li>
<li>
<form method='post' action='/auth/google_oauth2'>
<input type="hidden" name="authenticity_token" value="#{request.env['rack.session']['csrf']}">
<button type='submit'>Login with Google</button>
</form>
</li>
<li><a href='#' class="googleplus-login">Sign in with Google via AJAX</a></li>
</ul>
</body>
......@@ -109,12 +127,4 @@ class App < Sinatra::Base
end
end
use Rack::Session::Cookie, secret: ENV['RACK_COOKIE_SECRET']
use OmniAuth::Builder do
# For additional provider examples please look at 'omni_auth.rb'
# The key provider_ignores_state is only for AJAX flows. It is not recommended for normal logins.
provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], access_type: 'offline', prompt: 'consent', provider_ignores_state: true, scope: 'email,profile,calendar'
end
run App.new
......@@ -2,6 +2,6 @@
module OmniAuth
module GoogleOauth2
VERSION = '1.0.1'
VERSION = '1.1.1'
end
end
......@@ -15,13 +15,15 @@ module OmniAuth
DEFAULT_SCOPE = 'email,profile'
USER_INFO_URL = 'https://www.googleapis.com/oauth2/v3/userinfo'
IMAGE_SIZE_REGEXP = /(s\d+(-c)?)|(w\d+-h\d+(-c)?)|(w\d+(-c)?)|(h\d+(-c)?)|c/
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]
option :name, 'google_oauth2'
option :skip_friends, true
option :skip_image_info, true
option :skip_jwt, false
option :jwt_leeway, 60
option :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]
option :authorize_options, AUTHORIZE_OPTIONS
option :overridable_authorize_options, AUTHORIZE_OPTIONS
option :authorized_client_ids, []
option :client_options,
......@@ -31,7 +33,7 @@ module OmniAuth
def authorize_params
super.tap do |params|
options[:authorize_options].each do |k|
(options[:authorize_options] & options[:overridable_authorize_options]).each do |k|
params[k] = request.params[k.to_s] unless [nil, ''].include?(request.params[k.to_s])
end
......@@ -67,9 +69,10 @@ module OmniAuth
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
token = nil_or_empty?(access_token['id_token']) ? access_token.token : access_token['id_token']
hash[:id_token] = token
if !options[:skip_jwt] && !nil_or_empty?(token)
decoded = ::JWT.decode(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.
......@@ -106,6 +109,10 @@ module OmniAuth
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
......
......@@ -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'
......
......@@ -242,9 +242,18 @@ describe OmniAuth::Strategies::GoogleOauth2 do
context "authorize option #{k}" do
let(:request) { double('Request', params: { k.to_s => 'http://example.com' }, cookies: {}, env: {}) }
it "should set the #{k} authorize option dynamically in the request" do
@options = { k: '' }
expect(subject.authorize_params[k.to_s]).to eq('http://example.com')
context 'when overridable_authorize_options is default' do
it "should set the #{k} authorize option dynamically in the request" do
@options = { k: '' }
expect(subject.authorize_params[k.to_s]).to eq('http://example.com')
end
end
context 'when overridable_authorize_options is empty' do
it "should not set the #{k} authorize option dynamically in the request" do
@options = { k: '', overridable_authorize_options: [] }
expect(subject.authorize_params[k.to_s]).not_to eq('http://example.com')
end
end
end
end
......@@ -252,9 +261,18 @@ describe OmniAuth::Strategies::GoogleOauth2 do
describe 'custom authorize_options' do
let(:request) { double('Request', params: { 'foo' => 'something' }, cookies: {}, env: {}) }
it 'should support request overrides from custom authorize_options' do
@options = { authorize_options: [:foo], foo: '' }
expect(subject.authorize_params['foo']).to eq('something')
context 'when overridable_authorize_options is default' do
it 'should not support request overrides from custom authorize_options' do
@options = { authorize_options: [:foo], foo: '' }
expect(subject.authorize_params['foo']).not_to eq('something')
end
end
context 'when overridable_authorize_options is customized' do
it 'should support request overrides from custom authorize_options' do
@options = { authorize_options: [:foo], overridable_authorize_options: [:foo], foo: '' }
expect(subject.authorize_params['foo']).to eq('something')
end
end
end
end
......@@ -321,7 +339,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
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
......@@ -387,8 +405,6 @@ describe OmniAuth::Strategies::GoogleOauth2 do
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
......@@ -449,7 +465,10 @@ describe OmniAuth::Strategies::GoogleOauth2 do
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
......@@ -461,6 +480,19 @@ describe OmniAuth::Strategies::GoogleOauth2 do
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 }
......@@ -645,15 +677,22 @@ describe OmniAuth::Strategies::GoogleOauth2 do
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
......@@ -690,18 +729,24 @@ describe OmniAuth::Strategies::GoogleOauth2 do
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
......@@ -777,7 +822,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment