fixes #829
parent
140fdcca81
commit
b80aec90d0
|
@ -7,7 +7,10 @@
|
||||||
|
|
||||||
# Default credentials will be used with "ntfy publish" and "ntfy subscribe" if no other credentials are provided.
|
# Default credentials will be used with "ntfy publish" and "ntfy subscribe" if no other credentials are provided.
|
||||||
# You can set a default token to use or a default user:password combination, but not both. For an empty password,
|
# You can set a default token to use or a default user:password combination, but not both. For an empty password,
|
||||||
# use empty double-quotes ("")
|
# use empty double-quotes ("").
|
||||||
|
#
|
||||||
|
# To override the default user:password combination or default token for a particular subscription (e.g., to send
|
||||||
|
# no Authorization header), set the user:pass/token for the subscription to empty double-quotes ("").
|
||||||
|
|
||||||
# default-token:
|
# default-token:
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,9 @@ type Config struct {
|
||||||
// Subscribe is the struct for a Subscription within Config
|
// Subscribe is the struct for a Subscription within Config
|
||||||
type Subscribe struct {
|
type Subscribe struct {
|
||||||
Topic string `yaml:"topic"`
|
Topic string `yaml:"topic"`
|
||||||
User string `yaml:"user"`
|
User *string `yaml:"user"`
|
||||||
Password *string `yaml:"password"`
|
Password *string `yaml:"password"`
|
||||||
Token string `yaml:"token"`
|
Token *string `yaml:"token"`
|
||||||
Command string `yaml:"command"`
|
Command string `yaml:"command"`
|
||||||
If map[string]string `yaml:"if"`
|
If map[string]string `yaml:"if"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ subscribe:
|
||||||
require.Equal(t, 4, len(conf.Subscribe))
|
require.Equal(t, 4, len(conf.Subscribe))
|
||||||
require.Equal(t, "no-command-with-auth", conf.Subscribe[0].Topic)
|
require.Equal(t, "no-command-with-auth", conf.Subscribe[0].Topic)
|
||||||
require.Equal(t, "", conf.Subscribe[0].Command)
|
require.Equal(t, "", conf.Subscribe[0].Command)
|
||||||
require.Equal(t, "phil", conf.Subscribe[0].User)
|
require.Equal(t, "phil", *conf.Subscribe[0].User)
|
||||||
require.Equal(t, "mypass", *conf.Subscribe[0].Password)
|
require.Equal(t, "mypass", *conf.Subscribe[0].Password)
|
||||||
require.Equal(t, "echo-this", conf.Subscribe[1].Topic)
|
require.Equal(t, "echo-this", conf.Subscribe[1].Topic)
|
||||||
require.Equal(t, `echo "Message received: $message"`, conf.Subscribe[1].Command)
|
require.Equal(t, `echo "Message received: $message"`, conf.Subscribe[1].Command)
|
||||||
|
@ -67,7 +67,7 @@ subscribe:
|
||||||
require.Equal(t, 1, len(conf.Subscribe))
|
require.Equal(t, 1, len(conf.Subscribe))
|
||||||
require.Equal(t, "no-command-with-auth", conf.Subscribe[0].Topic)
|
require.Equal(t, "no-command-with-auth", conf.Subscribe[0].Topic)
|
||||||
require.Equal(t, "", conf.Subscribe[0].Command)
|
require.Equal(t, "", conf.Subscribe[0].Command)
|
||||||
require.Equal(t, "phil", conf.Subscribe[0].User)
|
require.Equal(t, "phil", *conf.Subscribe[0].User)
|
||||||
require.Equal(t, "", *conf.Subscribe[0].Password)
|
require.Equal(t, "", *conf.Subscribe[0].Password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ subscribe:
|
||||||
require.Equal(t, 1, len(conf.Subscribe))
|
require.Equal(t, 1, len(conf.Subscribe))
|
||||||
require.Equal(t, "no-command-with-auth", conf.Subscribe[0].Topic)
|
require.Equal(t, "no-command-with-auth", conf.Subscribe[0].Topic)
|
||||||
require.Equal(t, "", conf.Subscribe[0].Command)
|
require.Equal(t, "", conf.Subscribe[0].Command)
|
||||||
require.Equal(t, "phil", conf.Subscribe[0].User)
|
require.Equal(t, "phil", *conf.Subscribe[0].User)
|
||||||
require.Nil(t, conf.Subscribe[0].Password)
|
require.Nil(t, conf.Subscribe[0].Password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ subscribe:
|
||||||
require.Equal(t, 1, len(conf.Subscribe))
|
require.Equal(t, 1, len(conf.Subscribe))
|
||||||
require.Equal(t, "no-command-with-auth", conf.Subscribe[0].Topic)
|
require.Equal(t, "no-command-with-auth", conf.Subscribe[0].Topic)
|
||||||
require.Equal(t, "", conf.Subscribe[0].Command)
|
require.Equal(t, "", conf.Subscribe[0].Command)
|
||||||
require.Equal(t, "phil", conf.Subscribe[0].User)
|
require.Equal(t, "phil", *conf.Subscribe[0].User)
|
||||||
require.Nil(t, conf.Subscribe[0].Password)
|
require.Nil(t, conf.Subscribe[0].Password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ subscribe:
|
||||||
require.Equal(t, "tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2", conf.DefaultToken)
|
require.Equal(t, "tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2", conf.DefaultToken)
|
||||||
require.Equal(t, 1, len(conf.Subscribe))
|
require.Equal(t, 1, len(conf.Subscribe))
|
||||||
require.Equal(t, "mytopic", conf.Subscribe[0].Topic)
|
require.Equal(t, "mytopic", conf.Subscribe[0].Topic)
|
||||||
require.Equal(t, "", conf.Subscribe[0].User)
|
require.Nil(t, conf.Subscribe[0].User)
|
||||||
require.Nil(t, conf.Subscribe[0].Password)
|
require.Nil(t, conf.Subscribe[0].Password)
|
||||||
require.Equal(t, "", conf.Subscribe[0].Token)
|
require.Nil(t, conf.Subscribe[0].Token)
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,11 @@ func WithBearerAuth(token string) PublishOption {
|
||||||
return WithHeader("Authorization", fmt.Sprintf("Bearer %s", token))
|
return WithHeader("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithEmptyAuth clears the Authorization header
|
||||||
|
func WithEmptyAuth() PublishOption {
|
||||||
|
return RemoveHeader("Authorization")
|
||||||
|
}
|
||||||
|
|
||||||
// WithNoCache instructs the server not to cache the message server-side
|
// WithNoCache instructs the server not to cache the message server-side
|
||||||
func WithNoCache() PublishOption {
|
func WithNoCache() PublishOption {
|
||||||
return WithHeader("X-Cache", "no")
|
return WithHeader("X-Cache", "no")
|
||||||
|
@ -187,3 +192,13 @@ func WithQueryParam(param, value string) RequestOption {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveHeader is a generic option to remove a header from a request
|
||||||
|
func RemoveHeader(header string) RequestOption {
|
||||||
|
return func(r *http.Request) error {
|
||||||
|
if header != "" {
|
||||||
|
delete(r.Header, header)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -225,12 +225,17 @@ func doSubscribe(c *cli.Context, cl *client.Client, conf *client.Config, topic,
|
||||||
}
|
}
|
||||||
|
|
||||||
func maybeAddAuthHeader(s client.Subscribe, conf *client.Config) client.SubscribeOption {
|
func maybeAddAuthHeader(s client.Subscribe, conf *client.Config) client.SubscribeOption {
|
||||||
// check for subscription token then subscription user:pass
|
// if an explicit empty token or empty user:pass is given, exit without auth
|
||||||
if s.Token != "" {
|
if (s.Token != nil && *s.Token == "") || (s.User != nil && *s.User == "" && s.Password != nil && *s.Password == "") {
|
||||||
return client.WithBearerAuth(s.Token)
|
return client.WithEmptyAuth()
|
||||||
}
|
}
|
||||||
if s.User != "" && s.Password != nil {
|
|
||||||
return client.WithBasicAuth(s.User, *s.Password)
|
// check for subscription token then subscription user:pass
|
||||||
|
if s.Token != nil && *s.Token != "" {
|
||||||
|
return client.WithBearerAuth(*s.Token)
|
||||||
|
}
|
||||||
|
if s.User != nil && *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 no subscription token nor subscription user:pass, check for default token then default user:pass
|
||||||
|
|
|
@ -330,7 +330,7 @@ default-token: tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2
|
||||||
|
|
||||||
app, _, stdout, _ := newTestApp()
|
app, _, stdout, _ := newTestApp()
|
||||||
|
|
||||||
require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--config=" + filename, "mytopic"}))
|
require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename, "mytopic"}))
|
||||||
|
|
||||||
require.Equal(t, message, strings.TrimSpace(stdout.String()))
|
require.Equal(t, message, strings.TrimSpace(stdout.String()))
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,63 @@ default-password: mypass
|
||||||
|
|
||||||
app, _, stdout, _ := newTestApp()
|
app, _, stdout, _ := newTestApp()
|
||||||
|
|
||||||
require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--config=" + filename, "mytopic"}))
|
require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename, "mytopic"}))
|
||||||
|
|
||||||
|
require.Equal(t, message, strings.TrimSpace(stdout.String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCLI_Subscribe_Override_Default_UserPass_With_Empty_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, "", 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-user: philipp
|
||||||
|
default-password: mypass
|
||||||
|
subscribe:
|
||||||
|
- topic: mytopic
|
||||||
|
user: ""
|
||||||
|
password: ""
|
||||||
|
`, server.URL)), 0600))
|
||||||
|
|
||||||
|
app, _, stdout, _ := newTestApp()
|
||||||
|
|
||||||
|
require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename}))
|
||||||
|
|
||||||
|
require.Equal(t, message, strings.TrimSpace(stdout.String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCLI_Subscribe_Override_Default_Token_With_Empty_Token(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, "", 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_AgQdq7mVBoFD37zQVN29RhuMzNIz2
|
||||||
|
subscribe:
|
||||||
|
- topic: mytopic
|
||||||
|
token: ""
|
||||||
|
`, server.URL)), 0600))
|
||||||
|
|
||||||
|
app, _, stdout, _ := newTestApp()
|
||||||
|
|
||||||
|
require.Nil(t, app.Run([]string{"ntfy", "subscribe", "--poll", "--from-config", "--config=" + filename}))
|
||||||
|
|
||||||
require.Equal(t, message, strings.TrimSpace(stdout.String()))
|
require.Equal(t, message, strings.TrimSpace(stdout.String()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1262,6 +1262,7 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
|
||||||
|
|
||||||
* Fix issues with date/time with different locales ([#700](https://github.com/binwiederhier/ntfy/issues/700), thanks to [@nimbleghost](https://github.com/nimbleghost))
|
* Fix issues with date/time with different locales ([#700](https://github.com/binwiederhier/ntfy/issues/700), thanks to [@nimbleghost](https://github.com/nimbleghost))
|
||||||
* Re-init i18n on each service worker message to avoid missing translations ([#817](https://github.com/binwiederhier/ntfy/pull/817), thanks to [@nihalgonsalves](https://github.com/nihalgonsalves))
|
* Re-init i18n on each service worker message to avoid missing translations ([#817](https://github.com/binwiederhier/ntfy/pull/817), thanks to [@nihalgonsalves](https://github.com/nihalgonsalves))
|
||||||
|
* You can now unset the default user:pass/token in `client.yml` for an individual subscription to remove the Authorization header ([#829](https://github.com/binwiederhier/ntfy/issues/829), thanks to [tomeon](https://github.com/tomeon) for reporting and to [@wunter8](https://github.com/wunter8) for fixing)
|
||||||
|
|
||||||
### ntfy Android app v1.16.1 (UNRELEASED)
|
### ntfy Android app v1.16.1 (UNRELEASED)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue