mirror of
https://github.com/henrygd/beszel.git
synced 2026-09-21 17:07:47 +02:00
- Validate resolved IPs immediately before connecting. - Guard Shoutrrr requests during initialization and delivery. - Require admins for services without HTTP client support. - Test DNS rebinding, redirects, internal hosts, and authorization.
67 lines
2.1 KiB
Go
67 lines
2.1 KiB
Go
//go:build testing
|
|
|
|
package alerts_test
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"sync/atomic"
|
|
"testing"
|
|
|
|
"github.com/henrygd/beszel/internal/alerts"
|
|
beszelTests "github.com/henrygd/beszel/internal/tests"
|
|
"github.com/pocketbase/dbx"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestPersistedWebhooksUseCurrentOwnerRole(t *testing.T) {
|
|
hub, user := beszelTests.GetHubWithUser(t)
|
|
defer hub.Cleanup()
|
|
am := alerts.NewTestAlertManagerWithoutWorker(hub)
|
|
|
|
var delivered atomic.Int32
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
delivered.Add(1)
|
|
}))
|
|
defer server.Close()
|
|
|
|
settings, err := hub.FindFirstRecordByFilter("user_settings", "user={:user}", dbx.Params{"user": user.Id})
|
|
require.NoError(t, err)
|
|
settings.Set("settings", alerts.UserNotificationSettings{Webhooks: []string{"generic+" + server.URL}})
|
|
require.NoError(t, hub.Save(settings))
|
|
message := alerts.AlertMessageData{UserID: user.Id, Title: "Test", Message: "Persisted webhook"}
|
|
|
|
// Keep the same URL and manager while changing roles, so cached privileges
|
|
// or treating previously saved URLs as trusted would fail this test.
|
|
for _, tc := range []struct {
|
|
name string
|
|
role string
|
|
want int32
|
|
}{
|
|
{"regular user", "user", 0},
|
|
{"readonly user", "readonly", 0},
|
|
{"promoted admin", "admin", 1},
|
|
{"demoted admin", "user", 1},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
user.Set("role", tc.role)
|
|
require.NoError(t, hub.Save(user))
|
|
// Webhook errors are logged; SendAlert continues to email delivery.
|
|
require.NoError(t, am.SendAlert(message))
|
|
require.Equal(t, tc.want, delivered.Load())
|
|
})
|
|
}
|
|
|
|
t.Run("missing owner fails closed", func(t *testing.T) {
|
|
// Model an orphaned settings record without deleting it through the
|
|
// normal user deletion cascade.
|
|
const missingOwner = "missingowner123"
|
|
settings.Set("user", missingOwner)
|
|
require.NoError(t, hub.SaveNoValidate(settings))
|
|
message.UserID = missingOwner
|
|
err := am.SendAlert(message)
|
|
require.ErrorContains(t, err, "load notification owner")
|
|
require.EqualValues(t, 1, delivered.Load())
|
|
})
|
|
}
|