mirror of https://github.com/knative/func.git
fix: read pwd from non-tty input (#996)
Signed-off-by: Matej Vasek <mvasek@redhat.com>
This commit is contained in:
parent
b79683cc0c
commit
e9932cdf43
|
|
@ -119,7 +119,7 @@ func newTransport() fnhttp.RoundTripCloser {
|
|||
// of features or configuration nuances of cluster variants.
|
||||
func newCredentialsProvider(t http.RoundTripper) docker.CredentialsProvider {
|
||||
options := []creds.Opt{
|
||||
creds.WithPromptForCredentials(newPromptForCredentials()),
|
||||
creds.WithPromptForCredentials(newPromptForCredentials(os.Stdin, os.Stdout, os.Stderr)),
|
||||
creds.WithPromptForCredentialStore(newPromptForCredentialStore()),
|
||||
creds.WithTransport(t),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/term"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/AlecAivazis/survey/v2/terminal"
|
||||
"github.com/ory/viper"
|
||||
|
|
@ -202,10 +206,18 @@ func runDeploy(cmd *cobra.Command, _ []string, newClient ClientFactory) (err err
|
|||
return client.Deploy(cmd.Context(), config.Path)
|
||||
}
|
||||
|
||||
func newPromptForCredentials() func(registry string) (docker.Credentials, error) {
|
||||
func newPromptForCredentials(in io.Reader, out, errOut io.Writer) func(registry string) (docker.Credentials, error) {
|
||||
firstTime := true
|
||||
return func(registry string) (docker.Credentials, error) {
|
||||
var result docker.Credentials
|
||||
|
||||
if firstTime {
|
||||
firstTime = false
|
||||
fmt.Fprintf(out, "Please provide credentials for image registry (%s).\n", registry)
|
||||
} else {
|
||||
fmt.Fprintln(out, "Incorrect credentials, please try again.")
|
||||
}
|
||||
|
||||
var qs = []*survey.Question{
|
||||
{
|
||||
Name: "username",
|
||||
|
|
@ -222,16 +234,42 @@ func newPromptForCredentials() func(registry string) (docker.Credentials, error)
|
|||
Validate: survey.Required,
|
||||
},
|
||||
}
|
||||
if firstTime {
|
||||
firstTime = false
|
||||
fmt.Printf("Please provide credentials for image registry (%s).\n", registry)
|
||||
|
||||
var (
|
||||
fr terminal.FileReader
|
||||
ok bool
|
||||
)
|
||||
|
||||
isTerm := false
|
||||
if fr, ok = in.(terminal.FileReader); ok {
|
||||
isTerm = term.IsTerminal(int(fr.Fd()))
|
||||
}
|
||||
|
||||
if isTerm {
|
||||
err := survey.Ask(qs, &result, survey.WithStdio(fr, out.(terminal.FileWriter), errOut))
|
||||
if err != nil {
|
||||
return docker.Credentials{}, err
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Incorrect credentials, please try again.")
|
||||
}
|
||||
err := survey.Ask(qs, &result)
|
||||
if err != nil {
|
||||
return docker.Credentials{}, err
|
||||
reader := bufio.NewReader(in)
|
||||
|
||||
fmt.Fprintf(out, "Username: ")
|
||||
u, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return docker.Credentials{}, err
|
||||
}
|
||||
u = strings.Trim(u, "\r\n")
|
||||
|
||||
fmt.Fprintf(out, "Password: ")
|
||||
p, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return docker.Credentials{}, err
|
||||
}
|
||||
p = strings.Trim(p, "\r\n")
|
||||
|
||||
result = docker.Credentials{Username: u, Password: p}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hinshun/vt10x"
|
||||
|
||||
"knative.dev/kn-plugin-func/docker"
|
||||
)
|
||||
|
||||
func Test_newPromptForCredentials(t *testing.T) {
|
||||
expectedCreds := docker.Credentials{
|
||||
Username: "testuser",
|
||||
Password: "testpwd",
|
||||
}
|
||||
|
||||
console, _, err := vt10x.NewVT10XConsole()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer console.Close()
|
||||
|
||||
go func() {
|
||||
_, _ = console.ExpectEOF()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
chars := expectedCreds.Username + enter + expectedCreds.Password + enter
|
||||
for _, ch := range chars {
|
||||
_, _ = console.Send(string(ch))
|
||||
time.Sleep(time.Millisecond * 50)
|
||||
}
|
||||
}()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
in io.Reader
|
||||
out io.Writer
|
||||
errOut io.Writer
|
||||
}{
|
||||
{
|
||||
name: "with non-tty",
|
||||
in: strings.NewReader(expectedCreds.Username + "\r\n" + expectedCreds.Password + "\r\n"),
|
||||
out: io.Discard,
|
||||
errOut: io.Discard,
|
||||
},
|
||||
{
|
||||
name: "with tty",
|
||||
in: console.Tty(),
|
||||
out: console.Tty(),
|
||||
errOut: console.Tty(),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
credPrompt := newPromptForCredentials(tt.in, tt.out, tt.errOut)
|
||||
cred, err := credPrompt("example.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cred != expectedCreds {
|
||||
t.Errorf("bad credentials: %+v", cred)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue