omniauth-google-oauth2 0.4.1 → 0.5.0

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.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Google's OAuth2 docs. Make sure you are familiar with all the options
2
4
  # before attempting to configure this gem.
3
5
  # https://developers.google.com/accounts/docs/OAuth2Login
@@ -6,40 +8,26 @@ Rails.application.config.middleware.use OmniAuth::Builder do
6
8
  # Default usage, this will give you offline access and a refresh token
7
9
  # using default scopes 'email' and 'profile'
8
10
  #
9
- provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {
10
- :scope => 'email,profile'
11
- }
11
+ provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], scope: 'email,profile'
12
12
 
13
13
  # Manual setup for offline access with a refresh token.
14
14
  #
15
- # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {
16
- # :access_type => 'offline',
17
- # }
15
+ # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], access_type: 'offline'
18
16
 
19
17
  # Custom scope supporting youtube. If you are customizing scopes, remember
20
18
  # to include the default scopes 'email' and 'profile'
21
19
  #
22
- # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {
23
- # :scope => 'http://gdata.youtube.com,email,profile,plus.me'
24
- # }
20
+ # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], scope: 'http://gdata.youtube.com,email,profile,plus.me'
25
21
 
26
22
  # Custom scope for users only using Google for account creation/auth and do not require a refresh token.
27
23
  #
28
- # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {
29
- # :access_type => 'online',
30
- # :prompt => ''
31
- # }
24
+ # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], access_type: 'online', prompt: ''
32
25
 
33
26
  # To include information about people in your circles you must include the 'plus.login' scope.
34
27
  #
35
- # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {
36
- # :skip_friends => false,
37
- # :scope => "email,profile,plus.login"
38
- # }
28
+ # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], skip_friends: false, scope: 'email,profile,plus.login'
39
29
 
40
30
  # If you need to acquire whether user picture is a default one or uploaded by user.
41
31
  #
42
- # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {
43
- # :skip_image_info => false
44
- # }
32
+ # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], skip_image_info: false
45
33
  end
@@ -1 +1,3 @@
1
- require File.join('omniauth', 'google_oauth2')
1
+ # frozen_string_literal: true
2
+
3
+ require 'omniauth/google_oauth2'
@@ -1 +1,3 @@
1
- require File.join('omniauth', 'strategies', 'google_oauth2')
1
+ # frozen_string_literal: true
2
+
3
+ require 'omniauth/strategies/google_oauth2'
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OmniAuth
2
4
  module GoogleOauth2
3
- VERSION = "0.4.1"
5
+ VERSION = '0.5.0'
4
6
  end
5
7
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'multi_json'
2
4
  require 'jwt'
3
5
  require 'omniauth/strategies/oauth2'
@@ -5,23 +7,24 @@ require 'uri'
5
7
 
6
8
  module OmniAuth
7
9
  module Strategies
10
+ # Main class for Google OAuth2 strategy.
8
11
  class GoogleOauth2 < OmniAuth::Strategies::OAuth2
9
- BASE_SCOPE_URL = "https://www.googleapis.com/auth/"
10
- BASE_SCOPES = %w[profile email openid]
11
- DEFAULT_SCOPE = "email,profile"
12
+ BASE_SCOPE_URL = 'https://www.googleapis.com/auth/'
13
+ BASE_SCOPES = %w[profile email openid].freeze
14
+ DEFAULT_SCOPE = 'email,profile'
12
15
 
13
16
  option :name, 'google_oauth2'
14
17
  option :skip_friends, true
15
18
  option :skip_image_info, true
16
19
  option :skip_jwt, false
17
20
  option :jwt_leeway, 60
18
- option :authorize_options, [:access_type, :hd, :login_hint, :prompt, :request_visible_actions, :scope, :state, :redirect_uri, :include_granted_scopes, :openid_realm]
21
+ option :authorize_options, %i[access_type hd login_hint prompt request_visible_actions scope state redirect_uri include_granted_scopes openid_realm]
22
+ option :authorized_client_ids, []
19
23
 
20
- option :client_options, {
21
- :site => 'https://accounts.google.com',
22
- :authorize_url => '/o/oauth2/auth',
23
- :token_url => '/o/oauth2/token'
24
- }
24
+ option :client_options,
25
+ site: 'https://accounts.google.com',
26
+ authorize_url: '/o/oauth2/auth',
27
+ token_url: '/o/oauth2/token'
25
28
 
26
29
  def authorize_params
27
30
  super.tap do |params|
@@ -29,30 +32,27 @@ module OmniAuth
29
32
  params[k] = request.params[k.to_s] unless [nil, ''].include?(request.params[k.to_s])
30
33
  end
31
34
 
