Files
threshold/internal/cmd/commands/connect/credentials.go
T

62 lines
1.7 KiB
Go

package connect
import (
"errors"
"github.com/hashicorp/boundary/api/targets"
"github.com/hashicorp/boundary/internal/credential"
"github.com/mitchellh/mapstructure"
)
type usernamePasswordCredentials struct {
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
}
// TODO: this should support multiple types of credentials and return an interface instead
// of only usernamepassword. Each subcommand can use the returned credentials as it needs.
func parseCredentials(creds []*targets.SessionCredential) ([]usernamePasswordCredentials, error) {
if creds == nil {
return nil, nil
}
var out []usernamePasswordCredentials
for _, cred := range creds {
if cred.CredentialSource == nil {
return nil, errors.New("missing credential source")
}
var c usernamePasswordCredentials
if cred.CredentialSource.CredentialType == string(credential.UsernamePasswordType) {
// Decode attributes from credential struct
if err := mapstructure.Decode(cred.Credential, &c); err != nil {
return nil, err
}
if c.Username != "" && c.Password != "" {
out = append(out, c)
continue
}
}
// Credential type is unspecified, make a best effort attempt to parse both username
// and password from Decoded field if it exists
if cred.Secret == nil || cred.Secret.Decoded == nil {
// No secret data continue to next credential
continue
}
switch cred.CredentialSource.Type {
case "vault", "static":
// Attempt unmarshaling into creds
if err := mapstructure.Decode(cred.Secret.Decoded, &c); err != nil {
return nil, err
}
}
if c.Username != "" && c.Password != "" {
out = append(out, c)
}
}
return out, nil
}