Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions cmd/auth_get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package cmd

import (
"fmt"

"github.com/loops-so/cli/internal/config"
"github.com/spf13/cobra"
)

var authGetCmd = &cobra.Command{
Use: "get <name>",
Short: "Print a stored API key",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
name := args[0]
key, err := runAuthGet(name)
if err != nil {
return err
}

if isJSONOutput() {
return printJSON(cmd.OutOrStdout(), struct {
Name string `json:"name"`
APIKey string `json:"apiKey"`
}{name, key})
}

fmt.Fprintln(cmd.OutOrStdout(), key)
return nil
},
}

func runAuthGet(name string) (string, error) {
return config.Get(name)
}

func init() {
authCmd.AddCommand(authGetCmd)
}
38 changes: 38 additions & 0 deletions cmd/auth_get_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package cmd

import (
"testing"

"github.com/loops-so/cli/internal/config"
)

func TestRunAuthGet(t *testing.T) {
t.Run("returns stored key", func(t *testing.T) {
mockKeyring(t)
config.Save("key-abc1234", "acme")

key, err := runAuthGet("acme")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if key != "key-abc1234" {
t.Errorf("got %q, want %q", key, "key-abc1234")
}
})

t.Run("returns error when key does not exist", func(t *testing.T) {
mockKeyring(t)

if _, err := runAuthGet("nonexistent"); err == nil {
t.Fatal("expected error, got nil")
}
})

t.Run("returns error when name is empty", func(t *testing.T) {
mockKeyring(t)

if _, err := runAuthGet(""); err == nil {
t.Fatal("expected error, got nil")
}
})
}
18 changes: 18 additions & 0 deletions internal/config/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,24 @@ func ListKeys() ([]KeyEntry, error) {
return entries, nil
}

func Get(name string) (string, error) {
if name == "" {
return "", errors.New("a name is required")
}
pc, err := LoadPersistentConfig()
if err != nil {
return "", err
}
if !slices.Contains(pc.Teams, name) {
return "", fmt.Errorf("no key named %q — run `loops auth list` to see available keys", name)
}
key, err := keyring.Get(keyringService, "key:"+name)
if err != nil {
return "", fmt.Errorf("could not read key %q: %w", name, err)
}
return key, nil
}

func Delete(name string) error {
if name == "" {
return errors.New("a name is required — use --name to specify which key to remove")
Expand Down