You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
boundary/internal/cmd/commands/authenticate/funcs.go

106 lines
3.2 KiB

package authenticate
import (
"encoding/base64"
"encoding/json"
"fmt"
"time"
"github.com/hashicorp/boundary/api/authmethods"
"github.com/hashicorp/boundary/api/authtokens"
"github.com/hashicorp/boundary/internal/cmd/base"
nkeyring "github.com/jefferai/keyring"
zkeyring "github.com/zalando/go-keyring"
)
func saveAndOrPrintToken(c *base.Command, result *authmethods.AuthenticateResult) int {
token := new(authtokens.AuthToken)
if err := json.Unmarshal(result.GetRawAttributes(), token); err != nil {
c.PrintCliError(fmt.Errorf("Error trying to decode response as an auth token: %w", err))
return base.CommandCliError
}
switch base.Format(c.UI) {
case "table":
c.UI.Output(base.WrapForHelpText([]string{
"",
"Authentication information:",
fmt.Sprintf(" Account ID: %s", token.AccountId),
fmt.Sprintf(" Auth Method ID: %s", token.AuthMethodId),
fmt.Sprintf(" Expiration Time: %s", token.ExpirationTime.Local().Format(time.RFC1123)),
fmt.Sprintf(" User ID: %s", token.UserId),
}))
case "json":
if ok := c.PrintJsonItem(&dummyGenericResponse{
item: token,
response: result.GetResponse(),
}); !ok {
return base.CommandCliError
}
return base.CommandSuccess
}
var gotErr bool
keyringType, tokenName, err := c.DiscoverKeyringTokenInfo()
if err != nil {
c.UI.Error(fmt.Sprintf("Error fetching keyring information: %s", err))
gotErr = true
} else if keyringType != "none" &&
tokenName != "none" &&
keyringType != "" &&
tokenName != "" {
marshaled, err := json.Marshal(token)
if err != nil {
c.UI.Error(fmt.Sprintf("Error marshaling auth token to save to keyring: %s", err))
gotErr = true
} else {
switch keyringType {
case "wincred", "keychain":
if err := zkeyring.Set(base.StoredTokenName, tokenName, base64.RawStdEncoding.EncodeToString(marshaled)); err != nil {
c.UI.Error(fmt.Sprintf("Error saving auth token to %q keyring: %s", keyringType, err))
gotErr = true
}
default:
krConfig := nkeyring.Config{
LibSecretCollectionName: "login",
PassPrefix: "HashiCorp_Boundary",
AllowedBackends: []nkeyring.BackendType{nkeyring.BackendType(keyringType)},
}
kr, err := nkeyring.Open(krConfig)
if err != nil {
c.UI.Error(fmt.Sprintf("Error opening %q keyring: %s", keyringType, err))
gotErr = true
break
}
if err := kr.Set(nkeyring.Item{
Key: tokenName,
Data: []byte(base64.RawStdEncoding.EncodeToString(marshaled)),
}); err != nil {
c.UI.Error(fmt.Sprintf("Error storing token in %q keyring: %s", keyringType, err))
gotErr = true
break
}
}
if !gotErr {
c.UI.Output("\nThe token was successfully stored in the chosen keyring and is not displayed here.")
}
}
}
switch {
case gotErr:
c.UI.Warn(fmt.Sprintf("The token was not successfully saved to a system keyring. The token is:\n\n%s\n\nIt must be manually passed in via the BOUNDARY_TOKEN env var or -token flag. Storing the token can also be disabled via -keyring-type=none.", token.Token))
case c.FlagKeyringType == "none":
c.UI.Warn("\nStoring the token in a keyring was disabled. The token is:")
c.UI.Output(token.Token)
c.UI.Warn("Please be sure to store it safely!")
}
return base.CommandSuccess
}