Supports wildcard protected branch (#20825)
This PR introduce glob match for protected branch name. The separator is `/` and you can use `*` matching non-separator chars and use `**` across separator. It also supports input an exist or non-exist branch name as matching condition and branch name condition has high priority than glob rule. Should fix #2529 and #15705 screenshots <img width="1160" alt="image" src="https://user-images.githubusercontent.com/81045/205651179-ebb5492a-4ade-4bb4-a13c-965e8c927063.png"> Co-authored-by: zeripath <art27@cantab.net>
This commit is contained in:
parent
cc1f8cbe96
commit
2782c14396
39 changed files with 1222 additions and 819 deletions
|
@ -38,21 +38,21 @@ func testAPIGetBranchProtection(t *testing.T, branchName string, expectedHTTPSta
|
|||
if resp.Code == http.StatusOK {
|
||||
var branchProtection api.BranchProtection
|
||||
DecodeJSON(t, resp, &branchProtection)
|
||||
assert.EqualValues(t, branchName, branchProtection.BranchName)
|
||||
assert.EqualValues(t, branchName, branchProtection.RuleName)
|
||||
}
|
||||
}
|
||||
|
||||
func testAPICreateBranchProtection(t *testing.T, branchName string, expectedHTTPStatus int) {
|
||||
token := getUserToken(t, "user2")
|
||||
req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/branch_protections?token="+token, &api.BranchProtection{
|
||||
BranchName: branchName,
|
||||
RuleName: branchName,
|
||||
})
|
||||
resp := MakeRequest(t, req, expectedHTTPStatus)
|
||||
|
||||
if resp.Code == http.StatusCreated {
|
||||
var branchProtection api.BranchProtection
|
||||
DecodeJSON(t, resp, &branchProtection)
|
||||
assert.EqualValues(t, branchName, branchProtection.BranchName)
|
||||
assert.EqualValues(t, branchName, branchProtection.RuleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ func testAPIEditBranchProtection(t *testing.T, branchName string, body *api.Bran
|
|||
if resp.Code == http.StatusOK {
|
||||
var branchProtection api.BranchProtection
|
||||
DecodeJSON(t, resp, &branchProtection)
|
||||
assert.EqualValues(t, branchName, branchProtection.BranchName)
|
||||
assert.EqualValues(t, branchName, branchProtection.RuleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,8 +169,8 @@ func testAPICreateBranch(t testing.TB, session *TestSession, user, repo, oldBran
|
|||
func TestAPIBranchProtection(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
// Branch protection only on branch that exist
|
||||
testAPICreateBranchProtection(t, "master/doesnotexist", http.StatusNotFound)
|
||||
// Branch protection on branch that not exist
|
||||
testAPICreateBranchProtection(t, "master/doesnotexist", http.StatusCreated)
|
||||
// Get branch protection on branch that exist but not branch protection
|
||||
testAPIGetBranchProtection(t, "master", http.StatusNotFound)
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import (
|
|||
"path"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -43,15 +45,16 @@ func TestCreateFileOnProtectedBranch(t *testing.T) {
|
|||
|
||||
csrf := GetCSRF(t, session, "/user2/repo1/settings/branches")
|
||||
// Change master branch to protected
|
||||
req := NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/master", map[string]string{
|
||||
"_csrf": csrf,
|
||||
"protected": "on",
|
||||
req := NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/edit", map[string]string{
|
||||
"_csrf": csrf,
|
||||
"rule_name": "master",
|
||||
"enable_push": "true",
|
||||
})
|
||||
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
// Check if master branch has been locked successfully
|
||||
flashCookie := session.GetCookie("macaron_flash")
|
||||
assert.NotNil(t, flashCookie)
|
||||
assert.EqualValues(t, "success%3DBranch%2Bprotection%2Bfor%2Bbranch%2B%2527master%2527%2Bhas%2Bbeen%2Bupdated.", flashCookie.Value)
|
||||
assert.EqualValues(t, "success%3DBranch%2Bprotection%2Bfor%2Brule%2B%2527master%2527%2Bhas%2Bbeen%2Bupdated.", flashCookie.Value)
|
||||
|
||||
// Request editor page
|
||||
req = NewRequest(t, "GET", "/user2/repo1/_new/master/")
|
||||
|
@ -76,16 +79,22 @@ func TestCreateFileOnProtectedBranch(t *testing.T) {
|
|||
|
||||
// remove the protected branch
|
||||
csrf = GetCSRF(t, session, "/user2/repo1/settings/branches")
|
||||
|
||||
// Change master branch to protected
|
||||
req = NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/master", map[string]string{
|
||||
"_csrf": csrf,
|
||||
"protected": "off",
|
||||
req = NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/1/delete", map[string]string{
|
||||
"_csrf": csrf,
|
||||
})
|
||||
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
res := make(map[string]string)
|
||||
assert.NoError(t, json.NewDecoder(resp.Body).Decode(&res))
|
||||
assert.EqualValues(t, "/user2/repo1/settings/branches", res["redirect"])
|
||||
|
||||
// Check if master branch has been locked successfully
|
||||
flashCookie = session.GetCookie("macaron_flash")
|
||||
assert.NotNil(t, flashCookie)
|
||||
assert.EqualValues(t, "success%3DBranch%2Bprotection%2Bfor%2Bbranch%2B%2527master%2527%2Bhas%2Bbeen%2Bdisabled.", flashCookie.Value)
|
||||
assert.EqualValues(t, "error%3DRemoving%2Bbranch%2Bprotection%2Brule%2B%25271%2527%2Bfailed.", flashCookie.Value)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -414,9 +414,9 @@ func doProtectBranch(ctx APITestContext, branch, userToWhitelist, unprotectedFil
|
|||
|
||||
if userToWhitelist == "" {
|
||||
// Change branch to protected
|
||||
req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/settings/branches/%s", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), url.PathEscape(branch)), map[string]string{
|
||||
req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/settings/branches/edit", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame)), map[string]string{
|
||||
"_csrf": csrf,
|
||||
"protected": "on",
|
||||
"rule_name": branch,
|
||||
"unprotected_file_patterns": unprotectedFilePatterns,
|
||||
})
|
||||
ctx.Session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
|
@ -424,9 +424,9 @@ func doProtectBranch(ctx APITestContext, branch, userToWhitelist, unprotectedFil
|
|||
user, err := user_model.GetUserByName(db.DefaultContext, userToWhitelist)
|
||||
assert.NoError(t, err)
|
||||
// Change branch to protected
|
||||
req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/settings/branches/%s", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), url.PathEscape(branch)), map[string]string{
|
||||
req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/settings/branches/edit", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame)), map[string]string{
|
||||
"_csrf": csrf,
|
||||
"protected": "on",
|
||||
"rule_name": branch,
|
||||
"enable_push": "whitelist",
|
||||
"enable_whitelist": "on",
|
||||
"whitelist_users": strconv.FormatInt(user.ID, 10),
|
||||
|
@ -437,7 +437,7 @@ func doProtectBranch(ctx APITestContext, branch, userToWhitelist, unprotectedFil
|
|||
// Check if master branch has been locked successfully
|
||||
flashCookie := ctx.Session.GetCookie("macaron_flash")
|
||||
assert.NotNil(t, flashCookie)
|
||||
assert.EqualValues(t, "success%3DBranch%2Bprotection%2Bfor%2Bbranch%2B%2527"+url.QueryEscape(branch)+"%2527%2Bhas%2Bbeen%2Bupdated.", flashCookie.Value)
|
||||
assert.EqualValues(t, "success%3DBranch%2Bprotection%2Bfor%2Brule%2B%2527"+url.QueryEscape(branch)+"%2527%2Bhas%2Bbeen%2Bupdated.", flashCookie.Value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue