feat: CLI support for multiple user accounts logins

See #340
This commit is contained in:
quinton11
2023-04-04 16:27:47 +00:00
parent cca9476975
commit 5508434563
6 changed files with 152 additions and 13 deletions

View File

@@ -48,14 +48,24 @@ var loginCmd = &cobra.Command{
util.HandleError(err)
}
if currentLoggedInUserDetails.IsUserLoggedIn && !currentLoggedInUserDetails.LoginExpired && len(currentLoggedInUserDetails.UserCredentials.PrivateKey) != 0 {
shouldOverride, err := shouldOverrideLoginPrompt(currentLoggedInUserDetails.UserCredentials.Email)
addUser := false
if currentLoggedInUserDetails.UserCredentials.Email != "" {
addUser, err = addNewUserPrompt()
if err != nil {
util.HandleError(err)
}
}
if !shouldOverride {
return
if !addUser {
if currentLoggedInUserDetails.IsUserLoggedIn && !currentLoggedInUserDetails.LoginExpired && len(currentLoggedInUserDetails.UserCredentials.PrivateKey) != 0 {
shouldOverride, err := shouldOverrideLoginPrompt(currentLoggedInUserDetails.UserCredentials.Email)
if err != nil {
util.HandleError(err)
}
if !shouldOverride {
return
}
}
}
@@ -342,6 +352,19 @@ func getFreshUserCredentials(email string, password string) (*api.GetLoginOneV2R
return &loginOneResponseResult, &loginTwoResponseResult, nil
}
func addNewUserPrompt() (bool, error) {
prompt := promptui.Select{
Label: "Infisical detects previous logged in users. Would you like to add a new user? Select[Yes/No]",
Items: []string{"No", "Yes"},
}
_, result, err := prompt.Run()
if err != nil {
return false, err
}
return result == "Yes", err
}
func shouldOverrideLoginPrompt(currentLoggedInUserEmail string) (bool, error) {
prompt := promptui.Select{
Label: fmt.Sprintf("There seems to be a user already logged in with the email: %s. Would you like to override that login? Select[Yes/No]", currentLoggedInUserEmail),

View File

@@ -0,0 +1,93 @@
package cmd
import (
"errors"
"github.com/Infisical/infisical-merge/packages/util"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
)
var switchCmd = &cobra.Command{
Use: "switch",
Short: "Used to switch between Infisical profiles",
DisableFlagsInUseLine: true,
Example: "infisical switch",
Args: cobra.ExactArgs(0),
PreRun: func(cmd *cobra.Command, args []string) {
util.RequireLogin()
},
Run: func(cmd *cobra.Command, args []string) {
//get previous logged in profiles
loggedInProfiles, err := getLoggedInUsers()
if err != nil {
util.HandleError(err, "[infisical switch]: Unable to get logged Profiles")
}
//prompt user
profile, err := LoggedInUsersPrompt(loggedInProfiles)
if err != nil {
util.HandleError(err, "[infisical switch]: Prompt error")
}
//write to config file
configFile, err := util.GetConfigFile()
if err != nil {
util.HandleError(err, "[infisical switch]: Unable to get config file")
}
configFile.LoggedInUserEmail = profile
ok := util.Contains(configFile.LoggedInUsersEmail, profile)
if !ok {
configFile.LoggedInUsersEmail = append(configFile.LoggedInUsersEmail, profile)
}
err = util.WriteConfigFile(&configFile)
if err != nil {
util.HandleError(err, "")
}
},
}
func init() {
rootCmd.AddCommand(switchCmd)
}
func getLoggedInUsers() ([]string, error) {
loggedInProfiles := []string{}
if util.ConfigFileExists() {
configFile, err := util.GetConfigFile()
if err != nil {
return loggedInProfiles, err
}
//get logged in profiles
//
if configFile.LoggedInUsersEmail == nil {
loggedInProfiles = append(loggedInProfiles, configFile.LoggedInUserEmail)
} else {
if len(configFile.LoggedInUsersEmail) > 0 {
loggedInProfiles = append(loggedInProfiles, configFile.LoggedInUsersEmail...)
}
}
return loggedInProfiles, nil
} else {
//empty
return loggedInProfiles, errors.New("couldn't retrieve config file")
}
}
func LoggedInUsersPrompt(profiles []string) (string, error) {
prompt := promptui.Select{Label: "Which of your Infisical profiles would you like to use",
Items: profiles,
Size: 7,
}
idx, _, err := prompt.Run()
if err != nil {
return "", err
}
return profiles[idx], nil
}

View File

@@ -12,8 +12,9 @@ type UserCredentials struct {
// The file struct for Infisical config file
type ConfigFile struct {
LoggedInUserEmail string `json:"loggedInUserEmail"`
VaultBackendType keyring.BackendType `json:"vaultBackendType"`
LoggedInUserEmail string `json:"loggedInUserEmail"`
VaultBackendType keyring.BackendType `json:"vaultBackendType"`
LoggedInUsersEmail []string `json:"loggedInUsersEmail,omitempty"`
}
type SingleEnvironmentVariable struct {

View File

@@ -23,8 +23,5 @@ func WriteToFile(fileName string, dataToWrite []byte, filePerm os.FileMode) erro
func CheckIsConnectedToInternet() (ok bool) {
_, err := http.Get("http://clients3.google.com/generate_204")
if err != nil {
return false
}
return true
return err == nil
}

View File

@@ -31,9 +31,25 @@ func WriteInitalConfig(userCredentials *models.UserCredentials) error {
return fmt.Errorf("writeInitalConfig: unable to write config file because [err=%s]", err)
}
//if empty
if existingConfigFile.LoggedInUsersEmail == nil {
existingConfigFile.LoggedInUsersEmail = []string{}
}
//if profile exists
if len(existingConfigFile.LoggedInUsersEmail) > 0 {
ok := Contains(existingConfigFile.LoggedInUsersEmail, userCredentials.Email)
if !ok {
existingConfigFile.LoggedInUsersEmail = append(existingConfigFile.LoggedInUsersEmail, userCredentials.Email)
}
} else {
existingConfigFile.LoggedInUsersEmail = append(existingConfigFile.LoggedInUsersEmail, userCredentials.Email)
}
configFile := models.ConfigFile{
LoggedInUserEmail: userCredentials.Email,
VaultBackendType: existingConfigFile.VaultBackendType,
LoggedInUserEmail: userCredentials.Email,
VaultBackendType: existingConfigFile.VaultBackendType,
LoggedInUsersEmail: existingConfigFile.LoggedInUsersEmail,
}
configFileMarshalled, err := json.Marshal(configFile)
@@ -176,7 +192,7 @@ func GetConfigFile() (models.ConfigFile, error) {
return configFile, nil
}
// Write a ConfigFile to disk. Raise error if unable to save the model to ask
// Write a ConfigFile to disk. Raise error if unable to save the model to disk
func WriteConfigFile(configFile *models.ConfigFile) error {
fullConfigFilePath, fullConfigFileDirPath, err := GetFullConfigFilePath()
if err != nil {

View File

@@ -61,6 +61,15 @@ func IsSecretTypeValid(s string) bool {
return false
}
func Contains(iter []string, elem string) bool {
for _, value := range iter {
if value == elem {
return true
}
}
return false
}
func RequireLogin() {
currentUserDetails, err := GetCurrentLoggedInUserDetails()