Files
sailpoint-cli/cmd/root/configure.go
2022-12-21 00:28:50 -06:00

197 lines
4.5 KiB
Go

// Copyright (c) 2021, SailPoint Technologies, Inc. All rights reserved.
package root
import (
"bufio"
"errors"
"fmt"
"log"
"path/filepath"
"strconv"
"github.com/sailpoint-oss/sailpoint-cli/internal/auth"
"github.com/sailpoint-oss/sailpoint-cli/internal/client"
"github.com/sailpoint-oss/sailpoint-cli/internal/types"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"os"
)
const (
baseURLTemplate = "https://%s.api.identitynow.com"
tokenURLTemplate = "https://%s.api.identitynow.com/oauth/token"
authUrlTemplate = "https://%s.identitynow.com/oauth/authorize"
configFolder = ".sailpoint"
configYamlFile = "config.yaml"
)
func newConfigureCmd(client client.Client) *cobra.Command {
var debug bool
cmd := &cobra.Command{
Use: "configure",
Short: "Configure CLI",
Long: "Configure Authentication for the CLI Supported Methods: (PAT, OAuth)",
Aliases: []string{"conf"},
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
AuthType := args[0]
config, err := getConfigureParamsFromStdin(AuthType, debug)
if err != nil {
return err
}
fmt.Println("Finished getting config")
err = updateConfigFile(config)
if err != nil {
return err
}
fmt.Println("Finished writing config")
switch AuthType {
case "PAT":
_, err = auth.PATLogin(config, cmd.Context())
if err != nil {
return err
}
case "OAuth":
_, err := auth.OAuthLogin(config)
if err != nil {
return err
}
default:
return errors.New("invalid authtype")
}
return nil
},
}
cmd.Flags().BoolVarP(&debug, "Debug", "d", false, "Specifies if the debug flag should be set")
return cmd
}
func updateConfigFile(conf types.OrgConfig) error {
home, err := os.UserHomeDir()
if err != nil {
return err
}
if _, err := os.Stat(filepath.Join(home, configFolder)); os.IsNotExist(err) {
err = os.Mkdir(filepath.Join(home, configFolder), 0777)
if err != nil {
log.Printf("failed to create %s folder for config. %v", configFolder, err)
}
}
viper.Set("authtype", conf.AuthType)
viper.Set("debug", conf.Debug)
switch conf.AuthType {
case "PAT":
viper.Set("pat", conf.Pat)
case "OAuth":
viper.Set("oauth", conf.OAuth)
}
err = viper.WriteConfig()
if err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
err = viper.SafeWriteConfig()
if err != nil {
return err
}
} else {
return err
}
}
return nil
}
func getConfigureParamsFromStdin(AuthType string, debug bool) (types.OrgConfig, error) {
var conf types.OrgConfig
switch AuthType {
case "PAT":
paramsNames := []string{
"Tenant (ex. {tenant}.identitynow.com): ",
"Personal Access Token Client ID: ",
"Personal Access Token Client Secret: ",
}
scanner := bufio.NewScanner(os.Stdin)
for _, pm := range paramsNames {
fmt.Print(pm)
scanner.Scan()
value := scanner.Text()
if value == "" {
return conf, fmt.Errorf("%s parameter is empty", pm[:len(pm)-2])
}
switch pm {
case paramsNames[0]:
conf.Pat.Tenant = value
conf.Pat.BaseUrl = fmt.Sprintf(baseURLTemplate, value)
conf.Pat.TokenUrl = fmt.Sprintf(tokenURLTemplate, value)
case paramsNames[1]:
conf.Pat.ClientID = value
case paramsNames[2]:
conf.Pat.ClientSecret = value
}
}
conf.AuthType = AuthType
fmt.Println("got here")
return conf, nil
case "OAuth":
paramsNames := []string{
"Tenant (ex. {tenant}.identitynow.com): ",
"OAuth Client ID: ",
"OAuth Client Secret: ",
"OAuth Redirect Port (ex. http://localhost:{3000}/callback): ",
"OAuth Redirect Path (ex. http://localhost:3000{/callback}): ",
}
scanner := bufio.NewScanner(os.Stdin)
var OAuth types.OAuthConfig
for _, pm := range paramsNames {
fmt.Print(pm)
scanner.Scan()
value := scanner.Text()
if value == "" && pm != paramsNames[2] {
return conf, fmt.Errorf("%s parameter is empty", pm[:len(pm)-2])
}
switch pm {
case paramsNames[0]:
OAuth.Tenant = value
OAuth.BaseUrl = fmt.Sprintf(baseURLTemplate, value)
OAuth.TokenUrl = fmt.Sprintf(tokenURLTemplate, value)
OAuth.AuthUrl = fmt.Sprintf(authUrlTemplate, value)
case paramsNames[1]:
OAuth.ClientID = value
case paramsNames[2]:
OAuth.ClientSecret = value
case paramsNames[3]:
OAuth.Redirect.Port, _ = strconv.Atoi(value)
case paramsNames[4]:
OAuth.Redirect.Path = value
}
}
conf.OAuth = OAuth
conf.AuthType = AuthType
return conf, nil
}
return conf, errors.New("invalid auth type provided")
}