cf-uaa-lib 4.0.7 → 4.0.9
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/.github/workflows/ruby.yml +1 -1
- data/cf-uaa-lib.gemspec +2 -0
- data/lib/uaa/http.rb +1 -0
- data/lib/uaa/scim.rb +7 -1
- data/lib/uaa/token_issuer.rb +3 -0
- data/lib/uaa/version.rb +1 -1
- data/spec/scim_spec.rb +12 -0
- data/spec/token_issuer_spec.rb +101 -0
- metadata +31 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b1bef252c395d0a9dfbd30cb9b4e60be278d01ae09b496d97d7f8665ff273ba5
|
|
4
|
+
data.tar.gz: 0bfd4b2af11ca2261e399bf2c73e4710ba49de67fed16766e22ac110cac19ad9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c7ebce508854b456f17ca0980cbaa10326cc472c81008d0956d5c70401bd671a17a959ab41e6e3d1a4829819985daa9076f4a627c399726249fad9104aa9c787
|
|
7
|
+
data.tar.gz: 0d2a4528589995a7e5b9cf4badef1e8612232fdc07fa1af02bc5ee8d7211ad2e94489af2332f2a4e7271ea0d2bb0e8000361d6f8a446596c070618cc7e8974c9
|
data/.github/workflows/ruby.yml
CHANGED
data/cf-uaa-lib.gemspec
CHANGED
|
@@ -32,6 +32,8 @@ Gem::Specification.new do |s|
|
|
|
32
32
|
|
|
33
33
|
# dependencies
|
|
34
34
|
s.add_dependency 'json', '~>2.7'
|
|
35
|
+
s.add_dependency 'mutex_m'
|
|
36
|
+
s.add_dependency 'base64'
|
|
35
37
|
s.add_dependency 'httpclient', '~> 2.8', '>= 2.8.2.4'
|
|
36
38
|
s.add_dependency 'addressable', '~> 2.8', '>= 2.8.0'
|
|
37
39
|
|
data/lib/uaa/http.rb
CHANGED
data/lib/uaa/scim.rb
CHANGED
|
@@ -380,13 +380,19 @@ class Scim
|
|
|
380
380
|
# @param [String] jwks the JSON Web Key Set
|
|
381
381
|
# @param [String] kid If changeMode is DELETE provide the id of key
|
|
382
382
|
# @param [String] changeMode Change mode, possible is ADD, UPDATE, DELETE
|
|
383
|
+
# @param [String] iss Issuer in case of federation JWT trust
|
|
384
|
+
# @param [String] sub Subject in case of federation JWT trust
|
|
385
|
+
# @param [String] aud Audience in case of federation JWT trust
|
|
383
386
|
# @return [Hash] success message from server
|
|
384
|
-
def change_clientjwt(client_id, jwks_uri = nil, jwks = nil, kid = nil, changeMode = nil)
|
|
387
|
+
def change_clientjwt(client_id, jwks_uri = nil, jwks = nil, kid = nil, changeMode = nil, iss = nil, sub = nil, aud = nil)
|
|
385
388
|
req = {"client_id" => client_id }
|
|
386
389
|
req["jwks_uri"] = jwks_uri if jwks_uri
|
|
387
390
|
req["jwks"] = jwks if jwks
|
|
388
391
|
req["kid"] = kid if kid
|
|
389
392
|
req["changeMode"] = changeMode if changeMode
|
|
393
|
+
req["iss"] = iss if iss
|
|
394
|
+
req["sub"] = sub if sub
|
|
395
|
+
req["aud"] = aud if aud
|
|
390
396
|
json_parse_reply(@key_style, *json_put(@target,
|
|
391
397
|
"#{type_info(:client, :path)}/#{Addressable::URI.encode(client_id)}/clientjwt", req, headers))
|
|
392
398
|
end
|
data/lib/uaa/token_issuer.rb
CHANGED
|
@@ -83,6 +83,9 @@ class TokenIssuer
|
|
|
83
83
|
headers['X-CF-ENCODED-CREDENTIALS'] = 'true'
|
|
84
84
|
headers['authorization'] = Http.basic_auth(CGI.escape(@client_id), CGI.escape(@client_secret))
|
|
85
85
|
end
|
|
86
|
+
elsif @client_auth_method == 'client_secret_post' && @client_secret && @client_id
|
|
87
|
+
params[:client_id] = @client_id
|
|
88
|
+
params[:client_secret] = @client_secret
|
|
86
89
|
elsif @client_id && params[:code_verifier]
|
|
87
90
|
params[:client_id] = @client_id
|
|
88
91
|
else
|
data/lib/uaa/version.rb
CHANGED
data/spec/scim_spec.rb
CHANGED
|
@@ -184,6 +184,18 @@ describe Scim do
|
|
|
184
184
|
result['id'].should == 'id12345'
|
|
185
185
|
end
|
|
186
186
|
|
|
187
|
+
it "add federated client's jwt trust using issuer, subject and audience" do
|
|
188
|
+
subject.set_request_handler do |url, method, body, headers|
|
|
189
|
+
url.should == "#{@target}/oauth/clients/id12345/clientjwt"
|
|
190
|
+
method.should == :put
|
|
191
|
+
check_headers(headers, :json, :json, nil)
|
|
192
|
+
body.should include('"iss":"issuer"', '"sub":"subject"', '"aud":"audience"')
|
|
193
|
+
[200, '{"id":"id12345"}', {'content-type' => 'application/json'}]
|
|
194
|
+
end
|
|
195
|
+
result = subject.change_clientjwt('id12345', jwks_uri=nil, jwks=nil, kid=nil, changemod='ADD', iss='issuer', sub='subject', aud='audience')
|
|
196
|
+
result['id'].should == 'id12345'
|
|
197
|
+
end
|
|
198
|
+
|
|
187
199
|
it 'unlocks a user' do
|
|
188
200
|
subject.set_request_handler do |url, method, body, headers|
|
|
189
201
|
url.should == "#{@target}/Users/id12345/status"
|
data/spec/token_issuer_spec.rb
CHANGED
|
@@ -310,6 +310,41 @@ describe TokenIssuer do
|
|
|
310
310
|
|
|
311
311
|
end
|
|
312
312
|
|
|
313
|
+
|
|
314
|
+
context 'with basic_auth using auth code grant' do
|
|
315
|
+
let(:options) { {basic_auth: true} }
|
|
316
|
+
|
|
317
|
+
it 'basic_auth with authorization code' do
|
|
318
|
+
subject.set_request_handler do |url, method, body, headers|
|
|
319
|
+
headers['content-type'].should =~ /application\/x-www-form-urlencoded/
|
|
320
|
+
headers['accept'].should =~ /application\/json/
|
|
321
|
+
headers['X-CF-ENCODED-CREDENTIALS'].should_not
|
|
322
|
+
headers['authorization'].should == 'Basic dGVzdF9jbGllbnQ6dGVzdCFzZWNyZXQ='
|
|
323
|
+
params = Util.decode_form(body)
|
|
324
|
+
params['code_verifier'].should_not
|
|
325
|
+
params['grant_type'].should == 'authorization_code'
|
|
326
|
+
url.should match 'http://test.uaa.target/oauth/token'
|
|
327
|
+
method.should == :post
|
|
328
|
+
reply = {access_token: 'test_access_token', token_type: 'BEARER',
|
|
329
|
+
scope: 'openid', expires_in: 98765}
|
|
330
|
+
[200, Util.json(reply), {'content-type' => 'application/json'}]
|
|
331
|
+
end
|
|
332
|
+
cburi = 'http://call.back/uri_path'
|
|
333
|
+
params = Util.decode_form(cburi[1])
|
|
334
|
+
params['code_challenge'].should_not
|
|
335
|
+
params['code_challenge_method'].should_not
|
|
336
|
+
redir_uri = subject.authcode_uri(cburi)
|
|
337
|
+
state = /state=([^&]+)/.match(redir_uri)[1]
|
|
338
|
+
reply_query = "state=#{state}&code=kz8%2F5gQZ2pc%3D"
|
|
339
|
+
token = subject.authcode_grant(redir_uri, reply_query)
|
|
340
|
+
token.should be_an_instance_of TokenInfo
|
|
341
|
+
token.info['access_token'].should == 'test_access_token'
|
|
342
|
+
token.info['token_type'].should =~ /^bearer$/i
|
|
343
|
+
token.info['scope'].should == 'openid'
|
|
344
|
+
token.info['expires_in'].should == 98765
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
313
348
|
context 'pkce with own code verifier' do
|
|
314
349
|
let(:options) { {basic_auth: false, code_verifier: 'umoq1e_4XMYXvfHlaO9mSlSI17OKfxnwfR5ZD-oYreFxyn8yQZ-ZHPZfUZ4n3WjY_tkOB_MAisSy4ddqsa6aoTU5ZOcX4ps3de933PczYlC8pZpKL8EQWaDZOnpOyB2W'} }
|
|
315
350
|
|
|
@@ -324,6 +359,38 @@ describe TokenIssuer do
|
|
|
324
359
|
code_verifier.should == options[:code_verifier]
|
|
325
360
|
code_challenge.should == 'TAnM2AKGgiQKOC16cRpMdF_55qwmz3B333cq6T18z0s'
|
|
326
361
|
end
|
|
362
|
+
|
|
363
|
+
let(:client_secret) { nil }
|
|
364
|
+
it 'public token request with pkce without client_secret' do
|
|
365
|
+
subject.set_request_handler do |url, method, body, headers|
|
|
366
|
+
headers['content-type'].should =~ /application\/x-www-form-urlencoded/
|
|
367
|
+
headers['accept'].should =~ /application\/json/
|
|
368
|
+
headers['X-CF-ENCODED-CREDENTIALS'].should_not
|
|
369
|
+
headers['authorization'].should_not
|
|
370
|
+
params = Util.decode_form(body)
|
|
371
|
+
params['code_verifier'].should_not
|
|
372
|
+
params['grant_type'].should == 'authorization_code'
|
|
373
|
+
params['client_secret'].should_not
|
|
374
|
+
url.should match 'http://test.uaa.target/oauth/token'
|
|
375
|
+
method.should == :post
|
|
376
|
+
reply = {access_token: 'test_access_token', token_type: 'BEARER',
|
|
377
|
+
scope: 'openid', expires_in: 98765}
|
|
378
|
+
[200, Util.json(reply), {'content-type' => 'application/json'}]
|
|
379
|
+
end
|
|
380
|
+
cburi = 'http://call.back/uri_path'
|
|
381
|
+
params = Util.decode_form(cburi[1])
|
|
382
|
+
params['code_challenge'].should_not
|
|
383
|
+
params['code_challenge_method'].should_not
|
|
384
|
+
redir_uri = subject.authcode_uri(cburi)
|
|
385
|
+
state = /state=([^&]+)/.match(redir_uri)[1]
|
|
386
|
+
reply_query = "state=#{state}&code=kz8%2F5gQZ2pc%3D"
|
|
387
|
+
token = subject.authcode_grant(redir_uri, reply_query)
|
|
388
|
+
token.should be_an_instance_of TokenInfo
|
|
389
|
+
token.info['access_token'].should == 'test_access_token'
|
|
390
|
+
token.info['token_type'].should =~ /^bearer$/i
|
|
391
|
+
token.info['scope'].should == 'openid'
|
|
392
|
+
token.info['expires_in'].should == 98765
|
|
393
|
+
end
|
|
327
394
|
end
|
|
328
395
|
|
|
329
396
|
context 'no pkce active as this is the default' do
|
|
@@ -338,6 +405,40 @@ describe TokenIssuer do
|
|
|
338
405
|
end
|
|
339
406
|
end
|
|
340
407
|
|
|
408
|
+
context 'with client_auth_method using client_secret_post' do
|
|
409
|
+
let(:options) { {client_auth_method: 'client_secret_post'} }
|
|
410
|
+
let(:client_secret) { 'body!secret' }
|
|
411
|
+
|
|
412
|
+
it 'use client_secret_post in authorization code and expect client_id and secret in body' do
|
|
413
|
+
subject.set_request_handler do |url, method, body, headers|
|
|
414
|
+
headers['content-type'].should =~ /application\/x-www-form-urlencoded/
|
|
415
|
+
headers['accept'].should =~ /application\/json/
|
|
416
|
+
headers['X-CF-ENCODED-CREDENTIALS'].should_not
|
|
417
|
+
headers['authorization'].should_not
|
|
418
|
+
params = Util.decode_form(body)
|
|
419
|
+
params['code_verifier'].should_not
|
|
420
|
+
params['grant_type'].should == 'authorization_code'
|
|
421
|
+
params['client_id'].should == 'test_client'
|
|
422
|
+
params['client_secret'].should == 'body!secret'
|
|
423
|
+
url.should match 'http://test.uaa.target/oauth/token'
|
|
424
|
+
method.should == :post
|
|
425
|
+
reply = {access_token: 'test_access_token', token_type: 'BEARER',
|
|
426
|
+
scope: 'openid', expires_in: 98765}
|
|
427
|
+
[200, Util.json(reply), {'content-type' => 'application/json'}]
|
|
428
|
+
end
|
|
429
|
+
cburi = 'http://call.back/uri_path'
|
|
430
|
+
redir_uri = subject.authcode_uri(cburi)
|
|
431
|
+
state = /state=([^&]+)/.match(redir_uri)[1]
|
|
432
|
+
reply_query = "state=#{state}&code=kz8%2F5gQZ2pc%3D"
|
|
433
|
+
token = subject.authcode_grant(redir_uri, reply_query)
|
|
434
|
+
token.should be_an_instance_of TokenInfo
|
|
435
|
+
token.info['access_token'].should == 'test_access_token'
|
|
436
|
+
token.info['token_type'].should =~ /^bearer$/i
|
|
437
|
+
token.info['scope'].should == 'openid'
|
|
438
|
+
token.info['expires_in'].should == 98765
|
|
439
|
+
end
|
|
440
|
+
end
|
|
441
|
+
|
|
341
442
|
end
|
|
342
443
|
|
|
343
444
|
end
|
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: 4.0.
|
|
4
|
+
version: 4.0.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dave Syer
|
|
@@ -9,10 +9,9 @@ authors:
|
|
|
9
9
|
- Joel D'sa
|
|
10
10
|
- Vidya Valmikinathan
|
|
11
11
|
- Luke Taylor
|
|
12
|
-
autorequire:
|
|
13
12
|
bindir: bin
|
|
14
13
|
cert_chain: []
|
|
15
|
-
date:
|
|
14
|
+
date: 2025-02-19 00:00:00.000000000 Z
|
|
16
15
|
dependencies:
|
|
17
16
|
- !ruby/object:Gem::Dependency
|
|
18
17
|
name: json
|
|
@@ -28,6 +27,34 @@ dependencies:
|
|
|
28
27
|
- - "~>"
|
|
29
28
|
- !ruby/object:Gem::Version
|
|
30
29
|
version: '2.7'
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: mutex_m
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
requirements:
|
|
34
|
+
- - ">="
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: '0'
|
|
37
|
+
type: :runtime
|
|
38
|
+
prerelease: false
|
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
44
|
+
- !ruby/object:Gem::Dependency
|
|
45
|
+
name: base64
|
|
46
|
+
requirement: !ruby/object:Gem::Requirement
|
|
47
|
+
requirements:
|
|
48
|
+
- - ">="
|
|
49
|
+
- !ruby/object:Gem::Version
|
|
50
|
+
version: '0'
|
|
51
|
+
type: :runtime
|
|
52
|
+
prerelease: false
|
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: '0'
|
|
31
58
|
- !ruby/object:Gem::Dependency
|
|
32
59
|
name: httpclient
|
|
33
60
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -232,7 +259,6 @@ homepage: https://github.com/cloudfoundry/cf-uaa-lib
|
|
|
232
259
|
licenses:
|
|
233
260
|
- Apache-2.0
|
|
234
261
|
metadata: {}
|
|
235
|
-
post_install_message:
|
|
236
262
|
rdoc_options: []
|
|
237
263
|
require_paths:
|
|
238
264
|
- lib
|
|
@@ -247,8 +273,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
247
273
|
- !ruby/object:Gem::Version
|
|
248
274
|
version: '0'
|
|
249
275
|
requirements: []
|
|
250
|
-
rubygems_version: 3.
|
|
251
|
-
signing_key:
|
|
276
|
+
rubygems_version: 3.6.2
|
|
252
277
|
specification_version: 4
|
|
253
278
|
summary: Client library for CloudFoundry UAA
|
|
254
279
|
test_files: []
|