mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
host API support for login and switch commands
This commit is contained in:
@@ -10,9 +10,11 @@ import (
|
||||
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"regexp"
|
||||
|
||||
"github.com/Infisical/infisical-merge/packages/api"
|
||||
"github.com/Infisical/infisical-merge/packages/config"
|
||||
"github.com/Infisical/infisical-merge/packages/crypto"
|
||||
"github.com/Infisical/infisical-merge/packages/models"
|
||||
"github.com/Infisical/infisical-merge/packages/srp"
|
||||
@@ -73,6 +75,12 @@ var loginCmd = &cobra.Command{
|
||||
}
|
||||
// }
|
||||
|
||||
//prompt user to select domain between Infisical cloud and self hosting
|
||||
err = askForDomain()
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse domain url")
|
||||
}
|
||||
|
||||
email, password, err := askForLoginCredentials()
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse email and password for authentication")
|
||||
@@ -266,6 +274,51 @@ func init() {
|
||||
rootCmd.AddCommand(loginCmd)
|
||||
}
|
||||
|
||||
func askForDomain() error {
|
||||
//query user to choose between Infisical cloud or self hosting
|
||||
options := []string{"Infisical Cloud", "Self Hosting"}
|
||||
optionsPrompt := promptui.Select{
|
||||
Label: "Select your hosting option",
|
||||
Items: options,
|
||||
Size: 2,
|
||||
}
|
||||
|
||||
idx, _, err := optionsPrompt.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if idx == 0 {
|
||||
//cloud option
|
||||
config.INFISICAL_URL = util.INFISICAL_DEFAULT_API_URL
|
||||
return nil
|
||||
}
|
||||
|
||||
urlValidation := func(input string) error {
|
||||
_, err := url.ParseRequestURI(input)
|
||||
if err != nil {
|
||||
return errors.New("this is an invalid url")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//else run prompt to enter domain
|
||||
domainPrompt := promptui.Prompt{
|
||||
Label: "Domain",
|
||||
Validate: urlValidation,
|
||||
}
|
||||
|
||||
domain, err := domainPrompt.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//set api url
|
||||
config.INFISICAL_URL = domain
|
||||
//return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func askForLoginCredentials() (email string, password string, err error) {
|
||||
validateEmail := func(input string) error {
|
||||
matched, err := regexp.MatchString("^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$", input)
|
||||
|
||||
@@ -2,7 +2,10 @@ package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
|
||||
"github.com/Infisical/infisical-merge/packages/config"
|
||||
"github.com/Infisical/infisical-merge/packages/models"
|
||||
"github.com/Infisical/infisical-merge/packages/util"
|
||||
"github.com/manifoldco/promptui"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -30,25 +33,43 @@ var switchCmd = &cobra.Command{
|
||||
//get previous logged in profiles
|
||||
loggedInProfiles, err := getLoggedInUsers()
|
||||
if err != nil {
|
||||
util.HandleError(err, "[infisical switch]: Unable to get logged Profiles")
|
||||
util.HandleError(err, "[infisical user switch]: Unable to get logged Profiles")
|
||||
}
|
||||
|
||||
//prompt user
|
||||
profile, err := LoggedInUsersPrompt(loggedInProfiles)
|
||||
if err != nil {
|
||||
util.HandleError(err, "[infisical switch]: Prompt error")
|
||||
util.HandleError(err, "[infisical user switch]: Prompt error")
|
||||
}
|
||||
|
||||
//write to config file
|
||||
configFile, err := util.GetConfigFile()
|
||||
if err != nil {
|
||||
util.HandleError(err, "[infisical switch]: Unable to get config file")
|
||||
util.HandleError(err, "[infisical user switch]: Unable to get config file")
|
||||
}
|
||||
|
||||
configFile.LoggedInUserEmail = profile
|
||||
ok := util.Contains(configFile.LoggedInUsersEmail, profile)
|
||||
|
||||
//set logged in user domain
|
||||
ok := util.ConfigContainsEmail(configFile.LoggedInUsers, profile)
|
||||
|
||||
if !ok {
|
||||
configFile.LoggedInUsersEmail = append(configFile.LoggedInUsersEmail, profile)
|
||||
//profile not in loggedInUsers
|
||||
configFile.LoggedInUsers = append(configFile.LoggedInUsers, models.LoggedInUser{
|
||||
Email: profile,
|
||||
Domain: config.INFISICAL_URL,
|
||||
})
|
||||
//set logged in user domain
|
||||
configFile.LoggedInUserDomain = config.INFISICAL_URL
|
||||
|
||||
} else {
|
||||
//exists, set logged in user domain
|
||||
for _, v := range configFile.LoggedInUsers {
|
||||
if profile == v.Email {
|
||||
configFile.LoggedInUserDomain = v.Domain
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = util.WriteConfigFile(&configFile)
|
||||
@@ -58,7 +79,71 @@ var switchCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var domainCmd = &cobra.Command{
|
||||
Use: "domain",
|
||||
Short: "Used to update the domain of an Infisical profile",
|
||||
DisableFlagsInUseLine: true,
|
||||
Example: "infisical user domain",
|
||||
Args: cobra.ExactArgs(0),
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
util.RequireLogin()
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
//prompt for profiles selection
|
||||
loggedInProfiles, err := getLoggedInUsers()
|
||||
if err != nil {
|
||||
util.HandleError(err, "[infisical user domain]: Unable to get logged Profiles")
|
||||
}
|
||||
|
||||
//prompt user
|
||||
profile, err := LoggedInUsersPrompt(loggedInProfiles)
|
||||
if err != nil {
|
||||
util.HandleError(err, "[infisical user domain]: Prompt error")
|
||||
}
|
||||
|
||||
//prompt to update domain
|
||||
domain, err := NewDomainPrompt()
|
||||
if err != nil {
|
||||
util.HandleError(err, "[infisical user domain]: Prompt error")
|
||||
}
|
||||
|
||||
//write to config file
|
||||
configFile, err := util.GetConfigFile()
|
||||
if err != nil {
|
||||
util.HandleError(err, "[infisical user]: Unable to get config file")
|
||||
}
|
||||
|
||||
//check if profile in logged in profiles
|
||||
|
||||
//if not add new profile loggedInUsers
|
||||
//else update profile from loggedinUsers list
|
||||
ok := util.ConfigContainsEmail(configFile.LoggedInUsers, profile)
|
||||
if !ok {
|
||||
configFile.LoggedInUsers = append(configFile.LoggedInUsers, models.LoggedInUser{
|
||||
Email: profile,
|
||||
Domain: domain,
|
||||
})
|
||||
} else {
|
||||
//exists, set logged in user domain
|
||||
for _, v := range configFile.LoggedInUsers {
|
||||
if profile == v.Email {
|
||||
v.Domain = domain
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//check if current loggedinuser is selected profile
|
||||
//if yes set current domain to changed domain
|
||||
if configFile.LoggedInUserEmail == profile {
|
||||
configFile.LoggedInUserDomain = domain
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
userCmd.AddCommand(domainCmd)
|
||||
userCmd.AddCommand(switchCmd)
|
||||
rootCmd.AddCommand(userCmd)
|
||||
}
|
||||
@@ -74,12 +159,13 @@ func getLoggedInUsers() ([]string, error) {
|
||||
|
||||
//get logged in profiles
|
||||
//
|
||||
if configFile.LoggedInUsersEmail == nil {
|
||||
loggedInProfiles = append(loggedInProfiles, configFile.LoggedInUserEmail)
|
||||
} else {
|
||||
if len(configFile.LoggedInUsersEmail) > 0 {
|
||||
loggedInProfiles = append(loggedInProfiles, configFile.LoggedInUsersEmail...)
|
||||
if len(configFile.LoggedInUsers) > 0 {
|
||||
for _, v := range configFile.LoggedInUsers {
|
||||
loggedInProfiles = append(loggedInProfiles, v.Email)
|
||||
}
|
||||
} else {
|
||||
|
||||
loggedInProfiles = append(loggedInProfiles, configFile.LoggedInUserEmail)
|
||||
}
|
||||
return loggedInProfiles, nil
|
||||
} else {
|
||||
@@ -88,6 +174,29 @@ func getLoggedInUsers() ([]string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func NewDomainPrompt() (string, error) {
|
||||
urlValidation := func(input string) error {
|
||||
_, err := url.ParseRequestURI(input)
|
||||
if err != nil {
|
||||
return errors.New("this is an invalid url")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//else run prompt to enter domain
|
||||
domainPrompt := promptui.Prompt{
|
||||
Label: "New Domain",
|
||||
Validate: urlValidation,
|
||||
}
|
||||
|
||||
domain, err := domainPrompt.Run()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return domain, nil
|
||||
}
|
||||
|
||||
func LoggedInUsersPrompt(profiles []string) (string, error) {
|
||||
prompt := promptui.Select{Label: "Which of your Infisical profiles would you like to use",
|
||||
Items: profiles,
|
||||
|
||||
@@ -13,8 +13,14 @@ type UserCredentials struct {
|
||||
// The file struct for Infisical config file
|
||||
type ConfigFile struct {
|
||||
LoggedInUserEmail string `json:"loggedInUserEmail"`
|
||||
LoggedInUserDomain string `json:"LoggedInUserDomain,omitempty"`
|
||||
VaultBackendType keyring.BackendType `json:"vaultBackendType"`
|
||||
LoggedInUsersEmail []string `json:"loggedInUsersEmail,omitempty"`
|
||||
LoggedInUsers []LoggedInUser `json:"loggedInUsers,omitempty"`
|
||||
}
|
||||
|
||||
type LoggedInUser struct {
|
||||
Email string `json:"email"`
|
||||
Domain string `json:"domain"`
|
||||
}
|
||||
|
||||
type SingleEnvironmentVariable struct {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/Infisical/infisical-merge/packages/config"
|
||||
"github.com/Infisical/infisical-merge/packages/models"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
@@ -31,25 +32,25 @@ func WriteInitalConfig(userCredentials *models.UserCredentials) error {
|
||||
return fmt.Errorf("writeInitalConfig: unable to write config file because [err=%s]", err)
|
||||
}
|
||||
|
||||
//if empty, initialize
|
||||
if existingConfigFile.LoggedInUsersEmail == nil {
|
||||
existingConfigFile.LoggedInUsersEmail = []string{}
|
||||
}
|
||||
|
||||
//if profiles exists
|
||||
if len(existingConfigFile.LoggedInUsersEmail) > 0 {
|
||||
ok := Contains(existingConfigFile.LoggedInUsersEmail, userCredentials.Email)
|
||||
loggedInUser := models.LoggedInUser{
|
||||
Email: userCredentials.Email,
|
||||
Domain: config.INFISICAL_URL,
|
||||
}
|
||||
if len(existingConfigFile.LoggedInUsers) > 0 {
|
||||
ok := ConfigContainsEmail(existingConfigFile.LoggedInUsers, userCredentials.Email)
|
||||
if !ok {
|
||||
existingConfigFile.LoggedInUsersEmail = append(existingConfigFile.LoggedInUsersEmail, userCredentials.Email)
|
||||
existingConfigFile.LoggedInUsers = append(existingConfigFile.LoggedInUsers, loggedInUser)
|
||||
}
|
||||
} else {
|
||||
existingConfigFile.LoggedInUsersEmail = append(existingConfigFile.LoggedInUsersEmail, userCredentials.Email)
|
||||
existingConfigFile.LoggedInUsers = append(existingConfigFile.LoggedInUsers, loggedInUser)
|
||||
}
|
||||
|
||||
configFile := models.ConfigFile{
|
||||
LoggedInUserEmail: userCredentials.Email,
|
||||
LoggedInUserDomain: config.INFISICAL_URL,
|
||||
VaultBackendType: existingConfigFile.VaultBackendType,
|
||||
LoggedInUsersEmail: existingConfigFile.LoggedInUsersEmail,
|
||||
LoggedInUsers: existingConfigFile.LoggedInUsers,
|
||||
}
|
||||
|
||||
configFileMarshalled, err := json.Marshal(configFile)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/99designs/keyring"
|
||||
"github.com/Infisical/infisical-merge/packages/api"
|
||||
"github.com/Infisical/infisical-merge/packages/config"
|
||||
"github.com/Infisical/infisical-merge/packages/models"
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
@@ -87,6 +88,12 @@ func GetCurrentLoggedInUserDetails() (LoggedInUserDetails, error) {
|
||||
SetAuthToken(userCreds.JTWToken).
|
||||
SetHeader("Accept", "application/json")
|
||||
|
||||
//configFile.LoggedInUserDomain
|
||||
//if not empty set as infisical url
|
||||
if configFile.LoggedInUserDomain != "" {
|
||||
config.INFISICAL_URL = configFile.LoggedInUserDomain
|
||||
}
|
||||
|
||||
isAuthenticated := api.CallIsAuthenticated(httpClient)
|
||||
if !isAuthenticated {
|
||||
return LoggedInUserDetails{
|
||||
|
||||
@@ -9,6 +9,8 @@ import (
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/Infisical/infisical-merge/packages/models"
|
||||
)
|
||||
|
||||
type DecodedSymmetricEncryptionDetails = struct {
|
||||
@@ -61,9 +63,9 @@ func IsSecretTypeValid(s string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func Contains(iter []string, elem string) bool {
|
||||
func ConfigContainsEmail(iter []models.LoggedInUser, elem string) bool {
|
||||
for _, value := range iter {
|
||||
if value == elem {
|
||||
if value.Email == elem {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user