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.
|
// of features or configuration nuances of cluster variants.
|
||||||
func newCredentialsProvider(t http.RoundTripper) docker.CredentialsProvider {
|
func newCredentialsProvider(t http.RoundTripper) docker.CredentialsProvider {
|
||||||
options := []creds.Opt{
|
options := []creds.Opt{
|
||||||
creds.WithPromptForCredentials(newPromptForCredentials()),
|
creds.WithPromptForCredentials(newPromptForCredentials(os.Stdin, os.Stdout, os.Stderr)),
|
||||||
creds.WithPromptForCredentialStore(newPromptForCredentialStore()),
|
creds.WithPromptForCredentialStore(newPromptForCredentialStore()),
|
||||||
creds.WithTransport(t),
|
creds.WithTransport(t),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/term"
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/AlecAivazis/survey/v2/terminal"
|
"github.com/AlecAivazis/survey/v2/terminal"
|
||||||
"github.com/ory/viper"
|
"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)
|
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
|
firstTime := true
|
||||||
return func(registry string) (docker.Credentials, error) {
|
return func(registry string) (docker.Credentials, error) {
|
||||||
var result docker.Credentials
|
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{
|
var qs = []*survey.Question{
|
||||||
{
|
{
|
||||||
Name: "username",
|
Name: "username",
|
||||||
|
|
@ -222,16 +234,42 @@ func newPromptForCredentials() func(registry string) (docker.Credentials, error)
|
||||||
Validate: survey.Required,
|
Validate: survey.Required,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if firstTime {
|
|
||||||
firstTime = false
|
var (
|
||||||
fmt.Printf("Please provide credentials for image registry (%s).\n", registry)
|
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 {
|
} else {
|
||||||
fmt.Println("Incorrect credentials, please try again.")
|
reader := bufio.NewReader(in)
|
||||||
}
|
|
||||||
err := survey.Ask(qs, &result)
|
fmt.Fprintf(out, "Username: ")
|
||||||
if err != nil {
|
u, err := reader.ReadString('\n')
|
||||||
return docker.Credentials{}, err
|
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
|
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