Skip to content

Commit

Permalink
feat(logout): Add logout support for profile and config-file flags.
Browse files Browse the repository at this point in the history
feat(logout): Add `are you sure` prompts to `logout`.

Signed-off-by: spbsoluble <1661003+spbsoluble@users.noreply.github.com>
  • Loading branch information
spbsoluble committed Dec 11, 2024
1 parent 282f69a commit f2afc79
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 23 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
### CLI

- `auth`: Added support for authenticating to Keyfactor Command using a oAuth2 client credentials or access token.
- `logout`: Added support for logging out of specific `profile` and `config-file`.
- `logout`: Added `yes|no` prompt for logout actions, which can be skipped by using the `--no-prompt` flag.

### Store Types

Expand Down
23 changes: 19 additions & 4 deletions cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,17 @@ func getDomainFromUsername(username string) string {
return ""
}

func promptForInteractiveYesNo(parameterName string) bool {
var input string
fmt.Printf("%s [y/n]: \n", parameterName)
_, err := fmt.Scanln(&input)
_ = handleInteractiveError(err, parameterName)
if strings.ToLower(input) == "y" || strings.ToLower(input) == "yes" {
return true
}
return false
}

func promptForInteractiveParameter(parameterName string, defaultValue string) string {
var input string
fmt.Printf("Enter %s [%s]: \n", parameterName, defaultValue)
Expand Down Expand Up @@ -559,7 +570,7 @@ func authInteractive(
}

func prepHomeDir() (string, error) {
log.Debug().Msg("prepHomeDir() called")
log.Debug().Msg(fmt.Sprintf("%s prepHomeDir()", DebugFuncEnter))
// Set up home directory config
userHomeDir, hErr := os.UserHomeDir()

Expand All @@ -573,17 +584,21 @@ func prepHomeDir() (string, error) {
} else {
userHomeDir = fmt.Sprintf("%s/.keyfactor", userHomeDir)
}
//log.Println("[DEBUG] Configuration directory: ", userHomeDir)

log.Debug().Str("userHomeDir", userHomeDir).Msg("Configuration directory")
_, err := os.Stat(userHomeDir)

if os.IsNotExist(err) {
errDir := os.MkdirAll(userHomeDir, 0700)
if errDir != nil {
fmt.Println("Unable to create login config file. ", errDir)
log.Printf("[ERROR] creating directory: %s", errDir)
outputError(fmt.Errorf("error creating home directory: %v", errDir), false, outputFormat)
log.Error().Err(errDir)
log.Debug().Msg(fmt.Sprintf("%s prepHomeDir() returning", DebugFuncExit))
return userHomeDir, errDir
}
}
log.Debug().
Str("userHomeDir", userHomeDir).
Msg(fmt.Sprintf("%s prepHomeDir() returning", DebugFuncExit))
return userHomeDir, hErr
}
160 changes: 141 additions & 19 deletions cmd/logout.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,37 +63,95 @@ var logoutCmd = &cobra.Command{
configFilePath = configFile
}

// Remove environment variables
log.Info().Msg("Running logout command for environment variables")
envLogout()

log.Info().
Str("configFilePath", configFilePath).
Msg("Attempting to removing config file")
err := os.Remove(configFilePath)
if err != nil {
if os.IsNotExist(err) {
if profile != "" {
pErr := logoutProfile(profile, configFilePath)
if pErr != nil {
log.Error().
Err(err).
Msg("config file does not exist, unable to logout")
fmt.Println("Config file does not exist, unable to logout.")
return err
Err(pErr).
Str("profile", profile).
Msg("unable to logout profile")
return pErr
}
fmt.Printf(
"Logged out successfully, removed profile '%s' from config file '%s'.",
profile,
configFilePath,
)
return nil
}

logoutFileErr := logoutFile(configFilePath)
if logoutFileErr != nil {
log.Error().
Err(err).
Msg("unable to remove config file, logout failed")
fmt.Println("Error removing config file: ", err)
return err
Err(logoutFileErr).
Str("configFilePath", configFilePath).
Msg("unable to logout")
return logoutFileErr
}
log.Info().
Str("configFilePath", configFilePath).
Msg("Config file removed successfully")
fmt.Println("Logged out successfully!")
return nil
},
}

// logoutFile removes the config file
func logoutFile(f string) error {
log.Info().
Str("configFilePath", f).
Msg("Running logout command for config file")

var performLogout bool
if !noPrompt {
performLogout = promptForInteractiveYesNo(
fmt.Sprintf(
"Are you sure you want to remove the config file '%s'?",
f,
),
)
if !performLogout {
log.Info().Msg("Logout file cancelled")
fmt.Println(fmt.Sprintf("Logout file '%s' cancelled.", f))
return nil
}
}

log.Debug().
Str("configFilePath", f).
Msg("Removing config file")
err := os.Remove(f)

if err != nil {
if os.IsNotExist(err) {
log.Error().
Err(err).
Msg("config file does not exist, unable to logout")
return err
}
log.Error().
Err(err).
Msg("unable to remove config file, logout failed")
return err
}
log.Info().
Str("configFilePath", f).
Msg("Config file removed successfully")
fmt.Println(fmt.Sprintf("Logged out successfully, removed config file '%s'", f))
return nil
}

// envLogout unsets environment variables
func envLogout() {

if !noPrompt {
performLogout := promptForInteractiveYesNo("Are you sure you want to unset environment variables?")
if !performLogout {
log.Info().Msg("Logout environment variables cancelled")
fmt.Println("Logout environment variables cancelled.")
return
}
}

log.Debug().Msg("Running logout command for environment variables")

log.Debug().Msg("Unsetting base environment variables")
Expand Down Expand Up @@ -164,6 +222,70 @@ func envLogout() {

}

// logoutProfile removes the profile from the config file
func logoutProfile(p string, f string) error {
log.Info().
Str("profile", p).
Str("configFilePath", f).
Msg("Running logout command for profile")

var performLogout bool
if !noPrompt {
performLogout = promptForInteractiveYesNo(
fmt.Sprintf(
"Are you sure you want to remove profile '%s' from '%s?", p, f,
),
)
if !performLogout {
log.Info().Msg("Logout profile cancelled")
fmt.Println(fmt.Sprintf("Logout profile '%s' in '%s' cancelled.", p, f))
return nil
}
}

log.Debug().
Str("configFilePath", f).
Msg("Reading config file")
config, err := auth_providers.ReadConfigFromJSON(f)
if err != nil {
log.Error().
Err(err).
Str("configFilePath", f).
Str("profile", p).
Msg("unable to read config file, logout failed")
return err
} else if config == nil {
log.Error().
Str("configFilePath", f).
Str("profile", p).
Msg("config file is empty, unable to logout")
return fmt.Errorf("config file is empty, unable to logout profile '%s'", p)
}

// check if profile exists
if _, ok := config.Servers[p]; !ok {
log.Error().
Str("profile", p).
Msg("profile does not exist, unable to logout")
return fmt.Errorf("profile '%s' does not exist, unable to logout", p)
}
delete(config.Servers, p)
wErr := auth_providers.WriteConfigToJSON(f, config)
if wErr != nil {
log.Error().
Err(wErr).
Str("configFilePath", f).
Str("profile", p).
Msg("unable to write config file, logout failed")
return wErr
}
log.Info().
Str("configFilePath", f).
Str("profile", p).
Msg("Profile removed successfully")
return nil
}

func init() {
RootCmd.AddCommand(logoutCmd)
}

0 comments on commit f2afc79

Please sign in to comment.