Skip to content

Commit

Permalink
Generate CRUD functions for users, groups, clients
Browse files Browse the repository at this point in the history
- Add `uaa.ClientsEndpoint`
- Add `uaa.GroupsEndpoint`
- Add `uaa.UsersEndpoint`
- Remove `uaa.Context`
- Remove `uaa.Config`
- Remove `uaa.Target`
- Remove `uaa.AuthContext`
- Remove `uaa.NewConfigWithServerURL`
- Remove `uaa.NewContextWithToken`
- Remove `uaa.NewConfig`
- Remove `uaa.NewTarget`
- Remove `uaa.CurlManager`
- Remove `uaa.ClientManager`
- Remove `uaa.PaginatedClientList`
- Remove `uaa.ClientCredentialsClient`
- Remove `uaa.ResourceOwnerPasswordClient`
- Remove `uaa.AuthorizationCodeClient`
- Remove `uaa.RefreshTokenClient`
- Remove `uaa.TokenResponse`
- Remove `uaa.Requestor`
- Remove `uaa.UnauthenticatedRequestor`
- Remove `uaa.AuthenticatedRequestor`
- `uaa.ClientManager.Get` > `uaa.API.GetClient`
- `uaa.ClientManager.Delete` > `uaa.API.DeleteClient`
- `uaa.ClientManager.Create` > `uaa.API.CreateClient`
- `uaa.ClientManager.Update` > `uaa.API.UpdateClient`
- `uaa.ClientManager.ChangeSecret` > `uaa.API.ChangeClientSecret`
- Add `uaa.API.ListClients`
- `uaa.ClientManager.List` > `uaa.API.ListAllClients`
- `uaa.CurlManager.Curl` > `uaa.API.Curl`
- `uaa.GroupManager.Get` > `uaa.API.GetGroup`
- `uaa.GroupManager.Delete` > `uaa.API.DeleteGroup`
- `uaa.GroupManager.Create` > `uaa.API.CreateGroup`
- `uaa.GroupManager.Update` > `uaa.API.UpdateGroup`
- `uaa.GroupManager.List` > `uaa.API.ListGroups`
- `uaa.GroupManager.AddMember` > `uaa.API.AddGroupMember`
- `uaa.GroupManager.GetByName` > `uaa.API.GetGroupByName`
- Add `uaa.API.ListAllGroups`
- `uaa.Health` > `uaa.API.IsHealthy`
- Add `uaa.Page`
- `uaa.TokenKey` > `uaa.API.TokenKey`
- `uaa.TokenKeys` > `uaa.API.TokenKeys`
  • Loading branch information
joefitzgerald committed Jun 12, 2018
1 parent 852c0d0 commit 17ae85c
Show file tree
Hide file tree
Showing 39 changed files with 3,136 additions and 3,692 deletions.
2 changes: 2 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"golang.org/x/oauth2/clientcredentials"
)

//go:generate go run generator.go

// API is a client to the UAA API.
type API struct {
AuthenticatedClient *http.Client
Expand Down
21 changes: 21 additions & 0 deletions api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,27 @@ import (
"golang.org/x/oauth2"
)

func TestUAA(t *testing.T) {
spec.Run(t, "UAA", testUAA, spec.Report(report.Terminal{}))
}

func testUAA(t *testing.T, when spec.G, it spec.S) {
it.Before(func() {
RegisterTestingT(t)
})

when("TokenFormat.String()", func() {
it("prints the string representation appropriately", func() {
var t uaa.TokenFormat
Expect(t.String()).To(Equal("opaque"))
t = 3
Expect(t.String()).To(Equal(""))
Expect(uaa.JSONWebToken.String()).To(Equal("jwt"))
Expect(uaa.OpaqueToken.String()).To(Equal("opaque"))
})
})
}

func TestNew(t *testing.T) {
spec.Run(t, "New", testNew, spec.Report(report.Terminal{}))
}
Expand Down
158 changes: 30 additions & 128 deletions clients.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
package uaa

import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"strings"
)

const clientsResource string = "/oauth/clients"
// ClientsEndpoint is the path to the clients resource.
const ClientsEndpoint string = "/oauth/clients"

