cf-uaa-lib 3.6.0 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cbf0e4c510eb02fb7e828ffbe7f227c10fdc9e45
4
- data.tar.gz: e5718846645aabe80e2ab0e4bb581e2146110ed4
3
+ metadata.gz: 41d1d29707fa6dd64486407764cfaa01dddf0b39
4
+ data.tar.gz: 41a335fbc12c82462b3ca18ffbdd73613f89a7e2
5
5
  SHA512:
6
- metadata.gz: 08568f7f4c4763e269e39e52768c3d738a1c3df347b7d911e63fa48158ccfdc81c53d8c69cdc2b78f19a3fab3c82b5f7f12f42ab8a5f84c3c013e3e3270d5d10
7
- data.tar.gz: 72cc5995de5569c12f5e8a0b3a88890bef8df65b424fbccd038ec0d9c673ffaa62291f0ba39cc064b7a43f52f2c21588fd74c2a5784640b7d7514529cbcfe81a
6
+ metadata.gz: 171ff7b4dabbfe88d3939204fe5ea7d6142a9f5912d191979c78920d56b697d43810df85d80a6798702f3684c3414f1b0c0637d41fd772e08ab83a1f4cd50b56
7
+ data.tar.gz: 076de82f0fc91e1cb8388a310324fb66c86a017d24dbab52313167742400941b4b4865ccdb09f91844750f88edcbc8d2b88991cea7fbdbd7c92a75d5c8c68733
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
 
35
35
  # dependencies
36
36
  s.add_dependency "multi_json"
37
+ s.add_dependency "httpclient", "~> 2.8.2.4"
37
38
 
38
39
  s.add_development_dependency "bundler"
39
40
  s.add_development_dependency "rake", "~> 10.3.2"
@@ -12,9 +12,8 @@
12
12
  #++
13
13
 
14
14
  require 'base64'
15
- require 'net/http'
16
15
  require 'uaa/util'
17
- require 'uaa/proxy_options'
16
+ require 'httpclient'
18
17
 
19
18
  module CF::UAA
20
19
 
@@ -46,11 +45,10 @@ class InvalidToken < TargetError; end
46
45
 
47
46
  # Utility accessors and methods for objects that want to access JSON web APIs.
48
47
  module Http
49
- include ProxyOptions
50
48
 
51
49
  def self.included(base)
52
50
  base.class_eval do
53
- attr_accessor :http_proxy, :https_proxy, :skip_ssl_validation, :ssl_ca_file, :ssl_cert_store, :zone
51
+ attr_accessor :skip_ssl_validation, :ssl_ca_file, :ssl_cert_store, :zone
54
52
  end
55
53
  end
56
54
 
@@ -78,30 +76,30 @@ module Http
78
76
  # @return [String]
79
77
  def self.basic_auth(name, password)
80
78
  str = "#{name}:#{password}"
81
- "Basic " + (Base64.respond_to?(:strict_encode64)?
82
- Base64.strict_encode64(str): [str].pack("m").gsub(/\n/, ''))
79
+ 'Basic ' + (Base64.respond_to?(:strict_encode64)?
80
+ Base64.strict_encode64(str): [str].pack('m').gsub(/\n/, ''))
83
81
  end
84
82
 
85
- JSON_UTF8 = "application/json;charset=utf-8"
86
- FORM_UTF8 = "application/x-www-form-urlencoded;charset=utf-8"
83
+ JSON_UTF8 = 'application/json;charset=utf-8'
84
+ FORM_UTF8 = 'application/x-www-form-urlencoded;charset=utf-8'
87
85
 
88
86
  private
89
87
 
90
88
  def json_get(target, path = nil, style = nil, headers = {})
91
89
  raise ArgumentError unless style.nil? || style.is_a?(Symbol)
92
- json_parse_reply(style, *http_get(target, path, headers.merge("accept" => JSON_UTF8)))
90
+ json_parse_reply(style, *http_get(target, path, headers.merge('accept' => JSON_UTF8)))
93
91
  end
94
92
 
95
93
  def json_post(target, path, body, headers = {})
