diff --git a/pkg/cmd/auth/status/status.go b/pkg/cmd/auth/status/status.go index 5acf384..f32c586 100644 --- a/pkg/cmd/auth/status/status.go +++ b/pkg/cmd/auth/status/status.go @@ -15,6 +15,7 @@ type StatusOptions struct { IO *iostreams.IOStreams ConfigPath string HTTPClient *http.Client + Host string // filter to specific host (optional) } // NewCmdStatus creates the `copia auth status` command. @@ -29,6 +30,7 @@ func NewCmdStatus(f *cmdutil.Factory) *cobra.Command { opts.IO = f.IOStreams opts.ConfigPath = config.DefaultPath() opts.HTTPClient = &http.Client{} + opts.Host = f.Host return StatusRun(opts) }, } @@ -46,7 +48,17 @@ func StatusRun(opts *StatusOptions) error { return fmt.Errorf("not logged in to any Copia instance. Run 'copia auth login'") } + // If --host is specified, only show that host + if opts.Host != "" { + if _, ok := cfg.Hosts[opts.Host]; !ok { + return fmt.Errorf("not logged in to %s", opts.Host) + } + } + for host, hc := range cfg.Hosts { + if opts.Host != "" && host != opts.Host { + continue + } tokenStatus := "Token valid" if opts.HTTPClient != nil { url := fmt.Sprintf("https://%s/api/v1/user", host) diff --git a/pkg/cmd/auth/status/status_test.go b/pkg/cmd/auth/status/status_test.go index 3a2a04c..d1e57fc 100644 --- a/pkg/cmd/auth/status/status_test.go +++ b/pkg/cmd/auth/status/status_test.go @@ -60,6 +60,61 @@ func TestStatusRun_NoHosts(t *testing.T) { assert.Contains(t, err.Error(), "not logged in") } +func TestStatusRun_UnknownHost(t *testing.T) { + configPath := t.TempDir() + "/config.yml" + cfg := &config.Config{ + Hosts: map[string]*config.HostConfig{ + "app.copia.io": {Token: "abc123", User: "john"}, + }, + } + require.NoError(t, config.Save(configPath, cfg)) + + ios, _, _, _ := iostreams.Test() + + opts := &StatusOptions{ + IO: ios, + ConfigPath: configPath, + Host: "unknown.example.com", + } + + err := StatusRun(opts) + require.Error(t, err) + assert.Contains(t, err.Error(), "not logged in to unknown.example.com") +} + +func TestStatusRun_SpecificHost(t *testing.T) { + reg := &httpmock.Registry{} + defer reg.Verify(t) + + reg.Register( + httpmock.REST("GET", "/api/v1/user"), + httpmock.StringResponse(http.StatusOK, `{"login":"john","id":1}`), + ) + + configPath := t.TempDir() + "/config.yml" + cfg := &config.Config{ + Hosts: map[string]*config.HostConfig{ + "app.copia.io": {Token: "abc123", User: "john"}, + "other.copia.io": {Token: "xyz789", User: "jane"}, + }, + } + require.NoError(t, config.Save(configPath, cfg)) + + ios, _, stdout, _ := iostreams.Test() + + opts := &StatusOptions{ + IO: ios, + ConfigPath: configPath, + HTTPClient: &http.Client{Transport: reg}, + Host: "app.copia.io", + } + + err := StatusRun(opts) + require.NoError(t, err) + assert.Contains(t, stdout.String(), "app.copia.io") + assert.NotContains(t, stdout.String(), "other.copia.io") +} + func TestStatusRun_InvalidToken(t *testing.T) { reg := &httpmock.Registry{} defer reg.Verify(t)