Skip to content
This repository has been archived by the owner on Feb 16, 2023. It is now read-only.

Release v0.24.0 #154

Merged
merged 74 commits into from
Nov 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
b1ea4f1
Update README onle-line description
mackenbach Oct 4, 2019
b40d779
Merge pull request #137 from secrethub/feature/update-one-line-descri…
mackenbach Oct 7, 2019
676f744
Rephrase getting help in README
SimonBarendse Oct 16, 2019
de198d6
Merge pull request #139 from secrethub/feature/rephrase-readme-help
mackenbach Oct 16, 2019
66130f6
Merge pull request #140 from secrethub/master
SimonBarendse Oct 16, 2019
58c61f4
Restructure the readme
SimonBarendse Oct 17, 2019
133974e
Add shorthand for generating random alphanumeric characters
SimonBarendse Oct 17, 2019
a2ef9c2
Merge pull request #142 from secrethub/feature/generate-shorthand
mackenbach Oct 17, 2019
92fec28
Move examples up in the README
SimonBarendse Oct 17, 2019
ee24fb7
Merge pull request #141 from secrethub/feature/restructure-readme
SimonBarendse Oct 17, 2019
90b87ab
Only add query params to request when not empty
SimonBarendse Oct 22, 2019
b5564a7
Fix: use comma separated list when multiple subject types are supplied
SimonBarendse Oct 22, 2019
83e130d
Return iterators when listing audit events
SimonBarendse Oct 23, 2019
d0dfb20
Change fakes to return iterators as well
SimonBarendse Oct 23, 2019
bf9a749
Cache go modules in CI
SimonBarendse Oct 23, 2019
fadd354
Make download go modules a separate CI step
SimonBarendse Oct 23, 2019
93b139d
Merge pull request #145 from secrethub/feature/ci
SimonBarendse Oct 24, 2019
df40959
Merge pull request #143 from secrethub/feature/audit-query
SimonBarendse Oct 24, 2019
d930656
Rename vs => values
SimonBarendse Oct 24, 2019
0bf8d1e
Embed the iterator instead of a pointer to it
SimonBarendse Oct 24, 2019
3a0b0a7
Rename iterator.i to currentIndex
SimonBarendse Oct 24, 2019
b20098e
Rename iterator.pag to paginator
SimonBarendse Oct 24, 2019
b2b0027
Pass only decrypt functionality to the iterator instead of the whole …
SimonBarendse Oct 24, 2019
973c55f
Use AuditPaginator instead of generic Paginator
SimonBarendse Oct 24, 2019
989aa7f
Pass fetchPage functionality instead of a client to audit paginator
SimonBarendse Oct 24, 2019
f788948
Fail fast when server URL in client option is invalid
SimonBarendse Oct 24, 2019
a75cf91
Use a url.URL type for the http client base URL
SimonBarendse Oct 24, 2019
415f63a
Use base URL to construct a audit URL directly
SimonBarendse Oct 24, 2019
596203a
Don't return an error from http audit functions
SimonBarendse Oct 24, 2019
da99a13
Omit ignored value in range over map
SimonBarendse Oct 24, 2019
7b221dc
Add ListEvents back in for backwards compatability
SimonBarendse Oct 24, 2019
617fce3
Pass subject type filter as an option to EventIterator
SimonBarendse Oct 25, 2019
5f55b06
Add an audit event iterator constructor
SimonBarendse Oct 25, 2019
f7d22c6
gofmt
SimonBarendse Oct 25, 2019
7057833
Add EventIterator funcs to the interface
SimonBarendse Oct 25, 2019
ad0a4e2
Add usage to EventIterator godoc
SimonBarendse Oct 25, 2019
d118b53
Make usage godoc codeblocks
SimonBarendse Oct 25, 2019
7206ddf
Deprecate ListEvents functions
SimonBarendse Oct 25, 2019
8ce6aa0
Move audit event iterator options to audit.go
SimonBarendse Oct 25, 2019
282deba
Remove unused import
SimonBarendse Oct 25, 2019
78361f7
Merge remote-tracking branch 'origin/develop' into feature/audit-pagi…
SimonBarendse Oct 25, 2019
632679f
Update iteration usage examples to use iter var
SimonBarendse Nov 12, 2019
f310300
Create iterator using a constructor
SimonBarendse Nov 12, 2019
4a2ef3b
Lock iterator state to prevent data corruption when calling next conc…
SimonBarendse Nov 12, 2019
e9121ec
Add testcase for auditeventiterator Next
SimonBarendse Nov 12, 2019
fca6ebc
Release lock before calling next recursively
SimonBarendse Nov 12, 2019
32c968a
Make mutex a pointer reference
SimonBarendse Nov 12, 2019
ad69462
gofmt
SimonBarendse Nov 12, 2019
792f484
Move obtaining/releasing iterator locks to a separate function
SimonBarendse Nov 13, 2019
0a57c6e
Add CreateAll func to dir service to create dirs recursively
SimonBarendse Nov 13, 2019
125c15d
Fix: create parent dirs before creating their children in CreateAll
SimonBarendse Nov 14, 2019
fb6d31e
Add comments where err might be nil
SimonBarendse Nov 14, 2019
1cecfda
Add comment that CreateAll does not return an already exists error
SimonBarendse Nov 14, 2019
797aba9
Merge pull request #146 from secrethub/feature/dir-create-all
SimonBarendse Nov 14, 2019
be1ce1c
Fix indentation iteration examples and use else if
SimonBarendse Nov 14, 2019
c9ceb91
Move generic iterator to it's own package
SimonBarendse Nov 14, 2019
6acd4d7
Use a config struct instead of functional options for audit iterators
SimonBarendse Nov 19, 2019
2bf287b
Remove unused paginator field from AuditEventIterator
SimonBarendse Nov 19, 2019
1f2f6be
Delay creation of paginator to first call of Next on iterator
SimonBarendse Nov 19, 2019
ae65e39
Don't return an error when constructing an iterator
SimonBarendse Nov 19, 2019
733f583
Fix compilation of audit test
SimonBarendse Nov 19, 2019
f40add6
Fix typo == => !=
SimonBarendse Nov 19, 2019
3376b58
Remove ListEvents deprecation for now
SimonBarendse Nov 19, 2019
759ed0c
Make audit iterators mockable
SimonBarendse Nov 20, 2019
3210a1b
Separate audit event iterator from other fakes
SimonBarendse Nov 20, 2019
d304a89
Add Exists func to dir service
SimonBarendse Nov 25, 2019
c632359
Use Exists in CreateAll
SimonBarendse Nov 25, 2019
332f4d7
Don't return repo not found error from dirService.Exists
SimonBarendse Nov 25, 2019
24325dc
Add missing validation check
jpcoenen Nov 25, 2019
1fe163a
Merge pull request #151 from secrethub/feature/missing-validation
jpcoenen Nov 26, 2019
e2e462c
Merge pull request #149 from secrethub/feature/dir-exists
SimonBarendse Nov 26, 2019
0736401
Merge pull request #144 from secrethub/feature/audit-pagination
SimonBarendse Nov 26, 2019
23fd5b7
Add a fake for dirService.Exists
SimonBarendse Nov 26, 2019
fa815c5
Merge pull request #153 from secrethub/feature/mock-dir-exists
SimonBarendse Nov 26, 2019
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
8 changes: 8 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,12 @@ jobs:
- image: circleci/golang:1.12
steps:
- checkout
- restore_cache:
keys:
- go-modules-{{ checksum "go.mod" }}
- run: go mod download
- save_cache:
key: go-modules-{{ checksum "go.mod" }}
paths:
- /go/pkg/mod
- run: make test
36 changes: 18 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,22 @@