32
- raw_scope = params[:scope] || DEFAULT_SCOPE
33
- scope_list = raw_scope.split(" ").map {|item| item.split(",")}.flatten
34
- scope_list.map! { |s| s =~ /^https?:\/\// || BASE_SCOPES.include?(s) ? s : "#{BASE_SCOPE_URL}#{s}" }
35
- params[:scope] = scope_list.join(" ")
35
+ params[:scope] = get_scope(params)
36
36
  params[:access_type] = 'offline' if params[:access_type].nil?
37
37
  params['openid.realm'] = params.delete(:openid_realm) unless params[:openid_realm].nil?
38
38
 
39
- session['omniauth.state'] = params[:state] if params['state']
39
+ session['omniauth.state'] = params[:state] if params[:state]
40
40
  end
41
41
  end
42
42
 
43
- uid { raw_info['sub'] || verified_email }
43
+ uid { raw_info['sub'] }
44
44
 
45
45
  info do
46
- prune!({
47
- :name => raw_info['name'],
48
- :email => verified_email,
49
- :first_name => raw_info['given_name'],
50
- :last_name => raw_info['family_name'],
51
- :image => image_url,
52
- :urls => {
53
- 'Google' => raw_info['profile']
46
+ prune!(
47
+ name: raw_info['name'],
48
+ email: verified_email,
49
+ first_name: raw_info['given_name'],
50
+ last_name: raw_info['family_name'],
51
+ image: image_url,
52
+ urls: {
53
+ google: raw_info['profile']
54
54
  }
55
- })
55
+ )
56
56
  end
57
57
 
58
58
  extra do
@@ -60,18 +60,17 @@ module OmniAuth
60
60
  hash[:id_token] = access_token['id_token']
61
61
  if !options[:skip_jwt] && !access_token['id_token'].nil?
62
62
  hash[:id_info] = JWT.decode(
63
- access_token['id_token'], nil, false, {
64
- :verify_iss => true,
65
- 'iss' => 'accounts.google.com',
66
- :verify_aud => true,
67
- 'aud' => options.client_id,
68
- :verify_sub => false,
69
- :verify_expiration => true,
70
- :verify_not_before => true,
71
- :verify_iat => true,
72
- :verify_jti => false,
73
- :leeway => options[:jwt_leeway]
74
- }).first
63
+ access_token['id_token'], nil, false, verify_iss: true,
64
+ iss: 'accounts.google.com',
65
+ verify_aud: true,
66
+ aud: options.client_id,
67
+ verify_sub: false,
68
+ verify_expiration: true,
69
+ verify_not_before: true,
70
+ verify_iat: true,
71
+ verify_jti: false,
72
+ leeway: options[:jwt_leeway]
73
+ ).first
75
74
  end
76
75
  hash[:raw_info] = raw_info unless skip_info?
77
76
  hash[:raw_friend_info] = raw_friend_info(raw_info['sub']) unless skip_info? || options[:skip_friends]
@@ -92,10 +91,24 @@ module OmniAuth
92
91
  end
93
92
 
94
93
  def custom_build_access_token
95
- access_token =
94
+ access_token = get_access_token(request)
95
+
96
+ verify_hd(access_token)
97
+ access_token
98
+ end
99
+ alias build_access_token custom_build_access_token
100
+
101
+ private
102
+
103
+ def callback_url
104
+ options[:redirect_uri] || (full_host + script_name + callback_path)
105
+ end
106
+
107
+ def get_access_token(request)
96
108
  if request.xhr? && request.params['code']
97
109
  verifier = request.params['code']
98
- client.auth_code.get_token(verifier, get_token_options('postmessage'), deep_symbolize(options.auth_token_params || {}))
110
+ redirect_uri = request.params['redirect_uri'] || 'postmessage'
111
+ client.auth_code.get_token(verifier, get_token_options(redirect_uri), deep_symbolize(options.auth_token_params || {}))
99
112
  elsif request.params['code'] && request.params['redirect_uri']
100
113
  verifier = request.params['code']
101
114
  redirect_uri = request.params['redirect_uri']
@@ -103,23 +116,20 @@ module OmniAuth
103
116
  elsif verify_token(request.params['access_token'])
104
117
  ::OAuth2::AccessToken.from_hash(client, request.params.dup)
105
118
  else
106
- verifier = request.params["code"]
119
+ verifier = request.params['code']
107
120
  client.auth_code.get_token(verifier, get_token_options(callback_url), deep_symbolize(options.auth_token_params))
108
121
  end
109
-
110
- verify_hd(access_token)
111
- access_token
112
122
  end
113
- alias_method :build_access_token, :custom_build_access_token
114
123
 
115
- private
116
-
117
- def callback_url
118
- options[:redirect_uri] || (full_host + script_name + callback_path)
124
+ def get_scope(params)
125
+ raw_scope = params[:scope] || DEFAULT_SCOPE
126
+ scope_list = raw_scope.split(' ').map { |item| item.split(',') }.flatten
127
+ scope_list.map! { |s| s =~ %r{^https?://} || BASE_SCOPES.include?(s) ? s : "#{BASE_SCOPE_URL}#{s}" }
128
+ scope_list.join(' ')
119
129
  end
120
130
 
121
131
  def get_token_options(redirect_uri)
122
- { :redirect_uri => redirect_uri }.merge(token_params.to_hash(:symbolize_keys => true))
132
+ { redirect_uri: redirect_uri }.merge(token_params.to_hash(symbolize_keys: true))
123
133
  end
124
134
 
125
135
  def prune!(hash)
@@ -151,7 +161,7 @@ module OmniAuth
151
161
  end
152
162
 
153
163
  def image_size_opts_passed?
154
- !!(options[:image_size] || options[:image_aspect_ratio])
164
+ options[:image_size] || options[:image_aspect_ratio]
155
165
  end
156
166
 
157
167
  def image_params
@@ -172,7 +182,7 @@ module OmniAuth
172
182
  return nil if query_parameters.nil?
173
183
 
174
184
  params = CGI.parse(query_parameters)
175
- stripped_params = params.delete_if { |key| key == "sz" }
185
+ stripped_params = params.delete_if { |key| key == 'sz' }
176
186
 
177
187
  # don't return an empty Hash since that would result
178
188
  # in URLs with a trailing ? character: http://image.url?
@@ -185,15 +195,17 @@ module OmniAuth
185
195
  return false unless access_token
186
196
  raw_response = client.request(:get, 'https://www.googleapis.com/oauth2/v3/tokeninfo',
187
197
  params: { access_token: access_token }).parsed
188
- raw_response['aud'] == options.client_id
198
+ raw_response['aud'] == options.client_id || options.authorized_client_ids.include?(raw_response['aud'])
189
199
  end
190
200
 
191
201
  def verify_hd(access_token)
192
202
  return true unless options.hd
193
203
  @raw_info ||= access_token.get('https://www.googleapis.com/plus/v1/people/me/openIdConnect').parsed
204
+
205
+ options.hd = options.hd.call if options.hd.is_a? Proc
194
206
  allowed_hosted_domains = Array(options.hd)
195
207
 
196
- raise CallbackError.new(:invalid_hd, "Invalid Hosted Domain") unless allowed_hosted_domains.include? @raw_info['hd']
208
+ raise CallbackError.new(:invalid_hd, 'Invalid Hosted Domain') unless allowed_hosted_domains.include? @raw_info['hd']
197
209
  true
198
210
  end
199
211
  end
@@ -1,26 +1,32 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path(File.join('..', 'lib', 'omniauth', 'google_oauth2', 'version'), __FILE__)
2
+ # frozen_string_literal: true
3
+
4
+ require File.expand_path(
5
+ File.join('..', 'lib', 'omniauth', 'google_oauth2', 'version'),
6
+ __FILE__
7
+ )
3
8
 
4
9
  Gem::Specification.new do |gem|
5
- gem.name = "omniauth-google-oauth2"
10
+ gem.name = 'omniauth-google-oauth2'
6
11
  gem.version = OmniAuth::GoogleOauth2::VERSION
7
12
  gem.license = 'MIT'
8
- gem.summary = %q{A Google OAuth2 strategy for OmniAuth 1.x}
9
- gem.description = %q{A Google OAuth2 strategy for OmniAuth 1.x}
10
- gem.authors = ["Josh Ellithorpe", "Yury Korolev"]
11
- gem.email = ["quest@mac.com"]
12
- gem.homepage = "https://github.com/zquestz/omniauth-google-oauth2"
13
+ gem.summary = %(A Google OAuth2 strategy for OmniAuth 1.x)
14
+ gem.description = %(A Google OAuth2 strategy for OmniAuth 1.x. This allows you to login to Google with your ruby app.)
15
+ gem.authors = ['Josh Ellithorpe', 'Yury Korolev']
16
+ gem.email = ['quest@mac.com']
17
+ gem.homepage = 'https://github.com/zquestz/omniauth-google-oauth2'
13
18
 
14
19
  gem.files = `git ls-files`.split("\n")
15
- gem.require_paths = ["lib"]
20
+ gem.require_paths = ['lib']
16
21
 
17
22
  gem.required_ruby_version = '>= 2.0'
18
23
 
19
24
  gem.add_runtime_dependency 'omniauth', '>= 1.1.1'
20
25
  gem.add_runtime_dependency 'omniauth-oauth2', '>= 1.3.1'
21
- gem.add_runtime_dependency 'jwt', '~> 1.5.2'
26
+ gem.add_runtime_dependency 'jwt', '~> 1.5'
22
27
  gem.add_runtime_dependency 'multi_json', '~> 1.3'
23
28
 
24
- gem.add_development_dependency 'rspec', '>= 2.14.0'
25
- gem.add_development_dependency 'rake'
29
+ gem.add_development_dependency 'rspec', '~> 3.6'
30
+ gem.add_development_dependency 'rake', '~> 12.0'
31
+ gem.add_development_dependency 'rubocop', '~> 0.49'
26
32
  end
@@ -1,19 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'omniauth-google-oauth2'
3
5
 
4
6
  describe OmniAuth::Strategies::GoogleOauth2 do
5
- let(:request) { double('Request', :params => {}, :cookies => {}, :env => {}) }
6
- let(:app) {
7
+ let(:request) { double('Request', params: {}, cookies: {}, env: {}) }
8
+ let(:app) do
7
9
  lambda do
8
- [200, {}, ["Hello."]]
10
+ [200, {}, ['Hello.']]
9
11
  end
10
- }
12
+ end
11
13
 
12
14
  subject do
13
15
  OmniAuth::Strategies::GoogleOauth2.new(app, 'appid', 'secret', @options || {}).tap do |strategy|
14
- allow(strategy).to receive(:request) {
16
+ allow(strategy).to receive(:request) do
15
17
  request
16
- }
18
+ end
17
19
  end
18
20
  end
19
21
 
@@ -38,40 +40,59 @@ describe OmniAuth::Strategies::GoogleOauth2 do
38
40
  expect(subject.client.options[:token_url]).to eq('/o/oauth2/token')
39
41
  end
40
42
 
41
- describe "overrides" do
42
- it 'should allow overriding the site' do
43
- @options = {:client_options => {'site' => 'https://example.com'}}
44
- expect(subject.client.site).to eq('https://example.com')
45
- end
43
+ describe 'overrides' do
44
+ context 'as strings' do
45
+ it 'should allow overriding the site' do
46
+ @options = { client_options: { 'site' => 'https://example.com' } }
47
+ expect(subject.client.site).to eq('https://example.com')
48
+ end
49
+
50
+ it 'should allow overriding the authorize_url' do
51
+ @options = { client_options: { 'authorize_url' => 'https://example.com' } }
52
+ expect(subject.client.options[:authorize_url]).to eq('https://example.com')
53
+ end
46
54
 
47
- it 'should allow overriding the authorize_url' do
48
- @options = {:client_options => {'authorize_url' => 'https://example.com'}}
49
- expect(subject.client.options[:authorize_url]).to eq('https://example.com')
55
+ it 'should allow overriding the token_url' do
56
+ @options = { client_options: { 'token_url' => 'https://example.com' } }
57
+ expect(subject.client.options[:token_url]).to eq('https://example.com')
58
+ end
50
59
  end
51
60
 
52
- it 'should allow overriding the token_url' do
53
- @options = {:client_options => {'token_url' => 'https://example.com'}}
54
- expect(subject.client.options[:token_url]).to eq('https://example.com')
61
+ context 'as symbols' do
62
+ it 'should allow overriding the site' do
63
+ @options = { client_options: { site: 'https://example.com' } }
64
+ expect(subject.client.site).to eq('https://example.com')
65
+ end
66
+
67
+ it 'should allow overriding the authorize_url' do
68
+ @options = { client_options: { authorize_url: 'https://example.com' } }
69
+ expect(subject.client.options[:authorize_url]).to eq('https://example.com')
70
+ end
71
+
72
+ it 'should allow overriding the token_url' do
73
+ @options = { client_options: { token_url: 'https://example.com' } }
74
+ expect(subject.client.options[:token_url]).to eq('https://example.com')
75
+ end
55
76
  end
56
77
  end
57
78
  end
58
79
 
59
- describe "#authorize_options" do
60
- [:access_type, :hd, :login_hint, :prompt, :scope, :state].each do |k|
80
+ describe '#authorize_options' do
81
+ %i[access_type hd login_hint prompt scope state].each do |k|
61
82
  it "should support #{k}" do
62
- @options = {k => 'http://someval'}
83
+ @options = { k => 'http://someval' }
63
84
  expect(subject.authorize_params[k.to_s]).to eq('http://someval')
64
85
  end
65
86
  end
66
87
 
67
- describe "redirect_uri" do
88
+ describe 'redirect_uri' do
68
89
  it 'should default to nil' do
69
90
  @options = {}
70
91
  expect(subject.authorize_params['redirect_uri']).to eq(nil)
71
92
  end
72
93
 
73
94
  it 'should set the redirect_uri parameter if present' do
74
- @options = {:redirect_uri => 'https://example.com'}
95
+ @options = { redirect_uri: 'https://example.com' }
75
96
  expect(subject.authorize_params['redirect_uri']).to eq('https://example.com')
76
97
  end
77
98
  end
@@ -83,51 +104,56 @@ describe OmniAuth::Strategies::GoogleOauth2 do
83
104
  end
84
105
 
85
106
  it 'should set the access_type parameter if present' do
86
- @options = {:access_type => 'online'}
107
+ @options = { access_type: 'online' }
87
108
  expect(subject.authorize_params['access_type']).to eq('online')
88
109
  end
89
110
  end
90
111
 
91
112
  describe 'hd' do
92
- it "should default to nil" do
113
+ it 'should default to nil' do
93
114
  expect(subject.authorize_params['hd']).to eq(nil)
94
115
  end
95
116
 
96
117
  it 'should set the hd (hosted domain) parameter if present' do
97
- @options = {:hd => 'example.com'}
118
+ @options = { hd: 'example.com' }
98
119
  expect(subject.authorize_params['hd']).to eq('example.com')
99
120
  end
121
+
122
+ it 'should set the hd parameter and work with nil hd (gmail)' do
123
+ @options = { hd: nil }
124
+ expect(subject.authorize_params['hd']).to eq(nil)
125
+ end
100
126
  end
101
127
 
102
128
  describe 'login_hint' do
103
- it "should default to nil" do
129
+ it 'should default to nil' do
104
130
  expect(subject.authorize_params['login_hint']).to eq(nil)
105
131
  end
106
132
 
107
133
  it 'should set the login_hint parameter if present' do
108
- @options = {:login_hint => 'john@example.com'}
134
+ @options = { login_hint: 'john@example.com' }
109
135
  expect(subject.authorize_params['login_hint']).to eq('john@example.com')
110
136
  end
111
137
  end
112
138
 
113
139
  describe 'prompt' do
114
- it "should default to nil" do
140
+ it 'should default to nil' do
115
141
  expect(subject.authorize_params['prompt']).to eq(nil)
116
142
  end
117
143
 
118
144
  it 'should set the prompt parameter if present' do
119
- @options = {:prompt => 'consent select_account'}
145
+ @options = { prompt: 'consent select_account' }
120
146
  expect(subject.authorize_params['prompt']).to eq('consent select_account')
121
147
  end
122
148
  end
123
149
 
124
150
  describe 'request_visible_actions' do
125
- it "should default to nil" do
151
+ it 'should default to nil' do
126
152
  expect(subject.authorize_params['request_visible_actions']).to eq(nil)
127
153
  end
128
154
 
129
155
  it 'should set the request_visible_actions parameter if present' do
130
- @options = {:request_visible_actions => 'something'}
156
+ @options = { request_visible_actions: 'something' }
131
157
  expect(subject.authorize_params['request_visible_actions']).to eq('something')
132
158
  end
133
159
  end
@@ -138,29 +164,29 @@ describe OmniAuth::Strategies::GoogleOauth2 do
138
164
  end
139
165
 
140
166
  it 'should set the include_granted_scopes parameter if present' do
141
- @options = {:include_granted_scopes => 'true'}
167
+ @options = { include_granted_scopes: 'true' }
142
168
  expect(subject.authorize_params['include_granted_scopes']).to eq('true')
143
169
  end
144
170
  end
145
171
 
146
172
  describe 'scope' do
147
173
  it 'should expand scope shortcuts' do
148
- @options = {:scope => 'plus.me'}
174
+ @options = { scope: 'plus.me' }
149
175
  expect(subject.authorize_params['scope']).to eq('https://www.googleapis.com/auth/plus.me')
150
176
  end
151
177
 
152
178
  it 'should leave base scopes as is' do
153
- @options = {:scope => 'profile'}
179
+ @options = { scope: 'profile' }
154
180
  expect(subject.authorize_params['scope']).to eq('profile')
155
181
  end
156
182
 
157
183
  it 'should join scopes' do
158
- @options = {:scope => 'profile,email'}
184
+ @options = { scope: 'profile,email' }
159
185
  expect(subject.authorize_params['scope']).to eq('profile email')
160
186
  end
161
187
 
162
188
  it 'should deal with whitespace when joining scopes' do
163
- @options = {:scope => 'profile, email'}
189
+ @options = { scope: 'profile, email' }
164
190
  expect(subject.authorize_params['scope']).to eq('profile email')
165
191
  end
166
192
 
@@ -169,56 +195,58 @@ describe OmniAuth::Strategies::GoogleOauth2 do
169
195
  end
170
196
 
171
197
  it 'should support space delimited scopes' do
172
- @options = {:scope => 'profile email'}
198
+ @options = { scope: 'profile email' }
173
199
  expect(subject.authorize_params['scope']).to eq('profile email')
174
200
  end
175
201
 
176
- it "should support extremely badly formed scopes" do
177
- @options = {:scope => 'profile email,foo,steve yeah http://example.com'}
202
+ it 'should support extremely badly formed scopes' do
203
+ @options = { scope: 'profile email,foo,steve yeah http://example.com' }
178
204
  expect(subject.authorize_params['scope']).to eq('profile email https://www.googleapis.com/auth/foo https://www.googleapis.com/auth/steve https://www.googleapis.com/auth/yeah http://example.com')
179
205
  end
180
206
  end
181
207
 
182
208
  describe 'state' do
183
209
  it 'should set the state parameter' do
184
- @options = {:state => 'some_state'}
210
+ @options = { state: 'some_state' }
185
211
  expect(subject.authorize_params['state']).to eq('some_state')
212
+ expect(subject.authorize_params[:state]).to eq('some_state')
186
213
  expect(subject.session['omniauth.state']).to eq('some_state')
187
214
  end
188
215
 
189
216
  it 'should set the omniauth.state dynamically' do
190
- allow(subject).to receive(:request) { double('Request', {:params => {'state' => 'some_state'}, :env => {}}) }
217
+ allow(subject).to receive(:request) { double('Request', params: { 'state' => 'some_state' }, env: {}) }
191
218
  expect(subject.authorize_params['state']).to eq('some_state')
219
+ expect(subject.authorize_params[:state]).to eq('some_state')
192
220
  expect(subject.session['omniauth.state']).to eq('some_state')
193
221
  end
194
222
  end
195
223
 
196
- describe "overrides" do
224
+ describe 'overrides' do
197
225
  it 'should include top-level options that are marked as :authorize_options' do
198
- @options = {:authorize_options => [:scope, :foo, :request_visible_actions], :scope => 'http://bar', :foo => 'baz', :hd => "wow", :request_visible_actions => "something"}
226
+ @options = { authorize_options: %i[scope foo request_visible_actions], scope: 'http://bar', foo: 'baz', hd: 'wow', request_visible_actions: 'something' }
199
227
  expect(subject.authorize_params['scope']).to eq('http://bar')
200
228
  expect(subject.authorize_params['foo']).to eq('baz')
201
229
  expect(subject.authorize_params['hd']).to eq(nil)
202
230
  expect(subject.authorize_params['request_visible_actions']).to eq('something')
203
231
  end
204
232
 
205
- describe "request overrides" do
206
- [:access_type, :hd, :login_hint, :prompt, :scope, :state].each do |k|
233
+ describe 'request overrides' do
234
+ %i[access_type hd login_hint prompt scope state].each do |k|
207
235
  context "authorize option #{k}" do
208
- let(:request) { double('Request', :params => {k.to_s => 'http://example.com'}, :cookies => {}, :env => {}) }
236
+ let(:request) { double('Request', params: { k.to_s => 'http://example.com' }, cookies: {}, env: {}) }
209
237
 
210
238
  it "should set the #{k} authorize option dynamically in the request" do
211
- @options = {k => ''}
239
+ @options = { k: '' }
212
240
  expect(subject.authorize_params[k.to_s]).to eq('http://example.com')
213
241
  end
214
242
  end
215
243
  end
216
244
 
217
- describe "custom authorize_options" do
218
- let(:request) { double('Request', :params => {'foo' => 'something'}, :cookies => {}, :env => {}) }
245
+ describe 'custom authorize_options' do
246
+ let(:request) { double('Request', params: { 'foo' => 'something' }, cookies: {}, env: {}) }
219
247
 
220
- it "should support request overrides from custom authorize_options" do
221
- @options = {:authorize_options => [:foo], :foo => ''}
248
+ it 'should support request overrides from custom authorize_options' do
249
+ @options = { authorize_options: [:foo], foo: '' }
222
250
  expect(subject.authorize_params['foo']).to eq('something')
223
251
  end
224
252
  end
@@ -228,7 +256,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
228
256
 
229
257
  describe '#authorize_params' do
230
258
  it 'should include any authorize params passed in the :authorize_params option' do
231
- @options = {:authorize_params => {:request_visible_actions => 'something', :foo => 'bar', :baz => 'zip'}, :hd => 'wow', :bad => 'not_included'}
259
+ @options = { authorize_params: { request_visible_actions: 'something', foo: 'bar', baz: 'zip' }, hd: 'wow', bad: 'not_included' }
232
260
  expect(subject.authorize_params['request_visible_actions']).to eq('something')
233
261
  expect(subject.authorize_params['foo']).to eq('bar')
234
262
  expect(subject.authorize_params['baz']).to eq('zip')
@@ -239,15 +267,15 @@ describe OmniAuth::Strategies::GoogleOauth2 do
239
267
 
240
268
  describe '#token_params' do
241
269
  it 'should include any token params passed in the :token_params option' do
242
- @options = {:token_params => {:foo => 'bar', :baz => 'zip'}}
270
+ @options = { token_params: { foo: 'bar', baz: 'zip' } }
243
271
  expect(subject.token_params['foo']).to eq('bar')
244
272
  expect(subject.token_params['baz']).to eq('zip')
245
273
  end
246
274
  end
247
275
 
248
- describe "#token_options" do
276
+ describe '#token_options' do
249
277
  it 'should include top-level options that are marked as :token_options' do
250
- @options = {:token_options => [:scope, :foo], :scope => 'bar', :foo => 'baz', :bad => 'not_included'}
278
+ @options = { token_options: %i[scope foo], scope: 'bar', foo: 'baz', bad: 'not_included' }
251
279
  expect(subject.token_params['scope']).to eq('bar')
252
280
  expect(subject.token_params['foo']).to eq('baz')
253
281
  expect(subject.token_params['bad']).to eq(nil)
@@ -260,10 +288,9 @@ describe OmniAuth::Strategies::GoogleOauth2 do
260
288
  end
261
289
 
262
290
  it 'should set the callback_path parameter if present' do
263
- @options = {:callback_path => '/auth/foo/callback'}
291
+ @options = { callback_path: '/auth/foo/callback' }
264
292
  expect(subject.callback_path).to eq('/auth/foo/callback')
265
293
  end
266
-
267
294
  end
268
295
 
269
296
  describe '#extra' do
@@ -271,9 +298,9 @@ describe OmniAuth::Strategies::GoogleOauth2 do
271
298
  OAuth2::Client.new('abc', 'def') do |builder|
272
299
  builder.request :url_encoded
273
300
  builder.adapter :test do |stub|
274
- stub.get('/plus/v1/people/me/openIdConnect') {|env| [200, {'content-type' => 'application/json'}, '{"sub": "12345"}']}
275
- stub.get('/plus/v1/people/12345/people/visible') {|env| [200, {'content-type' => 'application/json'}, '[{"foo":"bar"}]']}
276
- stub.get('/plus/v1/people/12345?fields=image') {|env| [200, {'content-type' => 'application/json'}, '{"image":"imageData"}']}
301
+ stub.get('/plus/v1/people/me/openIdConnect') { [200, { 'content-type' => 'application/json' }, '{"sub": "12345"}'] }
302
+ stub.get('/plus/v1/people/12345/people/visible') { [200, { 'content-type' => 'application/json' }, '[{"foo":"bar"}]'] }
303
+ stub.get('/plus/v1/people/12345?fields=image') { [200, { 'content-type' => 'application/json' }, '{"image":"imageData"}'] }
277
304
  end
278
305
  end
279
306
  end
@@ -290,18 +317,18 @@ describe OmniAuth::Strategies::GoogleOauth2 do
290
317
  'nbf' => Time.now.to_i - 60,
291
318
  'iat' => Time.now.to_i,
292
319
  'aud' => 'appid',
293
- 'iss' => 'accounts.google.com',
320
+ 'iss' => 'accounts.google.com'
294
321
  }
295
322
  id_token = JWT.encode(token_info, 'secret')
296
- let(:access_token) { OAuth2::AccessToken.from_hash(client, {'id_token' => id_token}) }
323
+ let(:access_token) { OAuth2::AccessToken.from_hash(client, 'id_token' => id_token) }
297
324
 
298
325
  it 'should include id_token when set on the access_token' do
299
- expect(subject.extra).to include(:id_token => id_token)
326
+ expect(subject.extra).to include(id_token: id_token)
300
327
  end
301
328
 
302
329
  it 'should include id_info when id_token is set on the access_token and skip_jwt is false' do
303
330
  subject.options[:skip_jwt] = false
304
- expect(subject.extra).to include(:id_info => token_info)
331
+ expect(subject.extra).to include(id_info: token_info)
305
332
  end
306
333
 
307
334
  it 'should not include id_info when id_token is set on the access_token and skip_jwt is true' do
@@ -310,7 +337,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
310
337
  end
311
338
 
312
339
  it 'should include id_info when id_token is set on the access_token by default' do
313
- expect(subject.extra).to include(:id_info => token_info)
340
+ expect(subject.extra).to include(id_info: token_info)
314
341
  end
315
342
  end
316
343
 
@@ -367,7 +394,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
367
394
  before { subject.options[:skip_friends] = false }
368
395
 
369
396
  it 'should not include raw_friend_info' do
370
- expect(subject.extra[:raw_friend_info]).to eq([{'foo' => 'bar'}])
397
+ expect(subject.extra[:raw_friend_info]).to eq([{ 'foo' => 'bar' }])
371
398
  end
372
399
  end
373
400
  end
@@ -397,7 +424,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
397
424
  before { subject.options[:skip_image_info] = false }
398
425
 
399
426
  it 'should include raw_image_info' do
400
- expect(subject.extra[:raw_image_info]).to eq({'image' => 'imageData'})
427
+ expect(subject.extra[:raw_image_info]).to eq('image' => 'imageData')
401
428
  end
402
429
  end
403
430
  end
@@ -406,92 +433,92 @@ describe OmniAuth::Strategies::GoogleOauth2 do
406
433
 
407
434
  describe 'populate auth hash urls' do
408
435
  it 'should populate url map in auth hash if link present in raw_info' do
409
- allow(subject).to receive(:raw_info) { {'name' => 'Foo', 'profile' => 'https://plus.google.com/123456'} }
410
- expect(subject.info[:urls]['Google']).to eq('https://plus.google.com/123456')
436
+ allow(subject).to receive(:raw_info) { { 'name' => 'Foo', 'profile' => 'https://plus.google.com/123456' } }
437
+ expect(subject.info[:urls][:google]).to eq('https://plus.google.com/123456')
411
438
  end
412
439
 
413
440
  it 'should not populate url map in auth hash if no link present in raw_info' do
414
- allow(subject).to receive(:raw_info) { {'name' => 'Foo'} }
441
+ allow(subject).to receive(:raw_info) { { 'name' => 'Foo' } }
415
442
  expect(subject.info).not_to have_key(:urls)
416
443
  end
417
444
  end
418
445
 
419
446
  describe 'image options' do
420
- it "should have no image if a picture isn't present" do
421
- @options = {:image_aspect_ratio => 'square'}
422
- allow(subject).to receive(:raw_info) { {'name' => 'User Without Pic'} }
447
+ it 'should have no image if a picture is not present' do
448
+ @options = { image_aspect_ratio: 'square' }
449
+ allow(subject).to receive(:raw_info) { { 'name' => 'User Without Pic' } }
423
450
  expect(subject.info[:image]).to be_nil
424
451
  end
425
452
 
426
- describe "when a picture is returned from google" do
453
+ describe 'when a picture is returned from google' do
427
454
  it 'should return the image with size specified in the `image_size` option' do
428
- @options = {:image_size => 50}
429
- allow(subject).to receive(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
455
+ @options = { image_size: 50 }
456
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
430
457
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50/photo.jpg')
431
458
  end
432
459
 
433
460
  it 'should handle a picture with too many slashes correctly' do
434
- @options = {:image_size => 50}
435
- allow(subject).to receive(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url//photo.jpg'} }
461
+ @options = { image_size: 50 }
462
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url//photo.jpg' } }
436
463
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50/photo.jpg')
437
464
  end
438
465
 
439
466
  it 'should handle a picture with a size query parameter correctly' do
440
- @options = {:image_size => 50}
441
- allow(subject).to receive(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg?sz=50'} }
467
+ @options = { image_size: 50 }
468
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg?sz=50' } }
442
469
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50/photo.jpg')
443
470
  end
444
471
 
445
472
  it 'should handle a picture with a size query parameter and other valid query parameters correctly' do
446
- @options = {:image_size => 50}
447
- allow(subject).to receive(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg?sz=50&hello=true&life=42'} }
473
+ @options = { image_size: 50 }
474
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg?sz=50&hello=true&life=42' } }
448
475
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50/photo.jpg?hello=true&life=42')
449
476
  end
450
477
 
451
478
  it 'should handle a picture with other valid query parameters correctly' do
452
- @options = {:image_size => 50}
453
- allow(subject).to receive(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg?hello=true&life=42'} }
479
+ @options = { image_size: 50 }
480
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg?hello=true&life=42' } }
454
481
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50/photo.jpg?hello=true&life=42')
455
482
  end
456
483
 
457
484
  it 'should return the image with width and height specified in the `image_size` option' do
458
- @options = {:image_size => {:width => 50, :height => 40}}
459
- allow(subject).to receive(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
485
+ @options = { image_size: { width: 50, height: 40 } }
486
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
460
487
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/w50-h40/photo.jpg')
461
488
  end
462
489
 
463
490
  it 'should return square image when `image_aspect_ratio` is specified' do
464
- @options = {:image_aspect_ratio => 'square'}
465
- allow(subject).to receive(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
491
+ @options = { image_aspect_ratio: 'square' }
492
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
466
493
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/c/photo.jpg')
467
494
  end
468
495
 
469
496
  it 'should return square sized image when `image_aspect_ratio` and `image_size` is set' do
470
- @options = {:image_aspect_ratio => 'square', :image_size => 50}
471
- allow(subject).to receive(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
497
+ @options = { image_aspect_ratio: 'square', image_size: 50 }
498
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
472
499
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50-c/photo.jpg')
473
500
  end
474
501
 
475
502
  it 'should return square sized image when `image_aspect_ratio` and `image_size` has height and width' do
476
- @options = {:image_aspect_ratio => 'square', :image_size => {:width => 50, :height => 40}}
477
- allow(subject).to receive(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
503
+ @options = { image_aspect_ratio: 'square', image_size: { width: 50, height: 40 } }
504
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
478
505
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/w50-h40-c/photo.jpg')
479
506
  end
480
507
 
481
508
  it 'should return original image if image url does not end in `photo.jpg`' do
482
- @options = {:image_size => 50}
483
- allow(subject).to receive(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photograph.jpg'} }
509
+ @options = { image_size: 50 }
510
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photograph.jpg' } }
484
511
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/photograph.jpg')
485
512
  end
486
513
  end
487
514
 
488
515
  it 'should return original image if no options are provided' do
489
- allow(subject).to receive(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
516
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
490
517
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/photo.jpg')
491
518
  end
492
519
 
493
520
  it 'should return correct image if google image url has double https' do
494
- allow(subject).to receive(:raw_info) { {'picture' => 'https:https://lh3.googleusercontent.com/url/photo.jpg'} }
521
+ allow(subject).to receive(:raw_info) { { 'picture' => 'https:https://lh3.googleusercontent.com/url/photo.jpg' } }
495
522
  expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/photo.jpg')
496
523
  end
497
524
  end
@@ -505,7 +532,21 @@ describe OmniAuth::Strategies::GoogleOauth2 do
505
532
  auth_code = double(:auth_code)
506
533
  allow(client).to receive(:auth_code).and_return(auth_code)
507
534
  expect(subject).to receive(:client).and_return(client)
508
- expect(auth_code).to receive(:get_token).with('valid_code', { :redirect_uri => 'postmessage'}, {})
535
+ expect(auth_code).to receive(:get_token).with('valid_code', { redirect_uri: 'postmessage' }, {})
536
+
537
+ expect(subject).not_to receive(:orig_build_access_token)
538
+ subject.build_access_token
539
+ end
540
+
541
+ it 'should use a hybrid authorization request_uri if this is an AJAX request (mobile) with a code parameter' do
542
+ allow(request).to receive(:xhr?).and_return(true)
543
+ allow(request).to receive(:params).and_return('code' => 'valid_code', 'redirect_uri' => '')
544
+
545
+ client = double(:client)
546
+ auth_code = double(:auth_code)
547
+ allow(client).to receive(:auth_code).and_return(auth_code)
548
+ expect(subject).to receive(:client).and_return(client)
549
+ expect(auth_code).to receive(:get_token).with('valid_code', { redirect_uri: '' }, {})
509
550
 
510
551
  expect(subject).not_to receive(:orig_build_access_token)
511
552
  subject.build_access_token
@@ -519,7 +560,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
519
560
  auth_code = double(:auth_code)
520
561
  allow(client).to receive(:auth_code).and_return(auth_code)
521
562
  expect(subject).to receive(:client).and_return(client)
522
- expect(auth_code).to receive(:get_token).with('valid_code', { :redirect_uri => 'redirect_uri'}, {})
563
+ expect(auth_code).to receive(:get_token).with('valid_code', { redirect_uri: 'redirect_uri' }, {})
523
564
 
524
565
  expect(subject).not_to receive(:orig_build_access_token)
525
566
  subject.build_access_token
@@ -547,7 +588,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
547
588
  allow(subject).to receive(:callback_url).and_return('redirect_uri_without_query_string')
548
589
 
549
590
  expect(subject).to receive(:client).and_return(client)
550
- expect(auth_code).to receive(:get_token).with('valid_code', { :redirect_uri => 'redirect_uri_without_query_string'}, {})
591
+ expect(auth_code).to receive(:get_token).with('valid_code', { redirect_uri: 'redirect_uri_without_query_string' }, {})
551
592
  subject.build_access_token
552
593
  end
553
594
  end
@@ -557,19 +598,19 @@ describe OmniAuth::Strategies::GoogleOauth2 do
557
598
  subject.options.client_options[:connection_build] = proc do |builder|
558
599
  builder.request :url_encoded
559
600
  builder.adapter :test do |stub|
560
- stub.get('/oauth2/v3/tokeninfo?access_token=valid_access_token') do |env|
561
- [200, {'Content-Type' => 'application/json; charset=UTF-8'}, MultiJson.encode(
562
- :aud => "000000000000.apps.googleusercontent.com",
563
- :sub => "123456789",
564
- :email_verified => "true",
565
- :email => "example@example.com",
566
- :access_type => "offline",
567
- :scope => "profile email",
568
- :expires_in => 436
601
+ stub.get('/oauth2/v3/tokeninfo?access_token=valid_access_token') do
602
+ [200, { 'Content-Type' => 'application/json; charset=UTF-8' }, MultiJson.encode(
603
+ aud: '000000000000.apps.googleusercontent.com',
604
+ sub: '123456789',
605
+ email_verified: 'true',
606
+ email: 'example@example.com',
607
+ access_type: 'offline',
608
+ scope: 'profile email',
609
+ expires_in: 436
569
610
  )]
570
611
  end
571
- stub.get('/oauth2/v3/tokeninfo?access_token=invalid_access_token') do |env|
572
- [400, {'Content-Type' => 'application/json; charset=UTF-8'}, MultiJson.encode(:error_description => 'Invalid Value')]
612
+ stub.get('/oauth2/v3/tokeninfo?access_token=invalid_access_token') do
613
+ [400, { 'Content-Type' => 'application/json; charset=UTF-8' }, MultiJson.encode(error_description: 'Invalid Value')]
573
614
  end
574
615
  end
575
616
  end
@@ -580,14 +621,19 @@ describe OmniAuth::Strategies::GoogleOauth2 do
580
621
  expect(subject.send(:verify_token, 'valid_access_token')).to eq(true)
581
622
  end
582
623
 
624
+ it 'should verify token if access_token is valid and app_id authorized' do
625
+ subject.options.authorized_client_ids = ['000000000000.apps.googleusercontent.com']
626
+ expect(subject.send(:verify_token, 'valid_access_token')).to eq(true)
627
+ end
628
+
583
629
  it 'should not verify token if access_token is valid but app_id is false' do
584
630
  expect(subject.send(:verify_token, 'valid_access_token')).to eq(false)
585
631
  end
586
632
 
587
633
  it 'should raise error if access_token is invalid' do
588
- expect {
634
+ expect do
589
635
  subject.send(:verify_token, 'invalid_access_token')
590
- }.to raise_error(OAuth2::Error)
636
+ end.to raise_error(OAuth2::Error)
591
637
  end
592
638
  end
593
639
 
@@ -596,9 +642,9 @@ describe OmniAuth::Strategies::GoogleOauth2 do
596
642
  OAuth2::Client.new('abc', 'def') do |builder|
597
643
  builder.request :url_encoded
598
644
  builder.adapter :test do |stub|
599
- stub.get('/plus/v1/people/me/openIdConnect') do |env|
600
- [200, {'Content-Type' => 'application/json; charset=UTF-8'}, MultiJson.encode(
601
- :hd => 'example.com',
645
+ stub.get('/plus/v1/people/me/openIdConnect') do
646
+ [200, { 'Content-Type' => 'application/json; charset=UTF-8' }, MultiJson.encode(
647
+ hd: 'example.com'
602
648
  )]
603
649
  end
604
650
  end
@@ -606,6 +652,36 @@ describe OmniAuth::Strategies::GoogleOauth2 do
606
652
  end
607
653
  let(:access_token) { OAuth2::AccessToken.from_hash(client, {}) }
608
654
 
655
+ context 'when domain is nil' do
656
+ let(:client) do
657
+ OAuth2::Client.new('abc', 'def') do |builder|
658
+ builder.request :url_encoded
659
+ builder.adapter :test do |stub|
660
+ stub.get('/plus/v1/people/me/openIdConnect') do
661
+ [200, { 'Content-Type' => 'application/json; charset=UTF-8' }, MultiJson.encode({})]
662
+ end
663
+ end
664
+ end
665
+ end
666
+
667
+ it 'should verify hd if options hd is set and correct' do
668
+ subject.options.hd = nil
669
+ expect(subject.send(:verify_hd, access_token)).to eq(true)
670
+ end
671
+
672
+ it 'should verify hd if options hd is set as an array and is correct' do
673
+ subject.options.hd = ['example.com', 'example.co', nil]
674
+ expect(subject.send(:verify_hd, access_token)).to eq(true)
675
+ end
676
+
677
+ it 'should raise an exception if nil is not included' do
678
+ subject.options.hd = ['example.com', 'example.co']
679
+ expect do
680
+ subject.send(:verify_hd, access_token)
681
+ end.to raise_error(OmniAuth::Strategies::OAuth2::CallbackError)
682
+ end
683
+ end
684
+
609
685
  it 'should verify hd if options hd is not set' do
610
686
  expect(subject.send(:verify_hd, access_token)).to eq(true)
611
687
  end
@@ -616,22 +692,32 @@ describe OmniAuth::Strategies::GoogleOauth2 do
616
692
  end
617
693
 
618
694
  it 'should verify hd if options hd is set as an array and is correct' do
619
- subject.options.hd = ['example.com', 'example.co']
695
+ subject.options.hd = ['example.com', 'example.co', nil]
696
+ expect(subject.send(:verify_hd, access_token)).to eq(true)
697
+ end
698
+
699
+ it 'should verify hd if options hd is set as an Proc and is correct' do
700
+ subject.options.hd = proc { 'example.com' }
701
+ expect(subject.send(:verify_hd, access_token)).to eq(true)
702
+ end
703
+
704
+ it 'should verify hd if options hd is set as an Proc returning an array and is correct' do
705
+ subject.options.hd = proc { ['example.com', 'example.co'] }
620
706
  expect(subject.send(:verify_hd, access_token)).to eq(true)
621
707
  end
622
708
 
623
709
  it 'should raise error if options hd is set and wrong' do
624
710
  subject.options.hd = 'invalid.com'
625
- expect {
711
+ expect do
626
712
  subject.send(:verify_hd, access_token)
627
- }.to raise_error(OmniAuth::Strategies::GoogleOauth2::CallbackError)
713
+ end.to raise_error(OmniAuth::Strategies::GoogleOauth2::CallbackError)
628
714
  end
629
715
 
630
716
  it 'should raise error if options hd is set as an array and is not correct' do
631
717
  subject.options.hd = ['invalid.com', 'invalid.co']
632
- expect {
718
+ expect do
633
719
  subject.send(:verify_hd, access_token)
634
- }.to raise_error(OmniAuth::Strategies::GoogleOauth2::CallbackError)
720
+ end.to raise_error(OmniAuth::Strategies::GoogleOauth2::CallbackError)
635
721
  end
636
722
  end
637
723
  end