package federation
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"git.neuromancer.ovh/bastien-mrq/gitfed/internal/store"
)
// TestNotifyHandlerRejectsUnknownRecipient reproduces the gap the audit
// found: NotifyHandler only checked that a notification's principal ended
// in "@" + the local domain, never that the username part was a real local
// account. Since receiving a notification requires no pre-existing
// relationship (that's the point — see the package doc comment), anything
// that didn't check this let any instance bloat the store by notifying
// made-up usernames. This must be rejected before the signature is even
// looked at (a nonsense signature here still exercises the ordering).
func TestNotifyHandlerRejectsUnknownRecipient(t *testing.T) {
st := newTestStore(t)
body := `{"payload":{"from_domain":"chez-moi.fr","principal":"nobody@local.test","repo":"alice/x","role":"read","actor":"alice@chez-moi.fr","issued_at":0},"sig_format":"x","sig_blob":"AA=="}`
req := httptest.NewRequest(http.MethodPost, "/.well-known/gitfed-notify", strings.NewReader(body))
rec := httptest.NewRecorder()
NotifyHandler(st, "local.test", true).ServeHTTP(rec, req)
if rec.Code != http.StatusNotFound {
t.Fatalf("status = %d, want %d for a notification addressed to a nonexistent local user", rec.Code, http.StatusNotFound)
}
notifs, err := st.ListNotifications("nobody@local.test")
if err != nil {
t.Fatal(err)
}
if len(notifs) != 0 {
t.Fatal("a notification was stored for a nonexistent user")
}
}
// TestNotifyHandlerAcceptsKnownRecipient confirms the same request format
// clears the recipient check (and only fails later, on signature
// verification, which is exercised elsewhere) once the user actually
// exists — i.e. the fix in the test above didn't just make the handler
// reject everything.
func TestNotifyHandlerAcceptsKnownRecipient(t *testing.T) {
st := newTestStore(t)
if err := st.CreateUser(store.User{Username: "bob"}); err != nil {
t.Fatal(err)
}
body := `{"payload":{"from_domain":"chez-moi.fr","principal":"bob@local.test","repo":"alice/x","role":"read","actor":"alice@chez-moi.fr","issued_at":0},"sig_format":"x","sig_blob":"AA=="}`
req := httptest.NewRequest(http.MethodPost, "/.well-known/gitfed-notify", strings.NewReader(body))
rec := httptest.NewRecorder()
NotifyHandler(st, "local.test", true).ServeHTTP(rec, req)
if rec.Code == http.StatusNotFound {
t.Fatal("a known local user's notification was rejected as if the user didn't exist")
}
}