diff --git a/internal/vault/client.go b/internal/vault/client.go index 7fbda61..bc28c5e 100644 --- a/internal/vault/client.go +++ b/internal/vault/client.go @@ -115,6 +115,7 @@ func (c Client) listDir(mount string, name string) ([]dirEnt, error) { } type Secret struct { + Url string `json:"url"` Data struct { Data map[string]interface{} `json:"data"` Metadata map[string]interface{} `json:"metadata"` @@ -154,6 +155,7 @@ func (c Client) GetSecret(mount, name string) Secret { if response.StatusCode != 200 && isErrorForRealForReal { panic(fmt.Errorf("Got %s on url %s", response.Status, url)) } + secret.Url = fmt.Sprintf("%s/ui/vault/secrets/%s/show%s", c.Addr, mount, name) cachedSecrets[name] = secret return secret } diff --git a/internal/vault/client_test.go b/internal/vault/client_test.go index 9eea4b8..0fee3cb 100644 --- a/internal/vault/client_test.go +++ b/internal/vault/client_test.go @@ -77,6 +77,10 @@ func TestGetSecret(t *testing.T) { if !found || data != "d" { t.Fatalf("Expected secret to have data `c=d`, got %v", secret.Data.Data) } + expectedUrl := "http://127.0.0.1:8200/ui/vault/secrets/secret/show/bar/baz" + if secret.Url != expectedUrl { + t.Fatalf("Expected url to be %s, got %s", expectedUrl, secret.Url) + } } func startVault(token, addr string) (*exec.Cmd, error) { diff --git a/main.go b/main.go index f1cfd6c..12d8576 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "log" "log/slog" "os" + "os/exec" "reflect" "slices" "strings" @@ -145,6 +146,8 @@ func main() { ui.Result = bytes } return + case tcell.KeyCtrlO: + ui.openInBrowser() case tcell.KeyBackspace, tcell.KeyBackspace2: if len(ui.Prompt) > 0 { ui.Prompt = ui.Prompt[:len(ui.Prompt)-1] @@ -409,6 +412,14 @@ func (u *Ui) previousMount() { u.newKeysView() } +func (u *Ui) openInBrowser() { + url := u.Secret.Url + cmd := exec.Command("open", url) + if err := cmd.Run(); err != nil { + slog.Error("Failed to open secret in browser", "err", err, "url", url) + } +} + func matchesPrompt(prompt, s string) (bool, int) { if len(prompt) == 0 { return true, 0 @@ -436,4 +447,3 @@ func matchesPrompt(prompt, s string) (bool, int) { } // TODO: Handle panic when no secrets are found, usually due to incorrect vault token -// TODO: Print the url to the secret on pressing enter