omniauth-uaa-oauth2 0.0.3 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/NOTICE CHANGED
@@ -1,10 +1,11 @@
1
- omniauth-uaa-oauth2 09012012
1
+ Copyright (c) 2015-Present CloudFoundry.org Foundation, Inc. All Rights Reserved.
2
2
 
3
- Copyright (c) 2012 VMware, Inc. All Rights Reserved.
3
+ This project contains software that is Copyright (c) 2013-2015 Pivotal Software, Inc.
4
4
 
5
- This product is licensed to you under the Apache License, Version 2.0 (the "License").
6
- You may not use this product except in compliance with the License.
5
+ This project is licensed to you under the Apache License, Version 2.0 (the "License").
7
6
 
8
- This product may include a number of subcomponents with separate copyright notices
7
+ You may not use this project except in compliance with the License.
8
+
9
+ This project may include a number of subcomponents with separate copyright notices
9
10
  and license terms. Your use of these subcomponents is subject to the terms and
10
- conditions of the subcomponent's license, as noted in the LICENSE file.
11
+ conditions of the subcomponent's license, as noted in the LICENSE file.
@@ -18,6 +18,25 @@ require 'securerandom'
18
18
 
19
19
  module OmniAuth
20
20
  module Strategies
21
+ class CFAccessToken
22
+ EMPTY_INFO = {
23
+ 'access_token' => '',
24
+ 'refresh_token' => '',
25
+ 'scope' => ''
26
+ }
27
+
28
+ attr_reader :info, :auth_header
29
+
30
+ def initialize(info=EMPTY_INFO, auth_header='')
31
+ @info = info
32
+ @auth_header = auth_header
33
+ end
34
+
35
+ def empty?
36
+ @info == EMPTY_INFO
37
+ end
38
+ end
39
+
21
40
  class Cloudfoundry
22
41
  include OmniAuth::Strategy
23
42
 
@@ -28,13 +47,14 @@ module OmniAuth
28
47
  option :token_server_url, nil
29
48
  option :scope, nil
30
49
  option :async_calls, false
50
+ option :skip_ssl_validation, false
31
51
 
32
52
  attr_accessor :access_token
33
53
  attr_reader :token_issuer
54
+ attr_writer :uaa_info
34
55
  attr_reader :auth_server_url
35
56
  attr_reader :token_server_url
36
57
 
37
-
38
58
  def client
39
59
 
40
60
  unless @token_issuer
@@ -53,10 +73,14 @@ module OmniAuth
53
73
  end
54
74
  end
55
75
 
56
- @token_issuer ||= CF::UAA::TokenIssuer.new(@auth_server_url,
57
- options.client_id,
58
- options.client_secret,
59
- {:token_target => @token_server_url})
76
+ @token_issuer ||= CF::UAA::TokenIssuer.new(
77
+ @auth_server_url,
78
+ options.client_id,
79
+ options.client_secret,
80
+ {
81
+ :token_target => @token_server_url,
82
+ :skip_ssl_validation => options.skip_ssl_validation
83
+ })
60
84
  log :info, "Client: #{options.client_id} auth_server: #{@auth_server_url} token_server: #{@token_server_url}"
61
85
  @token_issuer.logger = OmniAuth.logger
62
86
  end
@@ -64,6 +88,13 @@ module OmniAuth
64
88
  @token_issuer
65
89
  end
66
90
 
91
+ def uaa_info
92
+ @uaa_info ||= CF::UAA::Info.new(
93
+ @token_server_url,
94
+ :skip_ssl_validation => options.skip_ssl_validation
95
+ )
96
+ end
97
+
67
98
  def callback_url
68
99
  full_host + script_name + callback_path
69
100
  end
@@ -89,12 +120,16 @@ module OmniAuth
89
120
  end
90
121
 
91
122
  def callback_phase
92
- log :info, "In callback phase #{request.query_string}"
93
- self.access_token = build_access_token(request.query_string)
94
- self.access_token = refresh(access_token) if expired?(access_token)
95
- log :info, "Got access token #{access_token.inspect}"
96
-
97
- super
123
+ if error = request.params['error_reason'] || request.params['error']
124
+ fail!(error, CallbackError.new(request.params['error'], request.params['error_description'] || request.params['error_reason'], request.params['error_uri']))
125
+ else
126
+ log :info, "In callback phase #{request.query_string}"
127
+ self.access_token = build_access_token(request.query_string)
128
+ self.access_token = refresh(access_token) if !access_token.empty? && expired?(access_token)
129
+ log :info, "Got access token #{access_token.inspect}"
130
+
131
+ super
132
+ end
98
133
  end
