copy subset of Sprig template functions
This commit is contained in:
@@ -34,6 +34,7 @@ import (
|
||||
"heckel.io/ntfy/v2/log"
|
||||
"heckel.io/ntfy/v2/user"
|
||||
"heckel.io/ntfy/v2/util"
|
||||
"heckel.io/ntfy/v2/util/sprig"
|
||||
)
|
||||
|
||||
// Server is the main server, providing the UI and API for ntfy
|
||||
@@ -1132,7 +1133,11 @@ func replaceTemplate(tpl string, source string) (string, error) {
|
||||
if err := json.Unmarshal([]byte(source), &data); err != nil {
|
||||
return "", errHTTPBadRequestTemplateMessageNotJSON
|
||||
}
|
||||
t, err := template.New("").Parse(tpl)
|
||||
sprigFuncs := sprig.FuncMap()
|
||||
// remove unsafe functions
|
||||
delete(sprigFuncs, "env")
|
||||
delete(sprigFuncs, "expandenv")
|
||||
t, err := template.New("").Funcs(sprigFuncs).Parse(tpl)
|
||||
if err != nil {
|
||||
return "", errHTTPBadRequestTemplateInvalid
|
||||
}
|
||||
|
||||
@@ -3024,6 +3024,51 @@ template ""}}`,
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_MessageTemplate_SprigFunctions(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := newTestServer(t, newTestConfig(t))
|
||||
bodies := []string{
|
||||
`{"foo":"bar","nested":{"title":"here"}}`,
|
||||
`{"topic":"ntfy-test"}`,
|
||||
`{"topic":"another-topic"}`,
|
||||
}
|
||||
templates := []string{
|
||||
`{{.foo | upper}} is {{.nested.title | repeat 3}}`,
|
||||
`{{if hasPrefix "ntfy-" .topic}}Topic: {{trimPrefix "ntfy-" .topic}}{{ else }}Topic: {{.topic}}{{end}}`,
|
||||
`{{if hasPrefix "ntfy-" .topic}}Topic: {{trimPrefix "ntfy-" .topic}}{{ else }}Topic: {{.topic}}{{end}}`,
|
||||
}
|
||||
targets := []string{
|
||||
`BAR is hereherehere`,
|
||||
`Topic: test`,
|
||||
`Topic: another-topic`,
|
||||
}
|
||||
for i, body := range bodies {
|
||||
template := templates[i]
|
||||
target := targets[i]
|
||||
t.Run(template, func(t *testing.T) {
|
||||
response := request(t, s, "PUT", `/mytopic`, body, map[string]string{
|
||||
"Template": "yes",
|
||||
"Message": template,
|
||||
})
|
||||
require.Equal(t, 200, response.Code)
|
||||
m := toMessage(t, response.Body.String())
|
||||
require.Equal(t, target, m.Message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_MessageTemplate_UnsafeSprigFunctions(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := newTestServer(t, newTestConfig(t))
|
||||
response := request(t, s, "POST", "/mytopic", `{}`, map[string]string{
|
||||
"X-Message": `{{ env "PATH" }}`,
|
||||
"X-Template": "1",
|
||||
})
|
||||
|
||||
require.Equal(t, 400, response.Code)
|
||||
require.Equal(t, 40043, toHTTPError(t, response.Body.String()).Code)
|
||||
}
|
||||
|
||||
func newTestConfig(t *testing.T) *Config {
|
||||
conf := NewConfig()
|
||||
conf.BaseURL = "http://127.0.0.1:12345"
|
||||
|
||||
Reference in New Issue
Block a user