@@ -836,7 +836,6 @@ def check_filtered_bindings(*bindings)
836836 credentials : { password : 'foo' }
837837 }
838838 }
839- let ( :service_instance ) { VCAP ::CloudController ::UserProvidedServiceInstance . make ( space : space , **service_instance_details ) }
840839 let ( :service_instance_guid ) { service_instance . guid }
841840
842841 context 'creating a credential binding to an app' do
@@ -983,6 +982,8 @@ def check_filtered_bindings(*bindings)
983982 end
984983
985984 context 'user-provided service' do
985+ let ( :service_instance ) { VCAP ::CloudController ::UserProvidedServiceInstance . make ( space : space , **service_instance_details ) }
986+
986987 it_behaves_like 'permissions for single object endpoint' , ALL_PERMISSIONS do
987988 let ( :expected_codes_and_responses ) do
988989 Hash . new ( code : 403 ) . tap do |h |
@@ -1472,6 +1473,7 @@ def check_filtered_bindings(*bindings)
14721473 end
14731474
14741475 context 'creating a credential binding as a key' do
1476+ let ( :service_instance ) { VCAP ::CloudController ::ManagedServiceInstance . make ( space : space , **service_instance_details ) }
14751477 let ( :create_body ) {
14761478 {
14771479 type : 'key' ,
@@ -1482,16 +1484,148 @@ def check_filtered_bindings(*bindings)
14821484 } . merge ( request_extra )
14831485 }
14841486
1485- it 'returns 422 when type is missing' do
1486- create_body . delete ( :type )
1487+ context 'permissions' do
1488+ context 'users in the originating service instance space' do
1489+ it_behaves_like 'permissions for single object endpoint' , ALL_PERMISSIONS do
1490+ let ( :expected_codes_and_responses ) do
1491+ Hash . new ( code : 403 ) . tap do |h |
1492+ h [ 'space_developer' ] = { code : 501 }
1493+ h [ 'admin' ] = { code : 501 }
1494+ h [ 'org_billing_manager' ] = { code : 422 }
1495+ h [ 'org_auditor' ] = { code : 422 }
1496+ h [ 'no_role' ] = { code : 422 }
1497+ end
1498+ end
1499+ end
1500+ end
14871501
1488- api_call . call admin_headers
1489- expect ( last_response ) . to have_status_code ( 422 )
1490- expect ( parsed_response [ 'errors' ] ) . to include ( include ( {
1491- 'detail' => include ( "Type must be 'app' or 'key'" ) ,
1492- 'title' => 'CF-UnprocessableEntity' ,
1493- 'code' => 10008 ,
1494- } ) )
1502+ context 'users in the space where the SI has been shared to' do
1503+ let ( :orginal_org ) { VCAP ::CloudController ::Organization . make }
1504+ let ( :original_space ) { VCAP ::CloudController ::Space . make ( organization : orginal_org ) }
1505+ let ( :service_instance ) { VCAP ::CloudController ::ManagedServiceInstance . make ( space : original_space ) }
1506+
1507+ before do
1508+ service_instance . add_shared_space ( space )
1509+ end
1510+
1511+ it_behaves_like 'permissions for single object endpoint' , ALL_PERMISSIONS do
1512+ let ( :expected_codes_and_responses ) do
1513+ Hash . new ( code : 403 ) . tap do |h |
1514+ h [ 'admin' ] = { code : 501 }
1515+ h [ 'org_billing_manager' ] = { code : 422 }
1516+ h [ 'org_auditor' ] = { code : 422 }
1517+ h [ 'no_role' ] = { code : 422 }
1518+ end
1519+ end
1520+ end
1521+ end
1522+ end
1523+
1524+ context 'request validation' do
1525+ it 'returns 422 when type is missing' do
1526+ create_body . delete ( :type )
1527+
1528+ api_call . call admin_headers
1529+ expect ( last_response ) . to have_status_code ( 422 )
1530+ expect ( parsed_response [ 'errors' ] ) . to include ( include ( {
1531+ 'detail' => include ( "Type must be 'app' or 'key'" ) ,
1532+ 'title' => 'CF-UnprocessableEntity' ,
1533+ 'code' => 10008 ,
1534+ } ) )
1535+ end
1536+
1537+ it 'returns 422 when service instance relationship is not included' do
1538+ create_body [ :relationships ] . delete ( :service_instance )
1539+ api_call . call admin_headers
1540+ expect ( last_response ) . to have_status_code ( 422 )
1541+ expect ( parsed_response [ 'errors' ] ) . to include ( include ( {
1542+ 'detail' => include ( "Relationships 'relationships' must include one or more valid relationships" ) ,
1543+ 'title' => 'CF-UnprocessableEntity' ,
1544+ 'code' => 10008 ,
1545+ } ) )
1546+ end
1547+
1548+ context 'when the service instance does not exist' do
1549+ let ( :service_instance_guid ) { 'fake-instance' }
1550+
1551+ it 'returns a 422 when the service instance does not exist' do
1552+ api_call . call admin_headers
1553+
1554+ expect ( last_response ) . to have_status_code ( 422 )
1555+ expect ( parsed_response [ 'errors' ] ) . to include ( include ( {
1556+ 'detail' => include ( "The service instance could not be found: 'fake-instance'" ) ,
1557+ 'title' => 'CF-UnprocessableEntity' ,
1558+ 'code' => 10008 ,
1559+ } ) )
1560+ end
1561+ end
1562+
1563+ context 'when the user has no access to the service instance' do
1564+ let ( :space_user ) do
1565+ u = VCAP ::CloudController ::User . make
1566+ other_space . organization . add_user ( u )
1567+ other_space . add_developer ( u )
1568+ u
1569+ end
1570+ let ( :space_dev_headers ) { headers_for ( space_user ) }
1571+
1572+ it 'returns a 422' do
1573+ api_call . call space_dev_headers
1574+ expect ( last_response ) . to have_status_code ( 422 )
1575+ expect ( parsed_response [ 'errors' ] ) . to include ( include ( {
1576+ 'detail' => include ( "The service instance could not be found: '#{ service_instance_guid } '" ) ,
1577+ 'title' => 'CF-UnprocessableEntity' ,
1578+ 'code' => 10008 ,
1579+ } ) )
1580+ end
1581+ end
1582+
1583+ context 'when the service instance is user-provided' do
1584+ let ( :service_instance ) { VCAP ::CloudController ::UserProvidedServiceInstance . make ( space : space , **service_instance_details ) }
1585+
1586+ it 'returns a 422' do
1587+ api_call . call admin_headers
1588+
1589+ expect ( last_response ) . to have_status_code ( 422 )
1590+ expect ( parsed_response [ 'errors' ] ) . to include ( include ( {
1591+ 'detail' => include ( "Service credential bindings of type 'key' are not supported for user-provided service instances." ) ,
1592+ 'title' => 'CF-UnprocessableEntity' ,
1593+ 'code' => 10008 ,
1594+ } ) )
1595+ end
1596+ end
1597+
1598+ context 'when the service instance is not bindable' do
1599+ let ( :plan ) { VCAP ::CloudController ::ServicePlan . make ( bindable : false ) }
1600+ let ( :service_instance ) { VCAP ::CloudController ::ManagedServiceInstance . make ( space : space , service_plan : plan ) }
1601+
1602+ it 'returns a 422' do
1603+ api_call . call admin_headers
1604+
1605+ expect ( last_response ) . to have_status_code ( 422 )
1606+ expect ( parsed_response [ 'errors' ] ) . to include ( include ( {
1607+ 'detail' => include ( "Service plan does not allow bindings." ) ,
1608+ 'title' => 'CF-UnprocessableEntity' ,
1609+ 'code' => 10008 ,
1610+ } ) )
1611+ end
1612+ end
1613+
1614+ context 'when the service instance is from unavailable plan' do
1615+ let ( :plan ) { VCAP ::CloudController ::ServicePlan . make ( active : false ) }
1616+ let ( :service_instance ) { VCAP ::CloudController ::ManagedServiceInstance . make ( space : space , service_plan : plan ) }
1617+
1618+ it 'returns a 422' do
1619+ api_call . call admin_headers
1620+
1621+ expect ( last_response ) . to have_status_code ( 422 )
1622+ expect ( parsed_response [ 'errors' ] ) . to include ( include ( {
1623+ 'detail' => include ( "Service plan is not available." ) ,
1624+ 'title' => 'CF-UnprocessableEntity' ,
1625+ 'code' => 10008 ,
1626+ } ) )
1627+ end
1628+ end
14951629 end
14961630
14971631 it 'should return 501' do
0 commit comments