99
134
 
100
135
  credentials do
@@ -123,7 +158,10 @@ module OmniAuth
123
158
  end
124
159
 
125
160
  def raw_info
126
- @raw_info ||= CF::UAA::Misc.whoami(@token_server_url, self.access_token.auth_header)
161
+ @raw_info ||= uaa_info.whoami(self.access_token.auth_header)
162
+ rescue CF::UAA::TargetError => e
163
+ log :error, "#{e.message}: #{e.info}"
164
+ {}
127
165
  end
128
166
 
129
167
  def prune!(hash)
@@ -135,7 +173,11 @@ module OmniAuth
135
173
 
136
174
  def build_access_token(query_string)
137
175
  log :info, "Fetching access token"
138
- client.authcode_grant(session.delete('redir_uri'), query_string)
176
+ token = client.authcode_grant(session.delete('redir_uri'), query_string)
177
+ CFAccessToken.new(token.info, token.auth_header)
178
+ rescue CF::UAA::InvalidToken => e
179
+ log :error, "Invalid token: #{e.message}"
180
+ CFAccessToken.new
139
181
  end
140
182
 
141
183
  def refresh(access_token)
@@ -148,6 +190,20 @@ module OmniAuth
148
190
  expiry = CF::UAA::TokenCoder.decode(access_token.split()[1], nil, nil, false)[:expires_at]
149
191
  expiry.is_a?(Integer) && expiry <= Time.now.to_i
150
192
  end
193
+
194
+ class CallbackError < StandardError
195
+ attr_accessor :error, :error_reason, :error_uri
196
+
197
+ def initialize(error, error_reason = nil, error_uri = nil)
198
+ self.error = error
199
+ self.error_reason = error_reason
200
+ self.error_uri = error_uri
201
+ end
202
+
203
+ def message
204
+ [error, error_reason, error_uri].compact.join(' | ')
205
+ end
206
+ end
151
207
  end
152
208
  end
153
209
  end
@@ -13,6 +13,6 @@
13
13
 
14
14
  module OmniAuth
15
15
  module Cloudfoundry
16
- VERSION = "0.0.3"
16
+ VERSION = "0.0.7"
17
17
  end
18
18
  end
@@ -15,9 +15,6 @@
15
15
  require File.expand_path('../lib/omniauth/uaa_oauth2/version', __FILE__)
16
16
 
17
17
  Gem::Specification.new do |gem|
18
- gem.add_dependency 'omniauth', '~> 1.0'
19
- gem.add_dependency 'cf-uaa-lib', ['>= 1.3.1', '< 2.0']
20
-
21
18
  gem.authors = ["Joel D'sa", "Dave Syer", "Dale Olds", "Vidya Valmikinathan", "Luke Taylor"]
22
19
  gem.email = ["jdsa@vmware.com", "olds@vmware.com", "dsyer@vmware.com", "vidya@vmware.com", "ltaylor@vmware.com"]
23
20
  gem.description = %q{An OmniAuth strategy for the Cloudfoundry UAA}
@@ -31,7 +28,8 @@ Gem::Specification.new do |gem|
31
28
  gem.require_paths = ["lib"]
32
29
  gem.version = OmniAuth::Cloudfoundry::VERSION
33
30
 
34
- gem.add_runtime_dependency 'cf-uaa-lib', ['>= 1.3.1', '< 2.0']
31
+ gem.add_runtime_dependency 'omniauth', '~> 1.0'
32
+ gem.add_runtime_dependency 'cf-uaa-lib', ['>= 3.2', '< 4.0']
35
33
 
36
34
  gem.add_development_dependency 'rspec', '~> 2.6.0'
37
35
  gem.add_development_dependency 'rake'
@@ -52,6 +52,63 @@ describe OmniAuth::Strategies::Cloudfoundry do
52
52
  end
53
53
  end
54
54
 
