Files
f.weber ae30ba1240 feat(vault-tui): implement KV client and service for managing secrets
- Added internal/vault/client.go for creating a Vault client with configuration settings.
- Introduced internal/vault/errors.go to classify Vault API errors for better UI handling.
- Created internal/vault/kv.go to manage KV secrets, including listing, reading, writing, and deleting operations.
- Implemented internal/vault/mounts.go to list and describe secret engine mounts.
- Developed internal/vault/service.go to provide a unified entry point for Vault operations.
- Added internal/vault/kv_test.go for comprehensive testing of KV operations.
- Introduced internal/ui/toast.go for transient notifications in the UI.
- Added renovate.json for dependency management and updates.
2026-08-14 11:09:03 +02:00

89 lines
2.2 KiB
Go

package token
import (
"context"
"strings"
"git.morlana.online/f.weber/vault-tui/internal/config"
)
// Source identifies which layer a resolved token came from.
type Source uint8
const (
SourceNone Source = iota
SourceFlag
SourceEnv
SourceConfig
SourceStore
)
func (s Source) String() string {
switch s {
case SourceFlag:
return "flag"
case SourceEnv:
return "env"
case SourceConfig:
return "config"
case SourceStore:
return "store"
default:
return "none"
}
}
// Resolved is the outcome of Resolve: the token plus enough provenance for
// the status bar to explain itself (a common source of confusion for any
// tool that shadows the Vault CLI's own ~/.vault-token).
//
// String/GoString are overridden so an accidental %v/%+v never leaks the
// token value into a log line.
type Resolved struct {
Token string
Source Source
Origin string // e.g. "VAULT_TOKEN", "~/.vault-token", "/usr/local/bin/vault-token-helper"
}
func (r Resolved) String() string {
if r.Token == "" {
return "<no token>"
}
return "<token via " + r.Origin + ">"
}
func (r Resolved) GoString() string { return r.String() }
// Options is the input to Resolve.
type Options struct {
Flag string // --token
Env string // VAULT_TOKEN, pre-read by the caller
Profile *config.Profile
Store Store // resolved by internal/cli from profile.token.storage
Getenv func(string) (string, bool)
}
// Resolve applies the precedence: --token flag > VAULT_TOKEN env >
// profile.token.value (discouraged) > the configured Store.
func Resolve(ctx context.Context, o Options) (Resolved, error) {
if v := strings.TrimSpace(o.Flag); v != "" {
return Resolved{Token: v, Source: SourceFlag, Origin: "--token"}, nil
}
if v := strings.TrimSpace(o.Env); v != "" {
return Resolved{Token: v, Source: SourceEnv, Origin: "VAULT_TOKEN"}, nil
}
if o.Profile != nil && o.Profile.Token.Value != "" {
return Resolved{Token: o.Profile.Token.Value, Source: SourceConfig, Origin: "config token.value"}, nil
}
if o.Store != nil {
tok, err := o.Store.Get(ctx)
if err != nil {
return Resolved{}, err
}
if tok != "" {
return Resolved{Token: tok, Source: SourceStore, Origin: o.Store.Location()}, nil
}
}
return Resolved{Source: SourceNone}, nil
}