Skip to content

Commit

Permalink
Add service token v2 api into cli
Browse files Browse the repository at this point in the history
  • Loading branch information
maidul98 committed Jan 5, 2023
1 parent c921eb8 commit 764636c
Show file tree
Hide file tree
Showing 12 changed files with 344 additions and 139 deletions.
8 changes: 5 additions & 3 deletions cli/packages/cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"fmt"
"regexp"

"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"
"github.com/Infisical/infisical-merge/packages/util"
Expand Down Expand Up @@ -76,7 +78,7 @@ var loginCmd = &cobra.Command{
paddedPassword := fmt.Sprintf("%032s", password)
key := []byte(paddedPassword)

decryptedPrivateKey, err := util.DecryptSymmetric(key, encryptedPrivateKey, tag, IV)
decryptedPrivateKey, err := crypto.DecryptSymmetric(key, encryptedPrivateKey, tag, IV)
if err != nil || len(decryptedPrivateKey) == 0 {
log.Errorln("There was an issue decrypting your keys")
log.Debugln(err)
Expand Down Expand Up @@ -178,7 +180,7 @@ func getFreshUserCredentials(email string, password string) (*models.LoginTwoRes
R().
SetBody(loginOneRequest).
SetResult(&loginOneResponseResult).
Post(fmt.Sprintf("%v/v1/auth/login1", util.INFISICAL_URL))
Post(fmt.Sprintf("%v/v1/auth/login1", config.INFISICAL_URL))

if err != nil {
return nil, err
Expand Down Expand Up @@ -214,7 +216,7 @@ func getFreshUserCredentials(email string, password string) (*models.LoginTwoRes
R().
SetBody(LoginTwoRequest).
SetResult(&loginTwoResponseResult).
Post(fmt.Sprintf("%v/v1/auth/login2", util.INFISICAL_URL))
Post(fmt.Sprintf("%v/v1/auth/login2", config.INFISICAL_URL))

if err != nil {
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions cli/packages/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package cmd
import (
"os"

"github.com/Infisical/infisical-merge/packages/util"
"github.com/Infisical/infisical-merge/packages/config"
"github.com/spf13/cobra"
)

Expand All @@ -30,7 +30,7 @@ func Execute() {
func init() {
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
rootCmd.PersistentFlags().BoolVarP(&debugLogging, "debug", "d", false, "Enable verbose logging")
rootCmd.PersistentFlags().StringVar(&util.INFISICAL_URL, "domain", "https://app.infisical.com/api", "Point the CLI to your own backend")
rootCmd.PersistentFlags().StringVar(&config.INFISICAL_URL, "domain", "http://localhost:8080/api", "Point the CLI to your own backend")
// rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
// }
}
2 changes: 0 additions & 2 deletions cli/packages/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ func executeSingleCommandWithEnvs(args []string, secrets []models.SingleEnvironm
numberOfSecretsInjected := fmt.Sprintf("\u2713 Injected %v Infisical secrets into your application process successfully", len(secrets))
log.Infof("\x1b[%dm%s\x1b[0m", 32, numberOfSecretsInjected)
log.Debugf("executing command: %s %s \n", command, strings.Join(argsForCommand, " "))
log.Debugln("Secrets injected:", secrets)

cmd := exec.Command(command, argsForCommand...)
cmd.Stdin = os.Stdin
Expand Down Expand Up @@ -158,7 +157,6 @@ func executeMultipleCommandWithEnvs(fullCommand string, secrets []models.SingleE
numberOfSecretsInjected := fmt.Sprintf("\u2713 Injected %v Infisical secrets into your application process successfully", len(secrets))
log.Infof("\x1b[%dm%s\x1b[0m", 32, numberOfSecretsInjected)
log.Debugf("executing command: %s %s %s \n", shell[0], shell[1], fullCommand)
log.Debugln("Secrets injected:", secrets)

return execCmd(cmd)
}
Expand Down
13 changes: 7 additions & 6 deletions cli/packages/cmd/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"crypto/sha256"

"github.com/Infisical/infisical-merge/packages/crypto"
"github.com/Infisical/infisical-merge/packages/http"
"github.com/Infisical/infisical-merge/packages/models"
"github.com/Infisical/infisical-merge/packages/util"
Expand Down Expand Up @@ -147,13 +148,13 @@ var secretsSetCmd = &cobra.Command{
return
}

encryptedWorkspaceKey, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.LatestKey.EncryptedKey)
encryptedWorkspaceKeySenderPublicKey, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.LatestKey.Sender.PublicKey)
encryptedWorkspaceKeyNonce, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.LatestKey.Nonce)
encryptedWorkspaceKey, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.EncryptedKey)
encryptedWorkspaceKeySenderPublicKey, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.Sender.PublicKey)
encryptedWorkspaceKeyNonce, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.Nonce)
currentUsersPrivateKey, _ := base64.StdEncoding.DecodeString(loggedInUserDetails.UserCredentials.PrivateKey)

// decrypt workspace key
plainTextEncryptionKey := util.DecryptAsymmetric(encryptedWorkspaceKey, encryptedWorkspaceKeyNonce, encryptedWorkspaceKeySenderPublicKey, currentUsersPrivateKey)
plainTextEncryptionKey := crypto.DecryptAsymmetric(encryptedWorkspaceKey, encryptedWorkspaceKeyNonce, encryptedWorkspaceKeySenderPublicKey, currentUsersPrivateKey)

// pull current secrets
secrets, err := util.GetAllEnvironmentVariables("", environmentName)
Expand Down Expand Up @@ -191,13 +192,13 @@ var secretsSetCmd = &cobra.Command{
value := splitKeyValueFromArg[1]

hashedKey := fmt.Sprintf("%x", sha256.Sum256([]byte(key)))
encryptedKey, err := util.EncryptSymmetric([]byte(key), []byte(plainTextEncryptionKey))
encryptedKey, err := crypto.EncryptSymmetric([]byte(key), []byte(plainTextEncryptionKey))
if err != nil {
log.Errorf("unable to encrypt your secrets [err=%v]", err)
}

hashedValue := fmt.Sprintf("%x", sha256.Sum256([]byte(value)))
encryptedValue, err := util.EncryptSymmetric([]byte(value), []byte(plainTextEncryptionKey))
encryptedValue, err := crypto.EncryptSymmetric([]byte(value), []byte(plainTextEncryptionKey))
if err != nil {
log.Errorf("unable to encrypt your secrets [err=%v]", err)
}
Expand Down
3 changes: 3 additions & 0 deletions cli/packages/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package config

var INFISICAL_URL = "http://localhost:8080/api"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package util
package crypto

import (
"crypto/aes"
Expand Down
43 changes: 30 additions & 13 deletions cli/packages/http/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package http
import (
"fmt"

"github.com/Infisical/infisical-merge/packages/config"
"github.com/Infisical/infisical-merge/packages/models"
"github.com/Infisical/infisical-merge/packages/util"
"github.com/go-resty/resty/v2"
)

func CallBatchModifySecretsByWorkspaceAndEnv(httpClient *resty.Client, request models.BatchModifySecretsByWorkspaceAndEnvRequest) error {
endpoint := fmt.Sprintf("%v/v2/secret/batch-modify/workspace/%v/environment/%v", util.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName)
endpoint := fmt.Sprintf("%v/v2/secret/batch-modify/workspace/%v/environment/%v", config.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName)
response, err := httpClient.
R().
SetBody(request).
Expand All @@ -27,7 +27,7 @@ func CallBatchModifySecretsByWorkspaceAndEnv(httpClient *resty.Client, request m
}

func CallBatchCreateSecretsByWorkspaceAndEnv(httpClient *resty.Client, request models.BatchCreateSecretsByWorkspaceAndEnvRequest) error {
endpoint := fmt.Sprintf("%v/v2/secret/batch-create/workspace/%v/environment/%v", util.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName)
endpoint := fmt.Sprintf("%v/v2/secret/batch-create/workspace/%v/environment/%v", config.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName)
response, err := httpClient.
R().
SetBody(request).
Expand All @@ -45,7 +45,7 @@ func CallBatchCreateSecretsByWorkspaceAndEnv(httpClient *resty.Client, request m
}

func CallBatchDeleteSecretsByWorkspaceAndEnv(httpClient *resty.Client, request models.BatchDeleteSecretsBySecretIdsRequest) error {
endpoint := fmt.Sprintf("%v/v2/secret/batch/workspace/%v/environment/%v", util.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName)
endpoint := fmt.Sprintf("%v/v2/secret/batch/workspace/%v/environment/%v", config.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName)
response, err := httpClient.
R().
SetBody(request).
Expand All @@ -63,7 +63,7 @@ func CallBatchDeleteSecretsByWorkspaceAndEnv(httpClient *resty.Client, request m
}

func CallGetEncryptedWorkspaceKey(httpClient *resty.Client, request models.GetEncryptedWorkspaceKeyRequest) (models.GetEncryptedWorkspaceKeyResponse, error) {
endpoint := fmt.Sprintf("%v/v1/key/%v/latest", util.INFISICAL_URL, request.WorkspaceId)
endpoint := fmt.Sprintf("%v/v2/workspace/%v/encrypted-key", config.INFISICAL_URL, request.WorkspaceId)
var result models.GetEncryptedWorkspaceKeyResponse
response, err := httpClient.
R().
Expand All @@ -81,22 +81,39 @@ func CallGetEncryptedWorkspaceKey(httpClient *resty.Client, request models.GetEn
return result, nil
}

func CallGetEncryptedSecretsByWorkspaceIdAndEnv(httpClient resty.Client, request models.GetSecretsByWorkspaceIdAndEnvironmentRequest) (models.PullSecretsResponse, error) {
var pullSecretsRequestResponse models.PullSecretsResponse
func CallGetServiceTokenDetailsV2(httpClient *resty.Client) (models.GetServiceTokenDetailsResponse, error) {
var tokenDetailsResponse models.GetServiceTokenDetailsResponse
response, err := httpClient.
R().
SetResult(&tokenDetailsResponse).
Get(fmt.Sprintf("%v/v2/service-token", config.INFISICAL_URL))

if err != nil {
return models.GetServiceTokenDetailsResponse{}, fmt.Errorf("CallGetServiceTokenDetails: Unable to complete api request [err=%s]", err)
}

if response.StatusCode() > 299 {
return models.GetServiceTokenDetailsResponse{}, fmt.Errorf("CallGetServiceTokenDetails: Unsuccessful response: [response=%s]", response)
}

return tokenDetailsResponse, nil
}

func CallGetSecretsV2(httpClient *resty.Client, request models.GetEncryptedSecretsV2Request) (models.GetEncryptedSecretsV2Response, error) {
var secretsResponse models.GetEncryptedSecretsV2Response
response, err := httpClient.
R().
SetResult(&secretsResponse).
SetQueryParam("environment", request.EnvironmentName).
SetQueryParam("channel", "cli").
SetResult(&pullSecretsRequestResponse).
Get(fmt.Sprintf("%v/v1/secret/%v", util.INFISICAL_URL, request.WorkspaceId))
Get(fmt.Sprintf("%v/v2/secret/workspace/%v", config.INFISICAL_URL, request.WorkspaceId))

if err != nil {
return models.PullSecretsResponse{}, fmt.Errorf("CallGetEncryptedSecretsByWorkspaceIdAndEnv: Unable to complete api request [err=%s]", err)
return models.GetEncryptedSecretsV2Response{}, fmt.Errorf("CallGetSecretsV2: Unable to complete api request [err=%s]", err)
}

if response.StatusCode() > 299 {
return models.PullSecretsResponse{}, fmt.Errorf("CallGetEncryptedSecretsByWorkspaceIdAndEnv: Unsuccessful response: [response=%s]", response)
return models.GetEncryptedSecretsV2Response{}, fmt.Errorf("CallGetSecretsV2: Unsuccessful response: [response=%s]", response)
}

return pullSecretsRequestResponse, nil
return secretsResponse, nil
}
80 changes: 59 additions & 21 deletions cli/packages/models/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,30 +169,68 @@ type GetEncryptedWorkspaceKeyRequest struct {
}

type GetEncryptedWorkspaceKeyResponse struct {
LatestKey struct {
ID string `json:"_id"`
EncryptedKey string `json:"encryptedKey"`
Nonce string `json:"nonce"`
Sender struct {
ID string `json:"_id"`
Email string `json:"email"`
RefreshVersion int `json:"refreshVersion"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
V int `json:"__v"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
PublicKey string `json:"publicKey"`
} `json:"sender"`
Receiver string `json:"receiver"`
Workspace string `json:"workspace"`
V int `json:"__v"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
} `json:"latestKey"`
ID string `json:"_id"`
EncryptedKey string `json:"encryptedKey"`
Nonce string `json:"nonce"`
Sender struct {
ID string `json:"_id"`
Email string `json:"email"`
RefreshVersion int `json:"refreshVersion"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
V int `json:"__v"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
PublicKey string `json:"publicKey"`
} `json:"sender"`
Receiver string `json:"receiver"`
Workspace string `json:"workspace"`
V int `json:"__v"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}

type GetSecretsByWorkspaceIdAndEnvironmentRequest struct {
EnvironmentName string `json:"environmentName"`
WorkspaceId string `json:"workspaceId"`
}

type GetEncryptedSecretsV2Request struct {
EnvironmentName string `json:"environmentName"`
WorkspaceId string `json:"workspaceId"`
}

type GetEncryptedSecretsV2Response []struct {
ID string `json:"_id"`
Version int `json:"version"`
Workspace string `json:"workspace"`
Type string `json:"type"`
Environment string `json:"environment"`
SecretKeyCiphertext string `json:"secretKeyCiphertext"`
SecretKeyIV string `json:"secretKeyIV"`
SecretKeyTag string `json:"secretKeyTag"`
SecretKeyHash string `json:"secretKeyHash"`
SecretValueCiphertext string `json:"secretValueCiphertext"`
SecretValueIV string `json:"secretValueIV"`
SecretValueTag string `json:"secretValueTag"`
SecretValueHash string `json:"secretValueHash"`
SecretCommentCiphertext string `json:"secretCommentCiphertext"`
SecretCommentIV string `json:"secretCommentIV"`
SecretCommentTag string `json:"secretCommentTag"`
SecretCommentHash string `json:"secretCommentHash"`
V int `json:"__v"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
User string `json:"user,omitempty"`
}

type GetServiceTokenDetailsResponse struct {
ID string `json:"_id"`
Name string `json:"name"`
Workspace string `json:"workspace"`
Environment string `json:"environment"`
User string `json:"user"`
EncryptedKey string `json:"encryptedKey"`
Iv string `json:"iv"`
Tag string `json:"tag"`
}
2 changes: 0 additions & 2 deletions cli/packages/util/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ const (
SECRET_TYPE_SHARED = "shared"
)

var INFISICAL_URL = "https://app.infisical.com/api"

func GetHomeDir() (string, error) {
directory, err := os.UserHomeDir()
return directory, err
Expand Down
5 changes: 3 additions & 2 deletions cli/packages/util/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"

"github.com/99designs/keyring"
"github.com/Infisical/infisical-merge/packages/config"
"github.com/Infisical/infisical-merge/packages/models"
"github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -92,7 +93,7 @@ func IsUserLoggedIn() (hasUserLoggedIn bool, theUsersEmail string, err error) {

response, err := httpClient.
R().
Post(fmt.Sprintf("%v/v1/auth/checkAuth", INFISICAL_URL))
Post(fmt.Sprintf("%v/v1/auth/checkAuth", config.INFISICAL_URL))

if err != nil {
return false, "", err
Expand Down Expand Up @@ -132,7 +133,7 @@ func GetCurrentLoggedInUserDetails() (LoggedInUserDetails, error) {

response, err := httpClient.
R().
Post(fmt.Sprintf("%v/v1/auth/checkAuth", INFISICAL_URL))
Post(fmt.Sprintf("%v/v1/auth/checkAuth", config.INFISICAL_URL))

if err != nil {
return LoggedInUserDetails{}, err
Expand Down
56 changes: 56 additions & 0 deletions cli/packages/util/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package util

import (
"encoding/base64"
"fmt"
)

type DecodedSymmetricEncryptionDetails = struct {
Cipher []byte
IV []byte
Tag []byte
Key []byte
}

func GetBase64DecodedSymmetricEncryptionDetails(key string, cipher string, IV string, tag string) (DecodedSymmetricEncryptionDetails, error) {
cipherx, err := base64.StdEncoding.DecodeString(cipher)
if err != nil {
return DecodedSymmetricEncryptionDetails{}, fmt.Errorf("Base64DecodeSymmetricEncryptionDetails: Unable to decode cipher text [err=%v]", err)
}

keyx, err := base64.StdEncoding.DecodeString(key)
if err != nil {
return DecodedSymmetricEncryptionDetails{}, fmt.Errorf("Base64DecodeSymmetricEncryptionDetails: Unable to decode key [err=%v]", err)
}

IVx, err := base64.StdEncoding.DecodeString(IV)
if err != nil {
return DecodedSymmetricEncryptionDetails{}, fmt.Errorf("Base64DecodeSymmetricEncryptionDetails: Unable to decode IV [err=%v]", err)
}

tagx, err := base64.StdEncoding.DecodeString(tag)
if err != nil {
return DecodedSymmetricEncryptionDetails{}, fmt.Errorf("Base64DecodeSymmetricEncryptionDetails: Unable to decode tag [err=%v]", err)
}

return DecodedSymmetricEncryptionDetails{
Key: keyx,
Cipher: cipherx,
IV: IVx,
Tag: tagx,
}, nil
}

func IsSecretEnvironmentValid(env string) bool {
if env == "prod" || env == "dev" || env == "test" || env == "staging" {
return true
}
return false
}

func IsSecretTypeValid(s string) bool {
if s == "personal" || s == "shared" {
return true
}
return false
}
Loading

0 comments on commit 764636c

Please sign in to comment.