package handlers_test import ( "context" "net/http" "net/http/httptest" "testing" "github.com/go-chi/chi" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/gorm/clause" "sneak.berlin/go/webhooker/internal/database" "sneak.berlin/go/webhooker/internal/handlers" "sneak.berlin/go/webhooker/internal/session" ) // seedDeliveredEvent records an event and a delivery for it in // the webhook's own database, so the log page has a delivery // to render against the target. func seedDeliveredEvent( t *testing.T, dbMgr *database.WebhookDBManager, webhookID, targetID string, ) { t.Helper() webhookDB, err := dbMgr.GetDB(webhookID) require.NoError(t, err) event := &database.Event{ WebhookID: webhookID, Method: http.MethodPost, Body: `{"test":true}`, ContentType: "application/json", } require.NoError(t, webhookDB.Omit( clause.Associations, ).Create(event).Error) dlv := &database.Delivery{ EventID: event.ID, TargetID: targetID, Status: database.DeliveryStatusDelivered, } require.NoError(t, webhookDB.Omit( clause.Associations, ).Create(dlv).Error) } // renderSourceLogsPage runs the real event log handler for a // webhook and returns the rendered HTML. func renderSourceLogsPage( t *testing.T, h *handlers.Handlers, sess *session.Session, webhookID string, ) string { t.Helper() req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/source/"+webhookID+"/logs", nil, ) for _, c := range authenticatedCookies( t, sess, deleteTestUserID, deleteTestUsername, ) { req.AddCookie(c) } rctx := chi.NewRouteContext() rctx.URLParams.Add(paramSourceID, webhookID) req = req.WithContext( context.WithValue( req.Context(), chi.RouteCtxKey, rctx, ), ) w := httptest.NewRecorder() h.HandleSourceLogs().ServeHTTP(w, req) require.Equal(t, http.StatusOK, w.Code) return w.Body.String() } // TestHandleSourceLogs_MasksSlackWebhookURL proves the event // log page is handed a display-safe projection of each target // rather than the stored row, so the credential cannot be // rendered from its template data. func TestHandleSourceLogs_MasksSlackWebhookURL(t *testing.T) { t.Parallel() var ( h *handlers.Handlers sess *session.Session db *database.Database dbMgr *database.WebhookDBManager ) app := newTestApp(t, &h, &sess, &db, &dbMgr) app.RequireStart() t.Cleanup(app.RequireStop) wh := seedWebhook(t, db) tgt := seedConfiguredTarget( t, db, wh.ID, database.TargetTypeSlack, `{"webhookUrl":"`+slackWebhookURL+`"}`, ) seedDeliveredEvent(t, dbMgr, wh.ID, tgt.ID) body := renderSourceLogsPage(t, h, sess, wh.ID) assert.NotContains(t, body, slackSecretPath) assert.NotContains(t, body, "T00000000") assert.NotContains(t, body, "B00000000") assert.NotContains( t, body, "XXXXXXXXXXXXXXXXXXXXXXXX", ) assert.NotContains(t, body, "webhookUrl") // The page still identifies the delivery's target. assert.Contains(t, body, tgt.Name) assert.Contains(t, body, "delivered") }