Added disallowed-topics

This commit is contained in:
binwiederhier 2023-02-09 08:32:51 -05:00
parent b37cf02a6e
commit bcb22d8d4c
7 changed files with 40 additions and 6 deletions

View file

@ -58,6 +58,10 @@ const (
var (
// DefaultVisitorStatsResetTime defines the time at which visitor stats are reset (wall clock only)
DefaultVisitorStatsResetTime = time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC)
// DefaultDisallowedTopics defines the topics that are forbidden, because they are used elsewhere. This array can be
// extended using the server.yml config. If updated, also update in Android and web app.
DefaultDisallowedTopics = []string{"docs", "static", "file", "app", "account", "settings", "signup", "login"}
)
// Config is the main config struct for the application. Use New to instantiate a default config struct.
@ -87,6 +91,7 @@ type Config struct {
AttachmentExpiryDuration time.Duration
KeepaliveInterval time.Duration
ManagerInterval time.Duration
DisallowedTopics []string
WebRootIsApp bool
DelayedSenderInterval time.Duration
FirebaseKeepaliveInterval time.Duration

View file

@ -52,7 +52,7 @@ var (
errHTTPBadRequestPriorityInvalid = &errHTTP{40007, http.StatusBadRequest, "invalid priority parameter", "https://ntfy.sh/docs/publish/#message-priority"}
errHTTPBadRequestSinceInvalid = &errHTTP{40008, http.StatusBadRequest, "invalid since parameter", "https://ntfy.sh/docs/subscribe/api/#fetch-cached-messages"}
errHTTPBadRequestTopicInvalid = &errHTTP{40009, http.StatusBadRequest, "invalid request: topic invalid", ""}
errHTTPBadRequestTopicDisallowed = &errHTTP{40010, http.StatusBadRequest, "invalid request: topic name is disallowed", ""}
errHTTPBadRequestTopicDisallowed = &errHTTP{40010, http.StatusBadRequest, "invalid request: topic name is not allowed", ""}
errHTTPBadRequestMessageNotUTF8 = &errHTTP{40011, http.StatusBadRequest, "invalid message: message must be UTF-8 encoded", ""}
errHTTPBadRequestAttachmentURLInvalid = &errHTTP{40013, http.StatusBadRequest, "invalid request: attachment URL is invalid", "https://ntfy.sh/docs/publish/#attachments"}
errHTTPBadRequestAttachmentsDisallowed = &errHTTP{40014, http.StatusBadRequest, "invalid request: attachments not allowed", "https://ntfy.sh/docs/config/#attachments"}

View file

@ -39,7 +39,8 @@ import (
- api
- HIGH Self-review
- MEDIUM: Test for expiring messages after reservation removal
- MEDIUM: disallowed-topics
- MEDIUM: uploading attachments leads to 404 -- race
- MEDIUM: Do not call tiers endoint when payments is not enabled
- MEDIUM: Test new token endpoints & never-expiring token
- LOW: UI: Flickering upgrade banner when logging in
@ -103,7 +104,6 @@ var (
staticRegex = regexp.MustCompile(`^/static/.+`)
docsRegex = regexp.MustCompile(`^/docs(|/.*)$`)
fileRegex = regexp.MustCompile(`^/file/([-_A-Za-z0-9]{1,64})(?:\.[A-Za-z0-9]{1,16})?$`)
disallowedTopics = []string{"docs", "static", "file", "app", "account", "settings", "pricing", "signup", "login", "reset-password"} // If updated, also update in Android and web app
urlRegex = regexp.MustCompile(`^https?://`)
//go:embed site
@ -496,7 +496,7 @@ func (s *Server) handleWebConfig(w http.ResponseWriter, _ *http.Request, _ *visi
EnableSignup: s.config.EnableSignup,
EnablePayments: s.config.StripeSecretKey != "",
EnableReservations: s.config.EnableReservations,
DisallowedTopics: disallowedTopics,
DisallowedTopics: s.config.DisallowedTopics,
}
b, err := json.MarshalIndent(response, "", " ")
if err != nil {
@ -1260,7 +1260,7 @@ func (s *Server) topicsFromIDs(ids ...string) ([]*topic, error) {
defer s.mu.Unlock()
topics := make([]*topic, 0)
for _, id := range ids {
if util.Contains(disallowedTopics, id) {
if util.Contains(s.config.DisallowedTopics, id) {
return nil, errHTTPBadRequestTopicDisallowed
}
if _, ok := s.topics[id]; !ok {

View file

@ -155,6 +155,17 @@
#
# manager-interval: "1m"
# Defines topic names that are not allowed, because they are otherwise used. There are a few default topics
# that cannot be used (e.g. app, account, settings, ...). To extend the default list, define them here.
#
# Example:
# disallowed-topics:
# - about
# - pricing
# - contact
#
# disallowed-topics:
# Defines if the root route (/) is pointing to the landing page (as on ntfy.sh) or the
# web app. If you self-host, you don't want to change this.
# Can be "app" (default), "home" or "disable" to disable the web app entirely.

View file

@ -158,6 +158,19 @@ func TestServer_PublishAndSubscribe(t *testing.T) {
require.Equal(t, []string{"tag1", "tag 2", "tag3"}, messages[2].Tags)
}
func TestServer_Publish_Disallowed_Topic(t *testing.T) {
c := newTestConfig(t)
c.DisallowedTopics = []string{"about", "time", "this", "got", "added"}
s := newTestServer(t, c)
rr := request(t, s, "PUT", "/mytopic", "my first message", nil)
require.Equal(t, 200, rr.Code)
rr = request(t, s, "PUT", "/about", "another message", nil)
require.Equal(t, 400, rr.Code)
require.Equal(t, 40010, toHTTPError(t, rr.Body.String()).Code)
}
func TestServer_StaticSites(t *testing.T) {
s := newTestServer(t, newTestConfig(t))