96
- http_post(target, path, Util.json(body), headers.merge("content-type" => JSON_UTF8))
94
+ http_post(target, path, Util.json(body), headers.merge('content-type' => JSON_UTF8))
97
95
  end
98
96
 
99
97
  def json_put(target, path, body, headers = {})
100
- http_put(target, path, Util.json(body), headers.merge("content-type" => JSON_UTF8))
98
+ http_put(target, path, Util.json(body), headers.merge('content-type' => JSON_UTF8))
101
99
  end
102
100
 
103
101
  def json_patch(target, path, body, headers = {})
104
- http_patch(target, path, Util.json(body), headers.merge("content-type" => JSON_UTF8))
102
+ http_patch(target, path, Util.json(body), headers.merge('content-type' => JSON_UTF8))
105
103
  end
106
104
 
107
105
  def json_parse_reply(style, status, body, headers)
@@ -110,17 +108,17 @@ module Http
110
108
  raise (status == 404 ? NotFound : BadResponse), "invalid status response: #{status}"
111
109
  end
112
110
  if body && !body.empty? && (status == 204 || headers.nil? ||
113
- headers["content-type"] !~ /application\/json/i)
114
- raise BadResponse, "received invalid response content or type"
111
+ headers['content-type'] !~ /application\/json/i)
112
+ raise BadResponse, 'received invalid response content or type'
115
113
  end
116
114
  parsed_reply = Util.json_parse(body, style)
117
115
  if status >= 400
118
- raise parsed_reply && parsed_reply["error"] == "invalid_token" ?
119
- InvalidToken.new(parsed_reply) : TargetError.new(parsed_reply), "error response"
116
+ raise parsed_reply && parsed_reply['error'] == 'invalid_token' ?
117
+ InvalidToken.new(parsed_reply) : TargetError.new(parsed_reply), 'error response'
120
118
  end
121
119
  parsed_reply
122
120
  rescue DecodeError
123
- raise BadResponse, "invalid JSON response"
121
+ raise BadResponse, 'invalid JSON response'
124
122
  end
125
123
 
126
124
  def http_get(target, path = nil, headers = {}) request(target, :get, path, nil, headers) end
@@ -129,7 +127,7 @@ module Http
129
127
  def http_patch(target, path, body, headers = {}) request(target, :patch, path, body, headers) end
130
128
 
131
129
  def http_delete(target, path, authorization, zone = nil)
132
- hdrs = { "authorization" => authorization }
130
+ hdrs = { 'authorization' => authorization }
133
131
  hdrs['X-Identity-Zone-Subdomain'] = zone if zone
134
132
  status = request(target, :delete, path, nil, hdrs)[0]
135
133
  unless [200, 204].include?(status)
@@ -138,7 +136,7 @@ module Http
138
136
  end
139
137
 
140
138
  def request(target, method, path, body = nil, headers = {})
141
- headers["accept"] = headers["content-type"] if headers["content-type"] && !headers["accept"]
139
+ headers['accept'] = headers['content-type'] if headers['content-type'] && !headers['accept']
142
140
  url = "#{target}#{path}"
143
141
 