55
+ describe '#callback_phase' do
56
+ let(:token_issuer) { CF::UAA::TokenIssuer.new('target', 'client_id') }
57
+ let(:uaa_info) do
58
+ info = double("UAA_INFO")
59
+ info.stub(:whoami) { { "omniauth.auth" => "something" } }
60
+ info
61
+ end
62
+
63
+ before do
64
+ subject.stub(:client).and_return(token_issuer)
65
+ subject.uaa_info = uaa_info
66
+ subject.stub(:session).and_return({})
67
+ subject.stub(:env).and_return({})
68
+ subject.stub(:expired?) { true }
69
+ @request.stub(:query_string)
70
+ end
71
+
72
+ context 'when the callback request contains an error message' do
73
+ it 'makes a call to #fail! with the error and a CallbackError' do
74
+ @request.stub(:params) do
75
+ {
76
+ 'error' => 'access_denied',
77
+ 'error_description' => 'User denied access',
78
+ 'state' => 'some-state-value'
79
+ }
80
+ end
81
+
82
+ subject.should_receive(:fail!).with('access_denied', instance_of(OmniAuth::Strategies::Cloudfoundry::CallbackError))
83
+ subject.callback_phase
84
+ end
85
+ end
86
+
87
+ context 'when the access token is not empty and expired' do
88
+ let(:refresh_access_token) { OmniAuth::Strategies::CFAccessToken.new({
89
+ 'access_token' => 'some-refreshed-token'
90
+ },
91
+ 'auth-header'
92
+ )}
93
+
94
+ it 'should call refresh on the access token' do
95
+ token_issuer.stub(:authcode_grant).and_return(CF::UAA::TokenInfo.new({}))
96
+
97
+ subject.should_receive(:refresh).with(anything).and_return(refresh_access_token)
98
+ subject.callback_phase
99
+ end
100
+ end
101
+
102
+ context 'when the access token is empty and expired' do
103
+ it 'should not call refresh on the access token' do
104
+ token_issuer.stub(:authcode_grant).and_raise(CF::UAA::InvalidToken)
105
+
106
+ subject.should_not_receive(:refresh)
107
+ subject.callback_phase
108
+ end
109
+ end
110
+ end
111
+
55
112
  describe 'set scopes' do
56
113
  it 'should set the right scopes if requested' do
57
114
  @options = {:auth_server_url => 'https://login.cloudfoundry.com', :token_server_url => 'https://uaa.cloudfoundry.com', :scope => "openid cloud_controller.read"}
@@ -66,4 +123,92 @@ describe OmniAuth::Strategies::Cloudfoundry do
66
123
  end
67
124
  end
68
125
 
126
+ describe 'empty?' do
127
+ it 'is empty when initialized without info' do
128
+ token = OmniAuth::Strategies::CFAccessToken.new
129
+ token.empty?.should be_true
130
+ end
131
+
132
+ it 'is not empty when initialized with info' do
133
+ token = OmniAuth::Strategies::CFAccessToken.new({
134
+ 'access_token' => 'some-token',
135
+ })
136
+ token.empty?.should be_false
137
+ end
138
+ end
139
+
140
+ describe 'raw_info' do
141
+ let(:uaa_info) do
142
+ info = double("UAA_INFO")
143
+ info.stub(:whoami) { "something" }
144
+ info
145
+ end
146
+
147
+ before do
148
+ subject.uaa_info = uaa_info
149
+ @omni_logger = OmniAuth.config.logger
150
+ end
151
+
152
+ after do
153
+ OmniAuth.config.logger = @omni_logger
154
+ end
155
+
156
+ it 'should return raw info' do
157
+ subject.access_token = OmniAuth::Strategies::CFAccessToken.new
158
+
159
+ subject.raw_info.should_not be_empty
160
+ end
161
+
162
+ context 'when whoami returns an error' do
163
+ let(:uaa_info) do
164
+ info = double("UAA_INFO")
165
+ info.stub(:whoami).and_raise(CF::UAA::TargetError)
166
+ info
167
+ end
168
+
169
+ before do
170
+ subject.uaa_info = uaa_info
171
+ end
172
+
173
+ it 'should rescue, log, and return empty hash on target error' do
174
+ logger = double("logger")
175
+ logger.should_receive(:error).once
176
+ OmniAuth.config.logger = logger
177
+
178
+ subject.access_token = OmniAuth::Strategies::CFAccessToken.new
179
+ subject.raw_info.should be_empty
180
+ end
181
+ end
182
+ end
183
+
184
+ describe 'build_access_token' do
185
+ let(:token_issuer) { CF::UAA::TokenIssuer.new('target', 'client_id') }
186
+ let(:logger) { double("logger") }
187
+ let!(:omni_logger) { OmniAuth.config.logger }
188
+
189
+ before do
190
+ OmniAuth.config.logger = logger
191
+ logger.should_receive(:info).once
192
+
193
+ subject.stub(:client).and_return(token_issuer)
194
+ subject.stub(:session).and_return({})
195
+ end
196
+
197
+ after do
198
+ OmniAuth.config.logger = omni_logger
199
+ end
200
+
201
+ it 'should return an access token' do
202
+ token_issuer.stub(:authcode_grant).and_return(CF::UAA::TokenInfo.new({}))
203
+
204
+ subject.build_access_token('query-string').should_not be_empty
205
+ end
206
+
207
+ it 'should rescue, log, and return empty token on invalid token error' do
208
+ token_issuer.stub(:authcode_grant).and_raise(CF::UAA::InvalidToken)
209
+ logger.should_receive(:error).once
210
+
211
+ subject.build_access_token('query-string').should be_empty
212
+ end
213
+ end
69
214
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-uaa-oauth2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel D'sa
@@ -12,88 +12,68 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2014-02-07 00:00:00.000000000 Z
15
+ date: 2018-07-22 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: omniauth
19
19
  requirement: !ruby/object:Gem::Requirement
