Skip to content

Commit

Permalink
Adding a provider for CloudFoundry's UAA OAuth
Browse files Browse the repository at this point in the history
* Added a cloudfoundry provider (cloudfoundry.go) to interface with cloudfoundry's UAA [1]
* Provide defaults for local Cloudfoundry installation on BOSH lite [2]
* One workaround for UAA bug [3] in provider_default is necessary, but only applied
  if provider "cloudfoundry" is used

[1] https://github.com/cloudfoundry/uaa
[2] https://github.com/cloudfoundry/bosh-lite
[3] cloudfoundry/uaa#308
  • Loading branch information
Omar Elazhary committed Feb 8, 2016
1 parent 10f47e3 commit 4b9da9b
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
77 changes: 77 additions & 0 deletions providers/cloudfoundry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package providers

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
)

type CloudFoundryProvider struct {
*ProviderData
}

func NewCloudFoundryProvider(p *ProviderData) *CloudFoundryProvider {
p.ProviderName = "CloudFoundry"
// Defaults for Bosh-Lite, must be configured for other OAuth Endpoints.
if p.LoginURL == nil || p.LoginURL.String() == "" {
p.LoginURL = &url.URL{
Scheme: "http",
Host: "login.bosh-lite.com",
Path: "/oauth/authorize",
}
}
if p.RedeemURL == nil || p.RedeemURL.String() == "" {
p.RedeemURL = &url.URL{
Scheme: "http",
Host: "login.bosh-lite.com",
Path: "/oauth/token",
}
}
if p.ValidateURL == nil || p.ValidateURL.String() == "" {
p.ValidateURL = &url.URL{
Scheme: "http",
Host: "login.bosh-lite.com",
Path: "/userinfo",
}
}
if p.Scope == "" {
p.Scope = "openid"
}
return &CloudFoundryProvider{ProviderData: p}
}

func (p *CloudFoundryProvider) GetEmailAddress(s *SessionState) (string, error) {

var email struct {
Email string `json:"email"`
}

params := url.Values{
"access_token": {s.AccessToken},
}
endpoint := p.ValidateURL.String() + "?" + params.Encode()
resp, err := http.DefaultClient.Get(endpoint)
if err != nil {
return "", err
}
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return "", err
}

if resp.StatusCode != 200 {
return "", fmt.Errorf("got %d from %q %s", resp.StatusCode, endpoint, body)
} else {
log.Printf("got %d from %q %s", resp.StatusCode, endpoint, body)
}

if err := json.Unmarshal(body, &email); err != nil {
return "", fmt.Errorf("%s unmarshaling %s", err, body)
}

return email.Email, nil
}
4 changes: 4 additions & 0 deletions providers/provider_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ func (p *ProviderData) Redeem(redirectURL, code string) (s *SessionState, err er
return
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// workaround for Cloudfoundry UAA bug https://github.com/cloudfoundry/uaa/issues/308
if (p.ProviderName == "CloudFoundry") {
req.SetBasicAuth(p.ClientID, p.ClientSecret)
}

var resp *http.Response
resp, err = http.DefaultClient.Do(req)
Expand Down
2 changes: 2 additions & 0 deletions providers/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ func New(provider string, p *ProviderData) Provider {
return NewGitHubProvider(p)
case "azure":
return NewAzureProvider(p)
case "cloudfoundry":
return NewCloudFoundryProvider(p)
default:
return NewGoogleProvider(p)
}
Expand Down

0 comments on commit 4b9da9b

Please sign in to comment.