cf-uaa-lib 1.3.5 → 1.3.6

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.
@@ -26,9 +26,6 @@ class NotFound < UAAError; end
26
26
  # Indicates a syntax error in a response from the UAA, e.g. missing required response field.
27
27
  class BadResponse < UAAError; end
28
28
 
29
- # Indicates a token is malformed or expired.
30
- class InvalidToken < UAAError; end
31
-
32
29
  # Indicates an error from the http client stack.
33
30
  class HTTPException < UAAError; end
34
31
 
@@ -40,6 +37,9 @@ class TargetError < UAAError
40
37
  end
41
38
  end
42
39
 
40
+ # Indicates a token is malformed or expired.
41
+ class InvalidToken < TargetError; end
42
+
43
43
  # Utility accessors and methods for objects that want to access JSON web APIs.
44
44
  module Http
45
45
 
@@ -91,7 +91,7 @@ module Http
91
91
 
92
92
  def json_parse_reply(style, status, body, headers)
93
93
  raise ArgumentError unless style.nil? || style.is_a?(Symbol)
94
- unless [200, 201, 204, 400, 401, 403].include? status
94
+ unless [200, 201, 204, 400, 401, 403, 409].include? status
95
95
  raise (status == 404 ? NotFound : BadResponse), "invalid status response: #{status}"
96
96
  end
