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

Commit 22adaf4

Browse files
Merge pull request #260 from secrethub/release/v0.37.0
Release v0.37.0
2 parents 2391c1e + 1e7293d commit 22adaf4

4 files changed

Lines changed: 81 additions & 18 deletions

File tree

.goreleaser.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ checksum:
5353
name_template: "secrethub-{{ .Tag }}-checksums.txt"
5454

5555
release:
56-
draft: true
56+
prerelease: true
5757

5858
brews:
5959
- name: secrethub-cli
@@ -67,6 +67,7 @@ brews:
6767
bin.install "bin/secrethub"
6868
homepage: https://secrethub.io
6969
description: Command-line interface for SecretHub
70+
skip_upload: false
7071

7172
scoop:
7273
name: secrethub-cli
@@ -79,6 +80,8 @@ scoop:
7980

8081
license: Apache-2.0
8182

83+
skip_upload: false
84+
8285
nfpms:
8386
- file_name_template: "secrethub-{{ .Tag }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
8487
builds:

internals/secrethub/generate.go

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"os"
66
"strconv"
7+
"strings"
78
"time"
89

910
"github.com/secrethub/secrethub-cli/internals/cli/clip"
@@ -23,6 +24,9 @@ var (
2324
// ErrInvalidRandLength is returned when an invalid length is given.
2425
ErrInvalidRandLength = errGenerate.Code("invalid_rand_length").Error("The secret length must be larger than 0")
2526
ErrCannotUseLengthArgAndFlag = errGenerate.Code("length_arg_and_flag").Error("length cannot be provided as an argument and a flag at the same time")
27+
ErrCouldNotFindCharSet = errGenerate.Code("charset_not_found").ErrorPref("could not find charset: %s")
28+
ErrMinFlagInvalidInteger = errGenerate.Code("min_flag_invalid_int").ErrorPref("second part of --min flag is not an integer: %s")
29+
ErrInvalidMinFlag = errGenerate.Code("min_flag_invalid").ErrorPref("min flag must be of the form <charset name>:<minimum count>, invalid min flag: %s")
2630
)
2731

