Skip to content

Commit

Permalink
Merge pull request #35 from SlimYang/master
Browse files Browse the repository at this point in the history
add an internal api for update handles
  • Loading branch information
CloudFoundry Services Team committed Mar 28, 2013
2 parents 9737ca6 + 143a27e commit fb33231
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Expand Up @@ -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)
Expand Down
41 changes: 41 additions & 0 deletions lib/cloud_controller/api/service_binding.rb
@@ -1,5 +1,7 @@
# Copyright (c) 2009-2012 VMware, Inc.

require 'services/api'

module VCAP::CloudController
rest_controller :ServiceBinding do
permissions_required do
Expand Down Expand Up @@ -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
40 changes: 40 additions & 0 deletions lib/cloud_controller/api/service_instance.rb
@@ -1,5 +1,7 @@
# Copyright (c) 2009-2012 VMware, Inc.

require 'services/api'

module VCAP::CloudController
rest_controller :ServiceInstance do
permissions_required do
Expand Down Expand Up @@ -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
45 changes: 45 additions & 0 deletions spec/api/service_binding_spec.rb
Expand Up @@ -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
44 changes: 44 additions & 0 deletions spec/api/service_instance_spec.rb
Expand Up @@ -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
4 changes: 2 additions & 2 deletions spec/support/fakes/service_gateway_client_fake.rb
Expand Up @@ -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)
Expand All @@ -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)
Expand Down

0 comments on commit fb33231

Please sign in to comment.