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

Commit

Permalink
Merge pull request #180 from secrethub/release/v0.27.0
Browse files Browse the repository at this point in the history
Release v0.27.0
  • Loading branch information
SimonBarendse authored Mar 26, 2020
2 parents b13a5c6 + 8d0dcaa commit 18305d8
Show file tree
Hide file tree
Showing 29 changed files with 873 additions and 690 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: 2
jobs:
test:
docker:
- image: circleci/golang:1.12
- image: circleci/golang:1.13
steps:
- checkout
- restore_cache:
Expand All @@ -16,7 +16,7 @@ jobs:
- run: make test
verify-version:
docker:
- image: circleci/golang:1.12
- image: circleci/golang:1.13
steps:
- checkout
- restore_cache:
Expand Down
8 changes: 5 additions & 3 deletions internals/api/server_errors.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package api

import (
"errors"
"net/http"

"fmt"
Expand Down Expand Up @@ -40,7 +41,7 @@ var (
ErrSignatureNotVerified = errHub.Code("invalid_signature").StatusError("request was not signed by a valid credential", http.StatusUnauthorized)

// Repos
ErrRepoNotFound = errHub.Code("repo_not_found").StatusError("Repo not found", http.StatusNotFound)
ErrRepoNotFound = errHub.Code("repo_not_found").StatusErrorPref("Repo '%s' not found", http.StatusNotFound)
ErrRepoAlreadyExists = errHub.Code("repo_already_exists").StatusError("Repo already exists, please create a different repo", http.StatusConflict)

// Dirs
Expand Down Expand Up @@ -104,9 +105,10 @@ var (

// IsErrNotFound returns whether the given error is caused by a un-existing resource.
func IsErrNotFound(err error) bool {
statusError, ok := err.(errio.PublicStatusError)
var publicStatusError errio.PublicStatusError
ok := errors.As(err, &publicStatusError)
if !ok {
return false
}
return statusError.StatusCode == 404
return publicStatusError.StatusCode == 404
}
4 changes: 4 additions & 0 deletions pkg/randchar/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ var (
All = Alphanumeric.Add(Symbols)
// Similar defines a character set containing similar looking characters.
Similar = NewCharset("iIlL1oO0")
// HumanReadable defines a character set containing all alphanumeric characters except the similar ones.
HumanReadable = Alphanumeric.Subtract(Similar)

// DefaultRand defines the default random generator to use. You can create
// your own generators using NewRand.
Expand Down Expand Up @@ -263,6 +265,8 @@ func CharsetByName(charsetName string) (Charset, bool) {
return All, true
case "similar":
return Similar, true
case "human-readable":
return HumanReadable, true
default:
return Charset{}, false
}
Expand Down
166 changes: 164 additions & 2 deletions pkg/secrethub/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"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/secrethub/iterator"
)

// AccessRuleService handles operations on access rules from SecretHub.
Expand All @@ -14,13 +15,20 @@ type AccessRuleService interface {
Set(path string, permission string, accountName string) (*api.AccessRule, error)
// Delete removes the accessrule for the given directory and account.
Delete(path string, accountName string) error
// List etrieves all access rules that apply to a directory, including
// List retrieves all access rules that apply to a directory, including
// rules that apply to its children up to a specified depth. When ancestors is set
// to true, it also includes rules for any parent directories. When the depth is
// set to -1, all children are retrieved without limit.
// Deprecated: Use iterator function instead.
List(path string, depth int, ancestors bool) ([]*api.AccessRule, error)
// Iterator returns an iterator that retrieves all access rules that apply to a
// directory.
Iterator(path string, _ *AccessRuleIteratorParams) AccessRuleIterator
// ListLevels lists the access levels on the given directory.
// Deprecated: Use iterator function instead.
ListLevels(path string) ([]*api.AccessLevel, error)
// LevelIterator returns an iterator that retrieves all access levels on the given directory.
LevelIterator(path string, _ *AccessLevelIteratorParams) AccessLevelIterator
}

func newAccessRuleService(client *Client) AccessRuleService {
Expand Down Expand Up @@ -87,7 +95,7 @@ func (s accessRuleService) Get(path string, accountName string) (*api.AccessRule
return accessRule, nil
}

// List etrieves all access rules that apply to a directory, including
// List retrieves all access rules that apply to a directory, including
// rules that apply to its children up to a specified depth. When ancestors is set
// to true, it also includes rules for any parent directories. When the depth is
// set to -1, all children are retrieved without limit.
Expand Down Expand Up @@ -286,3 +294,157 @@ func (c *Client) getAccessLevel(path api.BlindNamePath, accountName api.AccountN

return accessLevel, nil
}

// Iterator returns an iterator that retrieves all access rules that apply to a
// directory.
func (s accessRuleService) Iterator(path string, params *AccessRuleIteratorParams) AccessRuleIterator {
if params == nil {
params = &AccessRuleIteratorParams{}
}

depth := -1
if params.Depth != nil {
depth = int(*params.Depth)
}
ancestors := params.Ancestors

return &accessRuleIterator{
iterator: iterator.New(
iterator.PaginatorFactory(
func() ([]interface{}, error) {
p, err := api.NewDirPath(path)
if err != nil {
return nil, errio.Error(err)
}

blindName, err := s.client.convertPathToBlindName(p)
if err != nil {
return nil, errio.Error(err)
}

accessRules, err := s.client.httpClient.ListAccessRules(blindName, depth, ancestors)
if err != nil {
return nil, errio.Error(err)
}

res := make([]interface{}, len(accessRules))
for i, element := range accessRules {
res[i] = element
}
return res, nil
},
),
),
}
}

// LevelIterator returns an iterator that retrieves all access levels on the given directory.
func (s accessRuleService) LevelIterator(path string, _ *AccessLevelIteratorParams) AccessLevelIterator {
return &accessLevelIterator{
iterator: iterator.New(
iterator.PaginatorFactory(
func() ([]interface{}, error) {
p, err := api.NewDirPath(path)
if err != nil {
return nil, errio.Error(err)
}

blindName, err := s.client.convertPathToBlindName(p)
if err != nil {
return nil, errio.Error(err)
}

rules, err := s.client.httpClient.ListAccessRules(blindName, 0, true)
if err != nil {
return nil, errio.Error(err)
}

dir, err := s.dirService.GetTree(path, 0, false)
if err != nil {
return nil, errio.Error(err)
}

rights := make(map[uuid.UUID][]*api.AccessRule)
for _, rule := range rules {
list := rights[rule.AccountID]
rights[rule.AccountID] = append(list, rule)
}

accessLevels := make([]*api.AccessLevel, len(rights))
i := 0
for _, list := range rights {
first := list[0]
maxPerm := first.Permission
for _, rule := range list {
if maxPerm < rule.Permission {
maxPerm = rule.Permission
}
}

accessLevels[i] = &api.AccessLevel{
Account: first.Account,
AccountID: first.AccountID,
DirID: dir.RootDir.DirID, // add this for completeness
Permission: maxPerm,
}

i++
}

res := make([]interface{}, len(accessLevels))
for i, element := range accessLevels {
res[i] = element
}
return res, nil
},
),
),
}
}

// AccessLevelIterator iterates over access rules.
type AccessRuleIterator interface {
Next() (api.AccessRule, error)
}

type accessRuleIterator struct {
iterator iterator.Iterator
}

// Next returns the next access rule or iterator.Done if all of them have been returned.
func (it *accessRuleIterator) Next() (api.AccessRule, error) {
item, err := it.iterator.Next()
if err != nil {
return api.AccessRule{}, err
}

return *item.(*api.AccessRule), nil
}

// AccessRuleIteratorParams specify parameters used when listing access rules.
type AccessRuleIteratorParams struct {
Depth *uint // Depth defines the depth of traversal for the iterator, nil means listing all subdirectories.
Ancestors bool // Ancestors defines whether the iterator should also list access rules of parent directories.
}

// AccessLevelIteratorParams defines the parameters used when listing access levels.
type AccessLevelIteratorParams struct{}

// AccessLevelIterator iterates over access levels.
type AccessLevelIterator interface {
Next() (api.AccessLevel, error)
}

type accessLevelIterator struct {
iterator iterator.Iterator
}

// Next returns the next access level or iterator.Done if all of them have been returned.
func (it *accessLevelIterator) Next() (api.AccessLevel, error) {
item, err := it.iterator.Next()
if err != nil {
return api.AccessLevel{}, err
}

return *item.(*api.AccessLevel), nil
}
6 changes: 3 additions & 3 deletions pkg/secrethub/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import (
"github.com/secrethub/secrethub-go/pkg/secrethub/internals/http"
)

const (
userAgentPrefix = "SecretHub/v1 secrethub-go/" + ClientVersion
var (
userAgentPrefix = "SecretHub/1.0 secrethub-go/" + strings.TrimPrefix(ClientVersion, "v")
)

// Errors
Expand Down Expand Up @@ -86,7 +86,7 @@ type AppInfo struct {
func (i AppInfo) userAgentSuffix() string {
res := i.Name
if i.Version != "" {
res += "/" + i.Version
res += "/" + strings.TrimPrefix(i.Version, "v")
}
return res
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/secrethub/client_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ package secrethub

// ClientVersion is the current version of the client
// Do not edit this unless you know what you're doing.
const ClientVersion = "v0.26.0"
const ClientVersion = "v0.27.0"
Loading

0 comments on commit 18305d8

Please sign in to comment.