mirror of
https://github.com/binwiederhier/ntfy.git
synced 2025-07-20 10:04:08 +00:00
Add push service allowlist and topic limit
This commit is contained in:
parent
0f0074cbab
commit
46f34ca1e3
3 changed files with 74 additions and 21 deletions
|
@ -16,10 +16,14 @@ import (
|
|||
"heckel.io/ntfy/util"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultEndpoint = "https://updates.push.services.mozilla.com/wpush/v1/AAABBCCCDDEEEFFF"
|
||||
)
|
||||
|
||||
func TestServer_WebPush_TopicAdd(t *testing.T) {
|
||||
s := newTestServer(t, newTestConfigWithWebPush(t))
|
||||
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, []string{"test-topic"}), nil)
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, []string{"test-topic"}, defaultEndpoint), nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
require.Equal(t, `{"success":true}`+"\n", response.Body.String())
|
||||
|
||||
|
@ -27,19 +31,40 @@ func TestServer_WebPush_TopicAdd(t *testing.T) {
|
|||
require.Nil(t, err)
|
||||
|
||||
require.Len(t, subs, 1)
|
||||
require.Equal(t, subs[0].BrowserSubscription.Endpoint, "https://example.com/webpush")
|
||||
require.Equal(t, subs[0].BrowserSubscription.Endpoint, defaultEndpoint)
|
||||
require.Equal(t, subs[0].BrowserSubscription.Keys.P256dh, "p256dh-key")
|
||||
require.Equal(t, subs[0].BrowserSubscription.Keys.Auth, "auth-key")
|
||||
require.Equal(t, subs[0].UserID, "")
|
||||
}
|
||||
|
||||
func TestServer_WebPush_TopicAdd_InvalidEndpoint(t *testing.T) {
|
||||
s := newTestServer(t, newTestConfigWithWebPush(t))
|
||||
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, []string{"test-topic"}, "https://ddos-target.example.com/webpush"), nil)
|
||||
require.Equal(t, 400, response.Code)
|
||||
require.Equal(t, `{"code":40039,"http":400,"error":"invalid request: web push endpoint unknown"}`+"\n", response.Body.String())
|
||||
}
|
||||
|
||||
func TestServer_WebPush_TopicAdd_TooManyTopics(t *testing.T) {
|
||||
s := newTestServer(t, newTestConfigWithWebPush(t))
|
||||
|
||||
topicList := make([]string, 51)
|
||||
for i := range topicList {
|
||||
topicList[i] = util.RandomString(5)
|
||||
}
|
||||
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, topicList, defaultEndpoint), nil)
|
||||
require.Equal(t, 400, response.Code)
|
||||
require.Equal(t, `{"code":40040,"http":400,"error":"invalid request: too many web push topic subscriptions"}`+"\n", response.Body.String())
|
||||
}
|
||||
|
||||
func TestServer_WebPush_TopicUnsubscribe(t *testing.T) {
|
||||
s := newTestServer(t, newTestConfigWithWebPush(t))
|
||||
|
||||
addSubscription(t, s, "test-topic", "https://example.com/webpush")
|
||||
addSubscription(t, s, "test-topic", defaultEndpoint)
|
||||
requireSubscriptionCount(t, s, "test-topic", 1)
|
||||
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, []string{}), nil)
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, []string{}, defaultEndpoint), nil)
|
||||
require.Equal(t, 200, response.Code)
|
||||
require.Equal(t, `{"success":true}`+"\n", response.Body.String())
|
||||
|
||||
|
@ -54,7 +79,7 @@ func TestServer_WebPush_TopicSubscribeProtected_Allowed(t *testing.T) {
|
|||
require.Nil(t, s.userManager.AddUser("ben", "ben", user.RoleUser))
|
||||
require.Nil(t, s.userManager.AllowAccess("ben", "test-topic", user.PermissionReadWrite))
|
||||
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, []string{"test-topic"}), map[string]string{
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, []string{"test-topic"}, defaultEndpoint), map[string]string{
|
||||
"Authorization": util.BasicAuth("ben", "ben"),
|
||||
})
|
||||
require.Equal(t, 200, response.Code)
|
||||
|
@ -71,7 +96,7 @@ func TestServer_WebPush_TopicSubscribeProtected_Denied(t *testing.T) {
|
|||
config.AuthDefault = user.PermissionDenyAll
|
||||
s := newTestServer(t, config)
|
||||
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, []string{"test-topic"}), nil)
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, []string{"test-topic"}, defaultEndpoint), nil)
|
||||
require.Equal(t, 403, response.Code)
|
||||
|
||||
requireSubscriptionCount(t, s, "test-topic", 0)
|
||||
|
@ -84,7 +109,7 @@ func TestServer_WebPush_DeleteAccountUnsubscribe(t *testing.T) {
|
|||
require.Nil(t, s.userManager.AddUser("ben", "ben", user.RoleUser))
|
||||
require.Nil(t, s.userManager.AllowAccess("ben", "test-topic", user.PermissionReadWrite))
|
||||
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, []string{"test-topic"}), map[string]string{
|
||||
response := request(t, s, "PUT", "/v1/account/web-push", payloadForTopics(t, []string{"test-topic"}, defaultEndpoint), map[string]string{
|
||||
"Authorization": util.BasicAuth("ben", "ben"),
|
||||
})
|
||||
|
||||
|
@ -105,7 +130,7 @@ func TestServer_WebPush_Publish(t *testing.T) {
|
|||
|
||||
var received atomic.Bool
|
||||
|
||||
upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
pushService := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, err := io.ReadAll(r.Body)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, "/push-receive", r.URL.Path)
|
||||
|
@ -113,9 +138,9 @@ func TestServer_WebPush_Publish(t *testing.T) {
|
|||
require.Equal(t, "", r.Header.Get("Topic"))
|
||||
received.Store(true)
|
||||
}))
|
||||
defer upstreamServer.Close()
|
||||
defer pushService.Close()
|
||||
|
||||
addSubscription(t, s, "test-topic", upstreamServer.URL+"/push-receive")
|
||||
addSubscription(t, s, "test-topic", pushService.URL+"/push-receive")
|
||||
|
||||
request(t, s, "PUT", "/test-topic", "web push test", nil)
|
||||
|
||||
|
@ -129,18 +154,17 @@ func TestServer_WebPush_PublishExpire(t *testing.T) {
|
|||
|
||||
var received atomic.Bool
|
||||
|
||||
upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
pushService := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, err := io.ReadAll(r.Body)
|
||||
require.Nil(t, err)
|
||||
// Gone
|
||||
w.WriteHeader(410)
|
||||
w.Write([]byte(``))
|
||||
received.Store(true)
|
||||
}))
|
||||
defer upstreamServer.Close()
|
||||
defer pushService.Close()
|
||||
|
||||
addSubscription(t, s, "test-topic", upstreamServer.URL+"/push-receive")
|
||||
addSubscription(t, s, "test-topic-abc", upstreamServer.URL+"/push-receive")
|
||||
addSubscription(t, s, "test-topic", pushService.URL+"/push-receive")
|
||||
addSubscription(t, s, "test-topic-abc", pushService.URL+"/push-receive")
|
||||
|
||||
requireSubscriptionCount(t, s, "test-topic", 1)
|
||||
requireSubscriptionCount(t, s, "test-topic-abc", 1)
|
||||
|
@ -162,16 +186,16 @@ func TestServer_WebPush_Expiry(t *testing.T) {
|
|||
|
||||
var received atomic.Bool
|
||||
|
||||
upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
pushService := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, err := io.ReadAll(r.Body)
|
||||
require.Nil(t, err)
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(``))
|
||||
received.Store(true)
|
||||
}))
|
||||
defer upstreamServer.Close()
|
||||
defer pushService.Close()
|
||||
|
||||
addSubscription(t, s, "test-topic", upstreamServer.URL+"/push-receive")
|
||||
addSubscription(t, s, "test-topic", pushService.URL+"/push-receive")
|
||||
requireSubscriptionCount(t, s, "test-topic", 1)
|
||||
|
||||
_, err := s.webPush.db.Exec("UPDATE subscriptions SET updated_at = datetime('now', '-7 days')")
|
||||
|
@ -191,20 +215,20 @@ func TestServer_WebPush_Expiry(t *testing.T) {
|
|||
requireSubscriptionCount(t, s, "test-topic", 0)
|
||||
}
|
||||
|
||||
func payloadForTopics(t *testing.T, topics []string) string {
|
||||
func payloadForTopics(t *testing.T, topics []string, endpoint string) string {
|
||||
topicsJSON, err := json.Marshal(topics)
|
||||
require.Nil(t, err)
|
||||
|
||||
return fmt.Sprintf(`{
|
||||
"topics": %s,
|
||||
"browser_subscription":{
|
||||
"endpoint": "https://example.com/webpush",
|
||||
"endpoint": "%s",
|
||||
"keys": {
|
||||
"p256dh": "p256dh-key",
|
||||
"auth": "auth-key"
|
||||
}
|
||||
}
|
||||
}`, topicsJSON)
|
||||
}`, topicsJSON, endpoint)
|
||||
}
|
||||
|
||||
func addSubscription(t *testing.T, s *Server, topic string, url string) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue