diff --git a/client/config.go b/client/config.go index edb52121..d4337d47 100644 --- a/client/config.go +++ b/client/config.go @@ -12,19 +12,22 @@ const ( // Config is the config struct for a Client type Config struct { - DefaultHost string `yaml:"default-host"` - DefaultUser string `yaml:"default-user"` - DefaultPassword *string `yaml:"default-password"` - DefaultToken string `yaml:"default-token"` - DefaultCommand string `yaml:"default-command"` - Subscribe []struct { - Topic string `yaml:"topic"` - User string `yaml:"user"` - Password *string `yaml:"password"` - Token string `yaml:"token"` - Command string `yaml:"command"` - If map[string]string `yaml:"if"` - } `yaml:"subscribe"` + DefaultHost string `yaml:"default-host"` + DefaultUser string `yaml:"default-user"` + DefaultPassword *string `yaml:"default-password"` + DefaultToken string `yaml:"default-token"` + DefaultCommand string `yaml:"default-command"` + Subscribe []Subscribe `yaml:"subscribe"` +} + +// Subscribe is the struct for a Subscription within Config +type Subscribe struct { + Topic string `yaml:"topic"` + User string `yaml:"user"` + Password *string `yaml:"password"` + Token string `yaml:"token"` + Command string `yaml:"command"` + If map[string]string `yaml:"if"` } // NewConfig creates a new Config struct for a Client diff --git a/cmd/subscribe.go b/cmd/subscribe.go index 36a4e48c..dae06ae2 100644 --- a/cmd/subscribe.go +++ b/cmd/subscribe.go @@ -156,6 +156,9 @@ func execSubscribe(c *cli.Context) error { func doPoll(c *cli.Context, cl *client.Client, conf *client.Config, topic, command string, options ...client.SubscribeOption) error { for _, s := range conf.Subscribe { // may be nil + if auth := maybeAddAuthHeader(s, conf); auth != nil { + options = append(options, auth) + } if err := doPollSingle(c, cl, s.Topic, s.Command, options...); err != nil { return err } @@ -187,29 +190,8 @@ func doSubscribe(c *cli.Context, cl *client.Client, conf *client.Config, topic, topicOptions = append(topicOptions, client.WithFilter(filter, value)) } - // check for subscription token then subscription user:pass - var authSet bool - if s.Token != "" { - topicOptions = append(topicOptions, client.WithBearerAuth(s.Token)) - authSet = true - } else { - if s.User != "" && s.Password != nil { - topicOptions = append(topicOptions, client.WithBasicAuth(s.User, *s.Password)) - authSet = true - } - } - - // if no subscription token nor subscription user:pass, check for default token then default user:pass - if !authSet { - if conf.DefaultToken != "" { - topicOptions = append(topicOptions, client.WithBearerAuth(conf.DefaultToken)) - authSet = true - } else { - if conf.DefaultUser != "" && conf.DefaultPassword != nil { - topicOptions = append(topicOptions, client.WithBasicAuth(conf.DefaultUser, *conf.DefaultPassword)) - authSet = true - } - } + if auth := maybeAddAuthHeader(s, conf); auth != nil { + topicOptions = append(topicOptions, auth) } subscriptionID := cl.Subscribe(s.Topic, topicOptions...) @@ -236,6 +218,25 @@ func doSubscribe(c *cli.Context, cl *client.Client, conf *client.Config, topic, return nil } +func maybeAddAuthHeader(s client.Subscribe, conf *client.Config) client.SubscribeOption { + // check for subscription token then subscription user:pass + if s.Token != "" { + return client.WithBearerAuth(s.Token) + } + if s.User != "" && s.Password != nil { + return client.WithBasicAuth(s.User, *s.Password) + } + + // if no subscription token nor subscription user:pass, check for default token then default user:pass + if conf.DefaultToken != "" { + return client.WithBearerAuth(conf.DefaultToken) + } + if conf.DefaultUser != "" && conf.DefaultPassword != nil { + return client.WithBasicAuth(conf.DefaultUser, *conf.DefaultPassword) + } + return nil +} + func printMessageOrRunCommand(c *cli.Context, m *client.Message, command string) { if command != "" { runCommand(c, command, m) diff --git a/cmd/subscribe_test.go b/cmd/subscribe_test.go index 26ab55ea..a22b0c97 100644 --- a/cmd/subscribe_test.go +++ b/cmd/subscribe_test.go @@ -9,7 +9,6 @@ import ( "path/filepath" "strings" "testing" - "time" ) func TestCLI_Subscribe_Default_UserPass_Subscription_Token(t *testing.T) { @@ -35,9 +34,7 @@ subscribe: app, _, stdout, _ := newTestApp() - go app.Run([]string{"ntfy", "subscribe", "--from-config", "--config=" + filename}) - // Sleep to give the app time to subscribe - time.Sleep(time.Millisecond * 100) + require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename})) require.Equal(t, message, strings.TrimSpace(stdout.String())) } @@ -65,9 +62,7 @@ subscribe: app, _, stdout, _ := newTestApp() - go app.Run([]string{"ntfy", "subscribe", "--from-config", "--config=" + filename}) - // Sleep to give the app time to subscribe - time.Sleep(time.Millisecond * 100) + require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename})) require.Equal(t, message, strings.TrimSpace(stdout.String())) } @@ -94,9 +89,7 @@ subscribe: app, _, stdout, _ := newTestApp() - go app.Run([]string{"ntfy", "subscribe", "--from-config", "--config=" + filename}) - // Sleep to give the app time to subscribe - time.Sleep(time.Millisecond * 100) + require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename})) require.Equal(t, message, strings.TrimSpace(stdout.String())) } @@ -125,9 +118,7 @@ subscribe: app, _, stdout, _ := newTestApp() - go app.Run([]string{"ntfy", "subscribe", "--from-config", "--config=" + filename}) - // Sleep to give the app time to subscribe - time.Sleep(time.Millisecond * 100) + require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename})) require.Equal(t, message, strings.TrimSpace(stdout.String())) } @@ -153,9 +144,7 @@ subscribe: app, _, stdout, _ := newTestApp() - go app.Run([]string{"ntfy", "subscribe", "--from-config", "--config=" + filename}) - // Sleep to give the app time to subscribe - time.Sleep(time.Millisecond * 100) + require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename})) require.Equal(t, message, strings.TrimSpace(stdout.String())) } @@ -182,9 +171,7 @@ subscribe: app, _, stdout, _ := newTestApp() - go app.Run([]string{"ntfy", "subscribe", "--from-config", "--config=" + filename}) - // Sleep to give the app time to subscribe - time.Sleep(time.Millisecond * 100) + require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename})) require.Equal(t, message, strings.TrimSpace(stdout.String())) } @@ -210,9 +197,7 @@ subscribe: app, _, stdout, _ := newTestApp() - go app.Run([]string{"ntfy", "subscribe", "--from-config", "--config=" + filename}) - // Sleep to give the app time to subscribe - time.Sleep(time.Millisecond * 100) + require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename})) require.Equal(t, message, strings.TrimSpace(stdout.String())) } @@ -239,9 +224,7 @@ subscribe: app, _, stdout, _ := newTestApp() - go app.Run([]string{"ntfy", "subscribe", "--from-config", "--config=" + filename}) - // Sleep to give the app time to subscribe - time.Sleep(time.Millisecond * 100) + require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename})) require.Equal(t, message, strings.TrimSpace(stdout.String())) } @@ -265,9 +248,7 @@ default-token: tk_FAKETOKEN0123456789FAKETOKEN app, _, stdout, _ := newTestApp() - go app.Run([]string{"ntfy", "subscribe", "--from-config", "--config=" + filename, "--token", "tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2", "mytopic"}) - // Sleep to give the app time to subscribe - time.Sleep(time.Millisecond * 100) + require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename, "--token", "tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2", "mytopic"})) require.Equal(t, message, strings.TrimSpace(stdout.String())) } @@ -291,16 +272,41 @@ default-token: tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2 app, _, stdout, _ := newTestApp() - go app.Run([]string{"ntfy", "subscribe", "--from-config", "--config=" + filename, "--user", "philipp:mypass", "mytopic"}) - // Sleep to give the app time to subscribe - time.Sleep(time.Millisecond * 100) + require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename, "--user", "philipp:mypass", "mytopic"})) + + require.Equal(t, message, strings.TrimSpace(stdout.String())) +} + +func TestCLI_Subscribe_Default_Token_Subscription_Token_CLI_UserPass(t *testing.T) { + message := `{"id":"RXIQBFaieLVr","time":124,"expires":1124,"event":"message","topic":"mytopic","message":"triggered"}` + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "/mytopic/json", r.URL.Path) + require.Equal(t, "Bearer tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2", r.Header.Get("Authorization")) + + w.WriteHeader(http.StatusOK) + w.Write([]byte(message)) + })) + defer server.Close() + + filename := filepath.Join(t.TempDir(), "client.yml") + require.Nil(t, os.WriteFile(filename, []byte(fmt.Sprintf(` +default-host: %s +default-token: tk_FAKETOKEN01234567890FAKETOKEN +subscribe: + - topic: mytopic + token: tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2 +`, server.URL)), 0600)) + + app, _, stdout, _ := newTestApp() + + require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename, "--user", "philipp:mypass"})) require.Equal(t, message, strings.TrimSpace(stdout.String())) } func TestCLI_Subscribe_Token_And_UserPass(t *testing.T) { app, _, _, _ := newTestApp() - err := app.Run([]string{"ntfy", "subscribe", "--token", "tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2", "--user", "philipp:mypass", "mytopic", "triggered"}) + err := app.Run([]string{"ntfy", "subscribe", "--poll", "--token", "tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2", "--user", "philipp:mypass", "mytopic", "triggered"}) require.Error(t, err) require.Equal(t, "cannot set both --user and --token", err.Error()) }