cf-uaa-lib 3.6.0 → 3.14.3
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 +4 -4
- data/.travis.yml +3 -4
- data/NOTICE +12 -0
- data/README.md +1 -1
- data/cf-uaa-lib.gemspec +16 -15
- data/lib/uaa/http.rb +62 -42
- data/lib/uaa/info.rb +6 -7
- data/lib/uaa/scim.rb +79 -25
- data/lib/uaa/token_coder.rb +19 -1
- data/lib/uaa/token_issuer.rb +1 -5
- data/lib/uaa/version.rb +1 -1
- data/spec/http_spec.rb +99 -54
- data/spec/info_spec.rb +36 -38
- data/spec/integration_spec.rb +197 -106
- data/spec/scim_spec.rb +89 -81
- data/spec/token_issuer_spec.rb +130 -135
- metadata +61 -12
- data/NOTICE.TXT +0 -10
- data/lib/uaa/proxy_options.rb +0 -30
- /data/{LICENSE.TXT → LICENSE} +0 -0
data/spec/http_spec.rb
CHANGED
@@ -15,83 +15,128 @@ require 'spec_helper'
|
|
15
15
|
require 'uaa/http'
|
16
16
|
require 'uaa/version'
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
describe Http do
|
18
|
+
describe CF::UAA::Http do
|
21
19
|
|
22
20
|
class HttpTest
|
23
|
-
include Http
|
21
|
+
include CF::UAA::Http
|
24
22
|
|
25
23
|
public :http_get
|
26
24
|
end
|
27
25
|
|
28
26
|
let(:http_instance) { HttpTest.new }
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
let(:http_double) do
|
29
|
+
http_double = double('http').as_null_object
|
30
|
+
expect(HTTPClient).to receive(:new).and_return(http_double)
|
31
|
+
http_double
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:cert_store) { double('OpenSSL::X509::Store') }
|
35
|
+
|
36
|
+
describe 'set_request_handler' do
|
37
|
+
it 'sets a request handler' do
|
38
|
+
http_instance.set_request_handler do |url, method, body, headers|
|
39
|
+
[200, 'body', {'content-type' => 'text/plain'}]
|
40
|
+
end
|
41
|
+
status, body, resp_headers = http_instance.http_get('http://example.com')
|
42
|
+
status.should == 200
|
43
|
+
body.should == 'body'
|
44
|
+
resp_headers['content-type'].should == 'text/plain'
|
33
45
|
end
|
34
|
-
status, body, resp_headers = http_instance.http_get("http://example.com")
|
35
|
-
status.should == 200
|
36
|
-
body.should == "body"
|
37
|
-
resp_headers["content-type"].should == "text/plain"
|
38
46
|
end
|
39
47
|
|
40
|
-
|
41
|
-
reply_double = double('http reply', each_header: {}).as_null_object
|
42
|
-
http_double = double('http', request: reply_double, new: nil)
|
43
|
-
Net::HTTP.stub(:new).and_return(http_double)
|
44
|
-
http_instance.http_proxy = 'user:password@http-proxy.example.com:1234'
|
45
|
-
http_instance.https_proxy = 'user:password@https-proxy.example.com:1234'
|
48
|
+
describe 'http_get' do
|
46
49
|
|
47
|
-
|
50
|
+
context 'when response has no status' do
|
51
|
+
let(:response) { double('http::message') }
|
52
|
+
it 'raises an HTTPException error' do
|
53
|
+
expect(response).to receive(:status)
|
54
|
+
expect(response).to receive(:content).and_return('TEST')
|
55
|
+
expect(http_double).to receive(:get).and_return(response)
|
56
|
+
expect { http_instance.http_get('https://example.com') }.to raise_error(CF::UAA::HTTPException, "Can't parse response from the server TEST")
|
57
|
+
end
|
58
|
+
end
|
48
59
|
|
49
|
-
|
50
|
-
|
60
|
+
context 'when certificate is not valid' do
|
61
|
+
it 'raises an SSLException' do
|
62
|
+
expect(http_double).to receive(:get).and_raise(OpenSSL::SSL::SSLError)
|
51
63
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
http_double.stub(:request).and_raise(OpenSSL::SSL::SSLError)
|
64
|
+
expect { http_instance.http_get('https://example.com') }.to raise_error(CF::UAA::SSLException)
|
65
|
+
end
|
66
|
+
end
|
56
67
|
|
57
|
-
|
58
|
-
|
68
|
+
context 'when skipping ssl validation' do
|
69
|
+
let(:ssl_config) { double('ssl_config') }
|
59
70
|
|
60
|
-
|
61
|
-
|
62
|
-
Net::HTTP.stub(:new).and_return(http_double)
|
63
|
-
http_double.stub(:verify_mode=)
|
71
|
+
it 'sets verify mode to VERIFY_NONE' do
|
72
|
+
http_instance.initialize_http_options({skip_ssl_validation: true})
|
64
73
|
|
65
|
-
|
66
|
-
|
74
|
+
expect(http_double).to receive(:ssl_config).and_return(ssl_config)
|
75
|
+
expect(ssl_config).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
76
|
+
http_instance.http_get('https://uncached.example.com')
|
77
|
+
end
|
78
|
+
end
|
67
79
|
|
68
|
-
|
69
|
-
|
70
|
-
expect(http_double).to have_received(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
71
|
-
end
|
80
|
+
context 'when validating ssl' do
|
81
|
+
let(:ssl_config) { double('ssl_config') }
|
72
82
|
|
73
|
-
|
74
|
-
|
75
|
-
|
83
|
+
it 'sets default values' do
|
84
|
+
expect(http_double).to receive(:ssl_config).and_return(ssl_config)
|
85
|
+
expect(ssl_config).to receive(:set_default_paths)
|
86
|
+
http_instance.http_get('https://example.com')
|
87
|
+
end
|
88
|
+
end
|
76
89
|
|
77
|
-
|
78
|
-
|
90
|
+
context 'when ssl certificate is provided' do
|
91
|
+
let(:ssl_config) { double('ssl_config') }
|
79
92
|
|
80
|
-
|
81
|
-
|
82
|
-
end
|
93
|
+
it 'passes it' do
|
94
|
+
http_instance.initialize_http_options({ssl_ca_file: '/fake-ca-file'})
|
83
95
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
Net::HTTP.stub(:new).and_return(http_double)
|
96
|
+
expect(http_double).to receive(:ssl_config).and_return(ssl_config).twice
|
97
|
+
expect(ssl_config).to receive(:set_trust_ca).with('/fake-ca-file')
|
98
|
+
expect(ssl_config).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
|
88
99
|
|
89
|
-
|
90
|
-
|
100
|
+
http_instance.http_get('https://uncached.example.com')
|
101
|
+
end
|
102
|
+
end
|
91
103
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
104
|
+
context 'when ssl cert store is provided' do
|
105
|
+
let(:ssl_config) { double('ssl_config') }
|
106
|
+
|
107
|
+
it 'passes it' do
|
108
|
+
http_instance.initialize_http_options({ssl_cert_store: cert_store})
|
109
|
+
|
110
|
+
expect(http_double).to receive(:ssl_config).and_return(ssl_config).twice
|
111
|
+
expect(ssl_config).to receive(:cert_store=).with(cert_store)
|
112
|
+
expect(ssl_config).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
|
113
|
+
|
114
|
+
http_instance.http_get('https://uncached.example.com')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'when an http request timeout is provided' do
|
119
|
+
it 'sets all timeouts on the http clien to the http_timeout' do
|
120
|
+
http_instance.initialize_http_options({http_timeout: 10})
|
96
121
|
|
122
|
+
expect(http_double).to receive(:connect_timeout=).with(10)
|
123
|
+
expect(http_double).to receive(:send_timeout=).with(10)
|
124
|
+
expect(http_double).to receive(:receive_timeout=).with(10)
|
125
|
+
|
126
|
+
http_instance.http_get('https://uncached.example.com')
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when an http request timeout is not provided' do
|
131
|
+
it 'does not override the default' do
|
132
|
+
http_instance.initialize_http_options({})
|
133
|
+
|
134
|
+
expect(http_double).not_to receive(:connect_timeout=)
|
135
|
+
expect(http_double).not_to receive(:send_timeout=)
|
136
|
+
expect(http_double).not_to receive(:receive_timeout=)
|
137
|
+
|
138
|
+
http_instance.http_get('https://uncached.example.com')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
97
142
|
end
|
data/spec/info_spec.rb
CHANGED
@@ -19,44 +19,42 @@ module CF::UAA
|
|
19
19
|
describe Info do
|
20
20
|
let(:options) { {} }
|
21
21
|
let(:uaa_info) { Info.new(target, options) }
|
22
|
-
let(:target) {
|
22
|
+
let(:target) { 'https://login.cloudfoundry.com' }
|
23
23
|
let(:authorization) { nil }
|
24
24
|
|
25
25
|
before do
|
26
26
|
uaa_info.set_request_handler do |url, method, body, headers|
|
27
27
|
url.should == target_url
|
28
28
|
method.should == :get
|
29
|
-
headers[
|
30
|
-
headers[
|
31
|
-
headers[
|
32
|
-
[200, response_body, {
|
29
|
+
headers['content-type'].should be_nil
|
30
|
+
headers['accept'].gsub(/\s/, '').should =~ /application\/json;charset=utf-8/i
|
31
|
+
headers['authorization'].should == authorization
|
32
|
+
[200, response_body, {'content-type' => 'application/json'}]
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
describe
|
37
|
-
let(:options) { {:
|
36
|
+
describe 'initialize' do
|
37
|
+
let(:options) { {:skip_ssl_validation => true} }
|
38
38
|
|
39
|
-
it
|
40
|
-
uaa_info.http_proxy.should == 'http-proxy.com'
|
41
|
-
uaa_info.https_proxy.should == 'https-proxy.com'
|
39
|
+
it 'sets proxy information' do
|
42
40
|
uaa_info.skip_ssl_validation == true
|
43
41
|
end
|
44
42
|
end
|
45
43
|
|
46
|
-
describe
|
47
|
-
let(:target_url) {
|
44
|
+
describe 'getting server info' do
|
45
|
+
let(:target_url) { 'https://login.cloudfoundry.com/login' }
|
48
46
|
let(:response_body) { '{"commit_id":"12345","prompts":["one","two"]}' }
|
49
47
|
|
50
|
-
it
|
48
|
+
it 'gets server info' do
|
51
49
|
result = uaa_info.server
|
52
|
-
result[
|
53
|
-
result[
|
50
|
+
result['prompts'].should_not be_nil
|
51
|
+
result['commit_id'].should_not be_nil
|
54
52
|
end
|
55
53
|
|
56
|
-
context
|
54
|
+
context 'with symbolize_keys keys true' do
|
57
55
|
let(:options) { {:symbolize_keys => true} }
|
58
56
|
|
59
|
-
it
|
57
|
+
it 'gets server info' do
|
60
58
|
result = uaa_info.server
|
61
59
|
result[:prompts].should_not be_nil
|
62
60
|
result[:commit_id].should_not be_nil
|
@@ -64,63 +62,63 @@ module CF::UAA
|
|
64
62
|
end
|
65
63
|
end
|
66
64
|
|
67
|
-
describe
|
68
|
-
let(:target) {
|
69
|
-
let(:target_url) {
|
65
|
+
describe 'getting UAA target' do
|
66
|
+
let(:target) { 'https://login.cloudfoundry.com' }
|
67
|
+
let(:target_url) { 'https://login.cloudfoundry.com/login' }
|
70
68
|
let(:response_body) { '{"links":{"uaa":"https://uaa.cloudfoundry.com"},"prompts":["one","two"]}' }
|
71
69
|
|
72
|
-
it
|
70
|
+
it 'gets UAA target' do
|
73
71
|
result = uaa_info.discover_uaa
|
74
|
-
result.should ==
|
72
|
+
result.should == 'https://uaa.cloudfoundry.com'
|
75
73
|
end
|
76
74
|
|
77
75
|
context "when there is no 'links' key present" do
|
78
|
-
let(:target) {
|
79
|
-
let(:target_url) {
|
76
|
+
let(:target) { 'https://uaa.cloudfoundry.com' }
|
77
|
+
let(:target_url) { 'https://uaa.cloudfoundry.com/login' }
|
80
78
|
let(:response_body) { '{ "prompts" : ["one","two"]} ' }
|
81
79
|
|
82
|
-
it
|
80
|
+
it 'returns the target url' do
|
83
81
|
result = uaa_info.discover_uaa
|
84
|
-
result.should ==
|
82
|
+
result.should == 'https://uaa.cloudfoundry.com'
|
85
83
|
end
|
86
84
|
end
|
87
85
|
|
88
|
-
context
|
86
|
+
context 'with symbolize_keys keys true' do
|
89
87
|
let(:options) { {:symbolize_keys => true} }
|
90
88
|
|
91
|
-
it
|
89
|
+
it 'gets UAA target' do
|
92
90
|
result = uaa_info.discover_uaa
|
93
|
-
result.should ==
|
91
|
+
result.should == 'https://uaa.cloudfoundry.com'
|
94
92
|
end
|
95
93
|
end
|
96
94
|
end
|
97
95
|
|
98
|
-
describe
|
99
|
-
let(:target_url) {
|
96
|
+
describe 'whoami' do
|
97
|
+
let(:target_url) { 'https://login.cloudfoundry.com/userinfo?schema=openid' }
|
100
98
|
let(:response_body) { '{"user_id":"1111-1111-1111-1111","user_name":"user","given_name":"first","family_name":"last","name":"first last","email":"email@example.com"}' }
|
101
99
|
let(:authorization) { 'authentication_token' }
|
102
100
|
|
103
|
-
it
|
101
|
+
it 'returns the user info' do
|
104
102
|
result = uaa_info.whoami(authorization)
|
105
103
|
result['email'].should == 'email@example.com'
|
106
104
|
end
|
107
105
|
end
|
108
106
|
|
109
|
-
describe
|
110
|
-
let(:target_url) {
|
107
|
+
describe 'validation_key' do
|
108
|
+
let(:target_url) { 'https://login.cloudfoundry.com/token_key' }
|
111
109
|
let(:response_body) { '{"alg":"SHA256withRSA","value":"-----BEGIN PUBLIC KEY-----\nabc123\n-----END PUBLIC KEY-----\n"}' }
|
112
110
|
|
113
|
-
it
|
111
|
+
it 'returns the key data' do
|
114
112
|
result = uaa_info.validation_key(authorization)
|
115
113
|
result['alg'].should == 'SHA256withRSA'
|
116
114
|
end
|
117
115
|
end
|
118
116
|
|
119
|
-
describe
|
120
|
-
let(:target_url) {
|
117
|
+
describe 'validation keys' do
|
118
|
+
let(:target_url) { 'https://login.cloudfoundry.com/token_keys' }
|
121
119
|
let(:response_body) { '{ "keys": [ { "kid": "the_key", "alg": "SHA256withRSA", "value": "-----BEGIN PUBLIC KEY-----\nabc123\n-----END PUBLIC KEY-----\n", "kty": "RSA", "use": "sig", "n": "Ufn7Qc", "e": "EEXZ" }, { "kid": "the_other_key", "alg": "SHA256withRSA", "value": "-----BEGIN PUBLIC KEY-----\ndef456\n-----END PUBLIC KEY-----\n", "kty": "RSA", "use": "sig", "n": "AMcW9/P", "e": "AQAB" } ] }' }
|
122
120
|
|
123
|
-
it
|
121
|
+
it 'returns a hash of keys' do
|
124
122
|
result = uaa_info.validation_keys_hash(authorization)
|
125
123
|
|
126
124
|
the_key = result['the_key']
|