add support for multiple keyring

This commit is contained in:
Maidul Islam
2022-12-24 19:11:29 -05:00
parent 79333657ed
commit f22d4277dc
9 changed files with 372 additions and 43 deletions
+54
View File
@@ -24,8 +24,15 @@ func WriteInitalConfig(userCredentials *models.UserCredentials) error {
}
}
// get existing config
existingConfigFile, err := GetConfigFile()
if err != nil {
return fmt.Errorf("writeInitalConfig: unable to write config file because [err=%s]", err)
}
configFile := models.ConfigFile{
LoggedInUserEmail: userCredentials.Email,
VaultBackendType: existingConfigFile.VaultBackendType,
}
configFileMarshalled, err := json.Marshal(configFile)
@@ -152,3 +159,50 @@ func GetAllWorkSpaceConfigsStartingFromCurrentPath() (workspaces []models.Worksp
return listOfWorkSpaceConfigs, nil
}
// Get the infisical config file and if it doesn't exist, return empty config model, otherwise raise error
func GetConfigFile() (models.ConfigFile, error) {
fullConfigFilePath, _, err := GetFullConfigFilePath()
if err != nil {
return models.ConfigFile{}, err
}
configFileAsBytes, err := os.ReadFile(fullConfigFilePath)
if err != nil {
if err, ok := err.(*os.PathError); ok {
return models.ConfigFile{}, nil
} else {
return models.ConfigFile{}, err
}
}
var configFile models.ConfigFile
err = json.Unmarshal(configFileAsBytes, &configFile)
if err != nil {
return models.ConfigFile{}, err
}
return configFile, nil
}
// Write a ConfigFile to disk. Raise error if unable to save the model to ask
func WriteConfigFile(configFile *models.ConfigFile) error {
fullConfigFilePath, _, err := GetFullConfigFilePath()
if err != nil {
return fmt.Errorf("writeConfigFile: unable to write config file because an error occurred when getting config file path [err=%s]", err)
}
configFileMarshalled, err := json.Marshal(configFile)
if err != nil {
return fmt.Errorf("writeConfigFile: unable to write config file because an error occurred when marshalling the config file [err=%s]", err)
}
// Create file in directory
err = WriteToFile(fullConfigFilePath, configFileMarshalled, os.ModePerm)
if err != nil {
return fmt.Errorf("writeConfigFile: unable to write config file because an error occurred when write the config to file [err=%s]", err)
}
return nil
}
+15 -22
View File
@@ -3,12 +3,11 @@ package util
import (
"encoding/json"
"fmt"
"os"
"github.com/99designs/keyring"
"github.com/Infisical/infisical-merge/packages/models"
"github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
"github.com/zalando/go-keyring"
)
const SERVICE_NAME = "infisical"
@@ -17,26 +16,30 @@ const SERVICE_NAME = "infisical"
func StoreUserCredsInKeyRing(userCred *models.UserCredentials) error {
userCredMarshalled, err := json.Marshal(userCred)
if err != nil {
return fmt.Errorf("Something went wrong when marshalling user creds:", err)
return fmt.Errorf("StoreUserCredsInKeyRing: something went wrong when marshalling user creds [err=%s]", err)
}
err = keyring.Set(SERVICE_NAME, userCred.Email, string(userCredMarshalled))
err = keyringInstance.Set(keyring.Item{
Key: userCred.Email,
Data: []byte(string(userCredMarshalled)),
})
if err != nil {
return fmt.Errorf("Unable to store user credentials:", err)
return fmt.Errorf("StoreUserCredsInKeyRing: unable to store user credentials because [err=%s]", err)
}
return err
}
func GetUserCredsFromKeyRing(userEmail string) (credentials models.UserCredentials, err error) {
credentialsString, err := keyring.Get(SERVICE_NAME, userEmail)
credentialsValue, err := keyringInstance.Get(userEmail)
if err != nil {
return models.UserCredentials{}, fmt.Errorf("Unable to get key from Keyring:", err)
return models.UserCredentials{}, fmt.Errorf("Unable to get key from Keyring. could not find login credentials in your Keyring. This is common if you have switched vault backend recently. If so, please login in again and retry:", err)
}
var userCredentials models.UserCredentials
err = json.Unmarshal([]byte(credentialsString), &userCredentials)
err = json.Unmarshal([]byte(credentialsValue.Data), &userCredentials)
if err != nil {
return models.UserCredentials{}, fmt.Errorf("Something went wrong when unmarshalling user creds:", err)
}
@@ -50,23 +53,13 @@ func GetUserCredsFromKeyRing(userEmail string) (credentials models.UserCredentia
func IsUserLoggedIn() (hasUserLoggedIn bool, theUsersEmail string, err error) {
if ConfigFileExists() {
fullConfigFilePath, _, err := GetFullConfigFilePath()
configFile, err := GetConfigFile()
if err != nil {
log.Debugln("Error gettting full path:", err)
return false, "", err
return false, "", fmt.Errorf("IsUserLoggedIn: unable to get logged in user from config file [err=%s]", err)
}
configFileAsBytes, err := os.ReadFile(fullConfigFilePath)
if err != nil {
log.Debugln("Unable to read config file:", err)
return false, "", err
}
var configFile models.ConfigFile
err = json.Unmarshal(configFileAsBytes, &configFile)
if err != nil {
log.Debugln("Unable to unmarshal config file:", err)
return false, "", err
if configFile.LoggedInUserEmail == "" {
return false, "", nil
}
userCreds, err := GetUserCredsFromKeyRing(configFile.LoggedInUserEmail)
+71
View File
@@ -0,0 +1,71 @@
package util
import (
"fmt"
"os"
"github.com/99designs/keyring"
log "github.com/sirupsen/logrus"
"golang.org/x/term"
)
// Keyring instance
var keyringInstance keyring.Keyring
var keyringInstanceConfig keyring.Config
func GetCurrentVaultBackend() (keyring.BackendType, error) {
configFile, err := GetConfigFile()
if err != nil {
return "", fmt.Errorf("getCurrentVaultBackend: unable to get config file [err=%s]", err)
}
if configFile.VaultBackendType == "" {
if keyring.AvailableBackends()[0] == keyring.FileBackend {
}
return keyring.AvailableBackends()[0], nil
}
return configFile.VaultBackendType, nil
}
func InitKeyRingInstance() {
currentVaultBackend, err := GetCurrentVaultBackend()
if err != nil {
log.Infof("InitKeyRingInstance: unable to get the current vault backend, [err=%s]", err)
}
keyringInstanceConfig = keyring.Config{
FilePasswordFunc: fileKeyringPassphrasePrompt,
ServiceName: SERVICE_NAME,
LibSecretCollectionName: SERVICE_NAME,
KWalletAppID: SERVICE_NAME,
KWalletFolder: SERVICE_NAME,
KeychainTrustApplication: true,
WinCredPrefix: SERVICE_NAME,
FileDir: fmt.Sprintf("~/%s-file-vault", SERVICE_NAME),
KeychainAccessibleWhenUnlocked: true,
}
// if the user explicitly sets a vault backend, then only use that
if currentVaultBackend != "" {
keyringInstanceConfig.AllowedBackends = []keyring.BackendType{keyring.BackendType(currentVaultBackend)}
}
keyringInstance, err = keyring.Open(keyringInstanceConfig)
if err != nil {
log.Errorf("InitKeyRingInstance: Unable to create instance of Keyring because of [err=%s]", err)
}
}
func fileKeyringPassphrasePrompt(prompt string) (string, error) {
if password, ok := os.LookupEnv("INFISICAL_VAULT_FILE_PASSPHRASE"); ok {
return password, nil
}
fmt.Fprintf(os.Stderr, "%s: ", prompt)
b, err := term.ReadPassword(int(os.Stdin.Fd()))
if err != nil {
return "", err
}
return string(b), nil
}