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 CHANGED
@@ -1,7 +1,7 @@
1
- source 'http://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
5
  group :example do
6
6
  gem 'sinatra'
7
- end
7
+ end
data/README.md CHANGED
@@ -18,7 +18,7 @@ Then `bundle install`.
18
18
 
19
19
  ## Usage
20
20
 
21
- Here's an example, adding the middleware to a Rails app in `config/initializers/omniauth.rb`:
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) 2012 by Josh Ellithorpe
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
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
3
- require 'rspec/core/rake_task'
2
+ require File.join('bundler', 'gem_tasks')
3
+ require File.join('rspec', 'core', 'rake_task')
4
4
 
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
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
- # Regular usage
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
@@ -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
- # If you don't need a refresh token -- if you're only using Google for account creation/auth and don't need google services -- set the access_type to 'online'.
3
- # Also, set the approval prompt to an empty string, since otherwise it will be set to 'force', which makes users manually approve to the Oauth every time they log in.
4
- # See http://googleappsdeveloper.blogspot.com/2011/10/upcoming-changes-to-oauth-20-endpoint.html
5
- provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {access_type: 'online', approval_prompt: ''}
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 "omniauth/google_oauth2"
1
+ require File.join('omniauth', 'google_oauth2')
@@ -1 +1 @@
1
- require 'omniauth/strategies/google_oauth2'
1
+ require File.join('omniauth', 'strategies', 'google_oauth2')
@@ -1,5 +1,5 @@
1
1
  module OmniAuth
2
2
  module GoogleOauth2
3
- VERSION = "0.1.19"
3
+ VERSION = "0.2.0"
4
4
  end
