mirror of
https://github.com/multipleof4/ntfy.git
synced 2026-10-08 21:05:21 +00:00
Add trace logs
This commit is contained in:
+5
-5
@@ -1,14 +1,15 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/urfave/cli/v2"
|
||||
"heckel.io/ntfy/v2/server"
|
||||
"heckel.io/ntfy/v2/test"
|
||||
"heckel.io/ntfy/v2/user"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCLI_User_Add(t *testing.T) {
|
||||
@@ -128,8 +129,7 @@ func newTestServerWithAuth(t *testing.T) (s *server.Server, conf *server.Config,
|
||||
conf.File = configFile
|
||||
conf.AuthFile = filepath.Join(t.TempDir(), "user.db")
|
||||
conf.AuthDefault = user.PermissionDenyAll
|
||||
// Cache is off by default (matches self-hoster setup), so the server reads
|
||||
// authorizations directly from the DB and sees CLI mutations immediately.
|
||||
conf.AuthAccessCacheEnabled = false
|
||||
s, port = test.StartServerWithConfig(t, conf)
|
||||
return
|
||||
}
|
||||
|
||||
+2
-2
@@ -2284,7 +2284,7 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
|
||||
| `cache-batch-timeout` | `NTFY_CACHE_BATCH_TIMEOUT` | *duration* | 0s | Timeout for batched async writes to the message cache (if zero, writes are synchronous) |
|
||||
| `auth-file` | `NTFY_AUTH_FILE` | *filename* | - | Auth database file used for access control (SQLite). If set, enables authentication and access control. Not required if `database-url` is set. See [access control](#access-control). |
|
||||
| `auth-default-access` | `NTFY_AUTH_DEFAULT_ACCESS` | `read-write`, `read-only`, `write-only`, `deny-all` | `read-write` | Default permissions if no matching entries in the auth database are found. Default is `read-write`. |
|
||||
| `auth-access-cache` | `NTFY_AUTH_ACCESS_CACHE` | *bool* | false | Enables an in-memory snapshot of the access control list so authorization checks no longer hit the database. Off by default; only worth enabling on high-volume servers. ACL changes from a separate `ntfy access` CLI invocation against the same database become visible within ~60s; the server's own changes are immediate. |
|
||||
| `auth-access-cache` | `NTFY_AUTH_ACCESS_CACHE` | *bool* | false | Enables an in-memory ACL cache so authorization checks no longer hit the database. Only worth enabling on high-volume servers. |
|
||||
| `behind-proxy` | `NTFY_BEHIND_PROXY` | *bool* | false | If set, use forwarded header (e.g. X-Forwarded-For, X-Client-IP) to determine visitor IP address (for rate limiting) |
|
||||
| `proxy-forwarded-header` | `NTFY_PROXY_FORWARDED_HEADER` | *string* | `X-Forwarded-For` | Use specified header to determine visitor IP address (for rate limiting) |
|
||||
| `proxy-trusted-hosts` | `NTFY_PROXY_TRUSTED_HOSTS` | *comma-separated host/IP/CIDR list* | - | Comma-separated list of trusted IP addresses, hosts, or CIDRs to remove from forwarded header |
|
||||
@@ -2296,7 +2296,7 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
|
||||
| `smtp-sender-user` | `NTFY_SMTP_SENDER_USER` | *string* | - | SMTP user; only used if e-mail sending is enabled |
|
||||
| `smtp-sender-pass` | `NTFY_SMTP_SENDER_PASS` | *string* | - | SMTP password; only used if e-mail sending is enabled |
|
||||
| `smtp-sender-from` | `NTFY_SMTP_SENDER_FROM` | *e-mail address* | - | SMTP sender e-mail address; only used if e-mail sending is enabled |
|
||||
| `smtp-sender-verify` | `NTFY_SMTP_SENDER_VERIFY` | *bool* | `false` | If true, require verified email addresses for email notifications; anonymous email sending is disabled |
|
||||
| `smtp-sender-verify` | `NTFY_SMTP_SENDER_VERIFY` | *bool* | `false` | If true, require verified email addresses for email notifications; anonymous email sending is disabled |
|
||||
| `smtp-server-listen` | `NTFY_SMTP_SERVER_LISTEN` | `[ip]:port` | - | Defines the IP address and port the SMTP server will listen on, e.g. `:25` or `1.2.3.4:25` |
|
||||
| `smtp-server-domain` | `NTFY_SMTP_SERVER_DOMAIN` | *domain name* | - | SMTP server e-mail domain, e.g. `ntfy.sh` |
|
||||
| `smtp-server-addr-prefix` | `NTFY_SMTP_SERVER_ADDR_PREFIX` | *string* | - | Optional prefix for the e-mail addresses to prevent spam, e.g. `ntfy-` |
|
||||
|
||||
+23
-1
@@ -53,18 +53,40 @@ func newAccessCache() *accessCache {
|
||||
func (c *accessCache) Lookup(usernameOrEveryone, topic string) (read, write, found bool) {
|
||||
escapedTopic := escapeUnderscore(topic)
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
if usernameOrEveryone != Everyone {
|
||||
if entry, ok := c.pickBestNoLock(usernameOrEveryone, topic, escapedTopic); ok {
|
||||
c.mu.RUnlock()
|
||||
traceACLDecision(usernameOrEveryone, usernameOrEveryone, topic, entry.read, entry.write)
|
||||
return entry.read, entry.write, true
|
||||
}
|
||||
}
|
||||
if entry, ok := c.pickBestNoLock(Everyone, topic, escapedTopic); ok {
|
||||
c.mu.RUnlock()
|
||||
traceACLDecision(usernameOrEveryone, Everyone, topic, entry.read, entry.write)
|
||||
return entry.read, entry.write, true
|
||||
}
|
||||
c.mu.RUnlock()
|
||||
traceACLDecision(usernameOrEveryone, "", topic, false, false)
|
||||
return false, false, false
|
||||
}
|
||||
|
||||
// traceACLDecision logs an ACL lookup result
|
||||
func traceACLDecision(requestUser, matchedUser, topic string, read, write bool) {
|
||||
ev := log.Tag(tag).
|
||||
Field("user_name", requestUser).
|
||||
Field("topic", topic).
|
||||
Field("read", read).
|
||||
Field("write", write)
|
||||
if !ev.IsTrace() {
|
||||
return
|
||||
}
|
||||
if matchedUser == "" {
|
||||
ev.Trace("ACL no match")
|
||||
return
|
||||
}
|
||||
ev.Field("matched_user", matchedUser).Trace("ACL match")
|
||||
}
|
||||
|
||||
// Reload scans (user_name, topic, read, write) rows and merges them into the
|
||||
// cache. With no usernames the cache is replaced wholesale; otherwise the
|
||||
// query is invoked with those usernames as positional args and only the
|
||||
|
||||
+4
-5
@@ -748,10 +748,10 @@ func (a *Manager) AllowReservation(username string, topic string) error {
|
||||
// The found return value indicates whether an ACL entry was found at all.
|
||||
//
|
||||
// Priority:
|
||||
// - specific user beats Everyone
|
||||
// - longer pattern beats shorter (a more specific rule beats a more general one,
|
||||
// - Specific user beats Everyone
|
||||
// - Longer pattern beats shorter (a more specific rule beats a more general one,
|
||||
// e.g. "test*" > "*")
|
||||
// - write beats read at equal length
|
||||
// - Write beats read at equal length
|
||||
//
|
||||
// When AccessCacheEnabled is true (config), the lookup is served entirely from
|
||||
// the in-memory snapshot maintained by accessCache. Otherwise the original SQL
|
||||
@@ -1634,11 +1634,10 @@ func (a *Manager) maybeProvisionTokens(tx *sql.Tx, provisionUsernames []string,
|
||||
}
|
||||
|
||||
// Close stops background goroutines and closes the underlying database.
|
||||
// Safe to call multiple times.
|
||||
func (a *Manager) Close() error {
|
||||
select {
|
||||
case <-a.quit:
|
||||
// already closed
|
||||
// Already closed
|
||||
default:
|
||||
close(a.quit)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user