mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-29 09:42:13 +01:00
59fc009e6e
- Currently the confirmation for dangerous actions such as transferring the repository or deleting it only requires the user to ~~copy paste~~ type the repository name. - This can be problematic when the user has a fork or another repository with the same name as an organization's repository, and the confirmation doesn't make clear that it could be deleting the wrong repository. While it's mentioned in the dialog, it's better to be on the safe side and also add the owner's name to be an element that has to be typed for these dangerous actions. - Added integration tests. (cherry picked from commitbf679b24dd
) (cherry picked from commit1963085dd9
) (cherry picked from commitfb94095d19
) (cherry picked from commite1d1e46afe
) (cherry picked from commit93993029e4
) (cherry picked from commitdf3b058179
) (cherry picked from commit8ccc6b9cba
) (cherry picked from commit9fbe28fca3
)
164 lines
5.9 KiB
Go
164 lines
5.9 KiB
Go
// Copyright 2017 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package integration
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"path"
|
|
"strings"
|
|
"testing"
|
|
|
|
"code.gitea.io/gitea/modules/test"
|
|
"code.gitea.io/gitea/tests"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func testPullCreate(t *testing.T, session *TestSession, user, repo, branch, title string) *httptest.ResponseRecorder {
|
|
req := NewRequest(t, "GET", path.Join(user, repo))
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
// Click the PR button to create a pull
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
link, exists := htmlDoc.doc.Find("#new-pull-request").Attr("href")
|
|
assert.True(t, exists, "The template has changed")
|
|
if branch != "master" {
|
|
link = strings.Replace(link, ":master", ":"+branch, 1)
|
|
}
|
|
|
|
req = NewRequest(t, "GET", link)
|
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
// Submit the form for creating the pull
|
|
htmlDoc = NewHTMLParser(t, resp.Body)
|
|
link, exists = htmlDoc.doc.Find("form.ui.form").Attr("action")
|
|
assert.True(t, exists, "The template has changed")
|
|
req = NewRequestWithValues(t, "POST", link, map[string]string{
|
|
"_csrf": htmlDoc.GetCSRF(),
|
|
"title": title,
|
|
})
|
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
return resp
|
|
}
|
|
|
|
func TestPullCreate(t *testing.T) {
|
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
|
session := loginUser(t, "user1")
|
|
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
|
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
|
|
resp := testPullCreate(t, session, "user1", "repo1", "master", "This is a pull title")
|
|
|
|
// check the redirected URL
|
|
url := test.RedirectURL(resp)
|
|
assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url)
|
|
|
|
// check .diff can be accessed and matches performed change
|
|
req := NewRequest(t, "GET", url+".diff")
|
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
assert.Regexp(t, `\+Hello, World \(Edited\)`, resp.Body)
|
|
assert.Regexp(t, "^diff", resp.Body)
|
|
assert.NotRegexp(t, "diff.*diff", resp.Body) // not two diffs, just one
|
|
|
|
// check .patch can be accessed and matches performed change
|
|
req = NewRequest(t, "GET", url+".patch")
|
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
assert.Regexp(t, `\+Hello, World \(Edited\)`, resp.Body)
|
|
assert.Regexp(t, "diff", resp.Body)
|
|
assert.Regexp(t, `Subject: \[PATCH\] Update README.md`, resp.Body)
|
|
assert.NotRegexp(t, "diff.*diff", resp.Body) // not two diffs, just one
|
|
})
|
|
}
|
|
|
|
func TestPullCreate_TitleEscape(t *testing.T) {
|
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
|
session := loginUser(t, "user1")
|
|
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
|
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
|
|
resp := testPullCreate(t, session, "user1", "repo1", "master", "<i>XSS PR</i>")
|
|
|
|
// check the redirected URL
|
|
url := test.RedirectURL(resp)
|
|
assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url)
|
|
|
|
// Edit title
|
|
req := NewRequest(t, "GET", url)
|
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
editTestTitleURL, exists := htmlDoc.doc.Find("#save-edit-title").First().Attr("data-update-url")
|
|
assert.True(t, exists, "The template has changed")
|
|
|
|
req = NewRequestWithValues(t, "POST", editTestTitleURL, map[string]string{
|
|
"_csrf": htmlDoc.GetCSRF(),
|
|
"title": "<u>XSS PR</u>",
|
|
})
|
|
session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
req = NewRequest(t, "GET", url)
|
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
htmlDoc = NewHTMLParser(t, resp.Body)
|
|
titleHTML, err := htmlDoc.doc.Find(".comment-list .timeline-item.event .text b").First().Html()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "<strike><i>XSS PR</i></strike>", titleHTML)
|
|
titleHTML, err = htmlDoc.doc.Find(".comment-list .timeline-item.event .text b").Next().Html()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "<u>XSS PR</u>", titleHTML)
|
|
})
|
|
}
|
|
|
|
func testUIDeleteBranch(t *testing.T, session *TestSession, ownerName, repoName, branchName string) {
|
|
relURL := "/" + path.Join(ownerName, repoName, "branches")
|
|
req := NewRequest(t, "GET", relURL)
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
|
|
req = NewRequestWithValues(t, "POST", relURL+"/delete", map[string]string{
|
|
"_csrf": htmlDoc.GetCSRF(),
|
|
"name": branchName,
|
|
})
|
|
session.MakeRequest(t, req, http.StatusOK)
|
|
}
|
|
|
|
func testDeleteRepository(t *testing.T, session *TestSession, ownerName, repoName string) {
|
|
relURL := "/" + path.Join(ownerName, repoName, "settings")
|
|
req := NewRequest(t, "GET", relURL)
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
|
|
|
req = NewRequestWithValues(t, "POST", relURL+"?action=delete", map[string]string{
|
|
"_csrf": htmlDoc.GetCSRF(),
|
|
"repo_name": fmt.Sprintf("%s/%s", ownerName, repoName),
|
|
})
|
|
session.MakeRequest(t, req, http.StatusSeeOther)
|
|
}
|
|
|
|
func TestPullBranchDelete(t *testing.T) {
|
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
session := loginUser(t, "user1")
|
|
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
|
testCreateBranch(t, session, "user1", "repo1", "branch/master", "master1", http.StatusSeeOther)
|
|
testEditFile(t, session, "user1", "repo1", "master1", "README.md", "Hello, World (Edited)\n")
|
|
resp := testPullCreate(t, session, "user1", "repo1", "master1", "This is a pull title")
|
|
|
|
// check the redirected URL
|
|
url := test.RedirectURL(resp)
|
|
assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url)
|
|
req := NewRequest(t, "GET", url)
|
|
session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
// delete head branch and confirm pull page is ok
|
|
testUIDeleteBranch(t, session, "user1", "repo1", "master1")
|
|
req = NewRequest(t, "GET", url)
|
|
session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
// delete head repository and confirm pull page is ok
|
|
testDeleteRepository(t, session, "user1", "repo1")
|
|
req = NewRequest(t, "GET", url)
|
|
session.MakeRequest(t, req, http.StatusOK)
|
|
})
|
|
}
|