Skip to content
This repository was archived by the owner on Jun 2, 2021. It is now read-only.

Commit 4e46b84

Browse files
FelisiaMpivotal-marcela-campo
authored andcommitted
Added validation of unique name for service key
1 parent 8308d1f commit 4e46b84

4 files changed

Lines changed: 53 additions & 7 deletions

File tree

app/actions/service_credential_binding_key_create.rb

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,35 @@ class ServiceCredentialBindingKeyCreate
44
class UnprocessableCreate < StandardError
55
end
66

7-
def precursor(service_instance, volume_mount_services_enabled: false)
7+
def precursor(service_instance, name)
8+
validate!(service_instance)
9+
10+
binding_details = {
11+
service_instance: service_instance,
12+
name: name,
13+
credentials: {}
14+
}
15+
16+
ServiceKey.db.transaction do
17+
ServiceKey.create(**binding_details)
18+
end
19+
rescue Sequel::ValidationFailed => e
20+
raise UnprocessableCreate.new(e.message)
21+
end
22+
23+
private
24+
25+
def validate!(service_instance)
26+
827
if service_instance.managed_instance?
928
service_not_bindable! unless service_instance.service_plan.bindable?
1029
service_not_available! unless service_instance.service_plan.active?
11-
volume_mount_not_enabled! if service_instance.volume_service? && !volume_mount_services_enabled
1230
operation_in_progress! if service_instance.operation_in_progress?
1331
else
1432
key_not_supported_for_user_provided_service!
1533
end
1634
end
1735

18-
private
19-
2036
def key_not_supported_for_user_provided_service!
2137
raise UnprocessableCreate.new("Service credential bindings of type 'key' are not supported for user-provided service instances.")
2238
end

app/controllers/v3/service_credential_bindings_controller.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def create
5151
case message.type
5252
when 'app'
5353
app = VCAP::CloudController::AppModel.first(guid: message.app_guid)
54+
# TODO create two unprocessable_app/si methods
5455
resource_not_accessible!('app', message.app_guid) unless can_access_resource?(app)
5556

5657
unauthorized! unless can_write_to_space?(app.space)
@@ -71,7 +72,7 @@ def create
7172

7273
V3::ServiceCredentialBindingKeyCreate.new.precursor(
7374
service_instance,
74-
volume_mount_services_enabled: volume_services_enabled?
75+
message.name
7576
)
7677

7778
head :not_implemented

app/models/services/service_key.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def space
3333
def validate
3434
validates_presence :name
3535
validates_presence :service_instance
36-
validates_unique [:name, :service_instance_id]
36+
validates_unique [:name, :service_instance_id], message: Sequel.lit("The binding name is invalid. Key binding names must be unique. The service instance already has a key binding with name '#{name}'.")
3737

3838
if service_instance
3939
MaxServiceKeysPolicy.new(

spec/request/service_credential_bindings_spec.rb

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,9 @@ def check_filtered_bindings(*bindings)
879879
it 'returns 422 when the binding already exists' do
880880
api_call.call admin_headers
881881
expect(last_response.status).to eq(201).or eq(202)
882+
882883
api_call.call admin_headers
884+
883885
expect(last_response).to have_status_code(422)
884886
expect(parsed_response['errors']).to include(include({
885887
'detail' => include('The app is already bound to the service instance'),
@@ -1474,10 +1476,11 @@ def check_filtered_bindings(*bindings)
14741476

14751477
context 'creating a credential binding as a key' do
14761478
let(:service_instance) { VCAP::CloudController::ManagedServiceInstance.make(space: space, **service_instance_details) }
1479+
let(:binding_name) { 'some-key-name' }
14771480
let(:create_body) {
14781481
{
14791482
type: 'key',
1480-
name: 'some-key-name',
1483+
name: binding_name,
14811484
relationships: {
14821485
service_instance: { data: { guid: service_instance_guid } },
14831486
}
@@ -1580,6 +1583,32 @@ def check_filtered_bindings(*bindings)
15801583
end
15811584
end
15821585

1586+
context 'when a key with the same name exists for that SI' do
1587+
let(:service_cred_binding) {
1588+
VCAP::CloudController::ServiceKey.make(service_instance: service_instance)
1589+
}
1590+
let(:create_body) {
1591+
{
1592+
type: 'key',
1593+
name: service_cred_binding.name,
1594+
relationships: {
1595+
service_instance: { data: { guid: service_instance_guid } },
1596+
}
1597+
}.merge(request_extra)
1598+
}
1599+
1600+
it 'returns a 422' do
1601+
api_call.call space_dev_headers
1602+
1603+
expect(last_response).to have_status_code(422)
1604+
expect(parsed_response['errors']).to include(include({
1605+
'detail' => include("The binding name is invalid. Key binding names must be unique. The service instance already has a key binding with name '#{service_cred_binding.name}'."),
1606+
'title' => 'CF-UnprocessableEntity',
1607+
'code' => 10008,
1608+
}))
1609+
end
1610+
end
1611+
15831612
context 'when the service instance is user-provided' do
15841613
let(:service_instance) { VCAP::CloudController::UserProvidedServiceInstance.make(space: space, **service_instance_details) }
15851614

0 commit comments

Comments
 (0)