`secrethub-go` provides a client for various SecretHub APIs.

> [SecretHub][secrethub] is a developer tool to help you keep database passwords, API tokens, and other secrets out of IT automation scripts.
> [SecretHub][secrethub] is an end-to-end encrypted secret management service that helps developers keep database passwords, API keys, and other secrets out of source code.

<img src="https://secrethub.io/img/secrethub-gopher.png" alt="Gopher" width="160px"/>

## Getting started
## Usage

### Installation

Install secrethub-go with:
You can install secrethub-go with:

```sh
go get -u github.com/secrethub/secrethub-go
go get github.com/secrethub/secrethub-go
```

Or install a specific version with:

```sh
go get -u github.com/secrethub/secrethub-go@vX.Y.Z
go get github.com/secrethub/secrethub-go@vX.Y.Z
```

Then, import it using:
Expand All @@ -47,13 +45,13 @@ import (
> **Note:** only packages inside the `/pkg` directory should be considered library code that you can use in your projects.
> All other code is not guaranteed to be backwards compatible and may change in the future.

## Examples
### Examples

For details on all functionality of this library, see the [GoDoc][godoc] documentation.

Below are a few simple examples:

### Read Secrets
#### Read Secrets
```go
package main

Expand All @@ -71,7 +69,7 @@ func main() {
}
```

### Write Secrets
#### Write Secrets
```go
package main

Expand All @@ -87,7 +85,7 @@ func main() {
}
```

### Generate Secrets
#### Generate Secrets
```go
package main

Expand All @@ -100,16 +98,18 @@ import (

func main() {
client, _ := secrethub.NewClient()
rand, _ := randchar.NewRand(randchar.Alphanumeric)
data, _ := rand.Generate(30)
data, _ := randchar.Generate(30)
_, _ = client.Secrets().Write("path/to/secret", data)
}
```

> **Note:** to use the SecretHub Go client, you need to provide a credential for your __SecretHub__ account.
> You can create a free developer account by [signing up through the CLI](https://secrethub.io/docs/getting-started/).
>
> After signup, the credential is located at `$HOME/.secrethub/credential` by default.
### Credential

To use the SecretHub Go client, you need to provide a credential for your __SecretHub__ account.
You can create a free developer account by [signing up through the CLI](https://secrethub.io/docs/getting-started/).

After signup, the credential is located at `$HOME/.secrethub/credential` by default.
`secrethub.NewClient()` automatically uses this credential.

## Development

Expand All @@ -135,7 +135,7 @@ pull request][pulls].

## Getting help

Come chat with us on [Discord][discord] or email us at [support@secrethub.io](mailto:support@secrethub.io)
If you get stuck or just want advice, come chat with the engineers on [Discord][discord] or send an email to [support@secrethub.io](mailto:support@secrethub.io)

## Attributions

Expand Down
3 changes: 3 additions & 0 deletions internals/api/account_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ func (req CreateAccountKeyRequest) Validate() error {
if len(req.PublicKey) == 0 {
return ErrInvalidPublicKey
}
if req.EncryptedPrivateKey == nil {
return ErrMissingField("encrypted_private_key")
}
if err := req.EncryptedPrivateKey.Validate(); err != nil {
return err
}
Expand Down
7 changes: 5 additions & 2 deletions internals/assert/asserts.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
// assertions to help with writing tests.
package assert

import "testing"
import "github.com/kylelemons/godebug/pretty"
import (
"testing"

"github.com/kylelemons/godebug/pretty"
)

// Equal errors when actual and expected are not the same, printing out the diff.
func Equal(tb testing.TB, actual, expected interface{}) {
Expand Down
5 changes: 5 additions & 0 deletions pkg/randchar/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ type Generator interface {
Generate(n int) ([]byte, error)
}

// Generate generates a random slice of alphanumeric characters.
func Generate(n int) ([]byte, error) {
return DefaultRand.Generate(n)
}

// NewGenerator is a shorthand function to create a new random alphanumeric
// generator, optionally configured to use symbols too. For more flexibility
// to configure the random generator, use NewRand instead.
Expand Down
39 changes: 39 additions & 0 deletions pkg/secrethub/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package secrethub
import (
"github.com/secrethub/secrethub-go/internals/api"
"github.com/secrethub/secrethub-go/internals/errio"
"github.com/secrethub/secrethub-go/pkg/secrethub/internals/http"
"github.com/secrethub/secrethub-go/pkg/secrethub/iterator"
)

func (c *Client) decryptAuditEvents(events ...*api.Audit) error {
Expand Down Expand Up @@ -32,3 +34,40 @@ func (c *Client) decryptAuditEvents(events ...*api.Audit) error {

return nil
}

func newAuditEventIterator(newPaginator func() (*http.AuditPaginator, error), client *Client) *auditEventIterator {
return &auditEventIterator{
iterator: iterator.New(func() (iterator.Paginator, error) {
return newPaginator()
}),
decryptAuditEvents: client.decryptAuditEvents,
}
}

type AuditEventIterator interface {
Next() (api.Audit, error)
}

type auditEventIterator struct {
iterator iterator.Iterator
decryptAuditEvents func(...*api.Audit) error
}

func (it *auditEventIterator) Next() (api.Audit, error) {
item, err := it.iterator.Next()
if err != nil {
return api.Audit{}, err
}
audit := item.(api.Audit)
err = it.decryptAuditEvents(&audit)
if err != nil {
return api.Audit{}, err
}
return audit, nil
}

// AuditEventIteratorParams can be used to configure iteration of audit events.
//
// For now, there's nothing to configure. We'll add filter options soon.
// The struct is already added, so that adding parameters is backwards compatible.
type AuditEventIteratorParams struct{}
55 changes: 55 additions & 0 deletions pkg/secrethub/audit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package secrethub

import (
"testing"

"github.com/secrethub/secrethub-go/internals/api"
"github.com/secrethub/secrethub-go/internals/api/uuid"
"github.com/secrethub/secrethub-go/internals/assert"
"github.com/secrethub/secrethub-go/pkg/secrethub/iterator"
)

type fakeAuditPaginator struct {
events []api.Audit
returned bool
}

func (pag *fakeAuditPaginator) Next() ([]interface{}, error) {
if pag.returned {
return []interface{}{}, nil
}

res := make([]interface{}, len(pag.events))
for i, event := range pag.events {
res[i] = event
}
pag.returned = true
return res, nil
}

func TestAuditEventIterator_Next(t *testing.T) {
events := []api.Audit{
{
EventID: uuid.New(),
Action: api.AuditActionRead,
},
}

iter := auditEventIterator{
iterator: iterator.New(func() (iterator.Paginator, error) {
return &fakeAuditPaginator{events: events}, nil
}),
decryptAuditEvents: func(audit ...*api.Audit) error {
return nil
},
}

for _, event := range events {
actual, err := iter.Next()

assert.Equal(t, err, nil)
assert.Equal(t, actual, event)
}
_, err := iter.Next()
assert.Equal(t, err, iterator.Done)
}
15 changes: 13 additions & 2 deletions pkg/secrethub/client_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ package secrethub
import (
"errors"
"net/http"
"net/url"
"time"

"github.com/secrethub/secrethub-go/pkg/secrethub/configdir"
"github.com/secrethub/secrethub-go/pkg/secrethub/credentials"
httpclient "github.com/secrethub/secrethub-go/pkg/secrethub/internals/http"
)

// Errors
var (
ErrInvalidServerURL = errClient.Code("invalid_server_url").ErrorPref("%s")
)

// ClientOption is an option that can be set on a secrethub.Client.
type ClientOption func(*Client) error

Expand All @@ -22,9 +28,14 @@ func WithTimeout(timeout time.Duration) ClientOption {
}

// WithServerURL overrides the default server endpoint URL used by the HTTP client.
func WithServerURL(url string) ClientOption {
func WithServerURL(serverURL string) ClientOption {
return func(c *Client) error {
c.httpClient.Options(httpclient.WithServerURL(url))
parsedURL, err := url.Parse(serverURL)
if err != nil {
return ErrInvalidServerURL(err)
}

c.httpClient.Options(httpclient.WithServerURL(*parsedURL))
return nil
}
}
Expand Down
57 changes: 57 additions & 0 deletions pkg/secrethub/dir.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
package secrethub

import (
"strings"

"github.com/secrethub/secrethub-go/internals/api"
"github.com/secrethub/secrethub-go/internals/api/uuid"
"github.com/secrethub/secrethub-go/internals/errio"
"github.com/secrethub/secrethub-go/pkg/secretpath"
)

// DirService handles operations on directories from SecretHub.
type DirService interface {
// Create a directory at a given path.
Create(path string) (*api.Dir, error)
// CreateAll creates all directories in the given path that do not exist yet.
//
// Contrary to Create, it doesn't return an error when the directories already exist.
CreateAll(path string) error
// Exists returns whether a directory where you have access to exists at a given path.
Exists(path string) (bool, error)
// Get returns the directory with the given ID.
GetByID(id uuid.UUID) (*api.Dir, error)
// Delete removes the directory at the given path.
Expand Down Expand Up @@ -149,6 +158,17 @@ func (s dirService) Create(path string) (*api.Dir, error) {
return dir, errio.Error(err)
}

// Exists returns whether a directory where you have access to exists at a given path.
func (s dirService) Exists(path string) (bool, error) {
_, err := s.GetTree(path, 0, false)
if err == api.ErrDirNotFound || err == api.ErrRepoNotFound {
return false, nil
} else if err != nil {
return false, err
}
return true, nil
}

// Delete removes the directory at the given path.
func (s dirService) Delete(path string) error {
p, err := api.NewDirPath(path)
Expand All @@ -169,6 +189,43 @@ func (s dirService) Delete(path string) error {
return nil
}

// CreateAll creates all directories in the given path that do not exist yet.
//
// Contrary to Create, it doesn't return an error when the directories already exist.
func (s dirService) CreateAll(path string) error {
err := api.ValidateDirPath(path)
if err != nil {
return err
}
return s.createAll(path)
}

func (s dirService) createAll(path string) error {
if len(strings.Split(path, "/")) < 3 {
return nil
}

exists, err := s.Exists(path)
if err != nil {
return err
}
if exists {
return nil
}

err = s.createAll(secretpath.Parent(path))
if err != nil {
return err
}

_, err = s.Create(path)
if err == api.ErrDirAlreadyExists {
return nil
}
// err might be nil
return err
}

// listDirAccounts list the accounts with read permission.
func (c *Client) listDirAccounts(path api.BlindNamePath) ([]*api.Account, error) {
blindName, err := c.convertPathToBlindName(path)
Expand Down
Loading