// ClientManager allows you to interact with the Clients resource.
type ClientManager struct {
HTTPClient *http.Client
Config Config
// paginatedClientList is the response from the API for a single page of clients.
type paginatedClientList struct {
Page
Resources []Client `json:"resources"`
Schemas []string `json:"schemas"`
}

// Client is a UAA client
// http://docs.cloudfoundry.org/api/uaa/version/4.14.0/index.html#clients.
type Client struct {
ClientID string `json:"client_id,omitempty"`
ClientID string `json:"client_id,omitempty" generator:"id"`
ClientSecret string `json:"client_secret,omitempty"`
Scope []string `json:"scope,omitempty"`
ResourceIDs []string `json:"resource_ids,omitempty"`
Expand All @@ -34,6 +37,18 @@ type Client struct {
RefreshTokenValidity int64 `json:"refresh_token_validity,omitempty"`
}

// GrantType is a type of oauth2 grant.
type GrantType string

// Valid GrantType values.
const (
REFRESHTOKEN = GrantType("refresh_token")
AUTHCODE = GrantType("authorization_code")
IMPLICIT = GrantType("implicit")
PASSWORD = GrantType("password")
CLIENTCREDENTIALS = GrantType("client_credentials")
)

func errorMissingValueForGrantType(value string, grantType GrantType) error {
return fmt.Errorf("%v must be specified for %v grant type", value, grantType)
}
Expand Down Expand Up @@ -107,132 +122,19 @@ type changeSecretBody struct {
ClientSecret string `json:"secret,omitempty"`
}

// PaginatedClientList is the response from the API for a single page of clients.
type PaginatedClientList struct {
Resources []Client `json:"resources"`
StartIndex int `json:"startIndex"`
ItemsPerPage int `json:"itemsPerPage"`
TotalResults int `json:"totalResults"`
Schemas []string `json:"schemas"`
}

// Get the client with the given ID
// http://docs.cloudfoundry.org/api/uaa/version/4.14.0/index.html#retrieve-3.
func (cm *ClientManager) Get(id string) (Client, error) {
url := fmt.Sprintf("%s/%s", clientsResource, id)
bytes, err := AuthenticatedRequestor{}.Get(cm.HTTPClient, cm.Config, url, "")
if err != nil {
return Client{}, err
}

c := Client{}
err = json.Unmarshal(bytes, &c)
if err != nil {
return Client{}, parseError(url, bytes)
}

return c, err
}

// Delete the client with the given ID
// http://docs.cloudfoundry.org/api/uaa/version/4.14.0/index.html#delete-6.
func (cm *ClientManager) Delete(id string) (Client, error) {
url := fmt.Sprintf("%s/%s", clientsResource, id)
bytes, err := AuthenticatedRequestor{}.Delete(cm.HTTPClient, cm.Config, url, "")
if err != nil {
return Client{}, err
}

c := Client{}
err = json.Unmarshal(bytes, &c)
if err != nil {
return Client{}, parseError(url, bytes)
}

return c, err
}

// Create the given client
// http://docs.cloudfoundry.org/api/uaa/version/4.14.0/index.html#create-6.
func (cm *ClientManager) Create(client Client) (Client, error) {
bytes, err := AuthenticatedRequestor{}.PostJSON(cm.HTTPClient, cm.Config, clientsResource, "", client)
if err != nil {
return Client{}, err
}

c := Client{}
err = json.Unmarshal(bytes, &c)
if err != nil {
return Client{}, parseError(clientsResource, bytes)
}

return c, err
}

// Update the given client
// http://docs.cloudfoundry.org/api/uaa/version/4.14.0/index.html#update-6.
func (cm *ClientManager) Update(client Client) (Client, error) {
url := "/oauth/clients/" + client.ClientID
bytes, err := AuthenticatedRequestor{}.PutJSON(cm.HTTPClient, cm.Config, url, "", client)
if err != nil {
return Client{}, err
}

c := Client{}
err = json.Unmarshal(bytes, &c)
if err != nil {
return Client{}, parseError(url, bytes)
}

return c, err
}

// ChangeSecret updates the secret with the given value for the client
// ChangeClientSecret updates the secret with the given value for the client
// with the given id
// http://docs.cloudfoundry.org/api/uaa/version/4.14.0/index.html#change-secret.
func (cm *ClientManager) ChangeSecret(id string, newSecret string) error {
url := "/oauth/clients/" + id + "/secret"
body := changeSecretBody{ClientID: id, ClientSecret: newSecret}
_, err := AuthenticatedRequestor{}.PutJSON(cm.HTTPClient, cm.Config, url, "", body)
return err
}

func getClientPage(cm *ClientManager, startIndex, count int) (PaginatedClientList, error) {
query := fmt.Sprintf("startIndex=%v&count=%v", startIndex, count)
if startIndex == 0 {
query = ""
}

bytes, err := AuthenticatedRequestor{}.Get(cm.HTTPClient, cm.Config, "/oauth/clients", query)
if err != nil {
return PaginatedClientList{}, err
}

clientList := PaginatedClientList{}
err = json.Unmarshal(bytes, &clientList)
func (a *API) ChangeClientSecret(id string, newSecret string) error {
u := urlWithPath(*a.TargetURL, fmt.Sprintf("%s/%s/secret", ClientsEndpoint, id))
change := &changeSecretBody{ClientID: id, ClientSecret: newSecret}
j, err := json.Marshal(change)
if err != nil {
return PaginatedClientList{}, parseError("/oauth/clients", bytes)
return err
}
return clientList, nil
}

// List all clients.
func (cm *ClientManager) List() ([]Client, error) {
results, err := getClientPage(cm, 0, 0)
err = a.doJSON(http.MethodPut, &u, bytes.NewBuffer([]byte(j)), nil, true)
if err != nil {
return []Client{}, err
}

clientList := results.Resources
startIndex, count := results.StartIndex, results.ItemsPerPage
for results.TotalResults > len(clientList) {
startIndex += count
newResults, err := getClientPage(cm, startIndex, count)
if err != nil {
return []Client{}, err
}
clientList = append(clientList, newResults.Resources...)
return err
}

return clientList, nil
return nil
}
Loading

0 comments on commit 17ae85c

Please sign in to comment.