Gitfed
bastien-mrq/gitfed / internal / federation / notify_test.go
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")
	}
}