Skip to content

Commit a7d0413

Browse files
committed
First check whether user exists in UAA before trying to create in /v3/users
1 parent ebb0231 commit a7d0413

File tree

5 files changed

+84
-7
lines changed

5 files changed

+84
-7
lines changed

app/actions/user_create.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@ class Error < StandardError
44
end
55

66
def create(message:)
7-
shadow_user = User.create_uaa_shadow_user(message.username, message.origin) if message.username && message.origin
8-
user_guid = shadow_user ? shadow_user['id'] : message.guid
7+
if message.username && message.origin
8+
existing_user_guid = User.get_user_id_by_username_and_origin(message.username, message.origin)
99

10+
shadow_user = User.create_uaa_shadow_user(message.username, message.origin) unless existing_user_guid
11+
12+
user_guid = existing_user_guid || shadow_user['id']
13+
else
14+
user_guid = message.guid
15+
end
1016
user = User.create(guid: user_guid)
1117
User.db.transaction do
1218
MetadataUpdate.update(user, message)

app/models/runtime/user.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,11 @@ def self.uaa_users_info(user_guids)
252252
uaa_username_lookup_client.users_for_ids(user_guids)
253253
end
254254

255+
def self.get_user_id_by_username_and_origin(username, origin)
256+
uaa_username_lookup_client = CloudController::DependencyLocator.instance.uaa_username_lookup_client
257+
uaa_username_lookup_client.ids_for_usernames_and_origins([username], [origin]).first
258+
end
259+
255260
def self.create_uaa_shadow_user(username, origin)
256261
uaa_shadow_user_creation_client = CloudController::DependencyLocator.instance.uaa_shadow_user_creation_client
257262
uaa_shadow_user_creation_client.create_shadow_user(username, origin)

spec/request/users_spec.rb

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -705,8 +705,8 @@
705705
end
706706

707707
before do
708-
allow(CloudController::DependencyLocator.instance).to receive(:uaa_shadow_user_creation_client).and_return(uaa_client)
709-
allow(uaa_client).to receive(:create_shadow_user).and_return({ 'id' => user_guid })
708+
allow(CloudController::DependencyLocator.instance).to receive_messages(uaa_shadow_user_creation_client: uaa_client, uaa_username_lookup_client: uaa_client)
709+
allow(uaa_client).to receive_messages(create_shadow_user: { 'id' => user_guid }, ids_for_usernames_and_origins: [])
710710
end
711711

712712
it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS
@@ -867,7 +867,7 @@
867867
context 'when "allow_user_creation_by_org_manager" is enabled' do
868868
before do
869869
TestConfig.override(allow_user_creation_by_org_manager: true)
870-
allow(CloudController::DependencyLocator.instance).to receive(:uaa_shadow_user_creation_client).and_return(uaa_client)
870+
allow(CloudController::DependencyLocator.instance).to receive_messages(uaa_shadow_user_creation_client: uaa_client, uaa_username_lookup_client: uaa_client)
871871
end
872872

873873
describe 'when creating a user by guid' do
@@ -954,7 +954,7 @@
954954
end
955955

956956
before do
957-
allow(uaa_client).to receive(:create_shadow_user).and_return({ 'id' => user_guid })
957+
allow(uaa_client).to receive_messages(create_shadow_user: { 'id' => user_guid }, ids_for_usernames_and_origins: [])
958958
end
959959

960960
it_behaves_like 'permissions for single object endpoint', ALL_PERMISSIONS
@@ -967,6 +967,21 @@
967967

968968
expect(uaa_client).not_to have_received(:users_for_ids)
969969
end
970+
971+
context 'when user already exists in UAA' do
972+
before do
973+
allow(uaa_client).to receive(:ids_for_usernames_and_origins).and_return([user_guid])
974+
end
975+
976+
it 'does not try to create a shadow user' do
977+
post '/v3/users', params.to_json, admin_header
978+
979+
expect(last_response).to have_status_code(201)
980+
expect(parsed_response).to match_json_response(user_json)
981+
982+
expect(uaa_client).not_to have_received(:create_shadow_user)
983+
end
984+
end
970985
end
971986

972987
context 'when parameters are invalid' do

spec/unit/actions/user_create_spec.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ module VCAP::CloudController
5656

5757
describe 'creating users' do
5858
before do
59-
allow(User).to receive(:create_uaa_shadow_user).and_return({ 'id' => guid })
59+
allow(User).to receive_messages(create_uaa_shadow_user: { 'id' => guid }, get_user_id_by_username_and_origin: nil)
6060
end
6161

6262
context 'when creating a UAA user by guid' do
@@ -108,6 +108,17 @@ module VCAP::CloudController
108108
expect(User).to have_received(:create_uaa_shadow_user).with(username, origin)
109109
end
110110

111+
context 'when user already exists in UAA' do
112+
before do
113+
allow(User).to receive(:get_user_id_by_username_and_origin).and_return('some-user-guid')
114+
end
115+
116+
it 'does not try to create a shadow user' do
117+
subject.create(message:)
118+
expect(User).not_to have_received(:create_uaa_shadow_user)
119+
end
120+
end
121+
111122
context 'when an UaaUnavailable error is raised' do
112123
before do
113124
allow(User).to receive(:create_uaa_shadow_user).and_raise(UaaUnavailable)

spec/unit/models/runtime/user_spec.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,5 +578,45 @@ module VCAP::CloudController
578578
end
579579
end
580580
end
581+
582+
describe '#get_user_id_by_username_and_origin' do
583+
let(:uaa_client) { instance_double(UaaClient) }
584+
585+
before do
586+
allow(CloudController::DependencyLocator.instance).to receive(:uaa_username_lookup_client).and_return(uaa_client)
587+
end
588+
589+
context 'when uaa client returns user id' do
590+
before do
591+
allow(uaa_client).to receive(:ids_for_usernames_and_origins).and_return(['some-user-id'])
592+
end
593+
594+
it 'returns user id' do
595+
user_id = User.get_user_id_by_username_and_origin(['shadow-user'], ['idp.local'])
596+
expect(user_id).to eq('some-user-id')
597+
end
598+
end
599+
600+
context 'when uaa client returns empty array' do
601+
before do
602+
allow(uaa_client).to receive(:ids_for_usernames_and_origins).and_return([])
603+
end
604+
605+
it 'returns nil' do
606+
user_id = User.get_user_id_by_username_and_origin(['shadow-user'], ['idp.local'])
607+
expect(user_id).to be_nil
608+
end
609+
end
610+
611+
context 'when uaa client raises UaaUnavailable' do
612+
before do
613+
allow(uaa_client).to receive(:ids_for_usernames_and_origins).and_raise(UaaUnavailable)
614+
end
615+
616+
it 'raises UaaUnavailable' do
617+
expect { User.get_user_id_by_username_and_origin(['shadow-user'], ['idp.local']) }.to raise_error(UaaUnavailable)
618+
end
619+
end
620+
end
581621
end
582622
end

0 commit comments

Comments
 (0)