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