Skip to content

Commit c74b5fc

Browse files
committed
Check for protected branch also when committing to new branch
1 parent 6d23290 commit c74b5fc

File tree

6 files changed

+36
-27
lines changed

6 files changed

+36
-27
lines changed

routers/api/v1/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ func reqRepoWriter(unitTypes ...unit.Type) func(ctx *context.APIContext) {
434434
// reqRepoBranchWriter user should have a permission to write to a branch, or be a site admin
435435
func reqRepoBranchWriter(ctx *context.APIContext) {
436436
options, ok := web.GetForm(ctx).(api.FileOptionInterface)
437-
if !ok || (!ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, options.Branch()) && !ctx.IsUserSiteAdmin()) {
437+
if !ok || (!context.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.Repository, options.Branch()) && !ctx.IsUserSiteAdmin()) {
438438
ctx.APIError(http.StatusForbidden, "user should have a permission to write to this branch")
439439
return
440440
}

routers/api/v1/repo/file.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ func GetEditorconfig(ctx *context.APIContext) {
405405

406406
// canWriteFiles returns true if repository is editable and user has proper access level.
407407
func canWriteFiles(ctx *context.APIContext, branch string) bool {
408-
return ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, branch) &&
408+
return context.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.Repository, branch) &&
409409
!ctx.Repo.Repository.IsMirror &&
410410
!ctx.Repo.Repository.IsArchived
411411
}

