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

Commit 18305d8

Browse files
Merge pull request #180 from secrethub/release/v0.27.0
Release v0.27.0
2 parents b13a5c6 + 8d0dcaa commit 18305d8

29 files changed

+873
-690
lines changed

.circleci/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: 2
22
jobs:
33
test:
44
docker:
5-
- image: circleci/golang:1.12
5+
- image: circleci/golang:1.13
66
steps:
77
- checkout
88
- restore_cache:
@@ -16,7 +16,7 @@ jobs:
1616
- run: make test
1717
verify-version:
1818
docker:
19-
- image: circleci/golang:1.12
19+
- image: circleci/golang:1.13
2020
steps:
2121
- checkout
2222
- restore_cache:

internals/api/server_errors.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package api
22

33
import (
4+
"errors"
45
"net/http"
56

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

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

4647
// Dirs
@@ -104,9 +105,10 @@ var (
104105

105106
// IsErrNotFound returns whether the given error is caused by a un-existing resource.
106107
func IsErrNotFound(err error) bool {
107-
statusError, ok := err.(errio.PublicStatusError)
108+
var publicStatusError errio.PublicStatusError
109+
ok := errors.As(err, &publicStatusError)
108110
if !ok {
109111
return false
110112
}
111-
return statusError.StatusCode == 404
113+
return publicStatusError.StatusCode == 404
112114
}

pkg/randchar/generator.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ var (
3434
All = Alphanumeric.Add(Symbols)
3535
// Similar defines a character set containing similar looking characters.
3636
Similar = NewCharset("iIlL1oO0")
37+
// HumanReadable defines a character set containing all alphanumeric characters except the similar ones.
38+
HumanReadable = Alphanumeric.Subtract(Similar)
3739

3840
// DefaultRand defines the default random generator to use. You can create
3941
// your own generators using NewRand.
@@ -263,6 +265,8 @@ func CharsetByName(charsetName string) (Charset, bool) {
263265
return All, true
264266
case "similar":
265267
return Similar, true
268+
case "human-readable":
269+
return HumanReadable, true
266270
default:
267271
return Charset{}, false
268272
}

pkg/secrethub/acl.go

Lines changed: 164 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"github.com/secrethub/secrethub-go/internals/api"
55
"github.com/secrethub/secrethub-go/internals/api/uuid"
66
"github.com/secrethub/secrethub-go/internals/errio"
7+
"github.com/secrethub/secrethub-go/pkg/secrethub/iterator"
78
)
89

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

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

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

287295
return accessLevel, nil
288296
}
297+
298+
// Iterator returns an iterator that retrieves all access rules that apply to a
299+
// directory.
300+
func (s accessRuleService) Iterator(path string, params *AccessRuleIteratorParams) AccessRuleIterator {
301+
if params == nil {
302+
params = &AccessRuleIteratorParams{}
303+
}
304+
305+
depth := -1
306+
if params.Depth != nil {
307+
depth = int(*params.Depth)
308+
}
309+
ancestors := params.Ancestors
310+
311+
return &accessRuleIterator{
312+
iterator: iterator.New(
313+
iterator.PaginatorFactory(
314+
func() ([]interface{}, error) {
315+
p, err := api.NewDirPath(path)
316+
if err != nil {
317+
return nil, errio.Error(err)
318+
}
319+
320+
blindName, err := s.client.convertPathToBlindName(p)
321+
if err != nil {
322+
return nil, errio.Error(err)
323+
}
324+
325+
accessRules, err := s.client.httpClient.ListAccessRules(blindName, depth, ancestors)
326+
if err != nil {
327+
return nil, errio.Error(err)
328+
}
329+
330+
res := make([]interface{}, len(accessRules))
331+
for i, element := range accessRules {
332+
res[i] = element
333+
}
334+
return res, nil
335+
},
336+
),
337+
),
338+
}
339+
}
340+
341+
// LevelIterator returns an iterator that retrieves all access levels on the given directory.
342+
func (s accessRuleService) LevelIterator(path string, _ *AccessLevelIteratorParams) AccessLevelIterator {
343+
return &accessLevelIterator{
344+
iterator: iterator.New(
345+
iterator.PaginatorFactory(
346+
func() ([]interface{}, error) {
347+
p, err := api.NewDirPath(path)
348+
if err != nil {
349+
return nil, errio.Error(err)
350+
}
351+
352+
blindName, err := s.client.convertPathToBlindName(p)
353+
if err != nil {
354+
return nil, errio.Error(err)
355+
}
356+
357+
rules, err := s.client.httpClient.ListAccessRules(blindName, 0, true)
358+
if err != nil {
359+
return nil, errio.Error(err)
360+
}
361+
362+
dir, err := s.dirService.GetTree(path, 0, false)
363+
if err != nil {
364+
return nil, errio.Error(err)
365+
}
366+
367+
rights := make(map[uuid.UUID][]*api.AccessRule)
368+
for _, rule := range rules {
369+
list := rights[rule.AccountID]
370+
rights[rule.AccountID] = append(list, rule)
371+
}
372+
373+
accessLevels := make([]*api.AccessLevel, len(rights))
374+
i := 0
375+
for _, list := range rights {
376+
first := list[0]
377+
maxPerm := first.Permission
378+
for _, rule := range list {
379+
if maxPerm < rule.Permission {
380+
maxPerm = rule.Permission
381+
}
382+
}
383+
384+
accessLevels[i] = &api.AccessLevel{
385+
Account: first.Account,
386+
AccountID: first.AccountID,
387+
DirID: dir.RootDir.DirID, // add this for completeness
388+
Permission: maxPerm,
389+
}
390+
391+
i++
392+
}
393+
394+
res := make([]interface{}, len(accessLevels))
395+
for i, element := range accessLevels {
396+
res[i] = element
397+
}
398+
return res, nil
399+
},
400+
),
401+
),
402+
}
403+
}
404+
405+
// AccessLevelIterator iterates over access rules.
406+
type AccessRuleIterator interface {
407+
Next() (api.AccessRule, error)
408+
}
409+
410+
type accessRuleIterator struct {
411+
iterator iterator.Iterator
412+
}
413+
414+
// Next returns the next access rule or iterator.Done if all of them have been returned.
415+
func (it *accessRuleIterator) Next() (api.AccessRule, error) {
416+
item, err := it.iterator.Next()
417+
if err != nil {
418+
return api.AccessRule{}, err
419+
}
420+
421+
return *item.(*api.AccessRule), nil
422+
}
423+
424+
// AccessRuleIteratorParams specify parameters used when listing access rules.
425+
type AccessRuleIteratorParams struct {
426+
Depth *uint // Depth defines the depth of traversal for the iterator, nil means listing all subdirectories.
427+
Ancestors bool // Ancestors defines whether the iterator should also list access rules of parent directories.
428+
}
429+
430+
// AccessLevelIteratorParams defines the parameters used when listing access levels.
431+
type AccessLevelIteratorParams struct{}
432+
433+
// AccessLevelIterator iterates over access levels.
434+
type AccessLevelIterator interface {
435+
Next() (api.AccessLevel, error)
436+
}
437+
438+
type accessLevelIterator struct {
439+
iterator iterator.Iterator
440+
}
441+
442+
// Next returns the next access level or iterator.Done if all of them have been returned.
443+
func (it *accessLevelIterator) Next() (api.AccessLevel, error) {
444+
item, err := it.iterator.Next()
445+
if err != nil {
446+
return api.AccessLevel{}, err
447+
}
448+
449+
return *item.(*api.AccessLevel), nil
450+
}

pkg/secrethub/client.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import (
1717
"github.com/secrethub/secrethub-go/pkg/secrethub/internals/http"
1818
)
1919

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

2424
// Errors
@@ -86,7 +86,7 @@ type AppInfo struct {
8686
func (i AppInfo) userAgentSuffix() string {
8787
res := i.Name
8888
if i.Version != "" {
89-
res += "/" + i.Version
89+
res += "/" + strings.TrimPrefix(i.Version, "v")
9090
}
9191
return res
9292
}

pkg/secrethub/client_version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ package secrethub
22

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

0 commit comments

Comments
 (0)