97
97
  if body && !body.empty? && (status == 204 || headers.nil? ||
@@ -99,9 +99,9 @@ module Http
99
99
  raise BadResponse, "received invalid response content or type"
100
100
  end
101
101
  parsed_reply = Util.json_parse(body, style)
102
- if status >= 400
102
+ if status >= 400
103
103
  raise parsed_reply && parsed_reply["error"] == "invalid_token" ?
104
- InvalidToken : TargetError.new(parsed_reply), "error response"
104
+ InvalidToken.new(parsed_reply) : TargetError.new(parsed_reply), "error response"
105
105
  end
106
106
  parsed_reply
107
107
  rescue DecodeError
@@ -133,8 +133,7 @@ module Http
133
133
  [status, body, headers]
134
134
 
135
135
  rescue Exception => e
136
- e.message.replace "Target #{target}, #{e.message}"
137
- logger.debug { "<---- no response due to exception: #{e}" }
136
+ logger.debug { "<---- no response due to exception: #{e.inspect}" }
138
137
  raise e
139
138
  end
140
139
 
@@ -16,6 +16,17 @@ require "uaa/util"
16
16
 
17
17
  module CF::UAA
18
18
 
19
+ # this code does not support the given token signature algorithim
20
+ class SignatureNotSupported < DecodeError; end
21
+
22
+ # this instance policy does not accept the given token signature algorithim
23
+ class SignatureNotAccepted < DecodeError; end
24
+
25
+ class InvalidSignature < DecodeError; end
26
+ class InvalidTokenFormat < DecodeError; end
27
+ class TokenExpired < AuthError; end
28
+ class InvalidAudience < AuthError; end
29
+
19
30
  # This class is for OAuth Resource Servers.
20
31
  # Resource Servers get tokens and need to validate and decode them,
21
32
  # but they do not obtain them from the Authorization Server. This
@@ -68,7 +79,7 @@ class TokenCoder
68
79
  elsif algo == "none"
69
80
  sig = ""
70
81
  else
71
- raise ArgumentError, "unsupported signing method"
82
+ raise SignatureNotSupported, "unsupported signing method"
72
83
  end
73
84
  segments << Util.encode64(sig)
74
85
  segments.join('.')
@@ -90,24 +101,24 @@ class TokenCoder
90
101
  end
91
102
  options = normalize_options(options)
92
103
  segments = token.split('.')
93
- raise DecodeError, "Not enough or too many segments" unless [2,3].include? segments.length
104
+ raise InvalidTokenFormat, "Not enough or too many segments" unless [2,3].include? segments.length
94
105
  header_segment, payload_segment, crypto_segment = segments
95
106
  signing_input = [header_segment, payload_segment].join('.')
96
107
  header = Util.json_decode64(header_segment)
97
108
  payload = Util.json_decode64(payload_segment, (:sym if options[:symbolize_keys]))
98
109
  return payload unless options[:verify]
99
- raise DecodeError, "Signature algorithm not accepted" unless
110
+ raise SignatureNotAccepted, "Signature algorithm not accepted" unless
100
111
  options[:accept_algorithms].include?(algo = header["alg"])
101
112
  return payload if algo == 'none'
102
113
  signature = Util.decode64(crypto_segment)
103
114
  if ["HS256", "HS384", "HS512"].include?(algo)
104
- raise DecodeError, "Signature verification failed" unless
115
+ raise InvalidSignature, "Signature verification failed" unless
105
116
  signature == OpenSSL::HMAC.digest(init_digest(algo), options[:skey], signing_input)
106
117
  elsif ["RS256", "RS384", "RS512"].include?(algo)
107
- raise DecodeError, "Signature verification failed" unless
118
+ raise InvalidSignature, "Signature verification failed" unless
108
119
  options[:pkey].verify(init_digest(algo), signature, signing_input)
109
120
  else
110
- raise DecodeError, "Algorithm not supported"
121
+ raise SignatureNotSupported, "Algorithm not supported"
111
122
  end
112
123
  payload
113
124
  end
@@ -166,16 +177,16 @@ class TokenCoder
166
177
  # @return (see TokenCoder.decode)
167
178
  def decode(auth_header)
168
179
  unless auth_header && (tkn = auth_header.split(' ')).length == 2 && tkn[0] =~ /^bearer$/i
169
- raise DecodeError, "invalid authentication header: #{auth_header}"
180
+ raise InvalidTokenFormat, "invalid authentication header: #{auth_header}"
170
181
  end
171
182
  reply = self.class.decode(tkn[1], @options)
172
183
  auds = Util.arglist(reply[:aud] || reply['aud'])
173
184
  if @options[:audience_ids] && (!auds || (auds & @options[:audience_ids]).empty?)
174
- raise AuthError, "invalid audience: #{auds}"
185
+ raise InvalidAudience, "invalid audience: #{auds}"
175
186
  end
176
187
  exp = reply[:exp] || reply['exp']
177
188
  unless exp.is_a?(Integer) && exp > Time.now.to_i
178
- raise AuthError, "token expired"
189
+ raise TokenExpired, "token expired"
179
190
  end
180
191
  reply
181
192
  end
@@ -14,6 +14,6 @@
14
14
  # Cloud Foundry namespace
15
15
  module CF
16
16
  module UAA
17
- VERSION = "1.3.5"
17
+ VERSION = "1.3.6"
18
18
  end
19
19
  end
@@ -26,9 +26,9 @@ describe TokenCoder do
26
26
  @tkn_secret = "test_secret"
27
27
  end
28
28
 
29
- it "raises a decode error if the given auth header is bad" do
30
- expect { subject.decode(nil) }.to raise_exception(DecodeError)
31
- expect { subject.decode("one two three") }.to raise_exception(DecodeError)
29
+ it "raises error if the given auth header is bad" do
30
+ expect { subject.decode(nil) }.to raise_exception(InvalidTokenFormat)
31
+ expect { subject.decode("one two three") }.to raise_exception(InvalidTokenFormat)
32
32
  end
33
33
 
34
34
  it "encodes/decodes a token using a symmetrical key" do
@@ -73,37 +73,40 @@ describe TokenCoder do
73
73
 
74
74
  it "rejects a token with 'none' signature by default" do
75
75
  tkn = subject.encode(@tkn_body, 'none')
76
- expect { TokenCoder.decode(tkn) }.to raise_exception(DecodeError)
76
+ expect { TokenCoder.decode(tkn) }.to raise_exception(SignatureNotAccepted)
77
77
  end
78
78
 
79
79
  it "raises an error if the signing algorithm is not supported" do
80
- expect { subject.encode(@tkn_body, 'baz') }.to raise_exception(ArgumentError)
80
+ expect { subject.encode(@tkn_body, 'baz') }.to raise_exception(SignatureNotSupported)
81
81
  end
82
82
 
83
- it "raises an auth error if the token is for another resource server" do
83
+ it "raises an error if the token is for another resource server" do
84
84
  tkn = subject.encode({'aud' => ["other_resource"], 'foo' => "bar"})
85
- expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(AuthError)
85
+ expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(InvalidAudience)
86
86
  end
87
87
 
88
- it "raises a decode error if the token is signed by an unknown signing key" do
88
+ it "raises an error if the token is signed by an unknown signing key" do
89
89
  other = TokenCoder.new(:audience_ids => "test_resource", :skey => "other_secret")
90
90
  tkn = other.encode(@tkn_body)
91
- expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(DecodeError)
91
+ expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(InvalidSignature)
92
92
  end
93
93
 
94
- it "raises a decode error if the token is an unknown signing algorithm" do
94
+ it "raises an error if the token is an unknown signing algorithm" do
95
95
  segments = [Util.json_encode64(:typ => "JWT", :alg =>"BADALGO")]
96
96
  segments << Util.json_encode64(@tkn_body)
97
97
  segments << Util.encode64("BADSIG")
98
98
  tkn = segments.join('.')
99
- expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(DecodeError)
99
+ tc = TokenCoder.new(:audience_ids => "test_resource",
100
+ :skey => "test_secret", :pkey => OpenSSL::PKey::RSA.generate(512),
101
+ :accept_algorithms => "BADALGO")
102
+ expect { tc.decode("bEaReR #{tkn}") }.to raise_exception(SignatureNotSupported)
100
103
  end
101
104
 
102
- it "raises a decode error if the token is malformed" do
105
+ it "raises an error if the token is malformed" do
103
106
  tkn = "one.two.three.four"
104
- expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(DecodeError)
107
+ expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(InvalidTokenFormat)
105
108
  tkn = "onlyone"
106
- expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(DecodeError)
109
+ expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(InvalidTokenFormat)
107
110
  end
108
111
 
109
112
  it "raises a decode error if a token segment is malformed" do
@@ -114,9 +117,9 @@ describe TokenCoder do
114
117
  expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(DecodeError)
115
118
  end
116
119
 
117
- it "raises an auth error if the token has expired" do
120
+ it "raises an error if the token has expired" do
118
121
  tkn = subject.encode({'foo' => "bar", 'exp' => Time.now.to_i - 60 })
119
- expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(AuthError)
122
+ expect { subject.decode("bEaReR #{tkn}") }.to raise_exception(TokenExpired)
120
123
  end
121
124
 
122
125
  it "decodes a token without validation" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cf-uaa-lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 1.3.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2013-01-22 00:00:00.000000000 Z
16
+ date: 2013-01-29 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: multi_json
@@ -193,12 +193,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
193
193
  - - ! '>='
194
194
  - !ruby/object:Gem::Version
195
195
  version: '0'
196
+ segments:
197
+ - 0
198
+ hash: 1720438765571027333
196
199
  required_rubygems_version: !ruby/object:Gem::Requirement
197
200
  none: false
198
201
  requirements:
199
202
  - - ! '>='
200
203
  - !ruby/object:Gem::Version
201
204
  version: '0'
205
+ segments:
206
+ - 0
207
+ hash: 1720438765571027333
202
208
  requirements: []
203
209
  rubyforge_project: cf-uaa-lib
204
210
  rubygems_version: 1.8.23
@@ -206,4 +212,3 @@ signing_key:
206
212
  specification_version: 3
207
213
  summary: Client library for CloudFoundry UAA
208
214
  test_files: []
209
- has_rdoc: