omniauth-uaa-oauth2 0.0.3 → 0.0.7

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.
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