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 +4 -4
- data/cf-uaa-lib.gemspec +1 -0
- data/lib/uaa/http.rb +45 -42
- data/lib/uaa/info.rb +0 -2
- data/lib/uaa/scim.rb +0 -2
- data/lib/uaa/token_coder.rb +19 -1
- data/lib/uaa/token_issuer.rb +0 -2
- data/lib/uaa/version.rb +1 -1
- data/spec/http_spec.rb +74 -55
- data/spec/info_spec.rb +36 -38
- data/spec/integration_spec.rb +173 -110
- data/spec/scim_spec.rb +75 -80
- data/spec/token_issuer_spec.rb +130 -135
- metadata +16 -3
- data/lib/uaa/proxy_options.rb +0 -30
data/spec/integration_spec.rb
CHANGED
@@ -15,135 +15,198 @@ require 'spec_helper'
|
|
15
15
|
require 'uaa'
|
16
16
|
require 'pp'
|
17
17
|
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
18
|
+
# ENV['UAA_CLIENT_ID'] = 'admin'
|
19
|
+
# ENV['UAA_CLIENT_SECRET'] = 'admin_secret'
|
20
|
+
# ENV['UAA_CLIENT_TARGET'] = 'https://login.identity.cf-app.com'
|
21
|
+
# ENV['UAA_CLIENT_TARGET'] = 'http://localhost:8080/uaa'
|
22
22
|
|
23
|
-
|
23
|
+
#Set this variable if you want to test skip_ssl_validation option.
|
24
|
+
#Make sure that UAA_CLIENT_TARGET points to https endpoint with self-signed certificate.
|
25
|
+
#It will run all the tests with ssl validation set to false
|
26
|
+
# ENV['SKIP_SSL_VALIDATION'] = 'yes'
|
24
27
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def create_test_client
|
30
|
-
toki = TokenIssuer.new(@target, @admin_client, @admin_secret)
|
31
|
-
cr = Scim.new(@target, toki.client_credentials_grant.auth_header, :symbolize_keys => true)
|
32
|
-
@test_client = "test_client_#{Time.now.to_i}"
|
33
|
-
@test_secret = "+=tEsTsEcRet~!@"
|
34
|
-
gids = ["clients.read", "scim.read", "scim.write", "uaa.resource", "password.write"]
|
35
|
-
new_client = cr.add(:client, :client_id => @test_client, :client_secret => @test_secret,
|
36
|
-
:authorities => gids, :authorized_grant_types => ["client_credentials", "password"],
|
37
|
-
:scope => ["openid", "password.write"])
|
38
|
-
new_client[:client_id].should == @test_client
|
39
|
-
@username = "sam_#{Time.now.to_i}"
|
40
|
-
end
|
28
|
+
#Set this variable to test ssl_ca_file option.
|
29
|
+
#Make sure that UAA_CLIENT_TARGET points to https endpoint with self-signed certificate.
|
30
|
+
# ENV['SSL_CA_FILE'] = '~/workspace/identity-cf.cert'
|
41
31
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
@admin_secret = ENV["UAA_CLIENT_SECRET"] || "adminsecret"
|
46
|
-
@target = ENV["UAA_CLIENT_TARGET"]
|
47
|
-
@username = "sam_#{Time.now.to_i}"
|
48
|
-
end
|
32
|
+
#Set this variable to test cert_store option.
|
33
|
+
#Make sure that UAA_CLIENT_TARGET points to https endpoint with self-signed certificate.
|
34
|
+
# ENV['CERT_STORE'] = '~/workspace/identity-cf.cert'
|
49
35
|
|
50
|
-
|
51
|
-
VERSION.should =~ /\d.\d.\d/
|
52
|
-
end
|
36
|
+
module CF::UAA
|
53
37
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
38
|
+
def self.admin_scim(options)
|
39
|
+
admin_client = ENV['UAA_CLIENT_ID'] || 'admin'
|
40
|
+
admin_secret = ENV['UAA_CLIENT_SECRET'] || 'adminsecret'
|
41
|
+
target = ENV['UAA_CLIENT_TARGET']
|
58
42
|
|
59
|
-
|
60
|
-
|
61
|
-
tkn.auth_header.should =~ /^bearer\s/i
|
62
|
-
info = TokenCoder.decode(tkn.info["access_token"], :verify => false, :symbolize_keys => true)
|
63
|
-
info[:exp].should be
|
64
|
-
info[:jti].should be
|
43
|
+
admin_token_issuer = TokenIssuer.new(target, admin_client, admin_secret, options)
|
44
|
+
Scim.new(target, admin_token_issuer.client_credentials_grant.auth_header, options.merge(:symbolize_keys => true))
|
65
45
|
end
|
66
46
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
47
|
+
if ENV['UAA_CLIENT_TARGET']
|
48
|
+
describe 'UAA Integration:' do
|
49
|
+
|
50
|
+
let(:options) { @options }
|
51
|
+
let(:token_issuer) { TokenIssuer.new(@target, @test_client, @test_secret, options) }
|
52
|
+
let(:scim) { Scim.new(@target, token_issuer.client_credentials_grant.auth_header, options.merge(:symbolize_keys => true)) }
|
53
|
+
|
54
|
+
before :all do
|
55
|
+
@options = {}
|
56
|
+
if ENV['SKIP_SSL_VALIDATION']
|
57
|
+
@options = {:skip_ssl_validation => true}
|
58
|
+
end
|
59
|
+
@target = ENV['UAA_CLIENT_TARGET']
|
60
|
+
@test_client = "test_client_#{Time.now.to_i}"
|
61
|
+
@test_secret = '+=tEsTsEcRet~!@'
|
62
|
+
gids = ['clients.read', 'scim.read', 'scim.write', 'uaa.resource', 'password.write']
|
63
|
+
test_client = CF::UAA::admin_scim(@options).add(:client, :client_id => @test_client, :client_secret => @test_secret,
|
64
|
+
:authorities => gids, :authorized_grant_types => ['client_credentials', 'password'],
|
65
|
+
:scope => ['openid', 'password.write'])
|
66
|
+
expect(test_client[:client_id]).to eq(@test_client)
|
67
|
+
end
|
79
68
|
|
80
|
-
|
81
|
-
|
82
|
-
|
69
|
+
after :all do
|
70
|
+
admin_scim = CF::UAA::admin_scim(@options)
|
71
|
+
admin_scim.delete(:client, @test_client)
|
72
|
+
expect { admin_scim.id(:client, @test_client) }.to raise_exception(NotFound)
|
73
|
+
end
|
83
74
|
|
84
|
-
|
85
|
-
|
86
|
-
|
75
|
+
if ENV['SKIP_SSL_VALIDATION']
|
76
|
+
context 'when ssl certificate is self-signed' do
|
77
|
+
let(:options) { {:skip_ssl_validation => false} }
|
87
78
|
|
88
|
-
|
89
|
-
|
90
|
-
|
79
|
+
it 'fails if skip_ssl_validation is false' do
|
80
|
+
expect{ scim }.to raise_exception(CF::UAA::SSLException)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
91
84
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
85
|
+
if ENV['SSL_CA_FILE']
|
86
|
+
context 'when you do not skip SSL validation' do
|
87
|
+
context 'when you provide cert' do
|
88
|
+
let(:options) { {:ssl_ca_file => ENV['SSL_CA_FILE']} }
|
97
89
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
info = Misc.whoami(@target, token.auth_header)
|
103
|
-
info["user_name"].should == @username
|
104
|
-
contents = TokenCoder.decode(token.info["access_token"], :verify => false)
|
105
|
-
contents["user_name"].should == @username
|
106
|
-
end
|
90
|
+
it 'works' do
|
91
|
+
expect(token_issuer.prompts).to_not be_nil
|
92
|
+
end
|
93
|
+
end
|
107
94
|
|
108
|
-
|
109
|
-
|
110
|
-
end
|
95
|
+
context 'if you do not provide cert file' do
|
96
|
+
let(:options) { {} }
|
111
97
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
98
|
+
it 'fails' do
|
99
|
+
expect{ scim }.to raise_exception(CF::UAA::SSLException)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
116
104
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
105
|
+
if ENV['CERT_STORE']
|
106
|
+
context 'when you do not skip SSL validation' do
|
107
|
+
context 'when you provide cert store' do
|
108
|
+
let(:cert_store) do
|
109
|
+
cert_store = OpenSSL::X509::Store.new
|
110
|
+
cert_store.add_file File.expand_path(ENV['CERT_STORE'])
|
111
|
+
cert_store
|
112
|
+
end
|
113
|
+
|
114
|
+
let(:options) { {:ssl_cert_store => cert_store} }
|
115
|
+
it 'works' do
|
116
|
+
expect(token_issuer.prompts).to_not be_nil
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'when you do not provide cert store' do
|
121
|
+
let(:options) { {} }
|
122
|
+
|
123
|
+
it 'fails' do
|
124
|
+
expect{ scim }.to raise_exception(CF::UAA::SSLException)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
132
128
|
end
|
133
|
-
end
|
134
129
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
expect { @scim.get(:user, @user_id) }.to raise_exception(NotFound)
|
139
|
-
end
|
130
|
+
it 'should report the uaa client version' do
|
131
|
+
expect(VERSION).to match(/\d.\d.\d/)
|
132
|
+
end
|
140
133
|
|
141
|
-
|
142
|
-
|
143
|
-
|
134
|
+
it 'makes sure the server is there by getting the prompts for an implicit grant' do
|
135
|
+
expect(token_issuer.prompts).to_not be_nil
|
136
|
+
end
|
144
137
|
|
145
|
-
|
138
|
+
it 'gets a token with client credentials' do
|
139
|
+
tkn = token_issuer.client_credentials_grant
|
140
|
+
expect(tkn.auth_header).to match(/^bearer\s/i)
|
141
|
+
info = TokenCoder.decode(tkn.info['access_token'], :verify => false, :symbolize_keys => true)
|
142
|
+
expect(info[:exp]).to be
|
143
|
+
expect(info[:jti]).to be
|
144
|
+
end
|
146
145
|
|
147
|
-
|
146
|
+
it 'complains about an attempt to delete a non-existent user' do
|
147
|
+
expect { scim.delete(:user, 'non-existent-user') }.to raise_exception(NotFound)
|
148
|
+
end
|
148
149
|
|
149
|
-
|
150
|
+
context 'as a client' do
|
151
|
+
before :each do
|
152
|
+
@username = "sam_#{Time.now.to_i}"
|
153
|
+
@user_pwd = "sam's P@55w0rd~!`@\#\$%^&*()_/{}[]\\|:\";',.<>?/"
|
154
|
+
usr = scim.add(:user, :username => @username, :password => @user_pwd,
|
155
|
+
:emails => [{:value => 'sam@example.com'}],
|
156
|
+
:name => {:givenname => 'none', :familyname => 'none'})
|
157
|
+
@user_id = usr[:id]
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'deletes the user' do
|
161
|
+
scim.delete(:user, @user_id)
|
162
|
+
expect { scim.id(:user, @username) }.to raise_exception(NotFound)
|
163
|
+
expect { scim.get(:user, @user_id) }.to raise_exception(NotFound)
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'when user exists' do
|
167
|
+
after :each do
|
168
|
+
scim.delete(:user, @user_id)
|
169
|
+
expect { scim.id(:user, @username) }.to raise_exception(NotFound)
|
170
|
+
expect { scim.get(:user, @user_id) }.to raise_exception(NotFound)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'creates a user' do
|
174
|
+
expect(@user_id).to be
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'finds the user by name' do
|
178
|
+
expect(scim.id(:user, @username)).to eq(@user_id)
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'gets the user by id' do
|
182
|
+
user_info = scim.get(:user, @user_id)
|
183
|
+
expect(user_info[:id]).to eq(@user_id)
|
184
|
+
expect(user_info[:username]).to eq(@username)
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'lists all users' do
|
188
|
+
expect(scim.query(:user)).to be
|
189
|
+
end
|
190
|
+
|
191
|
+
it "changes the user's password by name" do
|
192
|
+
expect(scim.change_password(scim.id(:user, @username), 'newpassword')[:status]).to eq('ok')
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should get a uri to be sent to the user agent to initiate autologin' do
|
196
|
+
redir_uri = 'http://call.back/uri_path'
|
197
|
+
uri_parts = token_issuer.autologin_uri(redir_uri, :username => @username,
|
198
|
+
:password =>@user_pwd ).split('?')
|
199
|
+
expect(uri_parts[0]).to eq("#{ENV['UAA_CLIENT_TARGET']}/oauth/authorize")
|
200
|
+
params = Util.decode_form(uri_parts[1], :sym)
|
201
|
+
expect(params[:response_type]).to eq('code')
|
202
|
+
expect(params[:client_id]).to eq(@test_client)
|
203
|
+
expect(params[:scope]).to be_nil
|
204
|
+
expect(params[:redirect_uri]).to eq(redir_uri)
|
205
|
+
expect(params[:state]).to be
|
206
|
+
expect(params[:code]).to be
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
data/spec/scim_spec.rb
CHANGED
@@ -23,86 +23,81 @@ describe Scim do
|
|
23
23
|
|
24
24
|
before do
|
25
25
|
#Util.default_logger(:trace)
|
26
|
-
@authheader, @target =
|
26
|
+
@authheader, @target = 'bEareR xyz', 'https://test.target'
|
27
27
|
@scim = Scim.new(@target, @authheader, options)
|
28
28
|
end
|
29
29
|
|
30
30
|
subject { @scim }
|
31
31
|
|
32
32
|
def check_headers(headers, content, accept, zone)
|
33
|
-
headers[
|
34
|
-
headers[
|
35
|
-
headers[
|
36
|
-
headers[
|
37
|
-
headers[
|
38
|
-
headers[
|
33
|
+
headers['content-type'].should =~ /application\/json/ if content == :json
|
34
|
+
headers['content-type'].should be_nil unless content
|
35
|
+
headers['accept'].should =~ /application\/json/ if accept == :json
|
36
|
+
headers['accept'].should be_nil unless accept
|
37
|
+
headers['authorization'].should =~ /^(?i:bearer)\s+xyz$/
|
38
|
+
headers['X-Identity-Zone-Subdomain'].should eq zone
|
39
39
|
end
|
40
40
|
|
41
|
-
describe
|
41
|
+
describe 'initialize' do
|
42
42
|
let(:options) { {:http_proxy => 'http-proxy.com', :https_proxy => 'https-proxy.com', :skip_ssl_validation => true} }
|
43
43
|
|
44
|
-
it
|
45
|
-
subject.http_proxy.should == 'http-proxy.com'
|
46
|
-
subject.https_proxy.should == 'https-proxy.com'
|
47
|
-
end
|
48
|
-
|
49
|
-
it "sets skip_ssl_validation" do
|
44
|
+
it 'sets skip_ssl_validation' do
|
50
45
|
subject.skip_ssl_validation == true
|
51
46
|
end
|
52
47
|
end
|
53
48
|
|
54
|
-
it
|
49
|
+
it 'adds an object' do
|
55
50
|
subject.set_request_handler do |url, method, body, headers|
|
56
51
|
url.should == "#{@target}/Users"
|
57
52
|
method.should == :post
|
58
53
|
check_headers(headers, :json, :json, nil)
|
59
|
-
[200, '{"ID":"id12345"}', {
|
54
|
+
[200, '{"ID":"id12345"}', {'content-type' => 'application/json'}]
|
60
55
|
end
|
61
|
-
result = subject.add(:user, :hair =>
|
62
|
-
:eye_color => [
|
63
|
-
result[
|
56
|
+
result = subject.add(:user, :hair => 'brown', :shoe_size => 'large',
|
57
|
+
:eye_color => ['blue', 'green'], :name => 'fred')
|
58
|
+
result['id'].should == 'id12345'
|
64
59
|
end
|
65
60
|
|
66
|
-
it
|
67
|
-
obj = {:hair =>
|
68
|
-
:name =>
|
61
|
+
it 'replaces an object' do
|
62
|
+
obj = {:hair => 'black', :shoe_size => 'medium', :eye_color => ['hazel', 'brown'],
|
63
|
+
:name => 'fredrick', :meta => {:version => 'v567'}, :id => 'id12345'}
|
69
64
|
subject.set_request_handler do |url, method, body, headers|
|
70
65
|
url.should == "#{@target}/Users/id12345"
|
71
66
|
method.should == :put
|
72
67
|
check_headers(headers, :json, :json, nil)
|
73
|
-
headers[
|
74
|
-
[200, '{"ID":"id12345"}', {
|
68
|
+
headers['if-match'].should == 'v567'
|
69
|
+
[200, '{"ID":"id12345"}', {'content-type' => 'application/json'}]
|
75
70
|
end
|
76
71
|
result = subject.put(:user, obj)
|
77
|
-
result[
|
72
|
+
result['id'].should == 'id12345'
|
78
73
|
end
|
79
74
|
|
80
|
-
it
|
81
|
-
obj = {:hair =>
|
82
|
-
:name =>
|
75
|
+
it 'modifies an object' do
|
76
|
+
obj = {:hair => 'black', :shoe_size => 'medium', :eye_color => ['hazel', 'brown'],
|
77
|
+
:name => 'fredrick', :meta => {:version => 'v567'}, :id => 'id12345'}
|
83
78
|
subject.set_request_handler do |url, method, body, headers|
|
84
79
|
url.should == "#{@target}/Users/id12345"
|
85
80
|
method.should == :patch
|
86
81
|
check_headers(headers, :json, :json, nil)
|
87
|
-
headers[
|
88
|
-
[200, '{"ID":"id12345"}', {
|
82
|
+
headers['if-match'].should == 'v567'
|
83
|
+
[200, '{"ID":"id12345"}', {'content-type' => 'application/json'}]
|
89
84
|
end
|
90
85
|
result = subject.patch(:user, obj)
|
91
|
-
result[
|
86
|
+
result['id'].should == 'id12345'
|
92
87
|
end
|
93
88
|
|
94
|
-
it
|
89
|
+
it 'gets an object' do
|
95
90
|
subject.set_request_handler do |url, method, body, headers|
|
96
91
|
url.should == "#{@target}/Users/id12345"
|
97
92
|
method.should == :get
|
98
93
|
check_headers(headers, nil, :json, nil)
|
99
|
-
[200, '{"id":"id12345"}', {
|
94
|
+
[200, '{"id":"id12345"}', {'content-type' => 'application/json'}]
|
100
95
|
end
|
101
|
-
result = subject.get(:user,
|
102
|
-
result['id'].should ==
|
96
|
+
result = subject.get(:user, 'id12345')
|
97
|
+
result['id'].should == 'id12345'
|
103
98
|
end
|
104
99
|
|
105
|
-
it
|
100
|
+
it 'pages through all objects' do
|
106
101
|
subject.set_request_handler do |url, method, body, headers|
|
107
102
|
url.should =~ %r{^#{@target}/Users\?}
|
108
103
|
url.should =~ %r{[\?&]attributes=id(&|$)}
|
@@ -112,10 +107,10 @@ describe Scim do
|
|
112
107
|
reply = url =~ /startIndex=1/ ?
|
113
108
|
'{"TotalResults":2,"ItemsPerPage":1,"StartIndex":1,"RESOURCES":[{"id":"id12345"}]}' :
|
114
109
|
'{"TotalResults":2,"ItemsPerPage":1,"StartIndex":2,"RESOURCES":[{"id":"id67890"}]}'
|
115
|
-
[200, reply, {
|
110
|
+
[200, reply, {'content-type' => 'application/json'}]
|
116
111
|
end
|
117
112
|
result = subject.all_pages(:user, :attributes => 'id')
|
118
|
-
[result[0]['id'], result[1]['id']].to_set.should == [
|
113
|
+
[result[0]['id'], result[1]['id']].to_set.should == ['id12345', 'id67890'].to_set
|
119
114
|
end
|
120
115
|
|
121
116
|
it "changes a user's password" do
|
@@ -124,10 +119,10 @@ describe Scim do
|
|
124
119
|
method.should == :put
|
125
120
|
check_headers(headers, :json, :json, nil)
|
126
121
|
body.should include('"password":"newpwd"', '"oldPassword":"oldpwd"')
|
127
|
-
[200, '{"id":"id12345"}', {
|
122
|
+
[200, '{"id":"id12345"}', {'content-type' => 'application/json'}]
|
128
123
|
end
|
129
|
-
result = subject.change_password(
|
130
|
-
result['id'].should ==
|
124
|
+
result = subject.change_password('id12345', 'newpwd', 'oldpwd')
|
125
|
+
result['id'].should == 'id12345'
|
131
126
|
end
|
132
127
|
|
133
128
|
it "tries to change the user's password to be the same as the old one" do
|
@@ -135,9 +130,9 @@ describe Scim do
|
|
135
130
|
url.should == "#{@target}/Users/id12345/password"
|
136
131
|
method.should == :put
|
137
132
|
check_headers(headers, :json, :json, nil)
|
138
|
-
[400, '{"error":"invalid_password","message":"Your new password cannot be the same as the old password."}', {
|
133
|
+
[400, '{"error":"invalid_password","message":"Your new password cannot be the same as the old password."}', {'content-type' => 'application/json'}]
|
139
134
|
end
|
140
|
-
expect {subject.change_password(
|
135
|
+
expect {subject.change_password('id12345', 'oldpwd', 'oldpwd')}.to raise_error(error=TargetError)
|
141
136
|
end
|
142
137
|
|
143
138
|
it "changes a client's secret" do
|
@@ -146,90 +141,90 @@ describe Scim do
|
|
146
141
|
method.should == :put
|
147
142
|
check_headers(headers, :json, :json, nil)
|
148
143
|
body.should include('"secret":"newpwd"', '"oldSecret":"oldpwd"')
|
149
|
-
[200, '{"id":"id12345"}', {
|
144
|
+
[200, '{"id":"id12345"}', {'content-type' => 'application/json'}]
|
150
145
|
end
|
151
|
-
result = subject.change_secret(
|
152
|
-
result['id'].should ==
|
146
|
+
result = subject.change_secret('id12345', 'newpwd', 'oldpwd')
|
147
|
+
result['id'].should == 'id12345'
|
153
148
|
end
|
154
149
|
|
155
|
-
it
|
150
|
+
it 'unlocks a user' do
|
156
151
|
subject.set_request_handler do |url, method, body, headers|
|
157
152
|
url.should == "#{@target}/Users/id12345/status"
|
158
153
|
method.should == :patch
|
159
154
|
check_headers(headers, :json, :json, nil)
|
160
155
|
body.should include('"locked":false')
|
161
|
-
[200, '{"locked":false}', {
|
156
|
+
[200, '{"locked":false}', {'content-type' => 'application/json'}]
|
162
157
|
end
|
163
|
-
result = subject.unlock_user(
|
158
|
+
result = subject.unlock_user('id12345')
|
164
159
|
result['locked'].should == false
|
165
160
|
end
|
166
161
|
|
167
|
-
it
|
162
|
+
it 'adds a mapping from uaa groups to external group' do
|
168
163
|
subject.set_request_handler do |url, method, body, headers|
|
169
164
|
url.should == "#{@target}/Groups/External"
|
170
165
|
method.should == :post
|
171
166
|
check_headers(headers, :json, :json, nil)
|
172
167
|
body.should include('"displayName":"uaa-scope-name"', '"externalGroup":"external-group-name"', '"schemas":["urn:scim:schemas:core:1.0"]', '"origin":"test-origin"')
|
173
|
-
[201, '{"displayName":"uaa-scope-name", "externalGroup": "external-group-name"}', {
|
168
|
+
[201, '{"displayName":"uaa-scope-name", "externalGroup": "external-group-name"}', {'content-type' => 'application/json'}]
|
174
169
|
end
|
175
|
-
result = subject.map_group(
|
176
|
-
result['displayname'].should ==
|
177
|
-
result['externalgroup'].should ==
|
170
|
+
result = subject.map_group('uaa-scope-name', false, 'external-group-name', 'test-origin')
|
171
|
+
result['displayname'].should == 'uaa-scope-name'
|
172
|
+
result['externalgroup'].should == 'external-group-name'
|
178
173
|
end
|
179
174
|
|
180
|
-
it
|
175
|
+
it 'defaults to ldap origin when mapping a uaa group from an external group' do
|
181
176
|
subject.set_request_handler do |url, method, body, headers|
|
182
177
|
url.should == "#{@target}/Groups/External"
|
183
178
|
method.should == :post
|
184
179
|
check_headers(headers, :json, :json, nil)
|
185
180
|
body.should include('"displayName":"uaa-scope-name"', '"externalGroup":"external-group-name"', '"schemas":["urn:scim:schemas:core:1.0"]', '"origin":"ldap"')
|
186
|
-
[201, '{"displayName":"uaa-scope-name", "externalGroup": "external-group-name"}', {
|
181
|
+
[201, '{"displayName":"uaa-scope-name", "externalGroup": "external-group-name"}', {'content-type' => 'application/json'}]
|
187
182
|
end
|
188
|
-
result = subject.map_group(
|
189
|
-
result['displayname'].should ==
|
190
|
-
result['externalgroup'].should ==
|
183
|
+
result = subject.map_group('uaa-scope-name', false, 'external-group-name')
|
184
|
+
result['displayname'].should == 'uaa-scope-name'
|
185
|
+
result['externalgroup'].should == 'external-group-name'
|
191
186
|
end
|
192
187
|
|
193
|
-
it
|
188
|
+
it 'unmaps a uaa group from an external group' do
|
194
189
|
subject.set_request_handler do |url, method, body, headers|
|
195
190
|
url.should == "#{@target}/Groups/External/groupId/uaa-group-id/externalGroup/external%20group%20name/origin/test-origin"
|
196
191
|
method.should == :delete
|
197
192
|
check_headers(headers, nil, nil, nil)
|
198
193
|
|
199
|
-
[200, '{"displayName":"uaa-scope-name", "groupId": "uaa-group-id", "externalGroup": "external-group-name"}', {
|
194
|
+
[200, '{"displayName":"uaa-scope-name", "groupId": "uaa-group-id", "externalGroup": "external-group-name"}', {'content-type' => 'application/json'}]
|
200
195
|
end
|
201
|
-
subject.unmap_group(
|
196
|
+
subject.unmap_group('uaa-group-id', 'external group name', 'test-origin')
|
202
197
|
end
|
203
198
|
|
204
|
-
it
|
199
|
+
it 'defaults to ldap origin when unmapping a uaa group from an external group' do
|
205
200
|
subject.set_request_handler do |url, method, body, headers|
|
206
201
|
url.should == "#{@target}/Groups/External/groupId/uaa-group-id/externalGroup/external%20group%20name/origin/ldap"
|
207
202
|
method.should == :delete
|
208
203
|
check_headers(headers, nil, nil, nil)
|
209
204
|
|
210
|
-
[200, '{"displayName":"uaa-scope-name", "groupId": "uaa-group-id", "externalGroup": "external-group-name"}', {
|
205
|
+
[200, '{"displayName":"uaa-scope-name", "groupId": "uaa-group-id", "externalGroup": "external-group-name"}', {'content-type' => 'application/json'}]
|
211
206
|
end
|
212
|
-
subject.unmap_group(
|
207
|
+
subject.unmap_group('uaa-group-id', 'external group name')
|
213
208
|
end
|
214
209
|
|
215
|
-
describe
|
210
|
+
describe 'users in a zone' do
|
216
211
|
let(:options) { {:http_proxy => 'http-proxy.com', :https_proxy => 'https-proxy.com', :skip_ssl_validation => true, :zone => 'derpzone'} }
|
217
212
|
|
218
|
-
it
|
213
|
+
it 'sends zone header' do
|
219
214
|
subject.set_request_handler do |url, method, body, headers|
|
220
215
|
url.should == "#{@target}/Users"
|
221
216
|
method.should == :post
|
222
217
|
check_headers(headers, :json, :json, 'derpzone')
|
223
|
-
[200, '{"ID":"id12345"}', {
|
218
|
+
[200, '{"ID":"id12345"}', {'content-type' => 'application/json'}]
|
224
219
|
end
|
225
|
-
result = subject.add(:user, :hair =>
|
226
|
-
:eye_color => [
|
227
|
-
result[
|
220
|
+
result = subject.add(:user, :hair => 'brown', :shoe_size => 'large',
|
221
|
+
:eye_color => ['blue', 'green'], :name => 'fred')
|
222
|
+
result['id'].should == 'id12345'
|
228
223
|
end
|
229
224
|
end
|
230
225
|
|
231
|
-
describe
|
232
|
-
it
|
226
|
+
describe '#list_group_mappings' do
|
227
|
+
it 'lists all the external group mappings with default pagination' do
|
233
228
|
subject.set_request_handler do |url, method, body, headers|
|
234
229
|
url.should start_with("#{@target}/Groups/External/list")
|
235
230
|
method.should == :get
|
@@ -238,7 +233,7 @@ describe Scim do
|
|
238
233
|
[
|
239
234
|
200,
|
240
235
|
'{"resources": [{"groupId": "group-id", "displayName": "group-name", "externalGroup": "external-group-name"}], "totalResults": 1 }',
|
241
|
-
{
|
236
|
+
{'content-type' => 'application/json'}
|
242
237
|
]
|
243
238
|
end
|
244
239
|
|
@@ -247,23 +242,23 @@ describe Scim do
|
|
247
242
|
result['totalresults'].should == 1
|
248
243
|
end
|
249
244
|
|
250
|
-
it
|
245
|
+
it 'lists a page of external group mappings starting from an index' do
|
251
246
|
subject.set_request_handler do |url, method, body, headers|
|
252
247
|
url.should start_with("#{@target}/Groups/External/list")
|
253
248
|
method.should == :get
|
254
249
|
check_headers(headers, nil, :json, nil)
|
255
250
|
|
256
251
|
query_params = CGI::parse(URI.parse(url).query)
|
257
|
-
start_index = query_params[
|
258
|
-
count = query_params[
|
252
|
+
start_index = query_params['startIndex'].first
|
253
|
+
count = query_params['count'].first
|
259
254
|
|
260
|
-
start_index.should ==
|
261
|
-
count.should ==
|
255
|
+
start_index.should == '3'
|
256
|
+
count.should == '10'
|
262
257
|
|
263
258
|
[
|
264
259
|
200,
|
265
260
|
'{"resources": [{"groupId": "group-id", "displayName": "group-name", "externalGroup": "external-group-name"}], "totalResults": 1 }',
|
266
|
-
{
|
261
|
+
{'content-type' => 'application/json'}
|
267
262
|
]
|
268
263
|
end
|
269
264
|
|