2024-08-25 21:53:44 +00:00
|
|
|
package auth
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io/fs"
|
|
|
|
|
2024-09-01 16:22:18 +00:00
|
|
|
"github.com/databricks/cli/libs/auth"
|
2024-09-01 22:15:48 +00:00
|
|
|
"github.com/databricks/cli/libs/auth/cache"
|
2024-08-25 21:53:44 +00:00
|
|
|
"github.com/databricks/cli/libs/cmdio"
|
|
|
|
"github.com/databricks/cli/libs/databrickscfg/profile"
|
|
|
|
"github.com/databricks/databricks-sdk-go/config"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
)
|
|
|
|
|
2024-09-23 18:37:53 +00:00
|
|
|
type logoutSession struct {
|
|
|
|
profile string
|
|
|
|
file config.File
|
|
|
|
persistentAuth *auth.PersistentAuth
|
2024-08-25 21:53:44 +00:00
|
|
|
}
|
|
|
|
|
2024-09-23 18:37:53 +00:00
|
|
|
func (l *logoutSession) load(ctx context.Context, profileName string, persistentAuth *auth.PersistentAuth) error {
|
|
|
|
l.profile = profileName
|
|
|
|
l.persistentAuth = persistentAuth
|
2024-08-25 21:53:44 +00:00
|
|
|
iniFile, err := profile.DefaultProfiler.Get(ctx)
|
|
|
|
if errors.Is(err, fs.ErrNotExist) {
|
|
|
|
return err
|
|
|
|
} else if err != nil {
|
|
|
|
return fmt.Errorf("cannot parse config file: %w", err)
|
|
|
|
}
|
2024-09-23 18:37:53 +00:00
|
|
|
l.file = *iniFile
|
2024-09-01 22:15:48 +00:00
|
|
|
if err := l.setHostAndAccountIdFromProfile(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-09-23 18:37:53 +00:00
|
|
|
func (l *logoutSession) setHostAndAccountIdFromProfile() error {
|
2024-09-01 22:15:48 +00:00
|
|
|
sectionMap, err := l.getConfigSectionMap()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if sectionMap["host"] == "" {
|
2024-09-23 18:37:53 +00:00
|
|
|
return fmt.Errorf("no host configured for profile %s", l.profile)
|
2024-09-01 22:15:48 +00:00
|
|
|
}
|
2024-09-23 18:37:53 +00:00
|
|
|
l.persistentAuth.Host = sectionMap["host"]
|
|
|
|
l.persistentAuth.AccountID = sectionMap["account_id"]
|
2024-08-25 21:53:44 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-09-23 18:37:53 +00:00
|
|
|
func (l *logoutSession) getConfigSectionMap() (map[string]string, error) {
|
|
|
|
section, err := l.file.GetSection(l.profile)
|
2024-08-25 21:53:44 +00:00
|
|
|
if err != nil {
|
|
|
|
return map[string]string{}, fmt.Errorf("profile does not exist in config file: %w", err)
|
|
|
|
}
|
|
|
|
return section.KeysHash(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// clear token from ~/.databricks/token-cache.json
|
2024-09-23 18:37:53 +00:00
|
|
|
func (l *logoutSession) clearTokenCache(ctx context.Context) error {
|
|
|
|
return l.persistentAuth.ClearToken(ctx)
|
2024-08-25 21:53:44 +00:00
|
|
|
}
|
|
|
|
|
2024-09-01 16:22:18 +00:00
|
|
|
func newLogoutCommand(persistentAuth *auth.PersistentAuth) *cobra.Command {
|
2024-08-25 21:53:44 +00:00
|
|
|
cmd := &cobra.Command{
|
|
|
|
Use: "logout [PROFILE]",
|
|
|
|
Short: "Logout from specified profile",
|
2024-10-06 21:37:05 +00:00
|
|
|
Long: "Removes the OAuth token from the token-cache",
|
2024-08-25 21:53:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
|
|
|
ctx := cmd.Context()
|
2024-09-01 22:15:48 +00:00
|
|
|
profileNameFromFlag := cmd.Flag("profile").Value.String()
|
|
|
|
// If both [PROFILE] and --profile are provided, return an error.
|
|
|
|
if len(args) > 0 && profileNameFromFlag != "" {
|
|
|
|
return fmt.Errorf("please only provide a profile as an argument or a flag, not both")
|
|
|
|
}
|
|
|
|
// Determine the profile name from either args or the flag.
|
|
|
|
profileName := profileNameFromFlag
|
|
|
|
if len(args) > 0 {
|
|
|
|
profileName = args[0]
|
|
|
|
}
|
2024-09-01 16:22:18 +00:00
|
|
|
// If the user has not specified a profile name, prompt for one.
|
|
|
|
if profileName == "" {
|
|
|
|
var err error
|
|
|
|
profileName, err = promptForProfile(ctx, persistentAuth.ProfileName())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-08-25 21:53:44 +00:00
|
|
|
}
|
2024-09-01 16:22:18 +00:00
|
|
|
defer persistentAuth.Close()
|
2024-09-23 18:37:53 +00:00
|
|
|
logoutSession := &logoutSession{}
|
2024-10-06 21:37:05 +00:00
|
|
|
err := logoutSession.load(ctx, profileName, persistentAuth)
|
2024-09-01 16:22:18 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-09-01 22:15:48 +00:00
|
|
|
err = logoutSession.clearTokenCache(ctx)
|
2024-09-01 18:17:07 +00:00
|
|
|
if err != nil {
|
|
|
|
if errors.Is(err, cache.ErrNotConfigured) {
|
2024-10-06 21:37:05 +00:00
|
|
|
// It is OK to not have OAuth configured
|
2024-09-01 18:17:07 +00:00
|
|
|
} else {
|
|
|
|
return err
|
|
|
|
}
|
2024-08-25 21:53:44 +00:00
|
|
|
}
|
2024-10-06 21:37:05 +00:00
|
|
|
cmdio.LogString(ctx, fmt.Sprintf("Profile %s is logged out", profileName))
|
2024-08-25 21:53:44 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return cmd
|
|
|
|
}
|