144
142
  logger.debug { "--->\nrequest: #{method} #{url}\n" +
@@ -156,44 +154,49 @@ module Http
156
154
  end
157
155
 
158
156
  def net_http_request(url, method, body, headers)
159
- raise ArgumentError unless reqtype = {:delete => Net::HTTP::Delete,
160
- :get => Net::HTTP::Get, :post => Net::HTTP::Post, :put => Net::HTTP::Put, :patch => Net::HTTP::Patch}[method]
161
- headers["content-length"] = body.length if body
162
157
  uri = URI.parse(url)
163
- req = reqtype.new(uri.request_uri)
164
- headers.each { |k, v| req[k] = v }
165
158
  http = http_request(uri)
166
- reply, outhdrs = http.request(req, body), {}
167
- reply.each_header { |k, v| outhdrs[k] = v }
168
- [reply.code.to_i, reply.body, outhdrs]
159
+ headers['content-length'] = body.length.to_s if body
160
+ case method
161
+ when :get, :delete
162
+ response = http.send(method, uri, nil, headers)
163
+ when :post, :put, :patch
164
+ response = http.send(method, uri, body, headers)
165
+ else
166
+ raise ArgumentError
167
+ end
169
168
 
169
+ unless response.status
170
+ raise HTTPException.new "Can't parse response from the server #{response.content}"
171
+ end
172
+ response_headers = {}
173
+ response.header.all.each { |k, v| response_headers[k.downcase] = v }
174
+ return [response.status.to_i, response.content, response_headers]
170
175
  rescue OpenSSL::SSL::SSLError => e
171
176
  raise SSLException, "Invalid SSL Cert for #{url}. Use '--skip-ssl-validation' to continue with an insecure target"
172
177
  rescue URI::Error, SocketError, SystemCallError => e
173
178
  raise BadTarget, "error: #{e.message}"
174
- rescue Net::HTTPBadResponse => e
175
- raise HTTPException, "HTTP exception: #{e.class}: #{e}"
176
179
  end
177
180
 
178
181
  def http_request(uri)
179
- cache_key = URI.join(uri.to_s, "/")
182
+ cache_key = URI.join(uri.to_s, '/')
180
183
  @http_cache ||= {}
181
184
  return @http_cache[cache_key] if @http_cache[cache_key]
182
185
 
183
- http = Net::HTTP.new(uri.host, uri.port, *proxy_options_for(uri))
184
-
185
186
  if uri.is_a?(URI::HTTPS)
186
- http.use_ssl = true
187
-
188
- if skip_ssl_validation
189
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
190
- elsif ssl_ca_file
191
- http.ca_file = File.expand_path(ssl_ca_file)
192
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
193
- elsif ssl_cert_store
194
- http.cert_store = ssl_cert_store
195
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
187
+ http = HTTPClient.new.tap do |c|
188
+ if skip_ssl_validation
189
+ c.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
190
+ elsif ssl_ca_file
191
+ c.ssl_config.set_trust_ca File.expand_path(ssl_ca_file)
192
+ c.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER
193
+ elsif ssl_cert_store
194
+ c.ssl_config.cert_store = ssl_cert_store
195
+ c.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER
196
+ end
196
197
  end
198
+ else
199
+ http = HTTPClient.new
197
200
  end
198
201
 
199
202
  @http_cache[cache_key] = http
@@ -35,8 +35,6 @@ class Info
35
35
  self.ssl_ca_file = options[:ssl_ca_file]
36
36
  self.ssl_cert_store = options[:ssl_cert_store]
37
37
  self.symbolize_keys = options[:symbolize_keys]
38
- self.http_proxy = options[:http_proxy]
39
- self.https_proxy = options[:https_proxy]
40
38
  end
41
39
 
42
40
  # sets whether the keys in returned hashes should be symbols.
@@ -109,8 +109,6 @@ class Scim
109
109
  self.skip_ssl_validation = options[:skip_ssl_validation]
110
110
  self.ssl_ca_file = options[:ssl_ca_file]
111
111
  self.ssl_cert_store = options[:ssl_cert_store]
112
- self.http_proxy = options[:http_proxy]
113
- self.https_proxy = options[:https_proxy]
114
112
  @zone = options[:zone]
115
113
  end
116
114
 
@@ -113,7 +113,7 @@ class TokenCoder
113
113
  signature = Util.decode64(crypto_segment)
114
114
  if ["HS256", "HS384", "HS512"].include?(algo)
115
115
  raise InvalidSignature, "Signature verification failed" unless
116
- options[:skey] && signature == OpenSSL::HMAC.digest(init_digest(algo), options[:skey], signing_input)
116
+ options[:skey] && constant_time_compare(signature, OpenSSL::HMAC.digest(init_digest(algo), options[:skey], signing_input))
117
117
  elsif ["RS256", "RS384", "RS512"].include?(algo)
118
118
  raise InvalidSignature, "Signature verification failed" unless
119
119
  options[:pkey] && options[:pkey].verify(init_digest(algo), signature, signing_input)
@@ -123,6 +123,24 @@ class TokenCoder
123
123
  payload
124
124
  end
125
125
 
126
+ # Takes constant time to compare 2 strings (HMAC digests in this case)
127
+ # to avoid timing attacks while comparing the HMAC digests
128
+ # @param [String] a: the first digest to compare
129
+ # @param [String] b: the second digest to compare
130
+ # @return [boolean] true if they are equal, false otherwise
131
+ def self.constant_time_compare(a, b)
132
+ if a.length != b.length
133
+ return false
134
+ end
135
+
136
+ result = 0
137
+ a.chars.zip(b.chars).each do |x, y|
138
+ result |= x.ord ^ y.ord
139
+ end
140
+
141
+ result == 0
142
+ end
143
+
126
144
  # Creates a new token en/decoder for a service that is associated with
127
145
  # the the audience_ids, the symmetrical token validation key, and the
128
146
  # public and/or private keys.
@@ -112,8 +112,6 @@ class TokenIssuer
112
112
  self.skip_ssl_validation = options[:skip_ssl_validation]
113
113
  self.ssl_ca_file = options[:ssl_ca_file]
114
114
  self.ssl_cert_store = options[:ssl_cert_store]
115
- self.http_proxy = options[:http_proxy]
116
- self.https_proxy = options[:https_proxy]
117
115
  end
118
116
 
119
117
  # Allows an app to discover what credentials are required for
@@ -14,6 +14,6 @@
14
14
  # Cloud Foundry namespace
15
15
  module CF
16
16
  module UAA
17
- VERSION = "3.6.0"
17
+ VERSION = "3.7.0"
18
18
  end
19
19
  end
@@ -15,83 +15,102 @@ require 'spec_helper'
15
15
  require 'uaa/http'
16
16
  require 'uaa/version'
17
17
 
18
- module CF::UAA
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
- it "sets a request handler" do
31
- http_instance.set_request_handler do |url, method, body, headers|
32
- [200, "body", {"content-type" => "text/plain"}]
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
- it "utilizes proxy settings if given" do
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
- http_instance.http_get("http://example.com")
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
- expect(Net::HTTP).to have_received(:new).with(anything, anything, 'http-proxy.example.com', 1234, 'user', 'password')
50
- end
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
- it "raises an SSLException when the certificate is not valid" do
53
- http_double = double('http').as_null_object
54
- Net::HTTP.stub(:new).and_return(http_double)
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
- expect { http_instance.http_get("https://example.com") }.to raise_error(CF::UAA::SSLException)
58
- end
68
+ context 'when skipping ssl validation' do
69
+ let(:ssl_config) { double('ssl_config') }
59
70
 
60
- it "skips ssl validation if requested" do
61
- http_double = double('http').as_null_object
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.skip_ssl_validation = true
73
+
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
64
79
 
65
- http_instance.http_get("https://example.com")
66
- expect(http_double).not_to have_received(:verify_mode=)
80
+ context 'when validating ssl' do
81
+ it 'does not set verify mode' do
82
+ expect(http_double).not_to receive(:ssl_config)
83
+ http_instance.http_get('https://example.com')
84
+ end
85
+ end
67
86
 
68
- http_instance.skip_ssl_validation = true
69
- http_instance.http_get("https://uncached.example.com")
70
- expect(http_double).to have_received(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
71
- end
87
+ context 'when ssl certificate is provided' do
72
88
 
73
- it "passes ssl certificate file if provided" do
74
- http_double = double('http').as_null_object
75
- Net::HTTP.stub(:new).and_return(http_double)
89
+ let(:ssl_config) { double('ssl_config') }
76
90
 
77
- http_instance.ssl_ca_file = "/fake-ca-file"
78
- http_instance.http_get("https://uncached.example.com")
91
+ it 'passes it' do
92
+ http_instance.ssl_ca_file = '/fake-ca-file'
79
93
 
80
- expect(http_double).to have_received(:ca_file=).with("/fake-ca-file")
81
- expect(http_double).to have_received(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
82
- end
94
+ expect(http_double).to receive(:ssl_config).and_return(ssl_config).twice
95
+ expect(ssl_config).to receive(:set_trust_ca).with('/fake-ca-file')
96
+ expect(ssl_config).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
83
97
 
84
- it "passes ssl cert store if provided" do
85
- http_double = double('http').as_null_object
86
- cert_store = double('OpenSSL::X509::Store')
87
- Net::HTTP.stub(:new).and_return(http_double)
98
+ http_instance.http_get('https://uncached.example.com')
99
+ end
100
+ end
88
101
 
89
- http_instance.ssl_cert_store = cert_store
90
- http_instance.http_get("https://uncached.example.com")
102
+ context 'when ssl cert store is provided' do
103
+ let(:ssl_config) { double('ssl_config') }
91
104
 
92
- expect(http_double).to have_received(:cert_store=).with(cert_store)
93
- expect(http_double).to have_received(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
94
- end
95
- end
105
+ it 'passes it' do
106
+ http_instance.ssl_cert_store = cert_store
107
+
108
+ expect(http_double).to receive(:ssl_config).and_return(ssl_config).twice
109
+ expect(ssl_config).to receive(:cert_store=).with(cert_store)
110
+ expect(ssl_config).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
96
111
 
97
- end
112
+ http_instance.http_get('https://uncached.example.com')
113
+ end
114
+ end
115
+ end
116
+ end
@@ -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) { "https://login.cloudfoundry.com" }
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["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"}]
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 "initialize" do
37
- let(:options) { {:http_proxy => 'http-proxy.com', :https_proxy => 'https-proxy.com', :skip_ssl_validation => true} }
36
+ describe 'initialize' do
37
+ let(:options) { {:skip_ssl_validation => true} }
38
38
 
39
- it "sets proxy information" do
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 "getting server info" do
47
- let(:target_url) { "https://login.cloudfoundry.com/login" }
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 "gets server info" do
48
+ it 'gets server info' do
51
49
  result = uaa_info.server
52
- result["prompts"].should_not be_nil
53
- result["commit_id"].should_not be_nil
50
+ result['prompts'].should_not be_nil
51
+ result['commit_id'].should_not be_nil
54
52
  end
55
53
 
56
- context "with symbolize_keys keys true" do
54
+ context 'with symbolize_keys keys true' do
57
55
  let(:options) { {:symbolize_keys => true} }
58
56
 
59
- it "gets server info" do
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 "getting UAA target" do
68
- let(:target) { "https://login.cloudfoundry.com" }
69
- let(:target_url) { "https://login.cloudfoundry.com/login" }
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 "gets UAA target" do
70
+ it 'gets UAA target' do
73
71
  result = uaa_info.discover_uaa
74
- result.should == "https://uaa.cloudfoundry.com"
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) { "https://uaa.cloudfoundry.com" }
79
- let(:target_url) { "https://uaa.cloudfoundry.com/login" }
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 "returns the target url" do
80
+ it 'returns the target url' do
83
81
  result = uaa_info.discover_uaa
84
- result.should == "https://uaa.cloudfoundry.com"
82
+ result.should == 'https://uaa.cloudfoundry.com'
85
83
  end
86
84
  end
87
85
 
88
- context "with symbolize_keys keys true" do
86
+ context 'with symbolize_keys keys true' do
89
87
  let(:options) { {:symbolize_keys => true} }
90
88
 
91
- it "gets UAA target" do
89
+ it 'gets UAA target' do
92
90
  result = uaa_info.discover_uaa
93
- result.should == "https://uaa.cloudfoundry.com"
91
+ result.should == 'https://uaa.cloudfoundry.com'
94
92
  end
95
93
  end
96
94
  end
97
95
 
98
- describe "whoami" do
99
- let(:target_url) { "https://login.cloudfoundry.com/userinfo?schema=openid" }
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 "returns the user info" do
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 "validation_key" do
110
- let(:target_url) { "https://login.cloudfoundry.com/token_key" }
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 "returns the key data" do
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 "validation keys" do
120
- let(:target_url) { "https://login.cloudfoundry.com/token_keys" }
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 "returns a hash of keys" do
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']