Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement originating origin identity #2

Merged
merged 3 commits into from
Mar 3, 2018
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
implement originating origin identity
* added a interface to the context
* Exposing the concrete classes for casting if wanted
shawn-hurley committed Feb 28, 2018
commit 37fcbf8f52864ff8643605dbb2d1162794dd5f5b
5 changes: 3 additions & 2 deletions pkg/broker/logic.go
Original file line number Diff line number Diff line change
@@ -167,6 +167,7 @@ type BusinessLogic interface {
// - the original http request, in case access is required (to get special
// request headers, for example)
type RequestContext struct {
Writer http.ResponseWriter
Request *http.Request
Writer http.ResponseWriter
Request *http.Request
Identity Identity
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for readers, I'm talking to Shawn in real life, these are notes only.

Take this out for now.

}
82 changes: 82 additions & 0 deletions pkg/broker/user_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package broker

import (
"encoding/base64"
"encoding/json"
"fmt"
"strings"
)

// Identity that is sent from the OSB spec in the Originating Identity Header
// https://github.com/openservicebrokerapi/servicebroker/blob/master/profile.md#originating-identity-header
type Identity interface {
// Platform - Retrieve the platform for the identity.
Platform() string
// Value - Retrieve the value for the identity.
Value() interface{}
}

// NewIdentity - will return a new identity
func NewIdentity(platform, value string) (Identity, error) {
val, err := base64.StdEncoding.DecodeString(value)
if err != nil {
return nil, fmt.Errorf("unable decode identity value")
}
switch strings.ToLower(platform) {
case "kubernetes":
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make these (in a separate PR, if you please) methods that give you back the right formulation

u := UserInfo{}
err = json.Unmarshal(val, &u)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal json for value")
}
return K8SIdentity{userInfo: u, platform: platform}, nil
case "cloudfoundry":
m := map[string]interface{}{}
err = json.Unmarshal(val, &m)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal json for value")
}
return CloudFoundry{platform: platform, value: m}, nil
}
return nil, fmt.Errorf("unable to determine type of identity")
}

// K8SIdentity - Identity implementation based on the kubernetes user info object
type K8SIdentity struct {
platform string
userInfo UserInfo
}

// UserInfo - kubernetest user info object
type UserInfo struct {
Username string
UID string
Groups []string
Extra map[string][]string
}

// Platform - Retrieve the platform for the identity.
func (k K8SIdentity) Platform() string {
return k.platform
}

// Value - Retrieve the value for the identity.
func (k K8SIdentity) Value() interface{} {
return k.userInfo
}

// CloudFoundry - Identity implementation based on cloud foundry
type CloudFoundry struct {
platform string
value map[string]interface{}
}

// Platform - Retrieve the platform for the identity.
func (c CloudFoundry) Platform() string {
return c.platform
}

// Value - Retrieve the value for the identity.
func (c CloudFoundry) Value() interface{} {
return c.Value
}
65 changes: 55 additions & 10 deletions pkg/rest/apisurface.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package rest

import (
"fmt"
"net/http"
"strings"

@@ -79,9 +80,16 @@ func (s *APISurface) ProvisionHandler(w http.ResponseWriter, r *http.Request) {

glog.Infof("Received ProvisionRequest for instanceID %q", request.InstanceID)

identity, err := retrieveOriginatingIdentity(r)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part moves to unpack

if err != nil {
writeError(w, err, http.StatusBadRequest)
return
}

c := &broker.RequestContext{
Writer: w,
Request: r,
Writer: w,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Populate the originating identity field of the osb.Xrequest

Request: r,
Identity: identity,
}

response, err := s.BusinessLogic.Provision(request, c)
@@ -138,10 +146,16 @@ func (s *APISurface) DeprovisionHandler(w http.ResponseWriter, r *http.Request)
}

glog.Infof("Received DeprovisionRequest for instanceID %q", request.InstanceID)
identity, err := retrieveOriginatingIdentity(r)
if err != nil {
writeError(w, err, http.StatusBadRequest)
return
}

c := &broker.RequestContext{
Writer: w,
Request: r,
Writer: w,
Request: r,
Identity: identity,
}

response, err := s.BusinessLogic.Deprovision(request, c)
@@ -252,10 +266,16 @@ func (s *APISurface) BindHandler(w http.ResponseWriter, r *http.Request) {
}

glog.Infof("Received BindRequest for instanceID %q, bindingID %q", request.InstanceID, request.BindingID)
identity, err := retrieveOriginatingIdentity(r)
if err != nil {
writeError(w, err, http.StatusBadRequest)
return
}

c := &broker.RequestContext{
Writer: w,
Request: r,
Writer: w,
Request: r,
Identity: identity,
}

response, err := s.BusinessLogic.Bind(request, c)
@@ -299,10 +319,16 @@ func (s *APISurface) UnbindHandler(w http.ResponseWriter, r *http.Request) {
}

glog.Infof("Received UnbindRequest for instanceID %q, bindingID %q", request.InstanceID, request.BindingID)
identity, err := retrieveOriginatingIdentity(r)
if err != nil {
writeError(w, err, http.StatusBadRequest)
return
}

c := &broker.RequestContext{
Writer: w,
Request: r,
Writer: w,
Request: r,
Identity: identity,
}

response, err := s.BusinessLogic.Unbind(request, c)
@@ -344,9 +370,15 @@ func (s *APISurface) UpdateHandler(w http.ResponseWriter, r *http.Request) {

glog.Infof("Received Update Request for instanceID %q", request.InstanceID)

identity, err := retrieveOriginatingIdentity(r)
if err != nil {
writeError(w, err, http.StatusBadRequest)
return
}
c := &broker.RequestContext{
Writer: w,
Request: r,
Writer: w,
Request: r,
Identity: identity,
}

response, err := s.BusinessLogic.Update(request, c)
@@ -376,3 +408,16 @@ func unpackUpdateRequest(r *http.Request) (*osb.UpdateInstanceRequest, error) {

return osbRequest, nil
}

func retrieveOriginatingIdentity(r *http.Request) (broker.Identity, error) {
identityHeader := r.Header.Get("OriginatingIdentityHeader")
if identityHeader != "" {
identitySlice := strings.Split(identityHeader, " ")
if len(identitySlice) != 2 {
glog.Infof("invalid header for originating origin header - %v", identityHeader)
return nil, fmt.Errorf("invalid originating identity header")
}
return broker.NewIdentity(identitySlice[0], identitySlice[1])
}
return nil, fmt.Errorf("unable to find originating identity")
}