From 2cac3ccbf512574f923d8ee4dc0e643a1e0e1fd9 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Mon, 30 Sep 2024 10:28:09 +0800 Subject: [PATCH] Ensure `GetCSRF` doesn't return an empty token (#32130) Since page templates keep changing, some pages that contained forms with CSRF token no longer have them. It leads to some calls of `GetCSRF` returning an empty string, which fails the tests. Like https://github.com/go-gitea/gitea/blob/3269b04d61ffe6a7ce462cd05ee150e4491124e8/tests/integration/attachment_test.go#L62-L63 The test did try to get the CSRF token and provided it, but it was empty. --- tests/integration/attachment_test.go | 9 +++------ tests/integration/integration_test.go | 7 ++++++- tests/integration/org_test.go | 4 ---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/tests/integration/attachment_test.go b/tests/integration/attachment_test.go index 40969d26f2a2..11aa03bb7e71 100644 --- a/tests/integration/attachment_test.go +++ b/tests/integration/attachment_test.go @@ -29,7 +29,7 @@ func generateImg() bytes.Buffer { return buff } -func createAttachment(t *testing.T, session *TestSession, repoURL, filename string, buff bytes.Buffer, expectedStatus int) string { +func createAttachment(t *testing.T, session *TestSession, csrf, repoURL, filename string, buff bytes.Buffer, expectedStatus int) string { body := &bytes.Buffer{} // Setup multi-part @@ -41,8 +41,6 @@ func createAttachment(t *testing.T, session *TestSession, repoURL, filename stri err = writer.Close() assert.NoError(t, err) - csrf := GetCSRF(t, session, repoURL) - req := NewRequestWithBody(t, "POST", repoURL+"/issues/attachments", body) req.Header.Add("X-Csrf-Token", csrf) req.Header.Add("Content-Type", writer.FormDataContentType()) @@ -59,15 +57,14 @@ func createAttachment(t *testing.T, session *TestSession, repoURL, filename stri func TestCreateAnonymousAttachment(t *testing.T) { defer tests.PrepareTestEnv(t)() session := emptyTestSession(t) - // this test is not right because it just doesn't pass the CSRF validation - createAttachment(t, session, "user2/repo1", "image.png", generateImg(), http.StatusBadRequest) + createAttachment(t, session, GetCSRF(t, session, "/user/login"), "user2/repo1", "image.png", generateImg(), http.StatusSeeOther) } func TestCreateIssueAttachment(t *testing.T) { defer tests.PrepareTestEnv(t)() const repoURL = "user2/repo1" session := loginUser(t, "user2") - uuid := createAttachment(t, session, repoURL, "image.png", generateImg(), http.StatusOK) + uuid := createAttachment(t, session, GetCSRF(t, session, repoURL), repoURL, "image.png", generateImg(), http.StatusOK) req := NewRequest(t, "GET", repoURL+"/issues/new") resp := session.MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go index 18f415083c9e..96b2e9bf3d3d 100644 --- a/tests/integration/integration_test.go +++ b/tests/integration/integration_test.go @@ -37,6 +37,7 @@ import ( "github.com/PuerkitoBio/goquery" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/xeipuuv/gojsonschema" ) @@ -486,12 +487,16 @@ func VerifyJSONSchema(t testing.TB, resp *httptest.ResponseRecorder, schemaFile } // GetCSRF returns CSRF token from body +// If it fails, it means the CSRF token is not found in the response body returned by the url with the given session. +// In this case, you should find a better url to get it. func GetCSRF(t testing.TB, session *TestSession, urlStr string) string { t.Helper() req := NewRequest(t, "GET", urlStr) resp := session.MakeRequest(t, req, http.StatusOK) doc := NewHTMLParser(t, resp.Body) - return doc.GetCSRF() + csrf := doc.GetCSRF() + require.NotEmpty(t, csrf) + return csrf } // GetCSRFFrom returns CSRF token from body diff --git a/tests/integration/org_test.go b/tests/integration/org_test.go index 94c4e197271c..ef4ef2bb9b42 100644 --- a/tests/integration/org_test.go +++ b/tests/integration/org_test.go @@ -204,9 +204,7 @@ func TestTeamSearch(t *testing.T) { var results TeamSearchResults session := loginUser(t, user.Name) - csrf := GetCSRF(t, session, "/"+org.Name) req := NewRequestf(t, "GET", "/org/%s/teams/-/search?q=%s", org.Name, "_team") - req.Header.Add("X-Csrf-Token", csrf) resp := session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &results) assert.NotEmpty(t, results.Data) @@ -217,8 +215,6 @@ func TestTeamSearch(t *testing.T) { // no access if not organization member user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) session = loginUser(t, user5.Name) - csrf = GetCSRF(t, session, "/"+org.Name) req = NewRequestf(t, "GET", "/org/%s/teams/-/search?q=%s", org.Name, "team") - req.Header.Add("X-Csrf-Token", csrf) session.MakeRequest(t, req, http.StatusNotFound) }