feat(cli): set persistent file vault password

This commit is contained in:
Daniel Hougaard
2024-07-26 22:47:37 +02:00
parent c3038e3ca1
commit e619cfa313
+126 -68
View File
@@ -9,97 +9,88 @@ import (
"strings" "strings"
"github.com/Infisical/infisical-merge/packages/util" "github.com/Infisical/infisical-merge/packages/util"
"github.com/manifoldco/promptui"
"github.com/posthog/posthog-go" "github.com/posthog/posthog-go"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var AvailableVaultsAndDescriptions = []string{"auto (automatically select native vault on system)", "file (encrypted file vault)"} type VaultBackendType struct {
var AvailableVaults = []string{"auto", "file"} Name string
Description string
}
var vaultSetPassphraseCmd = &cobra.Command{ var AvailableVaults = []VaultBackendType{
Example: `infisical vault set-passphrase [your-passphrase]`, {
Use: "set-passphrase [your-passphrase]", Name: "auto",
Short: "Used to set the passphrase for the file vault", Description: "automatically select native vault on system",
DisableFlagsInUseLine: true, },
Args: cobra.MinimumNArgs(1), {
Run: func(cmd *cobra.Command, args []string) { Name: "file",
if len(args) != 1 { Description: "encrypted file vault",
log.Error().Msgf("Please provide a passphrase to set for the file vault")
return
}
passphrase := args[0]
configFile, err := util.GetConfigFile()
if err != nil {
log.Error().Msgf("Unable to set passphrase for file vault because of [err=%s]", err)
return
}
if configFile.VaultBackendType != "file" {
log.Error().Msgf("You are not using file vault to store your login details. You can only set passphrase for file vault")
return
}
// encode with base64
encodedPassphrase := base64.StdEncoding.EncodeToString([]byte(passphrase))
configFile.VaultBackendPassphrase = encodedPassphrase
err = util.WriteConfigFile(&configFile)
if err != nil {
log.Error().Msgf("Unable to set passphrase for file vault because of [err=%s]", err)
return
}
fmt.Printf("\nSuccessfully, set passphrase for file vault. You can now store your login details securely at rest\n")
}, },
} }
var vaultSetCmd = &cobra.Command{ var vaultSetCmd = &cobra.Command{
Example: `infisical vault set [file|auto]`, Example: `infisical vault set [file|auto] [option]`,
Use: "set [file|auto]", Use: "set [file|auto] [option]",
Short: "Used to set the type of vault backend to store your login details securely at rest", Short: "Used to set the type of vault backend to store your login details securely at rest",
Long: "Used to set the type of vault backend to store your login details securely at rest",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
wantedVaultTypeName := args[0]
currentVaultBackend, err := util.GetCurrentVaultBackend()
if err != nil {
log.Error().Msgf("Unable to set vault to [%s] because of [err=%s]", wantedVaultTypeName, err)
return
}
if wantedVaultTypeName == string(currentVaultBackend) { if len(args) >= 2 {
log.Error().Msgf("You are already on vault backend [%s]", currentVaultBackend) vaultType := args[0]
return option := args[1]
}
if wantedVaultTypeName == "auto" || wantedVaultTypeName == "file" { // Todo, add more vault types / configurations
configFile, err := util.GetConfigFile() if vaultType != util.VAULT_BACKEND_FILE_MODE {
if err != nil { log.Error().Msgf("No configuration options are available for vault type [%s]\n", vaultType)
log.Error().Msgf("Unable to set vault to [%s] because of [err=%s]", wantedVaultTypeName, err)
return return
} }
configFile.VaultBackendType = wantedVaultTypeName // save selected vault switch option {
configFile.LoggedInUserEmail = "" // reset the logged in user to prompt them to re login case "passphrase":
{
err = util.WriteConfigFile(&configFile) passphrasePrompt := promptui.Prompt{
if err != nil { Label: "File vault passphrase",
log.Error().Msgf("Unable to set vault to [%s] because an error occurred when saving the config file [err=%s]", wantedVaultTypeName, err) }
return
passphrase, err := passphrasePrompt.Run()
if err != nil {
log.Error().Msgf("Unable to set passphrase for file vault because of [err=%s]", err)
return
}
if passphrase == "" || len(passphrase) < 8 {
log.Error().Msgf("Passphrase must be at least 8 characters long")
return
}
setFileVaultPassphrase(passphrase)
}
default:
log.Error().Msgf("Unknown option [%s] for vault set command", option)
} }
fmt.Printf("\nSuccessfully, switched vault backend from [%s] to [%s]. Please login in again to store your login details in the new vault with [infisical login]\n", currentVaultBackend, wantedVaultTypeName) return
Telemetry.CaptureEvent("cli-command:vault set", posthog.NewProperties().Set("currentVault", currentVaultBackend).Set("wantedVault", wantedVaultTypeName).Set("version", util.CLI_VERSION))
} else {
log.Error().Msgf("The requested vault type [%s] is not available on this system. Only the following vault backends are available for you system: %s", wantedVaultTypeName, strings.Join(AvailableVaults, ", "))
} }
fmt.Printf("Warning: This command has been deprecated. Please use 'infisical vault use [file|auto]' to select which vault to use.\n")
selectVaultTypeCmd(cmd, args)
}, },
} }
var vaultUseCmd = &cobra.Command{
Example: `infisical vault use [file|auto]`,
Use: "use [file|auto]",
Short: "Used to set the type of vault backend to store your login details securely at rest",
DisableFlagsInUseLine: true,
Args: cobra.MinimumNArgs(1),
Run: selectVaultTypeCmd,
}
// runCmd represents the run command // runCmd represents the run command
var vaultCmd = &cobra.Command{ var vaultCmd = &cobra.Command{
Use: "vault", Use: "vault",
@@ -111,10 +102,35 @@ var vaultCmd = &cobra.Command{
}, },
} }
func setFileVaultPassphrase(passphrase string) {
configFile, err := util.GetConfigFile()
if err != nil {
log.Error().Msgf("Unable to set passphrase for file vault because of [err=%s]", err)
return
}
if configFile.VaultBackendType != "file" {
log.Error().Msgf("You are not using file vault to store your login details. You can only set passphrase for file vault")
return
}
// encode with base64
encodedPassphrase := base64.StdEncoding.EncodeToString([]byte(passphrase))
configFile.VaultBackendPassphrase = encodedPassphrase
err = util.WriteConfigFile(&configFile)
if err != nil {
log.Error().Msgf("Unable to set passphrase for file vault because of [err=%s]", err)
return
}
fmt.Printf("\nSuccessfully, set passphrase for file vault. You can now store your login details securely at rest\n")
}
func printAvailableVaultBackends() { func printAvailableVaultBackends() {
fmt.Printf("Vaults are used to securely store your login details locally. Available vaults:") fmt.Printf("Vaults are used to securely store your login details locally. Available vaults:")
for _, backend := range AvailableVaultsAndDescriptions { for _, vaultType := range AvailableVaults {
fmt.Printf("\n- %s", backend) fmt.Printf("\n- %s (%s)", vaultType.Name, vaultType.Description)
} }
currentVaultBackend, err := util.GetCurrentVaultBackend() currentVaultBackend, err := util.GetCurrentVaultBackend()
@@ -127,8 +143,50 @@ func printAvailableVaultBackends() {
fmt.Printf("\n\nYou are currently using [%s] vault to store your login credentials\n", string(currentVaultBackend)) fmt.Printf("\n\nYou are currently using [%s] vault to store your login credentials\n", string(currentVaultBackend))
} }
func selectVaultTypeCmd(cmd *cobra.Command, args []string) {
wantedVaultTypeName := args[0]
currentVaultBackend, err := util.GetCurrentVaultBackend()
if err != nil {
log.Error().Msgf("Unable to set vault to [%s] because of [err=%s]", wantedVaultTypeName, err)
return
}
if wantedVaultTypeName == string(currentVaultBackend) {
log.Error().Msgf("You are already on vault backend [%s]", currentVaultBackend)
return
}
if wantedVaultTypeName == util.VAULT_BACKEND_AUTO_MODE || wantedVaultTypeName == util.VAULT_BACKEND_FILE_MODE {
configFile, err := util.GetConfigFile()
if err != nil {
log.Error().Msgf("Unable to set vault to [%s] because of [err=%s]", wantedVaultTypeName, err)
return
}
configFile.VaultBackendType = wantedVaultTypeName // save selected vault
configFile.LoggedInUserEmail = "" // reset the logged in user to prompt them to re login
err = util.WriteConfigFile(&configFile)
if err != nil {
log.Error().Msgf("Unable to set vault to [%s] because an error occurred when saving the config file [err=%s]", wantedVaultTypeName, err)
return
}
fmt.Printf("\nSuccessfully, switched vault backend from [%s] to [%s]. Please login in again to store your login details in the new vault with [infisical login]\n", currentVaultBackend, wantedVaultTypeName)
Telemetry.CaptureEvent("cli-command:vault set", posthog.NewProperties().Set("currentVault", currentVaultBackend).Set("wantedVault", wantedVaultTypeName).Set("version", util.CLI_VERSION))
} else {
var availableVaultsNames []string
for _, vault := range AvailableVaults {
availableVaultsNames = append(availableVaultsNames, vault.Name)
}
log.Error().Msgf("The requested vault type [%s] is not available on this system. Only the following vault backends are available for you system: %s", wantedVaultTypeName, strings.Join(availableVaultsNames, ", "))
}
}
func init() { func init() {
vaultCmd.AddCommand(vaultSetCmd) vaultCmd.AddCommand(vaultSetCmd)
vaultCmd.AddCommand(vaultSetPassphraseCmd) vaultCmd.AddCommand(vaultUseCmd)
rootCmd.AddCommand(vaultCmd) rootCmd.AddCommand(vaultCmd)
} }