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.
- checksums.yaml +5 -5
- data/Gemfile +1 -1
- data/Gemfile.lock +12 -10
- data/LICENSE +789 -42
- data/NOTICE +7 -6
- data/lib/omniauth/strategies/cloudfoundry.rb +69 -13
- data/lib/omniauth/uaa_oauth2/version.rb +1 -1
- data/omniauth-uaa-oauth2.gemspec +2 -4
- data/spec/omniauth/strategies/uaa_oauth2_spec.rb +145 -0
- metadata +24 -42
data/NOTICE
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
|
1
|
+
Copyright (c) 2015-Present CloudFoundry.org Foundation, Inc. All Rights Reserved.
|
2
2
|
|
3
|
-
Copyright (c)
|
3
|
+
This project contains software that is Copyright (c) 2013-2015 Pivotal Software, Inc.
|
4
4
|
|
5
|
-
This
|
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
|
-
|
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(
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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 ||=
|
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
|
data/omniauth-uaa-oauth2.gemspec
CHANGED
@@ -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 '
|
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.
|
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:
|
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:
|
38
|
-
- - <
|
37
|
+
version: '3.2'
|
38
|
+
- - "<"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
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:
|
48
|
-
- - <
|
47
|
+
version: '3.2'
|
48
|
+
- - "<"
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version: '
|
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.
|
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
|