2832
const defaultLength = 22
@@ -36,6 +40,8 @@ type GenerateSecretCommand struct {
3640
firstArg string
3741
secondArg string
3842
lengthArg intValue
43+
charsetFlag charsetValue
44+
mins minRuleValue
3945
copyToClipboard bool
4046
clearClipboardAfter time.Duration
4147
clipper clip.Clipper
@@ -55,12 +61,12 @@ func NewGenerateSecretCommand(io ui.IO, newClient newClientFunc) *GenerateSecret
5561
// Register registers the command, arguments and flags on the provided Registerer.
5662
func (cmd *GenerateSecretCommand) Register(r command.Registerer) {
5763
clause := r.Command("generate", "Generate a random secret.")
58-
clause.HelpLong("By default, it uses numbers (0-9), lowercase letters (a-z) and uppercase letters (A-Z) and a length of 22.")
5964
clause.Arg("secret-path", "The path to write the generated secret to").Required().PlaceHolder(secretPathPlaceHolder).StringVar(&cmd.firstArg)
6065
clause.Flag("length", "The length of the generated secret. Defaults to "+strconv.Itoa(defaultLength)).PlaceHolder(strconv.Itoa(defaultLength)).Short('l').SetValue(&cmd.lengthFlag)
61-
clause.Flag("symbols", "Include symbols in secret.").Short('s').SetValue(&cmd.symbolsFlag)
66+
clause.Flag("min", "<charset>:<n> Ensure that the resulting password contains at least n characters from the given character set. Note that adding constrains reduces the strength of the secret. When possible, avoid any constraints.").SetValue(&cmd.mins)
6267
clause.Flag("clip", "Copy the generated value to the clipboard. The clipboard is automatically cleared after "+units.HumanDuration(cmd.clearClipboardAfter)+".").Short('c').BoolVar(&cmd.copyToClipboard)
63-
68+
clause.Flag("charset", "Define the set of characters to randomly generate a password from. Options are all, alphanumeric, numeric, lowercase, uppercase, letters, symbols and human-readable. Multiple character sets can be combined by supplying them in a comma separated list. Defaults to alphanumeric.").Default("alphanumeric").HintOptions("all", "alphanumeric", "numeric", "lowercase", "uppercase", "letters", "symbols", "human-readable").SetValue(&cmd.charsetFlag)
69+
clause.Flag("symbols", "Include symbols in secret.").Short('s').Hidden().SetValue(&cmd.symbolsFlag)
6470
clause.Arg("rand-command", "").Hidden().StringVar(&cmd.secondArg)
6571
clause.Arg("length", "").Hidden().SetValue(&cmd.lengthArg)
6672

@@ -74,7 +80,15 @@ func (cmd *GenerateSecretCommand) before() error {
7480
return err
7581
}
7682

77-
cmd.generator = randchar.NewGenerator(useSymbols)
83+
charset := cmd.charsetFlag.v
84+
if useSymbols {
85+
charset = charset.Add(randchar.Symbols)
86+
}
87+
88+
cmd.generator, err = randchar.NewRand(charset, cmd.mins.v...)
89+
if err != nil {
90+
return err
91+
}
7892

7993
return nil
8094
}
@@ -180,6 +194,62 @@ func (cmd *GenerateSecretCommand) useSymbols() (bool, error) {
180194
return false, nil
181195
}
182196

197+
type minRuleValue struct {
198+
v []randchar.Option
199+
}
200+
201+
func (ov *minRuleValue) String() string {
202+
return ""
203+
}
204+
205+
func (ov *minRuleValue) Set(flagValue string) error {
206+
elements := strings.Split(flagValue, ":")
207+
if len(elements) != 2 {
208+
return ErrInvalidMinFlag(flagValue)
209+
}
210+
211+
count, err := strconv.Atoi(elements[1])
212+
if err != nil {
213+
return ErrMinFlagInvalidInteger(elements[1])
214+
}
215+
216+
charset, found := randchar.CharsetByName(elements[0])
217+
if !found {
218+
return ErrCouldNotFindCharSet(elements[0])
219+
}
220+
221+
ov.v = append(ov.v, randchar.Min(count, charset))
222+
return nil
223+
}
224+
225+
func (ov *minRuleValue) IsCumulative() bool {
226+
return true
227+
}
228+
229+
type charsetValue struct {
230+
v randchar.Charset
231+
}
232+
233+
func (cv *charsetValue) String() string {
234+
return ""
235+
}
236+
237+
func (cv *charsetValue) Set(flagValue string) error {
238+
charsetNames := strings.Split(flagValue, ",")
239+
for _, charsetName := range charsetNames {
240+
charset, ok := randchar.CharsetByName(charsetName)
241+
if !ok {
242+
return ErrCouldNotFindCharSet(charsetName)
243+
}
244+
cv.v = cv.v.Add(charset)
245+
}
246+
return nil
247+
}
248+
249+
func (cv *charsetValue) IsCumulative() bool {
250+
return true
251+
}
252+
183253
type intValue struct {
184254
v *int
185255
}

internals/secrethub/list.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func (cmd *LsCommand) Run() error {
8585
dirFS, err := client.Dirs().GetTree(dirPath.Value(), 1, false)
8686
if api.IsErrNotFound(err) && dirPath.IsRepoPath() {
8787
return err
88-
} else if err != nil && !isErrNotFound(err) {
88+
} else if err != nil && !api.IsErrNotFound(err) {
8989
return err
9090
} else if err == nil {
9191
err = printDir(cmd.io.Stdout(), cmd.quiet, dirFS.RootDir, timeFormatter)

internals/secrethub/secret_reader.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package secrethub
22

33
import (
44
"github.com/secrethub/secrethub-cli/internals/secrethub/tpl"
5-
"github.com/secrethub/secrethub-go/internals/errio"
5+
"github.com/secrethub/secrethub-go/internals/api"
66
)
77

88
type secretReader struct {
@@ -82,18 +82,8 @@ func newIgnoreMissingSecretReader(sr tpl.SecretReader) *ignoreMissingSecretReade
8282
// errors for non-existing secrets. Instead, it returns the empty string.
8383
func (sr *ignoreMissingSecretReader) ReadSecret(path string) (string, error) {
8484
secret, err := sr.secretReader.ReadSecret(path)
85-
if isErrNotFound(err) {
85+
if api.IsErrNotFound(err) {
8686
return "", nil
8787
}
8888
return secret, err
8989
}
90-
91-
// isErrNotFound returns whether the given error is caused by a un-existing resource.
92-
// TODO: Replace this function with github.com/secrethub/secrethub-go/blob/develop/internals/api.IsErrNotFound once that is released.
93-
func isErrNotFound(err error) bool {
94-
statusError, ok := err.(errio.PublicStatusError)
95-
if !ok {
96-
return false
97-
}
98-
return statusError.StatusCode == 404
99-
}

0 commit comments

Comments
 (0)