Skip to content

Commit

Permalink
Adds Create/Get for clients
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick Calugar and Ryan Moran committed Mar 20, 2015
1 parent 2df580b commit 05e1d4e
Show file tree
Hide file tree
Showing 18 changed files with 415 additions and 52 deletions.
58 changes: 58 additions & 0 deletions acceptance/clients.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package acceptance

import (
"os"
"os/exec"
"time"

"github.com/pivotal-cf-experimental/warrant"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("Client Lifecycle", func() {
var (
warrantClient warrant.Warrant
token string
client warrant.Client
)

BeforeEach(func() {
token = os.Getenv("UAA_TOKEN")
client = warrant.Client{
ID: "warrant-client",
Scope: []string{"openid"},
ResourceIDs: []string{"none"},
Authorities: []string{"scim.read", "scim.write"},
AuthorizedGrantTypes: []string{"client_credentials"},
AccessTokenValidity: 5000 * time.Second,
}

warrantClient = warrant.New(warrant.Config{
Host: os.Getenv("UAA_HOST"),
SkipVerifySSL: true,
})
})

AfterEach(func() {
// TODO: replace with implementation that does not call out to UAAC
cmd := exec.Command("uaac", "client", "delete", client.ID)
output, err := cmd.Output()
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring("client registration deleted"))
})

It("creates, and retrieves a client", func() {
By("creating a client", func() {
err := warrantClient.Clients.Create(client, "secret", token)
Expect(err).NotTo(HaveOccurred())
})

By("find the client", func() {
fetchedClient, err := warrantClient.Clients.Get(client.ID, token)
Expect(err).NotTo(HaveOccurred())
Expect(fetchedClient).To(Equal(client))
})
})
})
12 changes: 10 additions & 2 deletions acceptance/passwords.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,27 @@ import (

var _ = Describe("Passwords", func() {
var (
client warrant.Client
client warrant.Warrant
token string
)

BeforeEach(func() {
token = os.Getenv("UAA_TOKEN")

client = warrant.NewClient(warrant.Config{
client = warrant.New(warrant.Config{
Host: os.Getenv("UAA_HOST"),
SkipVerifySSL: true,
})
})

AfterEach(func() {
// TODO: replace with implementation that does not call out to UAAC
cmd := exec.Command("uaac", "token", "client", "get", os.Getenv("UAA_ADMIN_CLIENT"), "-s", os.Getenv("UAA_ADMIN_SECRET"))
output, err := cmd.Output()
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring("Successfully fetched token via client credentials grant."))
})

It("allows a user password to be set/updated", func() {
var (
user warrant.User
Expand Down
7 changes: 3 additions & 4 deletions acceptance/tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

var _ = Describe("Tokens", func() {
var (
client warrant.Client
client warrant.Warrant
token string
user warrant.User
userToken string
Expand All @@ -22,15 +22,14 @@ var _ = Describe("Tokens", func() {
BeforeEach(func() {
token = os.Getenv("UAA_TOKEN")

client = warrant.NewClient(warrant.Config{
client = warrant.New(warrant.Config{
Host: os.Getenv("UAA_HOST"),
SkipVerifySSL: true,
})
})

AfterEach(func() {
var err error
err = client.Users.Delete(user.ID, token)
err := client.Users.Delete(user.ID, token)
Expect(err).NotTo(HaveOccurred())
})

Expand Down
4 changes: 2 additions & 2 deletions acceptance/user_lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import (

var _ = Describe("User Lifecycle", func() {
var (
client warrant.Client
client warrant.Warrant
token string
)

BeforeEach(func() {
token = os.Getenv("UAA_TOKEN")

client = warrant.NewClient(warrant.Config{
client = warrant.New(warrant.Config{
Host: os.Getenv("UAA_HOST"),
SkipVerifySSL: true,
})
Expand Down
36 changes: 19 additions & 17 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,23 @@ type response struct {
Headers http.Header
}

type Client struct {
config Config
Users UsersService
OAuth OAuthService
type Warrant struct {
config Config
Users UsersService
OAuth OAuthService
Clients ClientsService
}

func NewClient(config Config) Client {
return Client{
config: config,
Users: NewUsersService(config),
OAuth: NewOAuthService(config),
func New(config Config) Warrant {
return Warrant{
config: config,
Users: NewUsersService(config),
OAuth: NewOAuthService(config),
Clients: NewClientsService(config),
}
}

func (c Client) makeRequest(requestArgs requestArguments) (response, error) {
func (w Warrant) makeRequest(requestArgs requestArguments) (response, error) {
if requestArgs.AcceptableStatusCodes == nil {
panic("acceptable status codes for this request were not set")
}
Expand All @@ -86,7 +88,7 @@ func (c Client) makeRequest(requestArgs requestArguments) (response, error) {
}
}

requestURL := c.config.Host + requestArgs.Path
requestURL := w.config.Host + requestArgs.Path
request, err := http.NewRequest(requestArgs.Method, requestURL, bodyReader)
if err != nil {
return response{}, newRequestConfigurationError(err)
Expand All @@ -101,16 +103,16 @@ func (c Client) makeRequest(requestArgs requestArguments) (response, error) {
request.Header.Set("If-Match", requestArgs.IfMatch)
}

c.printRequest(request)
w.printRequest(request)

var resp *http.Response
if requestArgs.DoNotFollowRedirects {
resp, err = network.GetClient(network.Config{
SkipVerifySSL: c.config.SkipVerifySSL,
SkipVerifySSL: w.config.SkipVerifySSL,
}).Transport.RoundTrip(request)
} else {
resp, err = network.GetClient(network.Config{
SkipVerifySSL: c.config.SkipVerifySSL,
SkipVerifySSL: w.config.SkipVerifySSL,
}).Do(request)
}
if err != nil {
Expand All @@ -127,7 +129,7 @@ func (c Client) makeRequest(requestArgs requestArguments) (response, error) {
Body: responseBody,
Headers: resp.Header,
}
c.printResponse(parsedResponse)
w.printResponse(parsedResponse)

if resp.StatusCode == http.StatusNotFound {
return response{}, newNotFoundError(responseBody)
Expand All @@ -146,7 +148,7 @@ func (c Client) makeRequest(requestArgs requestArguments) (response, error) {
return response{}, newUnexpectedStatusError(resp.StatusCode, responseBody)
}

func (c Client) printRequest(request *http.Request) {
func (w Warrant) printRequest(request *http.Request) {
if os.Getenv("TRACE") != "" {
bodyCopy := bytes.NewBuffer([]byte{})
if request.Body != nil {
Expand All @@ -163,7 +165,7 @@ func (c Client) printRequest(request *http.Request) {
}
}

func (c Client) printResponse(resp response) {
func (w Warrant) printResponse(resp response) {
if os.Getenv("TRACE") != "" {
fmt.Printf("RESPONSE: %d %s %+v\n", resp.Code, resp.Body, resp.Headers)
}
Expand Down
16 changes: 8 additions & 8 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var unsupportedJSONType = func() {}
var _ = Describe("Client", func() {
var token string
var fakeServer *httptest.Server
var client warrant.Client
var client warrant.Warrant

BeforeEach(func() {
token = "TOKEN"
Expand All @@ -44,7 +44,7 @@ var _ = Describe("Client", func() {
w.Write(response)
}))

client = warrant.NewClient(warrant.Config{
client = warrant.New(warrant.Config{
Host: fakeServer.URL,
SkipVerifySSL: true,
})
Expand Down Expand Up @@ -105,7 +105,7 @@ var _ = Describe("Client", func() {
w.Write([]byte("did not redirect"))
}))

client = warrant.NewClient(warrant.Config{
client = warrant.New(warrant.Config{
Host: redirectingServer.URL,
SkipVerifySSL: true,
})
Expand Down Expand Up @@ -258,7 +258,7 @@ var _ = Describe("Client", func() {
})

It("returns a RequestConfigurationError when the request params are bad", func() {
client = warrant.NewClient(warrant.Config{
client = warrant.New(warrant.Config{
Host: "://example.com",
})

Expand All @@ -275,7 +275,7 @@ var _ = Describe("Client", func() {
})

It("returns a RequestHTTPError when the request fails", func() {
client = warrant.NewClient(warrant.Config{
client = warrant.New(warrant.Config{
Host: "banana://example.com",
})

Expand All @@ -297,7 +297,7 @@ var _ = Describe("Client", func() {
w.Write([]byte("{}"))
}))

client = warrant.NewClient(warrant.Config{
client = warrant.New(warrant.Config{
Host: unintelligibleServer.URL,
})

Expand Down Expand Up @@ -333,7 +333,7 @@ var _ = Describe("Client", func() {
w.WriteHeader(http.StatusNotFound)
}))

client = warrant.NewClient(warrant.Config{
client = warrant.New(warrant.Config{
Host: missingServer.URL,
})

Expand All @@ -356,7 +356,7 @@ var _ = Describe("Client", func() {
w.WriteHeader(http.StatusUnauthorized)
}))

client = warrant.NewClient(warrant.Config{
client = warrant.New(warrant.Config{
Host: lockedServer.URL,
})

Expand Down
93 changes: 93 additions & 0 deletions clients_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package warrant

import (
"encoding/json"
"fmt"
"net/http"
"time"

"github.com/pivotal-cf-experimental/warrant/internal/documents"
)

type Client struct {
ID string
Scope []string
ResourceIDs []string
Authorities []string
AuthorizedGrantTypes []string
AccessTokenValidity time.Duration
}

type ClientsService struct {
config Config
}

func NewClientsService(config Config) ClientsService {
return ClientsService{
config: config,
}
}

func (cs ClientsService) Create(client Client, secret, token string) error {
_, err := New(cs.config).makeRequest(requestArguments{
Method: "POST",
Path: "/oauth/clients",
Token: token,
Body: jsonRequestBody{client.ToDocument(secret)},
AcceptableStatusCodes: []int{http.StatusCreated},
})
if err != nil {
panic(err)
}

return nil
}

func (cs ClientsService) Get(id, token string) (Client, error) {
resp, err := New(cs.config).makeRequest(requestArguments{
Method: "GET",
Path: fmt.Sprintf("/oauth/clients/%s", id),
Token: token,
AcceptableStatusCodes: []int{http.StatusOK},
})
if err != nil {
return Client{}, err
}

var document documents.ClientResponse
err = json.Unmarshal(resp.Body, &document)
if err != nil {
panic(err)
}

return newClientFromDocument(document), nil
}

func newClientFromDocument(document documents.ClientResponse) Client {
return Client{
ID: document.ClientID,
Scope: document.Scope,
ResourceIDs: document.ResourceIDs,
Authorities: document.Authorities,
AuthorizedGrantTypes: document.AuthorizedGrantTypes,
AccessTokenValidity: time.Duration(document.AccessTokenValidity) * time.Second,
}
}

func (c Client) ToDocument(secret string) documents.CreateClientRequest {
client := documents.CreateClientRequest{
ClientID: c.ID,
ClientSecret: secret,
AccessTokenValidity: int(c.AccessTokenValidity.Seconds()),
Scope: make([]string, 0),
ResourceIDs: make([]string, 0),
Authorities: make([]string, 0),
AuthorizedGrantTypes: make([]string, 0),
}
client.Scope = append(client.Scope, c.Scope...)
client.ResourceIDs = append(client.ResourceIDs, c.ResourceIDs...)
client.Authorities = append(client.Authorities, c.Authorities...)
client.AuthorizedGrantTypes = append(client.AuthorizedGrantTypes, c.AuthorizedGrantTypes...)

return client
}
Loading

0 comments on commit 05e1d4e

Please sign in to comment.