5
- end
5
+ end
@@ -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, :prompt, :request_visible_actions, :scope, :state]
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
- scopes = (params[:scope] || DEFAULT_SCOPE).delete(' ').split(',')
27
- scopes.map! { |s| s =~ /^https?:\/\// ? s : "#{base_scope_url}#{s}" }
28
- params[:scope] = scopes.join(' ')
29
- # This makes sure we get a refresh_token.
30
- # http://googlecode.blogspot.com/2011/10/upcoming-changes-to-oauth-20-endpoint.html
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
- params[:login_hint] = request.params['login_hint'] if request.params['login_hint']
33
- # Override the state per request
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 build_access_token_with_access_token
64
- if !request.params['id_token'].nil? &&
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
- build_access_token_without_access_token
65
+ orig_build_access_token
70
66
  end
71
67
  end
72
- alias_method :build_access_token_without_access_token, :build_access_token
73
- alias :build_access_token :build_access_token_with_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 |_, value|
79
- prune!(value) if value.is_a?(Hash)
80
- value.nil? || (value.respond_to?(:empty?) && value.empty?)
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
- # Verify id_token as well
107
- # request fails and raises error when id_token or access_token is invalid
108
- raw_response = client.request(:get, 'https://www.googleapis.com/oauth2/v2/tokeninfo',
109
- :params => {:id_token => id_token, :access_token => access_token}).parsed
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
@@ -1,18 +1,18 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/omniauth/google_oauth2/version', __FILE__)
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 oauth2 strategy for OmniAuth 1.0}
10
- gem.summary = %q{A Google oauth2 strategy for OmniAuth 1.0}
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 -- {test,spec,features}/*`.split("\n")
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
- def app; lambda{|env| [200, {}, ["Hello."]]} end
5
+ let(:request) { double('Request', :params => {}, :cookies => {}, :env => {}) }
6
+ let(:app) {
7
+ lambda do
8
+ [200, {}, ["Hello."]]
9
+ end
10
+ }
6
11
 
7
- before :each do
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
- subject do
20
- args = ['appid', 'secret', @options || {}].compact
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 authorize url' do
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 token url' do
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
- describe '#callback_path' do
43
- it 'has the correct callback path' do
44
- subject.callback_path.should eq('/auth/google_oauth2/callback')
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 '#authorize_params' do
49
- %w(access_type hd prompt state any_other).each do |k|
50
- it "should set the #{k} authorize option dynamically in the request" do
51
- @options = {:authorize_options => [k.to_sym], k.to_sym => ''}
52
- subject.stub(:request) { double('Request', {:params => { k => 'something' }, :env => {}}) }
53
- subject.authorize_params[k].should eq('something')
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 = { :authorize_options => [:scope], :scope => 'userinfo.email'}
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 = { :authorize_options => [:scope], :scope => 'https://www.googleapis.com/auth/userinfo.profile'}
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 = { :authorize_options => [:scope], :scope => 'userinfo.profile,userinfo.email'}
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 = { :authorize_options => [:scope], :scope => 'userinfo.profile, userinfo.email'}
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 dynamically set the scope in the request' do
84
- @options = {:scope => 'http://example.com'}
85
- subject.stub(:request) { double('Request', {:params => { 'scope' => 'userinfo.email' }, :env => {}}) }
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 'should default to "offline"' do
104
- @options = {}
105
- subject.authorize_params['access_type'].should eq('offline')
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 => { 'state' => 'some_state' }, :env => {}}) }
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 'hd' do
124
- it 'should set the hd (hosted domain) parameter if present' do
125
- @options = {:hd => 'example.com'}
126
- subject.authorize_params['hd'].should eq('example.com')
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
- describe 'login_hint' do
131
- it 'should set the login_hint parameter if present' do
132
- subject.stub(:request) { double('Request', {:params => { 'login_hint' => 'example@example.com' }, :env => {}}) }
133
- subject.authorize_params['login_hint'].should eq('example@example.com')
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) { { :foo => 'bar' } }
141
- subject.extra[:raw_info].should eq({ :foo => 'bar' })
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 = { :skip_info => true }
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 url' do
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) { { 'name' => 'Foo', 'link' => 'https://plus.google.com/123456' } }
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) { { 'name' => 'Foo' } }
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 'should return the image with size specified in the `image_size` option' do
164
- @options = { :image_size => 50 }
165
- subject.stub(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
166
- main_url, image_params = subject.info[:image].match(/^(.*)\/(.*)\/photo.jpg/).captures
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
- it 'should return the image with width and height specified in the `image_size` option' do
172
- @options = { :image_size => { :width => 50, :height => 50 } }
173
- subject.stub(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
174
- main_url, image_params = subject.info[:image].match(/^(.*)\/(.*)\/photo.jpg/).captures
175
- image_params = image_params.split('-').inject({}) do |result, element|
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
- it 'should return square image when `image_aspect_ratio` is specified' do
185
- @options = { :image_aspect_ratio => 'square' }
186
- subject.stub(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
187
- main_url, image_params = subject.info[:image].match(/^(.*)\/(.*)\/photo.jpg/).captures
188
- main_url.should eq('https://lh3.googleusercontent.com/url')
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
- it 'should not break if no picture present in raw_info' do
193
- @options = { :image_aspect_ratio => 'square' }
194
- subject.stub(:raw_info) { { 'name' => 'User Without Pic' } }
195
- subject.info[:image].should be_nil
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) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } }
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
- @request.stub(:params).and_return('id_token' => 'valid_id_token', 'access_token' => 'valid_access_token')
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(:build_access_token_without_access_token)
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 = '000000000000.apps.googleusercontent.com'
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
@@ -1,7 +1,2 @@
1
- require 'bundler/setup'
2
- require 'rspec'
3
-
4
- Dir[File.expand_path('../support/**/*', __FILE__)].each { |f| require f }
5
-
6
- RSpec.configure do |config|
7
- end
1
+ require File.join('bundler', 'setup')
2
+ require 'rspec'
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.1.19
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-19 00:00:00.000000000 Z
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 oauth2 strategy for OmniAuth 1.0
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: 3969644160829709281
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: 3969644160829709281
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 oauth2 strategy for OmniAuth 1.0
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