omniauth-google-oauth2 0.1.19 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -2
- data/README.md +43 -2
- data/Rakefile +2 -2
- data/examples/config.ru +5 -5
- data/examples/omni_auth.rb +30 -4
- data/lib/omniauth-google-oauth2.rb +1 -1
- data/lib/omniauth/google_oauth2.rb +1 -1
- data/lib/omniauth/google_oauth2/version.rb +2 -2
- data/lib/omniauth/strategies/google_oauth2.rb +25 -28
- data/omniauth-contrib.gemspec +4 -4
- data/spec/omniauth/strategies/google_oauth2_spec.rb +197 -103
- data/spec/spec_helper.rb +2 -7
- metadata +7 -11
- data/spec/support/shared_examples.rb +0 -37
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -18,7 +18,7 @@ Then `bundle install`.
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
Here's an example
|
21
|
+
Here's an example for adding the middleware to a Rails app in `config/initializers/omniauth.rb`:
|
22
22
|
|
23
23
|
```ruby
|
24
24
|
Rails.application.config.middleware.use OmniAuth::Builder do
|
@@ -28,6 +28,8 @@ end
|
|
28
28
|
|
29
29
|
You can now access the OmniAuth Google OAuth2 URL: `/auth/google_oauth2`
|
30
30
|
|
31
|
+
Fore more examples please check out `examples/omni_auth.rb`
|
32
|
+
|
31
33
|
## Configuration
|
32
34
|
|
33
35
|
You can configure several options, which you pass in to the `provider` method via a hash:
|
@@ -106,9 +108,48 @@ Here's an example of an authentication hash available in the callback by accessi
|
|
106
108
|
}
|
107
109
|
```
|
108
110
|
|
111
|
+
### Devise
|
112
|
+
|
113
|
+
For devise, you should also make sure you have an OmniAuth callback controller setup
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
117
|
+
def google_oauth2
|
118
|
+
# You need to implement the method below in your model (e.g. app/models/user.rb)
|
119
|
+
@user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user)
|
120
|
+
|
121
|
+
if @user.persisted?
|
122
|
+
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
|
123
|
+
sign_in_and_redirect @user, :event => :authentication
|
124
|
+
else
|
125
|
+
session["devise.google_data"] = request.env["omniauth.auth"]
|
126
|
+
redirect_to new_user_registration_url
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
and bind to or create the user
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
def self.find_for_google_oauth2(access_token, signed_in_resource=nil)
|
136
|
+
data = access_token.info
|
137
|
+
user = User.where(:email => data["email"]).first
|
138
|
+
|
139
|
+
unless user
|
140
|
+
user = User.create(name: data["name"],
|
141
|
+
email: data["email"],
|
142
|
+
password: Devise.friendly_token[0,20]
|
143
|
+
)
|
144
|
+
end
|
145
|
+
user
|
146
|
+
end
|
147
|
+
```
|
148
|
+
Detailed example at https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview#google-oauth2-example
|
149
|
+
|
109
150
|
## License
|
110
151
|
|
111
|
-
Copyright (c)
|
152
|
+
Copyright (c) 2013 by Josh Ellithorpe
|
112
153
|
|
113
154
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
114
155
|
|
data/Rakefile
CHANGED
data/examples/config.ru
CHANGED
@@ -10,6 +10,9 @@ require 'omniauth-google-oauth2'
|
|
10
10
|
|
11
11
|
# Do not use for production code.
|
12
12
|
# This is only to make setup easier when running through the sample.
|
13
|
+
#
|
14
|
+
# If you do have issues with certs in production code, this could help:
|
15
|
+
# http://railsapps.github.io/openssl-certificate-verify-failed.html
|
13
16
|
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
|
14
17
|
|
15
18
|
class App < Sinatra::Base
|
@@ -25,7 +28,7 @@ class App < Sinatra::Base
|
|
25
28
|
content_type 'text/plain'
|
26
29
|
request.env['omniauth.auth'].to_hash.inspect rescue "No Data"
|
27
30
|
end
|
28
|
-
|
31
|
+
|
29
32
|
get '/auth/failure' do
|
30
33
|
content_type 'text/plain'
|
31
34
|
request.env['omniauth.auth'].to_hash.inspect rescue "No Data"
|
@@ -35,11 +38,8 @@ end
|
|
35
38
|
use Rack::Session::Cookie, :secret => ENV['RACK_COOKIE_SECRET']
|
36
39
|
|
37
40
|
use OmniAuth::Builder do
|
38
|
-
#
|
41
|
+
# For additional provider examples please look at 'omni_auth.rb'
|
39
42
|
provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {}
|
40
|
-
|
41
|
-
# Custom scope supporting youtube
|
42
|
-
# provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {:scope => 'http://gdata.youtube.com,userinfo.email,userinfo.profile,plus.me', :access_type => 'online', :approval_prompt => ''}
|
43
43
|
end
|
44
44
|
|
45
45
|
run App.new
|
data/examples/omni_auth.rb
CHANGED
@@ -1,6 +1,32 @@
|
|
1
|
+
# Google's OAuth2 docs. Make sure you are familiar with all the options
|
2
|
+
# before attempting to configure this gem.
|
3
|
+
# https://developers.google.com/accounts/docs/OAuth2Login
|
4
|
+
|
1
5
|
Rails.application.config.middleware.use OmniAuth::Builder do
|
2
|
-
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {
|
6
|
+
# Default usage, this will give you offline access and a refresh token
|
7
|
+
# using default scopes 'userinfo.email' and 'userinfo.profile'
|
8
|
+
#
|
9
|
+
provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {}
|
10
|
+
|
11
|
+
# Manual setup for offline access with a refresh token.
|
12
|
+
# The prompt must be set to 'consent'
|
13
|
+
#
|
14
|
+
# provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {
|
15
|
+
# :access_type => 'offline',
|
16
|
+
# :prompt => 'consent'
|
17
|
+
# }
|
18
|
+
|
19
|
+
# Custom scope supporting youtube. If you are customizing scopes, remember
|
20
|
+
# to include the default scopes 'userinfo.email' and 'userinfo.profile'
|
21
|
+
#
|
22
|
+
# provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {
|
23
|
+
# :scope => 'http://gdata.youtube.com,userinfo.email,userinfo.profile,plus.me'
|
24
|
+
# }
|
25
|
+
|
26
|
+
# Custom scope for users only using Google for account creation/auth and do not require a refresh token.
|
27
|
+
#
|
28
|
+
# provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {
|
29
|
+
# :access_type => 'online',
|
30
|
+
# :prompt => ''
|
31
|
+
# }
|
6
32
|
end
|
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require File.join('omniauth', 'google_oauth2')
|
@@ -1 +1 @@
|
|
1
|
-
require 'omniauth
|
1
|
+
require File.join('omniauth', 'strategies', 'google_oauth2')
|
@@ -3,12 +3,12 @@ require 'omniauth/strategies/oauth2'
|
|
3
3
|
module OmniAuth
|
4
4
|
module Strategies
|
5
5
|
class GoogleOauth2 < OmniAuth::Strategies::OAuth2
|
6
|
-
|
6
|
+
BASE_SCOPE_URL = "https://www.googleapis.com/auth/"
|
7
7
|
DEFAULT_SCOPE = "userinfo.email,userinfo.profile"
|
8
8
|
|
9
9
|
option :name, 'google_oauth2'
|
10
10
|
|
11
|
-
option :authorize_options, [:access_type, :hd, :
|
11
|
+
option :authorize_options, [:access_type, :hd, :login_hint, :prompt, :scope, :state]
|
12
12
|
|
13
13
|
option :client_options, {
|
14
14
|
:site => 'https://accounts.google.com',
|
@@ -17,21 +17,19 @@ module OmniAuth
|
|
17
17
|
}
|
18
18
|
|
19
19
|
def authorize_params
|
20
|
-
base_scope_url = "https://www.googleapis.com/auth/"
|
21
20
|
super.tap do |params|
|
22
|
-
# Read the params if passed directly to omniauth_authorize_path
|
23
21
|
options[:authorize_options].each do |k|
|
24
22
|
params[k] = request.params[k.to_s] unless [nil, ''].include?(request.params[k.to_s])
|
25
23
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
|
25
|
+
raw_scope = params[:scope] || DEFAULT_SCOPE
|
26
|
+
scope_list = raw_scope.split(" ").map {|item| item.split(",")}.flatten
|
27
|
+
scope_list.map! { |s| s =~ /^https?:\/\// ? s : "#{BASE_SCOPE_URL}#{s}" }
|
28
|
+
params[:scope] = scope_list.join(" ")
|
29
|
+
|
31
30
|
params[:access_type] = 'offline' if params[:access_type].nil?
|
32
|
-
|
33
|
-
|
34
|
-
session['omniauth.state'] = params[:state] if request.params['state']
|
31
|
+
|
32
|
+
session['omniauth.state'] = params[:state] if params['state']
|
35
33
|
end
|
36
34
|
end
|
37
35
|
|
@@ -60,24 +58,22 @@ module OmniAuth
|
|
60
58
|
@raw_info ||= access_token.get('https://www.googleapis.com/oauth2/v1/userinfo').parsed
|
61
59
|
end
|
62
60
|
|
63
|
-
def
|
64
|
-
if
|
65
|
-
!request.params['access_token'].nil? &&
|
66
|
-
verify_token(request.params['id_token'], request.params['access_token'])
|
61
|
+
def custom_build_access_token
|
62
|
+
if verify_token(request.params['id_token'], request.params['access_token'])
|
67
63
|
::OAuth2::AccessToken.from_hash(client, request.params.dup)
|
68
64
|
else
|
69
|
-
|
65
|
+
orig_build_access_token
|
70
66
|
end
|
71
67
|
end
|
72
|
-
alias_method :
|
73
|
-
alias :build_access_token :
|
68
|
+
alias_method :orig_build_access_token, :build_access_token
|
69
|
+
alias :build_access_token :custom_build_access_token
|
74
70
|
|
75
71
|
private
|
76
72
|
|
77
73
|
def prune!(hash)
|
78
|
-
hash.delete_if do |_,
|
79
|
-
prune!(
|
80
|
-
|
74
|
+
hash.delete_if do |_, v|
|
75
|
+
prune!(v) if v.is_a?(Hash)
|
76
|
+
v.nil? || (v.respond_to?(:empty?) && v.empty?)
|
81
77
|
end
|
82
78
|
end
|
83
79
|
|
@@ -99,17 +95,18 @@ module OmniAuth
|
|
99
95
|
image_params << 'c' if options[:image_aspect_ratio] == 'square'
|
100
96
|
|
101
97
|
params_index = original_url.index('/photo.jpg')
|
102
|
-
original_url.insert(params_index, '/'+image_params.join('-'))
|
98
|
+
original_url.insert(params_index, ('/' + image_params.join('-')))
|
103
99
|
end
|
104
100
|
|
105
101
|
def verify_token(id_token, access_token)
|
106
|
-
|
107
|
-
|
108
|
-
raw_response = client.request(:get, 'https://www.googleapis.com/oauth2/v2/tokeninfo',
|
109
|
-
|
102
|
+
return false unless (id_token && access_token)
|
103
|
+
|
104
|
+
raw_response = client.request(:get, 'https://www.googleapis.com/oauth2/v2/tokeninfo', :params => {
|
105
|
+
:id_token => id_token,
|
106
|
+
:access_token => access_token
|
107
|
+
}).parsed
|
110
108
|
raw_response['issued_to'] == options.client_id
|
111
109
|
end
|
112
|
-
|
113
110
|
end
|
114
111
|
end
|
115
112
|
end
|
data/omniauth-contrib.gemspec
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
require File.expand_path('
|
2
|
+
require File.expand_path(File.join('..', 'lib', 'omniauth', 'google_oauth2', 'version'), __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.add_dependency 'omniauth', '~> 1.0'
|
6
6
|
|
7
7
|
gem.authors = ["Josh Ellithorpe", "Yury Korolev"]
|
8
8
|
gem.email = ["quest@mac.com"]
|
9
|
-
gem.description = %q{A Google
|
10
|
-
gem.summary = %q{A Google
|
9
|
+
gem.description = %q{A Google OAuth2 strategy for OmniAuth 1.x}
|
10
|
+
gem.summary = %q{A Google OAuth2 strategy for OmniAuth 1.x}
|
11
11
|
gem.homepage = ""
|
12
12
|
|
13
13
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
14
14
|
gem.files = `git ls-files`.split("\n")
|
15
|
-
gem.test_files = `git ls-files -- {
|
15
|
+
gem.test_files = `git ls-files -- {spec}/*`.split("\n")
|
16
16
|
gem.name = "omniauth-google-oauth2"
|
17
17
|
gem.require_paths = ["lib"]
|
18
18
|
gem.version = OmniAuth::GoogleOauth2::VERSION
|
@@ -2,107 +2,146 @@ require 'spec_helper'
|
|
2
2
|
require 'omniauth-google-oauth2'
|
3
3
|
|
4
4
|
describe OmniAuth::Strategies::GoogleOauth2 do
|
5
|
-
|
5
|
+
let(:request) { double('Request', :params => {}, :cookies => {}, :env => {}) }
|
6
|
+
let(:app) {
|
7
|
+
lambda do
|
8
|
+
[200, {}, ["Hello."]]
|
9
|
+
end
|
10
|
+
}
|
6
11
|
|
7
|
-
|
12
|
+
subject do
|
13
|
+
OmniAuth::Strategies::GoogleOauth2.new(app, 'appid', 'secret', @options || {}).tap do |strategy|
|
14
|
+
strategy.stub(:request) {
|
15
|
+
request
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
before do
|
8
21
|
OmniAuth.config.test_mode = true
|
9
|
-
@request = double('Request')
|
10
|
-
@request.stub(:params) { {} }
|
11
|
-
@request.stub(:cookies) { {} }
|
12
|
-
@request.stub(:env) { {} }
|
13
22
|
end
|
14
23
|
|
15
24
|
after do
|
16
25
|
OmniAuth.config.test_mode = false
|
17
26
|
end
|
18
27
|
|
19
|
-
|
20
|
-
|
21
|
-
OmniAuth::Strategies::GoogleOauth2.new(app, *args).tap do |strategy|
|
22
|
-
strategy.stub(:request) { @request }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
it_should_behave_like 'an oauth2 strategy'
|
27
|
-
|
28
|
-
describe '#client' do
|
29
|
-
it 'has correct Google site' do
|
28
|
+
describe '#client_options' do
|
29
|
+
it 'has correct site' do
|
30
30
|
subject.client.site.should eq('https://accounts.google.com')
|
31
31
|
end
|
32
32
|
|
33
|
-
it 'has correct
|
33
|
+
it 'has correct authorize_url' do
|
34
34
|
subject.client.options[:authorize_url].should eq('/o/oauth2/auth')
|
35
35
|
end
|
36
36
|
|
37
|
-
it 'has correct
|
37
|
+
it 'has correct token_url' do
|
38
38
|
subject.client.options[:token_url].should eq('/o/oauth2/token')
|
39
39
|
end
|
40
|
-
end
|
41
40
|
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
describe "overrides" do
|
42
|
+
it 'should allow overriding the site' do
|
43
|
+
@options = {:client_options => {'site' => 'https://example.com'}}
|
44
|
+
subject.client.site.should == 'https://example.com'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should allow overriding the authorize_url' do
|
48
|
+
@options = {:client_options => {'authorize_url' => 'https://example.com'}}
|
49
|
+
subject.client.options[:authorize_url].should == 'https://example.com'
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should allow overriding the token_url' do
|
53
|
+
@options = {:client_options => {'token_url' => 'https://example.com'}}
|
54
|
+
subject.client.options[:token_url].should == 'https://example.com'
|
55
|
+
end
|
45
56
|
end
|
46
57
|
end
|
47
58
|
|
48
|
-
describe
|
49
|
-
|
50
|
-
it "should
|
51
|
-
@options = {
|
52
|
-
subject.
|
53
|
-
|
59
|
+
describe "#authorize_options" do
|
60
|
+
[:access_type, :hd, :login_hint, :prompt, :scope, :state].each do |k|
|
61
|
+
it "should support #{k}" do
|
62
|
+
@options = {k => 'http://someval'}
|
63
|
+
subject.authorize_params[k.to_s].should eq('http://someval')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'access_type' do
|
68
|
+
it 'should default to "offline"' do
|
69
|
+
@options = {}
|
70
|
+
subject.authorize_params['access_type'].should eq('offline')
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should set the access_type parameter if present' do
|
74
|
+
@options = {:access_type => 'online'}
|
75
|
+
subject.authorize_params['access_type'].should eq('online')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'hd' do
|
80
|
+
it "should default to nil" do
|
81
|
+
subject.authorize_params['hd'].should eq(nil)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should set the hd (hosted domain) parameter if present' do
|
85
|
+
@options = {:hd => 'example.com'}
|
86
|
+
subject.authorize_params['hd'].should eq('example.com')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'login_hint' do
|
91
|
+
it "should default to nil" do
|
92
|
+
subject.authorize_params['login_hint'].should eq(nil)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should set the login_hint parameter if present' do
|
96
|
+
@options = {:login_hint => 'john@example.com'}
|
97
|
+
subject.authorize_params['login_hint'].should eq('john@example.com')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'prompt' do
|
102
|
+
it "should default to nil" do
|
103
|
+
subject.authorize_params['prompt'].should eq(nil)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should set the prompt parameter if present' do
|
107
|
+
@options = {:prompt => 'consent select_account'}
|
108
|
+
subject.authorize_params['prompt'].should eq('consent select_account')
|
54
109
|
end
|
55
110
|
end
|
56
111
|
|
57
112
|
describe 'scope' do
|
58
113
|
it 'should expand scope shortcuts' do
|
59
|
-
@options = {
|
114
|
+
@options = {:scope => 'userinfo.email'}
|
60
115
|
subject.authorize_params['scope'].should eq('https://www.googleapis.com/auth/userinfo.email')
|
61
116
|
end
|
62
117
|
|
63
118
|
it 'should leave full scopes as is' do
|
64
|
-
@options = {
|
119
|
+
@options = {:scope => 'https://www.googleapis.com/auth/userinfo.profile'}
|
65
120
|
subject.authorize_params['scope'].should eq('https://www.googleapis.com/auth/userinfo.profile')
|
66
121
|
end
|
67
122
|
|
68
123
|
it 'should join scopes' do
|
69
|
-
@options = {
|
124
|
+
@options = {:scope => 'userinfo.profile,userinfo.email'}
|
70
125
|
subject.authorize_params['scope'].should eq('https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email')
|
71
126
|
end
|
72
127
|
|
73
128
|
it 'should deal with whitespace when joining scopes' do
|
74
|
-
@options = {
|
129
|
+
@options = {:scope => 'userinfo.profile, userinfo.email'}
|
75
130
|
subject.authorize_params['scope'].should eq('https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email')
|
76
131
|
end
|
77
132
|
|
78
133
|
it 'should set default scope to userinfo.email,userinfo.profile' do
|
79
|
-
@options = { :authorize_options => [:scope]}
|
80
134
|
subject.authorize_params['scope'].should eq('https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile')
|
81
135
|
end
|
82
136
|
|
83
|
-
it 'should
|
84
|
-
@options = {:scope => '
|
85
|
-
subject.
|
86
|
-
subject.authorize_params['scope'].should eq('https://www.googleapis.com/auth/userinfo.email')
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
describe 'prompt' do
|
91
|
-
it 'should set the prompt parameter if present' do
|
92
|
-
@options = {:prompt => 'consent select_account'}
|
93
|
-
subject.authorize_params['prompt'].should eq('consent select_account')
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
describe 'access_type' do
|
98
|
-
it 'should set the access_type parameter if present' do
|
99
|
-
@options = {:access_type => 'type'}
|
100
|
-
subject.authorize_params['access_type'].should eq('type')
|
137
|
+
it 'should support space delimited scopes' do
|
138
|
+
@options = {:scope => 'userinfo.profile userinfo.email'}
|
139
|
+
subject.authorize_params['scope'].should eq('https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email')
|
101
140
|
end
|
102
141
|
|
103
|
-
it
|
104
|
-
@options = {}
|
105
|
-
subject.authorize_params['
|
142
|
+
it "should support extremely badly formed scopes" do
|
143
|
+
@options = {:scope => 'userinfo.profile userinfo.email,foo,steve yeah http://example.com'}
|
144
|
+
subject.authorize_params['scope'].should eq('https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/foo https://www.googleapis.com/auth/steve https://www.googleapis.com/auth/yeah http://example.com')
|
106
145
|
end
|
107
146
|
end
|
108
147
|
|
@@ -114,96 +153,151 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
114
153
|
end
|
115
154
|
|
116
155
|
it 'should set the omniauth.state dynamically' do
|
117
|
-
subject.stub(:request) { double('Request', {:params => {
|
156
|
+
subject.stub(:request) { double('Request', {:params => {'state' => 'some_state'}, :env => {}}) }
|
118
157
|
subject.authorize_params['state'].should eq('some_state')
|
119
158
|
subject.session['omniauth.state'].should eq('some_state')
|
120
159
|
end
|
121
160
|
end
|
122
161
|
|
123
|
-
describe
|
124
|
-
it 'should
|
125
|
-
@options = {:
|
126
|
-
subject.authorize_params['
|
162
|
+
describe "overrides" do
|
163
|
+
it 'should include top-level options that are marked as :authorize_options' do
|
164
|
+
@options = {:authorize_options => [:scope, :foo, :request_visible_actions], :scope => 'http://bar', :foo => 'baz', :hd => "wow", :request_visible_actions => "something"}
|
165
|
+
subject.authorize_params['scope'].should eq('http://bar')
|
166
|
+
subject.authorize_params['foo'].should eq('baz')
|
167
|
+
subject.authorize_params['hd'].should eq(nil)
|
168
|
+
subject.authorize_params['request_visible_actions'].should eq('something')
|
127
169
|
end
|
128
|
-
end
|
129
170
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
171
|
+
describe "request overrides" do
|
172
|
+
[:access_type, :hd, :login_hint, :prompt, :scope, :state].each do |k|
|
173
|
+
context "authorize option #{k}" do
|
174
|
+
let(:request) { double('Request', :params => {k.to_s => 'http://example.com'}, :cookies => {}, :env => {}) }
|
175
|
+
|
176
|
+
it "should set the #{k} authorize option dynamically in the request" do
|
177
|
+
@options = {k => ''}
|
178
|
+
subject.authorize_params[k.to_s].should eq('http://example.com')
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe "custom authorize_options" do
|
184
|
+
let(:request) { double('Request', :params => {'foo' => 'something'}, :cookies => {}, :env => {}) }
|
185
|
+
|
186
|
+
it "should support request overrides from custom authorize_options" do
|
187
|
+
@options = {:authorize_options => [:foo], :foo => ''}
|
188
|
+
subject.authorize_params['foo'].should eq('something')
|
189
|
+
end
|
190
|
+
end
|
134
191
|
end
|
135
192
|
end
|
136
193
|
end
|
137
194
|
|
195
|
+
describe '#authorize_params' do
|
196
|
+
it 'should include any authorize params passed in the :authorize_params option' do
|
197
|
+
@options = {:authorize_params => {:request_visible_actions => 'something', :foo => 'bar', :baz => 'zip'}, :hd => 'wow', :bad => 'not_included'}
|
198
|
+
subject.authorize_params['request_visible_actions'].should eq('something')
|
199
|
+
subject.authorize_params['foo'].should eq('bar')
|
200
|
+
subject.authorize_params['baz'].should eq('zip')
|
201
|
+
subject.authorize_params['hd'].should eq('wow')
|
202
|
+
subject.authorize_params['bad'].should eq(nil)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe '#token_params' do
|
207
|
+
it 'should include any token params passed in the :token_params option' do
|
208
|
+
@options = {:token_params => {:foo => 'bar', :baz => 'zip'}}
|
209
|
+
subject.token_params['foo'].should eq('bar')
|
210
|
+
subject.token_params['baz'].should eq('zip')
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe "#token_options" do
|
215
|
+
it 'should include top-level options that are marked as :token_options' do
|
216
|
+
@options = {:token_options => [:scope, :foo], :scope => 'bar', :foo => 'baz', :bad => 'not_included'}
|
217
|
+
subject.token_params['scope'].should eq('bar')
|
218
|
+
subject.token_params['foo'].should eq('baz')
|
219
|
+
subject.token_params['bad'].should eq(nil)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe '#callback_path' do
|
224
|
+
it 'has the correct callback path' do
|
225
|
+
subject.callback_path.should eq('/auth/google_oauth2/callback')
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
138
229
|
describe 'raw info' do
|
139
230
|
it 'should include raw_info in extras hash by default' do
|
140
|
-
subject.stub(:raw_info) { {
|
141
|
-
subject.extra[:raw_info].should eq({
|
231
|
+
subject.stub(:raw_info) { {:foo => 'bar'} }
|
232
|
+
subject.extra[:raw_info].should eq({:foo => 'bar'})
|
142
233
|
end
|
143
234
|
|
144
235
|
it 'should not include raw_info in extras hash when skip_info is specified' do
|
145
|
-
@options = {
|
236
|
+
@options = {:skip_info => true}
|
146
237
|
subject.extra.should_not have_key(:raw_info)
|
147
238
|
end
|
148
239
|
end
|
149
240
|
|
150
|
-
describe 'populate auth hash
|
241
|
+
describe 'populate auth hash urls' do
|
151
242
|
it 'should populate url map in auth hash if link present in raw_info' do
|
152
|
-
subject.stub(:raw_info) { {
|
243
|
+
subject.stub(:raw_info) { {'name' => 'Foo', 'link' => 'https://plus.google.com/123456'} }
|
153
244
|
subject.info[:urls]['Google'].should eq('https://plus.google.com/123456')
|
154
245
|
end
|
155
246
|
|
156
247
|
it 'should not populate url map in auth hash if no link present in raw_info' do
|
157
|
-
subject.stub(:raw_info) { {
|
248
|
+
subject.stub(:raw_info) { {'name' => 'Foo'} }
|
158
249
|
subject.info.should_not have_key(:urls)
|
159
250
|
end
|
160
251
|
end
|
161
252
|
|
162
253
|
describe 'image options' do
|
163
|
-
it
|
164
|
-
@options = {
|
165
|
-
subject.stub(:raw_info) { {
|
166
|
-
|
167
|
-
main_url.should eq('https://lh3.googleusercontent.com/url')
|
168
|
-
image_params.should eq('s50')
|
254
|
+
it "should have no image if a picture isn't present" do
|
255
|
+
@options = {:image_aspect_ratio => 'square'}
|
256
|
+
subject.stub(:raw_info) { {'name' => 'User Without Pic'} }
|
257
|
+
subject.info[:image].should be_nil
|
169
258
|
end
|
170
259
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
result[element.slice!(0)] = element
|
177
|
-
result
|
260
|
+
describe "when a picture is returned from google" do
|
261
|
+
it 'should return the image with size specified in the `image_size` option' do
|
262
|
+
@options = {:image_size => 50}
|
263
|
+
subject.stub(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
|
264
|
+
subject.info[:image].should eq('https://lh3.googleusercontent.com/url/s50/photo.jpg')
|
178
265
|
end
|
179
|
-
main_url.should eq('https://lh3.googleusercontent.com/url')
|
180
|
-
image_params['w'].should eq('50')
|
181
|
-
image_params['h'].should eq('50')
|
182
|
-
end
|
183
266
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
image_params.should eq('c')
|
190
|
-
end
|
267
|
+
it 'should return the image with width and height specified in the `image_size` option' do
|
268
|
+
@options = {:image_size => {:width => 50, :height => 40}}
|
269
|
+
subject.stub(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
|
270
|
+
subject.info[:image].should eq('https://lh3.googleusercontent.com/url/w50-h40/photo.jpg')
|
271
|
+
end
|
191
272
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
273
|
+
it 'should return square image when `image_aspect_ratio` is specified' do
|
274
|
+
@options = {:image_aspect_ratio => 'square'}
|
275
|
+
subject.stub(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
|
276
|
+
subject.info[:image].should eq('https://lh3.googleusercontent.com/url/c/photo.jpg')
|
277
|
+
end
|
278
|
+
|
279
|
+
it 'should return square sized image when `image_aspect_ratio` and `image_size` is set' do
|
280
|
+
@options = {:image_aspect_ratio => 'square', :image_size => 50}
|
281
|
+
subject.stub(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
|
282
|
+
subject.info[:image].should eq('https://lh3.googleusercontent.com/url/s50-c/photo.jpg')
|
283
|
+
end
|
284
|
+
|
285
|
+
it 'should return square sized image when `image_aspect_ratio` and `image_size` has height and width' do
|
286
|
+
@options = {:image_aspect_ratio => 'square', :image_size => {:width => 50, :height => 40}}
|
287
|
+
subject.stub(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
|
288
|
+
subject.info[:image].should eq('https://lh3.googleusercontent.com/url/w50-h40-c/photo.jpg')
|
289
|
+
end
|
196
290
|
end
|
197
291
|
|
198
292
|
it 'should return original image if no options are provided' do
|
199
|
-
subject.stub(:raw_info) { {
|
293
|
+
subject.stub(:raw_info) { {'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg'} }
|
200
294
|
subject.info[:image].should eq('https://lh3.googleusercontent.com/url/photo.jpg')
|
201
295
|
end
|
202
296
|
end
|
203
297
|
|
204
298
|
describe 'build_access_token' do
|
205
299
|
it 'should read access_token from hash' do
|
206
|
-
|
300
|
+
request.stub(:params).and_return('id_token' => 'valid_id_token', 'access_token' => 'valid_access_token')
|
207
301
|
subject.should_receive(:verify_token).with('valid_id_token', 'valid_access_token').and_return true
|
208
302
|
subject.should_receive(:client).and_return(:client)
|
209
303
|
|
@@ -214,7 +308,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
214
308
|
end
|
215
309
|
|
216
310
|
it 'should call super' do
|
217
|
-
subject.should_receive(:
|
311
|
+
subject.should_receive(:orig_build_access_token)
|
218
312
|
subject.build_access_token
|
219
313
|
end
|
220
314
|
end
|
@@ -244,7 +338,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do
|
|
244
338
|
end
|
245
339
|
|
246
340
|
it 'should verify token if access_token and id_token are valid and app_id equals' do
|
247
|
-
subject.options.client_id =
|
341
|
+
subject.options.client_id = '000000000000.apps.googleusercontent.com'
|
248
342
|
subject.send(:verify_token, 'valid_id_token', 'valid_access_token').should == true
|
249
343
|
end
|
250
344
|
|
data/spec/spec_helper.rb
CHANGED
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: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-06-
|
13
|
+
date: 2013-06-26 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: omniauth
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
- - ! '>='
|
77
77
|
- !ruby/object:Gem::Version
|
78
78
|
version: '0'
|
79
|
-
description: A Google
|
79
|
+
description: A Google OAuth2 strategy for OmniAuth 1.x
|
80
80
|
email:
|
81
81
|
- quest@mac.com
|
82
82
|
executables: []
|
@@ -97,7 +97,6 @@ files:
|
|
97
97
|
- omniauth-contrib.gemspec
|
98
98
|
- spec/omniauth/strategies/google_oauth2_spec.rb
|
99
99
|
- spec/spec_helper.rb
|
100
|
-
- spec/support/shared_examples.rb
|
101
100
|
homepage: ''
|
102
101
|
licenses: []
|
103
102
|
post_install_message:
|
@@ -112,7 +111,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
112
111
|
version: '0'
|
113
112
|
segments:
|
114
113
|
- 0
|
115
|
-
hash:
|
114
|
+
hash: 3419223679075282688
|
116
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
116
|
none: false
|
118
117
|
requirements:
|
@@ -121,14 +120,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
120
|
version: '0'
|
122
121
|
segments:
|
123
122
|
- 0
|
124
|
-
hash:
|
123
|
+
hash: 3419223679075282688
|
125
124
|
requirements: []
|
126
125
|
rubyforge_project:
|
127
126
|
rubygems_version: 1.8.25
|
128
127
|
signing_key:
|
129
128
|
specification_version: 3
|
130
|
-
summary: A Google
|
131
|
-
test_files:
|
132
|
-
- spec/omniauth/strategies/google_oauth2_spec.rb
|
133
|
-
- spec/spec_helper.rb
|
134
|
-
- spec/support/shared_examples.rb
|
129
|
+
summary: A Google OAuth2 strategy for OmniAuth 1.x
|
130
|
+
test_files: []
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# NOTE it would be useful if this lived in omniauth-oauth2 eventually
|
2
|
-
shared_examples 'an oauth2 strategy' do
|
3
|
-
describe '#client' do
|
4
|
-
it 'should be initialized with symbolized client_options' do
|
5
|
-
@options = { :client_options => { 'authorize_url' => 'https://example.com' } }
|
6
|
-
subject.client.options[:authorize_url].should == 'https://example.com'
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
describe '#authorize_params' do
|
11
|
-
it 'should include any authorize params passed in the :authorize_params option' do
|
12
|
-
@options = { :authorize_params => { :foo => 'bar', :baz => 'zip' } }
|
13
|
-
subject.authorize_params['foo'].should eq('bar')
|
14
|
-
subject.authorize_params['baz'].should eq('zip')
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'should include top-level options that are marked as :authorize_options' do
|
18
|
-
@options = { :authorize_options => [:scope, :foo], :scope => 'http://bar', :foo => 'baz' }
|
19
|
-
subject.authorize_params['scope'].should eq('http://bar')
|
20
|
-
subject.authorize_params['foo'].should eq('baz')
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe '#token_params' do
|
25
|
-
it 'should include any token params passed in the :token_params option' do
|
26
|
-
@options = { :token_params => { :foo => 'bar', :baz => 'zip' } }
|
27
|
-
subject.token_params['foo'].should eq('bar')
|
28
|
-
subject.token_params['baz'].should eq('zip')
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'should include top-level options that are marked as :token_options' do
|
32
|
-
@options = { :token_options => [:scope, :foo], :scope => 'bar', :foo => 'baz' }
|
33
|
-
subject.token_params['scope'].should eq('bar')
|
34
|
-
subject.token_params['foo'].should eq('baz')
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|