Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Commit

Permalink
Added full documentation and contributing file
Browse files Browse the repository at this point in the history
  • Loading branch information
Taylor Thomas committed May 8, 2017
1 parent 44a3a7c commit ca68097
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 8 deletions.
39 changes: 39 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# How to contribute

There are a few guidelines that we need contributors to follow so that we are able to process requests as efficiently as possible. If you have any questions or concerns please feel free to contact us at [opensource@nike.com](mailto:opensource@nike.com).

## Getting Started

* Review our [Code of Conduct](https://github.com/Nike-Inc/nike-inc.github.io/blob/master/CONDUCT.md)
* Submit the [Individual Contributor License Agreement](https://www.clahub.com/agreements/Nike-Inc/fastbreak)
* Make sure you have a [GitHub account](https://github.com/signup/free)
* Submit a ticket for your issue, assuming one does not already exist.
* Clearly describe the issue including steps to reproduce when it is a bug.
* Make sure you fill in the earliest version that you know has the issue.
* Fork the repository on GitHub

## Making Changes

* Create a topic branch off of `master` before you start your work.
* Please avoid working directly on the `master` branch.
* Make commits of logical units.
* You may be asked to squash unnecessary commits down to logical units.
* Check for unnecessary whitespace with `git diff --check` before committing.
* Write meaningful, descriptive commit messages.
* Please follow existing code conventions when working on a file.

## Submitting Changes

* Push your changes to a topic branch in your fork of the repository.
* Submit a pull request to the repository in the Nike-Inc organization.
* After feedback has been given we expect responses within two weeks. After two weeks we may close the pull request if it isn't showing any activity.
* Bug fixes or features that lack appropriate tests may not be considered for merge.
* Changes that lower test coverage may not be considered for merge.

# Additional Resources

* [General GitHub documentation](https://help.github.com/)
* [GitHub pull request documentation](https://help.github.com/send-pull-requests/)
* [Nike's Code of Conduct](https://github.com/Nike-Inc/nike-inc.github.io/blob/master/CONDUCT.md)
* [Nike's Individual Contributor License Agreement](https://www.clahub.com/agreements/Nike-Inc/fastbreak)
* [Nike OSS](https://nike-inc.github.io/)
209 changes: 206 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,209 @@
# Cerberus Go Client
This library is a port of the [official Cerberus Python client](https://github.com/Nike-Inc/cerberus-python-client).
A Golang client for accessing Cerberus

## Usage

### Quick Start
The simplest way to get started is to use the user authentication:
```go
import (
"fmt"

cerberus "github.nike.com/ngp/cerberus-client-go"
"github.nike.com/ngp/cerberus-client-go/auth"
)
...
authMethod, _ := auth.NewUserAuth("https://cerberus.example.com", "my-cerberus-user", "my-password")
// This will prompt you for an MFA token if you have MFA enabled
client, err := cerberus.NewClient(authMethod, nil)
if err != nil {
panic(err)
}
sdbs, _ := client.SDB().List()
fmt.Println(sdbs)
```

### Supported endpoints
All of the most recent endpoints at the time of writing (2 May 2017) are supported while older
versions are not. The full list is below

- `/v2/auth/user`
- `/v2/auth/mfa_check`
- `/v2/auth/user/refresh`
- `/v2/auth/iam-principal`
- `/v1/auth` (used for `DELETE` operations)
- `/v2/safe-deposit-box`
- `/v1/role`
- `/v1/category`
- `/v1/metadata`

### Authentication
Cerberus supports 3 types of authentication, all of which are explained below. The auth types
are designed to be used independently of the full Cerberus client if desired. This allows you
to just get a token for use in other applications. There are also methods for returning a
set of headers needed to authenticate to Cerberus. With all of the authentication types, `GetToken`
triggers the actual authentication process for the given type.

All 3 types support setting the URL for Cerberus using the `CERBERUS_URL` environment variable,
which will always override anything you pass to the `New*Auth` methods.

#### AWS
AWS authentication expects an IAM principal ARN and an AWS region to be able to authenticate.
For more information, see the [API docs](https://github.com/Nike-Inc/cerberus-management-service/blob/master/API.md#app-login-v2-v2authiam-principal)

```go
authMethod, _ := auth.NewAWSAuth("https://cerberus.example.com", "arn:aws:iam::111111111:role/cerberus-api-tester", "us-west-2")
tok, err := authMethod.GetToken(nil)
```

#### Token
Token authentication is meant to be used when there is already an existing Cerberus token you
wish to use. No validation is done on the token, so if it is invalid or expired, method calls
will likely return an `api.ErrorUnauthorized`.

This method also allows you to set a token using the `CERBERUS_TOKEN` environment variable.
Like `CERBERUS_URL`, this will override anything you pass to the `NewTokenAuth` method.

```go
authMethod, _ := auth.NewTokenAuth("https://cerberus.example.com", "my-cool-token")
tok, err := authMethod.GetToken(nil)
```

#### User
User authentication is for using a username and password (with optional MFA) to log in to Cerberus.
There are some [known limitations](#known-limitations) with MFA. The `GetToken` method takes an `*os.File`
argument that expects a file with one line containing the MFA token to use. Otherwise, if `nil` is passed
it will prompt for the MFA token.

```go
authMethod, _ := auth.NewUserAuth("https://cerberus.example.com", "my-cerberus-user", "my-password")
tok, err := authMethod.GetToken(nil)
```

### Client
Once you have an authentication method, you can pass it to `NewClient` along with an optional file argument
for where to read the MFA token from. `NewClient` will take care of actually authenticating to Cerberus

```go
client, err := cerberus.NewClient(authMethod, nil)
```

The client is organized with various "subclients" to access different endpoints. For example, to list all
SDBs and secrets for each SDB:

```go
list, err := client.SDB().List()
for _, v := range list {
l, _ := client.Secret().List(v.Path)
fmt.Println(l)
}
```

For full information on every method, see the [Godoc]()

## Development

### Code organization
The code is broken up into 4 parts, including 3 subpackages. The top level package contains all of
the code for the Cerberus client proper. A breakdown of all the subpackages follows:

#### API
The `api` package contains all type definitions for API objects as well as common errors. It also contains
API error handling methods

#### Auth
The `auth` package contains implementations for all authentication types and the definition for the `Auth`
interface that all authentication types must satisfy.

#### Utils
The `utils` package contains common methods used by the top level client and multiple subpackages. This
**is not** meant to be a kitchen sink in which to throw things that don't belong.

### Tests
We use [GoConvey](https://github.com/smartystreets/goconvey) for our testing. There are plenty of tests
in the code that you can use for examples

### Contributing
See the [CONTRIBUTING.md](CONTRIBUTING.md) document for more information on how to begin contributing.

The tl;dr is that we encourage any PRs you'd like to submit. Please remember to keep your commits
small and focused and try to write tests for any new features you add.

## Roadmap
Currently, we are only implementing the `UserAuth` type for authenticating to the API.
The AWS Auth has been stubbed out and will be implemented in the future
All endpoints have been implemented with unit tests. The other major task remaining is to write
integration tests.

### Known limitations
Currently, this will only support one enrolled MFA device (the first one you enable). In the
future we want to make this cleaner for CLI usage

## Full example
Below is a full, runnable example of how to use the Cerberus client with a simple CLI

```go
package main

import (
"fmt"
"os"

cerberus "github.nike.com/ngp/cerberus-client-go"
"github.nike.com/ngp/cerberus-client-go/api"
"github.nike.com/ngp/cerberus-client-go/auth"
"golang.org/x/crypto/ssh/terminal"
)

func main() {
var username string
fmt.Print("Input username: ")
fmt.Scan(&username)
fmt.Print("Input password: ")
password, _ := terminal.ReadPassword(0)
fmt.Print("\n")
authMethod, err := auth.NewUserAuth("https://cerberus.example.com", username, string(password))
if err != nil {
fmt.Printf("Error when creating auth method: %v\n", err)
os.Exit(1)
}

client, err := cerberus.NewClient(authMethod, nil)
if err != nil {
fmt.Printf("Error when creating client: %v\n", err)
os.Exit(1)
}
tok, _ := client.Authentication.GetToken(nil)
fmt.Println(tok)

sdb, err := client.SDB().GetByName("TestBoxForScience")
if err != nil {
fmt.Printf("Error when getting sdb: %v\n", err)
os.Exit(1)
}

fmt.Println(sdb)

sec, err := client.Secret().List(sdb.Path)
if err != nil {
fmt.Printf("Error when getting secrets: %v\n", err)
os.Exit(1)
}
fmt.Println(sec)

newSDB, err := client.SDB().Create(&api.SafeDepositBox{
Name: "testtest",
Description: "A test thing",
Owner: "Lst.test.cerberus",
CategoryID: sdb.CategoryID,
})
if err != nil {
fmt.Printf("Error when creating SDB: %v\n", err)
os.Exit(1)
}
fmt.Println(newSDB)

if err := client.SDB().Delete(newSDB.ID); err != nil {
fmt.Printf("Error when deleting SDB: %v\n", err)
os.Exit(1)
}
}
```
10 changes: 5 additions & 5 deletions api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ type UserMetadata struct {

// SafeDepositBox represents a safe deposit box API object
type SafeDepositBox struct {
ID string `json:",omitempty"`
Name string `json:",omitempty"`
Path string `json:",omitempty"`
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Path string `json:"path,omitempty"`
CategoryID string `json:"category_id,omitempty"`
Description string `json:",omitempty"`
Owner string `json:",omitempty"`
Description string `json:"description,omitempty"`
Owner string `json:"owner,omitempty"`
UserGroupPermissions []UserGroupPermission `json:"user_group_permissions,omitempty"`
IAMRolePermissions []IAMRole `json:"iam_role_permissions,omitempty"`
}
Expand Down
5 changes: 5 additions & 0 deletions cerberus.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"net/url"
"os"

"io/ioutil"

vault "github.com/hashicorp/vault/api"
"github.nike.com/ngp/cerberus-client-go/api"
"github.nike.com/ngp/cerberus-client-go/auth"
Expand Down Expand Up @@ -110,6 +112,9 @@ func (c *Client) DoRequest(method, path string, params map[string]string, data i
if err != nil {
return nil, err
}
thing, _ := ioutil.ReadAll(body)
fmt.Println(string(thing))
body = bytes.NewBuffer(thing)
req, err = http.NewRequest(method, baseURL.String(), body)
}

Expand Down

0 comments on commit ca68097

Please sign in to comment.