diff --git a/app/controllers/v3/routes_controller.rb b/app/controllers/v3/routes_controller.rb index a30d764e840..8783fe8d049 100644 --- a/app/controllers/v3/routes_controller.rb +++ b/app/controllers/v3/routes_controller.rb @@ -249,7 +249,7 @@ def update_destination require_writable_space!(route.space) destination = RouteMappingModel.find(guid: hashed_params[:destination_guid]) - unprocessable_destination! unless destination + unprocessable_destination! unless destination && destination.route_guid == route.guid RouteDestinationUpdate.update(destination, message) @@ -286,7 +286,7 @@ def destroy_destination require_writable_space!(route.space) destination = RouteMappingModel.find(guid: hashed_params[:destination_guid]) - unprocessable_destination! unless destination + unprocessable_destination! unless destination && destination.route_guid == route.guid UpdateRouteDestinations.delete(destination, route, user_audit_info) diff --git a/spec/request/route_destinations_spec.rb b/spec/request/route_destinations_spec.rb index b15762ae897..9c73dc2bb5e 100644 --- a/spec/request/route_destinations_spec.rb +++ b/spec/request/route_destinations_spec.rb @@ -1279,6 +1279,25 @@ end end + context 'when the destination belongs to a different route than the one in the URL' do + let(:other_space) { create(:space) } + let(:other_route) { create(:route, space: other_space) } + let(:other_app) { create(:app_model, space: other_space) } + let!(:other_destination) { create(:route_mapping_model, app: other_app, route: other_route, process_type: 'web') } + + before do + set_current_user_as_role(user: user, role: 'space_developer', org: org, space: space) + end + + it 'returns 422 and does not modify the destination' do + patch "/v3/routes/#{route.guid}/destinations/#{other_destination.guid}", + { protocol: 'http2' }.to_json, headers_for(user) + expect(last_response.status).to eq(422) + expect(last_response).to have_error_message('Unable to unmap route from destination. Ensure the route has a destination with this guid.') + expect(other_destination.reload.protocol).not_to eq('http2') + end + end + context 'when the route has a protocol of tcp' do let(:routing_api_client) { double('routing_api_client', router_group:) } let(:router_group) { double('router_group', type: 'tcp', guid: 'router-group-guid') } @@ -1421,6 +1440,24 @@ end end + context 'when the destination belongs to a different route than the one in the URL' do + let(:other_space) { create(:space) } + let(:other_route) { create(:route, space: other_space) } + let(:other_app) { create(:app_model, space: other_space) } + let!(:other_destination) { create(:route_mapping_model, app: other_app, route: other_route, process_type: 'web') } + + before do + set_current_user_as_role(user: user, role: 'space_developer', org: org, space: space) + end + + it 'returns 422 and does not delete the destination' do + delete "/v3/routes/#{route.guid}/destinations/#{other_destination.guid}", nil, headers_for(user) + expect(last_response.status).to eq(422) + expect(last_response).to have_error_message('Unable to unmap route from destination. Ensure the route has a destination with this guid.') + expect { other_destination.reload }.not_to raise_error + end + end + context 'when there is an existing weighted destination' do let!(:existing_destination) { create(:route_mapping_model, app: app_model, process_type: 'something', route: route, weight: 10) }