security: add permission check to 'delete branch after merge'

- Add a permission check that the doer has write permissions to the head
repository if the the 'delete branch after merge' is enabled when
merging a pull request.
- Unify the checks in the web and API router to `DeleteBranchAfterMerge`.
- Added integration tests.
This commit is contained in:
Gusted 2024-10-23 00:48:46 +02:00 committed by Earl Warren
parent 00379db370
commit 266e0b2ce9
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
7 changed files with 139 additions and 37 deletions

View file

@ -7,6 +7,8 @@ import (
"fmt"
"io"
"net/http"
"net/url"
"strings"
"testing"
auth_model "code.gitea.io/gitea/models/auth"
@ -17,6 +19,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/services/forms"
issue_service "code.gitea.io/gitea/services/issue"
"code.gitea.io/gitea/tests"
@ -309,3 +312,38 @@ func doAPIGetPullFiles(ctx APITestContext, pr *api.PullRequest, callback func(*t
}
}
}
func TestAPIPullDeleteBranchPerms(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
user2Session := loginUser(t, "user2")
user4Session := loginUser(t, "user4")
testRepoFork(t, user4Session, "user2", "repo1", "user4", "repo1")
testEditFileToNewBranch(t, user2Session, "user2", "repo1", "master", "base-pr", "README.md", "Hello, World\n(Edited - base PR)\n")
req := NewRequestWithValues(t, "POST", "/user4/repo1/compare/master...user2/repo1:base-pr", map[string]string{
"_csrf": GetCSRF(t, user4Session, "/user4/repo1/compare/master...user2/repo1:base-pr"),
"title": "Testing PR",
})
resp := user4Session.MakeRequest(t, req, http.StatusOK)
elem := strings.Split(test.RedirectURL(resp), "/")
token := getTokenForLoggedInUser(t, user4Session, auth_model.AccessTokenScopeWriteRepository)
req = NewRequestWithValues(t, "POST", "/api/v1/repos/user4/repo1/pulls/"+elem[4]+"/merge", map[string]string{
"do": "merge",
"delete_branch_after_merge": "on",
}).AddTokenAuth(token)
resp = user4Session.MakeRequest(t, req, http.StatusForbidden)
type userResponse struct {
Message string `json:"message"`
}
var bodyResp userResponse
DecodeJSON(t, resp, &bodyResp)
assert.EqualValues(t, "insufficient permission to delete head branch", bodyResp.Message)
// Check that the branch still exist.
req = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/branches/base-pr").AddTokenAuth(token)
user4Session.MakeRequest(t, req, http.StatusOK)
})
}