20
20
  requirements:
21
- - - ~>
21
+ - - "~>"
22
22
  - !ruby/object:Gem::Version
23
23
  version: '1.0'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - ~>
28
+ - - "~>"
29
29
  - !ruby/object:Gem::Version
30
30
  version: '1.0'
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: cf-uaa-lib
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  requirements:
35
- - - '>='
35
+ - - ">="
36
36
  - !ruby/object:Gem::Version
37
- version: 1.3.1
38
- - - <
37
+ version: '3.2'
38
+ - - "<"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.0'
40
+ version: '4.0'
41
41
  type: :runtime
42
42
  prerelease: false
43
43
  version_requirements: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 1.3.1
48
- - - <
47
+ version: '3.2'
48
+ - - "<"
49
49
  - !ruby/object:Gem::Version
50
- version: '2.0'
51
- - !ruby/object:Gem::Dependency
52
- name: cf-uaa-lib
53
- requirement: !ruby/object:Gem::Requirement
54
- requirements:
55
- - - '>='
56
- - !ruby/object:Gem::Version
57
- version: 1.3.1
58
- - - <
59
- - !ruby/object:Gem::Version
60
- version: '2.0'
61
- type: :runtime
62
- prerelease: false
63
- version_requirements: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - '>='
66
- - !ruby/object:Gem::Version
67
- version: 1.3.1
68
- - - <
69
- - !ruby/object:Gem::Version
70
- version: '2.0'
50
+ version: '4.0'
71
51
  - !ruby/object:Gem::Dependency
72
52
  name: rspec
73
53
  requirement: !ruby/object:Gem::Requirement
74
54
  requirements:
75
- - - ~>
55
+ - - "~>"
76
56
  - !ruby/object:Gem::Version
77
57
  version: 2.6.0
78
58
  type: :development
79
59
  prerelease: false
80
60
  version_requirements: !ruby/object:Gem::Requirement
81
61
  requirements:
82
- - - ~>
62
+ - - "~>"
83
63
  - !ruby/object:Gem::Version
84
64
  version: 2.6.0
85
65
  - !ruby/object:Gem::Dependency
86
66
  name: rake
87
67
  requirement: !ruby/object:Gem::Requirement
88
68
  requirements:
89
- - - '>='
69
+ - - ">="
90
70
  - !ruby/object:Gem::Version
91
71
  version: '0'
92
72
  type: :development
93
73
  prerelease: false
94
74
  version_requirements: !ruby/object:Gem::Requirement
95
75
  requirements:
96
- - - '>='
76
+ - - ">="
97
77
  - !ruby/object:Gem::Version
98
78
  version: '0'
99
79
  description: An OmniAuth strategy for the Cloudfoundry UAA
@@ -107,8 +87,8 @@ executables: []
107
87
  extensions: []
108
88
  extra_rdoc_files: []
109
89
  files:
110
- - .gitignore
111
- - .travis.yml
90
+ - ".gitignore"
91
+ - ".travis.yml"
112
92
  - Gemfile
113
93
  - Gemfile.lock
114
94
  - LICENSE
@@ -132,18 +112,20 @@ require_paths:
132
112
  - lib
133
113
  required_ruby_version: !ruby/object:Gem::Requirement
134
114
  requirements:
135
- - - '>='
115
+ - - ">="
136
116
  - !ruby/object:Gem::Version
137
117
  version: '0'
138
118
  required_rubygems_version: !ruby/object:Gem::Requirement
139
119
  requirements:
140
- - - '>='
120
+ - - ">="
141
121
  - !ruby/object:Gem::Version
142
122
  version: '0'
143
123
  requirements: []
144
124
  rubyforge_project:
145
- rubygems_version: 2.0.3
125
+ rubygems_version: 2.7.6
146
126
  signing_key:
147
127
  specification_version: 4
148
128
  summary: An OmniAuth strategy for the Cloudfoundry UAA
149
- test_files: []
129
+ test_files:
130
+ - spec/omniauth/strategies/uaa_oauth2_spec.rb
131
+ - spec/spec_helper.rb