Permalink
Browse files

Merge pull request #35 from SlimYang/master

add an internal api for update handles
  • Loading branch information...
2 parents 9737ca6 + 143a27e commit fb3323119a0e0a6efbd75a3b4e2ded0ded7128d1 CloudFoundry Services Team committed Mar 28, 2013
View
@@ -11,7 +11,7 @@ gem "sinatra-contrib"
gem "yajl-ruby"
gem 'vcap-concurrency', :git => 'https://github.com/cloudfoundry/vcap-concurrency.git', :ref => '2a5b0179'
gem "membrane", "~> 0.0.2"
-gem "vcap_common", "~> 2.0.8", :git => 'https://github.com/cloudfoundry/vcap-common.git', :ref => 'e437aeb'
+gem "vcap_common", "~> 2.0.8", :git => 'https://github.com/cloudfoundry/vcap-common.git', :ref => '2e755172'
gem "cf-uaa-lib", "~> 1.3.7", :git => 'https://github.com/cloudfoundry/cf-uaa-lib.git', :ref => '8d34eede'
gem "httpclient"
gem "steno", "~> 1.0.0"
View
@@ -18,8 +18,8 @@ GIT
GIT
remote: https://github.com/cloudfoundry/vcap-common.git
- revision: e437aeb74708d150b0171edb4647d1f973b6de4c
- ref: e437aeb
+ revision: 2e755172e0cb76b82fedb77e16e33d71dcde140a
+ ref: 2e755172
specs:
vcap_common (2.0.10)
em-http-request (~> 1.0.0.beta3, < 1.0.0.beta4)
@@ -1,5 +1,7 @@
# Copyright (c) 2009-2012 VMware, Inc.
+require 'services/api'
+
module VCAP::CloudController
rest_controller :ServiceBinding do
permissions_required do
@@ -27,5 +29,44 @@ def self.translate_validation_exception(e, attributes)
Errors::ServiceBindingInvalid.new(e.errors.full_messages)
end
end
+
+ def update_binding(gateway_name)
+ begin
+ req = VCAP::Services::Api::HandleUpdateRequestV2.decode(body)
+ rescue
+ raise Errors::InvalidRequest
+ end
+
+ binding_handle = Models::ServiceBinding[:gateway_name => gateway_name]
+ raise Errors::ServiceBindingNotFound, "gateway_name=#{gateway_name}" unless binding_handle
+
+ instance_handle = Models::ServiceInstance[:id => binding_handle[:service_instance_id]]
+ plan_handle = Models::ServicePlan[:id => instance_handle[:service_plan_id]]
+ service_handle = Models::Service[:id => plan_handle[:service_id]]
+
+ validate_update(service_handle[:label], service_handle[:provider], req.token)
+
+ binding_handle.set(
+ :gateway_data => req.gateway_data,
+ :credentials => req.credentials,
+ )
+ binding_handle.save_changes
+ end
+
+ def validate_update(label, provider, token)
+ raise Errors::NotAuthorized unless label && provider && token
+
+ svc_auth_token = Models::ServiceAuthToken[
+ :label => label,
+ :provider => provider,
+ ]
+
+ unless (svc_auth_token && svc_auth_token.token_matches?(token))
+ logger.warn("unauthorized service offering")
+ raise Errors::NotAuthorized
+ end
+ end
+
+ put "/v2/service_bindings/internal/:gateway_name", :update_binding
end
end
@@ -1,5 +1,7 @@
# Copyright (c) 2009-2012 VMware, Inc.
+require 'services/api'
+
module VCAP::CloudController
rest_controller :ServiceInstance do
permissions_required do
@@ -36,5 +38,43 @@ def self.translate_validation_exception(e, attributes)
Errors::ServiceInstanceInvalid.new(e.errors.full_messages)
end
end
+
+ def update_instance(gateway_name)
+ begin
+ req = VCAP::Services::Api::HandleUpdateRequestV2.decode(body)
+ rescue
+ raise Errors::InvalidRequest
+ end
+
+ instance_handle = Models::ServiceInstance[:gateway_name => gateway_name]
+ raise Errors::ServiceInstanceNotFound, "gateway_name=#{gateway_name}" unless instance_handle
+
+ plan_handle = Models::ServicePlan[:id => instance_handle[:service_plan_id]]
+ service_handle = Models::Service[:id => plan_handle[:service_id]]
+
+ validate_update(service_handle[:label], service_handle[:provider], req.token)
+
+ instance_handle.set(
+ :gateway_data => req.gateway_data,
+ :credentials => req.credentials,
+ )
+ instance_handle.save_changes
+ end
+
+ def validate_update(label, provider, token)
+ raise Errors::NotAuthorized unless label && provider && token
+
+ svc_auth_token = Models::ServiceAuthToken[
+ :label => label,
+ :provider => provider,
+ ]
+
+ unless (svc_auth_token && svc_auth_token.token_matches?(token))
+ logger.warn("unauthorized service offering")
+ raise Errors::NotAuthorized
+ end
+ end
+
+ put "/v2/service_instances/internal/:gateway_name", :update_instance
end
end
@@ -190,5 +190,50 @@ module VCAP::CloudController
end
end
end
+
+ describe "PUT /v2/service_bindings/internal/:id" do
+ let(:service) { Models::Service.make }
+ let(:plan) { Models::ServicePlan.make({ :service => service })}
+ let(:service_instance) { Models::ServiceInstance.make({ :service_plan => plan })}
+ let(:service_binding) { Models::ServiceBinding.make({ :service_instance => service_instance })}
+ let(:admin) { Models::User.make({ :admin => true })}
+
+ let(:new_configuration) {{ :plan => "100" }}
+ let(:new_credentials) {{ :name => "svcs-instance-1" }}
+
+ let(:binding_id) { service_binding.gateway_name }
+
+ it "should allow access with valid token" do
+ req_body = {
+ :token => service.service_auth_token.token,
+ :gateway_data => new_configuration,
+ :credentials => new_credentials
+ }.to_json
+
+ put "/v2/service_bindings/internal/#{binding_id}", req_body, headers_for(admin)
+ last_response.status.should == 200
+ end
+
+ it "should forbidden access with invalid token" do
+ req_body = {
+ :token => "wrong_token",
+ :gateway_data => new_configuration,
+ :credentials => new_credentials
+ }.to_json
+
+ put "/v2/service_bindings/internal/#{binding_id}", req_body, headers_for(admin)
+ last_response.status.should == 403
+ end
+
+ it "should forbidden access with invalid request body" do
+ req_body = {
+ :token => service.service_auth_token.token,
+ :credentials => new_credentials
+ }.to_json
+
+ put "/v2/service_bindings/internal/#{binding_id}", req_body, headers_for(admin)
+ last_response.status.should == 400
+ end
+ end
end
end
@@ -198,5 +198,49 @@ module VCAP::CloudController
end
end
end
+
+ describe "PUT /v2/service_instances/internal/:instance_id" do
+ let(:service) { Models::Service.make }
+ let(:plan) { Models::ServicePlan.make({ :service => service })}
+ let(:service_instance) { Models::ServiceInstance.make({ :service_plan => plan })}
+ let(:admin) { Models::User.make({ :admin => true })}
+
+ let(:new_configuration) {{ :plan => "100" }}
+ let(:new_credentials) {{ :name => "svcs-instance-1" }}
+
+ let(:instance_id) { service_instance.gateway_name }
+
+ it "should allow access with valid token" do
+ req_body = {
+ :token => service.service_auth_token.token,
+ :gateway_data => new_configuration,
+ :credentials => new_credentials
+ }.to_json
+
+ put "/v2/service_instances/internal/#{instance_id}", req_body, headers_for(admin)
+ last_response.status.should == 200
+ end
+
+ it "should forbidden access with invalid token" do
+ req_body = {
+ :token => "wrong_token",
+ :gateway_data => new_configuration,
+ :credentials => new_credentials
+ }.to_json
+
+ put "/v2/service_instances/internal/#{instance_id}", req_body, headers_for(admin)
+ last_response.status.should == 403
+ end
+
+ it "should forbidden access with invalid request body" do
+ req_body = {
+ :token => service.service_auth_token.token,
+ :credentials => new_credentials
+ }.to_json
+
+ put "/v2/service_instances/internal/#{instance_id}", req_body, headers_for(admin)
+ last_response.status.should == 400
+ end
+ end
end
end
@@ -2,7 +2,7 @@ module VCAP::Services::Api
class ServiceGatewayClientFake < ServiceGatewayClient
def provision(*)
GatewayHandleResponse.decode({
- :service_id => "SERVICE_ID",
+ :service_id => SecureRandom.uuid,
:configuration => "CONFIGURATION",
:credentials => {"password" => "PASSWORD"},
}.to_json)
@@ -13,7 +13,7 @@ def unprovision(*)
def bind(*)
GatewayHandleResponse.decode({
- :service_id => "SERVICE_ID",
+ :service_id => SecureRandom.uuid,
:configuration => "CONFIGURATION",
:credentials => {"password" => "PASSWORD"},
}.to_json)

0 comments on commit fb33231

Please sign in to comment.