routers/web/repo/editor.go

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func canCreateBasePullRequest(ctx *context.Context, editRepo *repo_model.Reposit
5353
func renderCommitRights(ctx *context.Context, editRepo *repo_model.Repository) bool {
5454
if editRepo == ctx.Repo.Repository {
5555
// Editing the same repository that we are viewing
56-
canCommitToBranch, err := ctx.Repo.CanCommitToBranch(ctx, ctx.Doer)
56+
canCommitToBranch, err := context.CanCommitToBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.BranchName)
5757
if err != nil {
5858
log.Error("CanCommitToBranch: %v", err)
5959
}
@@ -64,7 +64,7 @@ func renderCommitRights(ctx *context.Context, editRepo *repo_model.Repository) b
6464
return canCommitToBranch.CanCommitToBranch
6565
}
6666

67-
// Editing a user fork of the repository we are viewing
67+
// Editing a user fork of the repository we are viewing, always choose a new branch
6868
ctx.Data["CanCommitToBranch"] = context.CanCommitToBranchResults{}
6969
ctx.Data["CanCreatePullRequest"] = canCreateBasePullRequest(ctx, editRepo)
7070

@@ -121,7 +121,7 @@ func getParentTreeFields(treePath string) (treeNames, treePaths []string) {
121121
// This may be a fork of the repository owned by the user. If no repository can be found
122122
// for editing, nil is returned along with a message explaining why editing is not possible.
123123
func getEditRepository(ctx *context.Context) (*repo_model.Repository, any) {
124-
if ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
124+
if context.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.BranchName) {
125125
return ctx.Repo.Repository, nil
126126
}
127127

@@ -197,18 +197,23 @@ func GetEditRepositoryOrError(ctx *context.Context, tpl templates.TplName, form
197197

198198
// CheckPushEditBranch chesk if pushing to the branch in the edit repository is possible,
199199
// and if not renders an error and returns false.
200-
func CheckCanPushEditBranch(ctx *context.Context, editRepo *repo_model.Repository, branchName string, canCommit bool, tpl templates.TplName, form any) bool {
200+
func CheckCanPushEditBranch(ctx *context.Context, editRepo *repo_model.Repository, branchName string, tpl templates.TplName, form any) bool {
201+
// When pushing to a fork or another branch on the same repository, it should not exist yet
201202
if ctx.Repo.Repository != editRepo || ctx.Repo.BranchName != branchName {
202-
// When pushing to a fork or another branch on the same repository, it should not exist yet
203203
if exist, err := git_model.IsBranchExist(ctx, editRepo.ID, branchName); err == nil && exist {
204204
ctx.Data["Err_NewBranchName"] = true
205205
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchName), tpl, form)
206206
return false
207207
}
208-
} else if ctx.Repo.Repository == editRepo && !canCommit {
209-
// When we can't commit to the same branch on the same repository, it's protected
208+
}
209+
210+
// Check for protected branch
211+
canCommitToBranch, err := context.CanCommitToBranch(ctx, ctx.Doer, editRepo, branchName)
212+
if err != nil {
213+
log.Error("CanCommitToBranch: %v", err)
214+
}
215+
if !canCommitToBranch.CanCommitToBranch {
210216
ctx.Data["Err_NewBranchName"] = true
211-
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
212217
ctx.RenderWithErr(ctx.Tr("repo.editor.cannot_commit_to_protected_branch", branchName), tpl, form)
213218
return false
214219
}
@@ -464,10 +469,10 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
464469
return
465470
}
466471

467-
canCommit := renderCommitRights(ctx, editRepo)
472+
renderCommitRights(ctx, editRepo)
468473

469474
// Cannot commit to an existing branch if user doesn't have rights
470-
if !CheckCanPushEditBranch(ctx, editRepo, branchName, canCommit, tplEditFile, &form) {
475+
if !CheckCanPushEditBranch(ctx, editRepo, branchName, tplEditFile, &form) {
471476
return
472477
}
473478

@@ -704,10 +709,10 @@ func DeleteFilePost(ctx *context.Context) {
704709
return
705710
}
706711

707-
canCommit := renderCommitRights(ctx, editRepo)
712+
renderCommitRights(ctx, editRepo)
708713

709714
// Cannot commit to an existing branch if user doesn't have rights
710-
if !CheckCanPushEditBranch(ctx, editRepo, branchName, canCommit, tplDeleteFile, &form) {
715+
if !CheckCanPushEditBranch(ctx, editRepo, branchName, tplDeleteFile, &form) {
711716
return
712717
}
713718

@@ -903,9 +908,9 @@ func UploadFilePost(ctx *context.Context) {
903908
return
904909
}
905910

906-
canCommit := renderCommitRights(ctx, editRepo)
911+
renderCommitRights(ctx, editRepo)
907912

908-
if !CheckCanPushEditBranch(ctx, editRepo, branchName, canCommit, tplUploadFile, &form) {
913+
if !CheckCanPushEditBranch(ctx, editRepo, branchName, tplUploadFile, &form) {
909914
return
910915
}
911916

routers/web/repo/patch.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ func NewDiffPatchPost(ctx *context.Context) {
7676
return
7777
}
7878

79-
canCommit := renderCommitRights(ctx, editRepo)
79+
renderCommitRights(ctx, editRepo)
8080

8181
// Cannot commit to an existing branch if user doesn't have rights
82-
if !CheckCanPushEditBranch(ctx, editRepo, branchName, canCommit, tplPatchFile, &form) {
82+
if !CheckCanPushEditBranch(ctx, editRepo, branchName, tplPatchFile, &form) {
8383
return
8484
}
8585

services/context/permission.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func RequireRepoAdmin() func(ctx *Context) {
2424
// MustBeAbleToCherryPick checks if the user is allowed to cherry-pick to a branch of the repo
2525
func MustBeAbleToCherryPick() func(ctx *Context) {
2626
return func(ctx *Context) {
27-
if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) || !ctx.Repo.Repository.CanEnableEditor() {
27+
if !CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.BranchName) || !ctx.Repo.Repository.CanEnableEditor() {
2828
ctx.NotFound(nil)
2929
return
3030
}

services/context/repo.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,13 @@ type Repository struct {
6767
}
6868

6969
// CanWriteToBranch checks if the branch is writable by the user
70-
func (r *Repository) CanWriteToBranch(ctx context.Context, user *user_model.User, branch string) bool {
71-
return issues_model.CanMaintainerWriteToBranch(ctx, r.Permission, branch, user)
70+
func CanWriteToBranch(ctx context.Context, user *user_model.User, repo *repo_model.Repository, branch string) bool {
71+
permission, err := access_model.GetUserRepoPermission(ctx, repo, user)
72+
if err != nil {
73+
return false
74+
}
75+
76+
return issues_model.CanMaintainerWriteToBranch(ctx, permission, branch, user)
7277
}
7378

7479
// CanEnableEditor returns true if the web editor can be enabled for this repository,
@@ -124,24 +129,23 @@ type CanCommitToBranchResults struct {
124129
}
125130

126131
// CanCommitToBranch returns true if repository is editable and user has proper access level
127-
//
128132
// and branch is not protected for push
129-
func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.User) (CanCommitToBranchResults, error) {
130-
protectedBranch, err := git_model.GetFirstMatchProtectedBranchRule(ctx, r.Repository.ID, r.BranchName)
133+
func CanCommitToBranch(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, branchName string) (CanCommitToBranchResults, error) {
134+
protectedBranch, err := git_model.GetFirstMatchProtectedBranchRule(ctx, repo.ID, branchName)
131135
if err != nil {
132136
return CanCommitToBranchResults{}, err
133137
}
134138
userCanPush := true
135139
requireSigned := false
136140
if protectedBranch != nil {
137-
protectedBranch.Repo = r.Repository
141+
protectedBranch.Repo = repo
138142
userCanPush = protectedBranch.CanUserPush(ctx, doer)
139143
requireSigned = protectedBranch.RequireSignedCommits
140144
}
141145

142-
sign, keyID, _, err := asymkey_service.SignCRUDAction(ctx, r.Repository.RepoPath(), doer, r.Repository.RepoPath(), git.BranchPrefix+r.BranchName)
146+
sign, keyID, _, err := asymkey_service.SignCRUDAction(ctx, repo.RepoPath(), doer, repo.RepoPath(), git.BranchPrefix+branchName)
143147

144-
canCommit := r.CanEnableEditor() && r.CanWriteToBranch(ctx, doer, r.BranchName) && userCanPush
148+
canCommit := repo.CanEnableEditor() && CanWriteToBranch(ctx, doer, repo, branchName) && userCanPush
145149
if requireSigned {
146150
canCommit = canCommit && sign
147151
}

0 commit comments

Comments
 (0)