package app import ( "net/http" "net/http/httptest" "strings" "testing" "github.com/DATA-DOG/go-sqlmock" ) func TestHandleGitHTTPPermissionFailures(t *testing.T) { s, mock, cleanup := newMockServer(t) defer cleanup() owner := User{ID: 1, Email: "alice@example.com", Username: "alice"} privateRepo := Repository{ID: 10, OwnerUserID: owner.ID, Owner: "alice", Name: "demo", Visibility: "private", DefaultBranch: "main"} rr := httptest.NewRecorder() s.handleGitHTTP(rr, httptest.NewRequest(http.MethodGet, "/bad/path", nil)) if rr.Code != http.StatusNotFound { t.Fatalf("invalid path status=%d", rr.Code) } expectLoadRepo(mock, "alice", "demo", privateRepo) rr = httptest.NewRecorder() s.handleGitHTTP(rr, httptest.NewRequest(http.MethodGet, "/alice/demo.git/info/refs?service=git-upload-pack", nil)) if rr.Code != http.StatusUnauthorized || rr.Header().Get("WWW-Authenticate") == "" { t.Fatalf("private fetch status=%d headers=%#v body=%s", rr.Code, rr.Header(), rr.Body.String()) } expectLoadRepo(mock, "alice", "demo", privateRepo) rr = httptest.NewRecorder() s.handleGitHTTP(rr, httptest.NewRequest(http.MethodPost, "/alice/demo.git/git-receive-pack", nil)) if rr.Code != http.StatusUnauthorized { t.Fatalf("push without auth status=%d body=%s", rr.Code, rr.Body.String()) } archived := privateRepo archived.Archived = true expectLoadRepo(mock, "alice", "demo", archived) mock.ExpectQuery("FROM auth_tokens t JOIN users u").WithArgs(hashToken("tok"), "alice").WillReturnRows(sqlmockUserRows(owner)) rr = httptest.NewRecorder() req := httptest.NewRequest(http.MethodPost, "/alice/demo.git/git-receive-pack", nil) req.SetBasicAuth("alice", "tok") s.handleGitHTTP(rr, req) if rr.Code != http.StatusForbidden || !strings.Contains(rr.Body.String(), "archived") { t.Fatalf("archived push status=%d body=%s", rr.Code, rr.Body.String()) } if err := mock.ExpectationsWereMet(); err != nil { t.Fatal(err) } } func sqlmockUserRows(user User) *sqlmock.Rows { return sqlmock.NewRows([]string{"id", "email", "username", "is_admin"}).AddRow(user.ID, user.Email, user.Username, user.IsAdmin) }