Merge pull request #3499 from cli/secret-prompt

tweak secret set to allow prompting
This commit is contained in:
Nate Smith 2021-04-28 13:28:33 -05:00 committed by GitHub
commit d5954e2e94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 19 deletions

View file

@ -10,6 +10,7 @@ import (
"regexp"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/MakeNowJust/heredoc"
"github.com/cli/cli/api"
"github.com/cli/cli/internal/config"
@ -17,6 +18,7 @@ import (
"github.com/cli/cli/pkg/cmd/secret/shared"
"github.com/cli/cli/pkg/cmdutil"
"github.com/cli/cli/pkg/iostreams"
"github.com/cli/cli/pkg/prompt"
"github.com/spf13/cobra"
"golang.org/x/crypto/nacl/box"
)
@ -48,19 +50,25 @@ func NewCmdSet(f *cmdutil.Factory, runF func(*SetOptions) error) *cobra.Command
Short: "Create or update secrets",
Long: "Locally encrypt a new or updated secret at either the repository or organization level and send it to GitHub for storage.",
Example: heredoc.Doc(`
$ gh secret set FROM_FLAG -b"some literal value"
$ gh secret set FROM_ENV -b"${ENV_VALUE}"
$ gh secret set FROM_FILE < file.json
$ gh secret set ORG_SECRET -bval --org=anOrg --visibility=all
$ gh secret set ORG_SECRET -bval --org=anOrg --repos="repo1,repo2,repo3"
Paste secret in prompt
$ gh secret set MYSECRET
Use environment variable as secret value
$ gh secret set MYSECRET -b"${ENV_VALUE}"
Use file as secret value
$ gh secret set MYSECRET < file.json
Set organization level secret visible to entire organization
$ gh secret set MYSECRET -bval --org=anOrg --visibility=all
Set organization level secret visible only to certain repositories
$ gh secret set MYSECRET -bval --org=anOrg --repos="repo1,repo2,repo3"
`),
Args: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return &cmdutil.FlagError{Err: errors.New("must pass single secret name")}
}
if !cmd.Flags().Changed("body") && opts.IO.IsStdinTTY() {
return &cmdutil.FlagError{Err: errors.New("no --body specified but nothing on STIDN")}
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
@ -209,12 +217,22 @@ func validSecretName(name string) error {
func getBody(opts *SetOptions) ([]byte, error) {
if opts.Body == "" {
body, err := ioutil.ReadAll(opts.IO.In)
if err != nil {
return nil, fmt.Errorf("failed to read from STDIN: %w", err)
}
if opts.IO.CanPrompt() {
err := prompt.SurveyAskOne(&survey.Password{
Message: "Paste your secret",
}, &opts.Body)
if err != nil {
return nil, err
}
fmt.Fprintln(opts.IO.Out)
} else {
body, err := ioutil.ReadAll(opts.IO.In)
if err != nil {
return nil, fmt.Errorf("failed to read from STDIN: %w", err)
}
return body, nil
return body, nil
}
}
return []byte(opts.Body), nil

View file

@ -14,6 +14,7 @@ import (
"github.com/cli/cli/pkg/cmdutil"
"github.com/cli/cli/pkg/httpmock"
"github.com/cli/cli/pkg/iostreams"
"github.com/cli/cli/pkg/prompt"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
)
@ -51,12 +52,6 @@ func TestNewCmdSet(t *testing.T) {
cli: "cool_secret good_secret",
wantsErr: true,
},
{
name: "no body, stdin is terminal",
cli: "cool_secret",
stdinTTY: true,
wantsErr: true,
},
{
name: "visibility without org",
cli: "cool_secret -vall",
@ -326,3 +321,21 @@ func Test_getBody(t *testing.T) {
})
}
}
func Test_getBodyPrompt(t *testing.T) {
io, _, _, _ := iostreams.Test()
io.SetStdinTTY(true)
io.SetStdoutTTY(true)
as, teardown := prompt.InitAskStubber()
defer teardown()
as.StubOne("cool secret")
body, err := getBody(&SetOptions{
IO: io,
})
assert.NoError(t, err)
assert.Equal(t, string(body), "cool secret")
}