cf-uaa-lib 3.6.0 → 3.7.0

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 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']