Skip to content

Commit beb3cdc

Browse files
committed
🗄 Allow encrypted values to be read from files in vault
1 parent 0ef1eb1 commit beb3cdc

File tree

10 files changed

+68
-41
lines changed

10 files changed

+68
-41
lines changed

‎cmd/info/env.go‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import (
66
"sort"
77
"strings"
88

9+
"github.com/spf13/cobra"
10+
911
"github.com/kloudkit/ws-cli/internals/env"
1012
"github.com/kloudkit/ws-cli/internals/styles"
11-
"github.com/spf13/cobra"
1213
)
1314

1415
func showEnvironment(writer io.Writer) {

‎cmd/info/extensions.go‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import (
44
"bufio"
55
"bytes"
66
"fmt"
7-
"github.com/kloudkit/ws-cli/internals/styles"
8-
"github.com/spf13/cobra"
97
"io"
108
"os/exec"
119
"strings"
10+
11+
"github.com/spf13/cobra"
12+
13+
"github.com/kloudkit/ws-cli/internals/styles"
1214
)
1315

1416
func fetchExtensions() [][]string {

‎cmd/info/info.go‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import (
66
"io"
77
"os"
88

9+
"github.com/spf13/cobra"
10+
911
"github.com/kloudkit/ws-cli/internals/config"
1012
internalIO "github.com/kloudkit/ws-cli/internals/io"
1113
"github.com/kloudkit/ws-cli/internals/styles"
12-
"github.com/spf13/cobra"
1314
)
1415

1516
type Manifest struct {

‎cmd/info/resources.go‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import (
99
"syscall"
1010
"time"
1111

12-
"github.com/kloudkit/ws-cli/internals/styles"
1312
"github.com/spf13/cobra"
13+
14+
"github.com/kloudkit/ws-cli/internals/styles"
1415
)
1516

1617
type resources struct {

‎cmd/info/uptime.go‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package info
33
import (
44
"fmt"
55
"io"
6-
7-
"github.com/kloudkit/ws-cli/internals/styles"
8-
"github.com/spf13/cobra"
96
"os"
107
"strings"
118
"time"
9+
10+
"github.com/spf13/cobra"
11+
12+
"github.com/kloudkit/ws-cli/internals/styles"
1213
)
1314

1415
func readStartup() (time.Time, time.Duration, error) {
@@ -60,11 +61,12 @@ func showUptime(writer io.Writer) {
6061
}
6162

6263
var statusValue string
63-
if running.Hours() < 1 {
64+
switch {
65+
case running.Hours() < 1:
6466
statusValue = "Recently started"
65-
} else if running.Hours() < 36 {
67+
case running.Hours() < 36:
6668
statusValue = "Active"
67-
} else {
69+
default:
6870
statusValue = "Long running"
6971
}
7072

‎cmd/info/version.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package info
22

3-
var Version = "0.0.43"
3+
var Version = "0.0.44"

‎cmd/logs/logs.go‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@ package logs
22

33
import (
44
"fmt"
5+
"slices"
6+
7+
"github.com/spf13/cobra"
58

69
"github.com/kloudkit/ws-cli/internals/logger"
710
"github.com/kloudkit/ws-cli/internals/styles"
8-
"github.com/spf13/cobra"
911
)
1012

13+
var validLogLevels = []string{"debug", "info", "warn", "error"}
14+
1115
var LogsCmd = &cobra.Command{
1216
Use: "logs",
1317
Short: "Retrieve workspace logs",
@@ -20,7 +24,7 @@ func execute(cmd *cobra.Command, args []string) error {
2024
tail, _ := cmd.Flags().GetInt("tail")
2125
level, _ := cmd.Flags().GetString("level")
2226

23-
if level != "" && level != "info" && level != "warn" && level != "error" && level != "debug" {
27+
if level != "" && !slices.Contains(validLogLevels, level) {
2428
styles.PrintErrorWithOptions(cmd.ErrOrStderr(), "Invalid log level. Must be one of:", [][]string{
2529
{"debug", "Debug information"},
2630
{"info", "General information"},

‎internals/io/password.go‎

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,32 @@ func ReadPasswordInput() (string, error) {
1414
}
1515

1616
func ReadPasswordFromReader(reader io.Reader) (string, error) {
17-
if file, ok := reader.(*os.File); ok {
18-
stat, err := file.Stat()
19-
if err != nil {
20-
return "", fmt.Errorf("failed to stat stdin: %w", err)
21-
}
22-
23-
if (stat.Mode() & os.ModeCharDevice) == 0 {
24-
data, err := io.ReadAll(file)
25-
if err != nil {
26-
return "", fmt.Errorf("failed to read from stdin: %w", err)
27-
}
28-
password := string(data)
29-
if strings.TrimSpace(password) == "" {
30-
return "", fmt.Errorf("empty password provided")
31-
}
32-
return password, nil
33-
}
34-
35-
fmt.Fprint(os.Stderr, "Enter password: ")
36-
passwordBytes, err := term.ReadPassword(int(file.Fd()))
37-
fmt.Fprintln(os.Stderr)
38-
if err != nil {
39-
return "", fmt.Errorf("failed to read password: %w", err)
40-
}
41-
42-
return string(passwordBytes), nil
17+
file, ok := reader.(*os.File)
18+
if !ok {
19+
return readPasswordFromStream(reader)
4320
}
4421

22+
stat, err := file.Stat()
23+
if err != nil {
24+
return "", fmt.Errorf("failed to stat stdin: %w", err)
25+
}
26+
27+
isTerminal := (stat.Mode() & os.ModeCharDevice) != 0
28+
if !isTerminal {
29+
return readPasswordFromStream(file)
30+
}
31+
32+
fmt.Fprint(os.Stderr, "Enter password: ")
33+
passwordBytes, err := term.ReadPassword(int(file.Fd()))
34+
fmt.Fprintln(os.Stderr)
35+
if err != nil {
36+
return "", fmt.Errorf("failed to read password: %w", err)
37+
}
38+
39+
return string(passwordBytes), nil
40+
}
41+
42+
func readPasswordFromStream(reader io.Reader) (string, error) {
4543
data, err := io.ReadAll(reader)
4644
if err != nil {
4745
return "", fmt.Errorf("failed to read from stdin: %w", err)

‎internals/secrets/crypto.go‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"encoding/base64"
88
"fmt"
99
"io"
10+
"os"
1011
"strings"
1112

1213
"golang.org/x/crypto/argon2"
@@ -53,6 +54,20 @@ func NormalizeEncrypted(encrypted string) string {
5354
return encrypted
5455
}
5556

57+
func ResolveEncryptedValue(encrypted string) (string, error) {
58+
if !strings.HasPrefix(encrypted, "file:") {
59+
return encrypted, nil
60+
}
61+
62+
filePath := strings.TrimPrefix(encrypted, "file:")
63+
content, err := os.ReadFile(filePath)
64+
if err != nil {
65+
return "", fmt.Errorf("failed to read encrypted file %s: %w", filePath, err)
66+
}
67+
68+
return NormalizeEncrypted(string(content)), nil
69+
}
70+
5671
func Decrypt(encodedValue string, masterKey []byte) ([]byte, error) {
5772
parts := strings.Split(encodedValue, "$")
5873
if len(parts) != 2 {

‎internals/secrets/vault.go‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,10 @@ func ProcessVault(vault *Vault, opts ProcessOptions) (map[string]string, error)
213213

214214
effectiveForce := opts.Force || secret.Force
215215

216-
encryptedValue := NormalizeEncrypted(secret.Encrypted)
216+
encryptedValue, err := ResolveEncryptedValue(secret.Encrypted)
217+
if err != nil {
218+
return nil, fmt.Errorf("failed to resolve encrypted value for %q: %w", key, err)
219+
}
217220

218221
decrypted, err := Decrypt(encryptedValue, opts.MasterKey)
219222
if err != nil {

0 commit comments

Comments
 (0)