Merge pull request #372 from wunter8/default-user-password-command

Client: default-user, default-password, default-command
pull/386/head
Philipp C. Heckel 2022-08-18 20:25:46 -04:00 committed by GitHub
commit 9d0231ea07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 8 deletions

View File

@ -5,6 +5,12 @@
# #
# default-host: https://ntfy.sh # default-host: https://ntfy.sh
# Defaults below will be used when a topic does not have its own settings
#
# default-user:
# default-password:
# default-command:
# Subscriptions to topics and their actions. This option is primarily used by the systemd service, # Subscriptions to topics and their actions. This option is primarily used by the systemd service,
# or if you cann "ntfy subscribe --from-config" directly. # or if you cann "ntfy subscribe --from-config" directly.
# #

View File

@ -12,8 +12,11 @@ const (
// Config is the config struct for a Client // Config is the config struct for a Client
type Config struct { type Config struct {
DefaultHost string `yaml:"default-host"` DefaultHost string `yaml:"default-host"`
Subscribe []struct { DefaultUser string `yaml:"default-user"`
DefaultPassword string `yaml:"default-password"`
DefaultCommand string `yaml:"default-command"`
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"`
@ -25,8 +28,11 @@ type Config struct {
// NewConfig creates a new Config struct for a Client // NewConfig creates a new Config struct for a Client
func NewConfig() *Config { func NewConfig() *Config {
return &Config{ return &Config{
DefaultHost: DefaultBaseURL, DefaultHost: DefaultBaseURL,
Subscribe: nil, DefaultUser: "",
DefaultPassword: "",
DefaultCommand: "",
Subscribe: nil,
} }
} }

View File

@ -12,6 +12,9 @@ func TestConfig_Load(t *testing.T) {
filename := filepath.Join(t.TempDir(), "client.yml") filename := filepath.Join(t.TempDir(), "client.yml")
require.Nil(t, os.WriteFile(filename, []byte(` require.Nil(t, os.WriteFile(filename, []byte(`
default-host: http://localhost default-host: http://localhost
default-user: phil
default-password: mypass
default-command: 'echo "Got the message: $message"'
subscribe: subscribe:
- topic: no-command-with-auth - topic: no-command-with-auth
user: phil user: phil
@ -22,12 +25,16 @@ subscribe:
command: notify-send -i /usr/share/ntfy/logo.png "Important" "$m" command: notify-send -i /usr/share/ntfy/logo.png "Important" "$m"
if: if:
priority: high,urgent priority: high,urgent
- topic: defaults
`), 0600)) `), 0600))
conf, err := client.LoadConfig(filename) conf, err := client.LoadConfig(filename)
require.Nil(t, err) require.Nil(t, err)
require.Equal(t, "http://localhost", conf.DefaultHost) require.Equal(t, "http://localhost", conf.DefaultHost)
require.Equal(t, 3, len(conf.Subscribe)) require.Equal(t, "phil", conf.DefaultUser)
require.Equal(t, "mypass", conf.DefaultPassword)
require.Equal(t, `echo "Got the message: $message"`, conf.DefaultCommand)
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)
@ -37,4 +44,5 @@ subscribe:
require.Equal(t, "alerts", conf.Subscribe[2].Topic) require.Equal(t, "alerts", conf.Subscribe[2].Topic)
require.Equal(t, `notify-send -i /usr/share/ntfy/logo.png "Important" "$m"`, conf.Subscribe[2].Command) require.Equal(t, `notify-send -i /usr/share/ntfy/logo.png "Important" "$m"`, conf.Subscribe[2].Command)
require.Equal(t, "high,urgent", conf.Subscribe[2].If["priority"]) require.Equal(t, "high,urgent", conf.Subscribe[2].If["priority"])
require.Equal(t, "defaults", conf.Subscribe[3].Topic)
} }

View File

@ -175,11 +175,32 @@ func doSubscribe(c *cli.Context, cl *client.Client, conf *client.Config, topic,
for filter, value := range s.If { for filter, value := range s.If {
topicOptions = append(topicOptions, client.WithFilter(filter, value)) topicOptions = append(topicOptions, client.WithFilter(filter, value))
} }
if s.User != "" && s.Password != "" { var user, password string
topicOptions = append(topicOptions, client.WithBasicAuth(s.User, s.Password)) if s.User != "" {
user = s.User
} else if conf.DefaultUser != "" {
user = conf.DefaultUser
} else {
user = ""
}
if s.Password != "" {
password = s.Password
} else if conf.DefaultPassword != "" {
password = conf.DefaultPassword
} else {
password = ""
}
if user != "" && password != "" {
topicOptions = append(topicOptions, client.WithBasicAuth(user, password))
} }
subscriptionID := cl.Subscribe(s.Topic, topicOptions...) subscriptionID := cl.Subscribe(s.Topic, topicOptions...)
cmds[subscriptionID] = s.Command if s.Command != "" {
cmds[subscriptionID] = s.Command
} else if conf.DefaultCommand != "" {
cmds[subscriptionID] = conf.DefaultCommand
} else {
cmds[subscriptionID] = ""
}
} }
if topic != "" { if topic != "" {
subscriptionID := cl.Subscribe(topic, options...) subscriptionID := cl.Subscribe(topic, options...)

View File

@ -254,6 +254,14 @@ I hope this shows how powerful this command is. Here's a short video that demons
<figcaption>Execute all the things</figcaption> <figcaption>Execute all the things</figcaption>
</figure> </figure>
If most (or all) of your subscription usernames, passwords, and commands are the same, you can specify a `default-user`, `default-password`, and `default-command` at the top of the
`client.yml`. If a subscription does not specify a username/password to use or does not have a command, the defaults will be used, otherwise, the subscription settings will
override the defaults.
!!! warning
Because the `default-user` and `default-password` will be sent for each topic that does not have its own username/password (even if the topic does not require authentication),
be sure that the servers/topics you subscribe to use HTTPS to prevent leaking the username and password.
### Using the systemd service ### Using the systemd service
You can use the `ntfy-client` systemd service (see [ntfy-client.service](https://github.com/binwiederhier/ntfy/blob/main/client/ntfy-client.service)) You can use the `ntfy-client` systemd service (see [ntfy-client.service](https://github.com/binwiederhier/ntfy/blob/main/client/ntfy-client.service))
to subscribe to multiple topics just like in the example above. The service is automatically installed (but not started) to subscribe to multiple topics just like in the example above. The service is automatically installed (but not started)