Skip to content

Commit

Permalink
Merge branch 'fitzoh-originating-identity'
Browse files Browse the repository at this point in the history
  • Loading branch information
FelisiaM committed Jan 3, 2019
2 parents 588de80 + 834cef1 commit 63fe461
Show file tree
Hide file tree
Showing 6 changed files with 1,003 additions and 11 deletions.
50 changes: 41 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,65 @@
# brokerapi

[![Build Status](https://travis-ci.org/pivotal-cf/brokerapi.svg?branch=master)](https://travis-ci.org/pivotal-cf/brokerapi)
[![Build
Status](https://travis-ci.org/pivotal-cf/brokerapi.svg?branch=master)](https://travis-ci.org/pivotal-cf/brokerapi)

A Go package for building [V2 Open Service Broker API](https://github.com/openservicebrokerapi/servicebroker/) compliant Service Brokers.
A Go package for building [V2 Open Service Broker
API](https://github.com/openservicebrokerapi/servicebroker/) compliant Service
Brokers.

## [Docs](https://godoc.org/github.com/pivotal-cf/brokerapi)

## Dependencies

- Go 1.7+
- [lager](https://github.com/cloudfoundry/lager)
- [gorilla/mux](https://github.com/gorilla/mux)
- [gorilla/mux v1.6.1+](https://github.com/gorilla/mux)

We use [dep](https://github.com/golang/dep) to manager our dependencies. Use `dep ensure` in order to download the required packages.
We use [dep](https://github.com/golang/dep) to manager our dependencies. Use
`dep ensure` in order to download the required packages.

## Usage

`brokerapi` defines a [`ServiceBroker`](https://godoc.org/github.com/pivotal-cf/brokerapi#ServiceBroker) interface. Pass an implementation of this to [`brokerapi.New`](https://godoc.org/github.com/pivotal-cf/brokerapi#New), which returns an `http.Handler` that you can use to serve handle HTTP requests.
`brokerapi` defines a
[`ServiceBroker`](https://godoc.org/github.com/pivotal-cf/brokerapi#ServiceBroker)
interface. Pass an implementation of this to
[`brokerapi.New`](https://godoc.org/github.com/pivotal-cf/brokerapi#New), which
returns an `http.Handler` that you can use to serve handle HTTP requests.

Alternatively, if you already have a `*mux.Router` that you want to attach service broker routes to, you can use [`brokerapi.AttachRoutes`](https://godoc.org/github.com/pivotal-cf/brokerapi#AttachRoutes).
Alternatively, if you already have a `*mux.Router` that you want to attach
service broker routes to, you can use
[`brokerapi.AttachRoutes`](https://godoc.org/github.com/pivotal-cf/brokerapi#AttachRoutes).
Note in this case, the Basic Authentication and Originating Identity middleware
will not be set up, so you will have to attach them manually if required.

## Error types

`brokerapi` defines a handful of error types in `service_broker.go` for some common error cases that your service broker may encounter. Return these from your `ServiceBroker` methods where appropriate, and `brokerapi` will do the "right thing" (™), and give Cloud Foundry an appropriate status code, as per the [Service Broker API specification](https://docs.cloudfoundry.org/services/api.html).
`brokerapi` defines a handful of error types in `service_broker.go` for some
common error cases that your service broker may encounter. Return these from
your `ServiceBroker` methods where appropriate, and `brokerapi` will do the
"right thing" (™), and give Cloud Foundry an appropriate status code, as per
the [Service Broker API
specification](https://docs.cloudfoundry.org/services/api.html).

### Custom Errors

`NewFailureResponse()` allows you to return a custom error from any of the `ServiceBroker` interface methods which return an error. Within this you must define an error, a HTTP response status code and a logging key. You can also use the `NewFailureResponseBuilder()` to add a custom `Error:` value in the response, or indicate that the broker should return an empty response rather than the error message.
`NewFailureResponse()` allows you to return a custom error from any of the
`ServiceBroker` interface methods which return an error. Within this you must
define an error, a HTTP response status code and a logging key. You can also
use the `NewFailureResponseBuilder()` to add a custom `Error:` value in the
response, or indicate that the broker should return an empty response rather
than the error message.

## Originating Identity

The request context for every request contains the unparsed
`X-Broker-API-Originating-Identity` header under the key
`originatingIdentityKey`. More details on how the Open Service Broker API
manages request originating identity is available
[here](https://github.com/openservicebrokerapi/servicebroker/blob/master/spec.md#originating-identity).

## Example Service Broker

You can see the [cf-redis](https://github.com/pivotal-cf/cf-redis-broker/blob/2f0e9a8ebb1012a9be74bbef2d411b0b3b60352f/broker/broker.go) service broker uses the BrokerAPI package to create a service broker for Redis.
You can see the
[cf-redis](https://github.com/pivotal-cf/cf-redis-broker/blob/2f0e9a8ebb1012a9be74bbef2d411b0b3b60352f/broker/broker.go)
service broker uses the BrokerAPI package to create a service broker for Redis.
10 changes: 8 additions & 2 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/pivotal-cf/brokerapi/middlewares/originating_identity_header"
"net/http"
"strconv"

Expand Down Expand Up @@ -80,7 +81,12 @@ type BrokerCredentials struct {
func New(serviceBroker ServiceBroker, logger lager.Logger, brokerCredentials BrokerCredentials) http.Handler {
router := mux.NewRouter()
AttachRoutes(router, serviceBroker, logger)
return auth.NewWrapper(brokerCredentials.Username, brokerCredentials.Password).Wrap(router)

authMiddleware := auth.NewWrapper(brokerCredentials.Username, brokerCredentials.Password).Wrap
router.Use(authMiddleware)
router.Use(originating_identity_header.AddToContext)

return router
}

func AttachRoutes(router *mux.Router, serviceBroker ServiceBroker, logger lager.Logger) {
Expand Down Expand Up @@ -791,4 +797,4 @@ func checkBrokerAPIVersionHdr(req *http.Request) (brokerVersion, error) {
return version, errors.New("X-Broker-API-Version Header must be 2.x")
}
return version, nil
}
}
50 changes: 50 additions & 0 deletions api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,56 @@ var _ = Describe("Service Broker API", func() {
})
})

Describe("OriginatingIdentityHeader", func(){

var (
fakeServiceBroker *fakes.AutoFakeServiceBroker
req *http.Request
testServer *httptest.Server
)

BeforeEach(func() {
fakeServiceBroker = new(fakes.AutoFakeServiceBroker)
brokerAPI = brokerapi.New(fakeServiceBroker, brokerLogger, credentials)

testServer = httptest.NewServer(brokerAPI)
var err error
req, err = http.NewRequest("GET", testServer.URL+"/v2/catalog", nil)
Expect(err).NotTo(HaveOccurred())
req.Header.Add("X-Broker-API-Version", "2.14")
req.SetBasicAuth(credentials.Username, credentials.Password)
})

AfterEach(func() {
testServer.Close()
})

When("X-Broker-API-Originating-Identity is passed", func(){
It("Adds it to the context", func(){
originatingIdentity := "Originating Identity Name"
req.Header.Add("X-Broker-API-Originating-Identity", originatingIdentity)

_, err := http.DefaultClient.Do(req)
Expect(err).NotTo(HaveOccurred())

Expect(fakeServiceBroker.ServicesCallCount()).To(Equal(1), "Services was not called")
ctx := fakeServiceBroker.ServicesArgsForCall(0)
Expect(ctx.Value("originatingIdentity")).To(Equal(originatingIdentity))

})
})
When("X-Broker-API-Originating-Identity is not passed", func(){
It("Adds empty originatingIdentity to the context", func(){
_, err := http.DefaultClient.Do(req)
Expect(err).NotTo(HaveOccurred())

Expect(fakeServiceBroker.ServicesCallCount()).To(Equal(1), "Services was not called")
ctx := fakeServiceBroker.ServicesArgsForCall(0)
Expect(ctx.Value("originatingIdentity")).To(Equal(""))
})
})
})

Describe("catalog endpoint", func() {
makeCatalogRequest := func(apiVersion string, fail bool) *httptest.ResponseRecorder {
recorder := httptest.NewRecorder()
Expand Down
Loading

0 comments on commit 63fe461

Please sign in to comment.