Skip to content

Commit d82bad6

Browse files
committed
Do not allow commiting to protected branch from online editor
1 parent 2368bbb commit d82bad6

File tree

5 files changed

+83
-8
lines changed

5 files changed

+83
-8
lines changed

models/branches.go

+17
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,23 @@ func (repo *Repository) GetProtectedBranches() ([]*ProtectedBranch, error) {
6363
return protectedBranches, x.Find(&protectedBranches, &ProtectedBranch{RepoID: repo.ID})
6464
}
6565

66+
// IsProtectedBranch checks if branch is protected
67+
func (repo *Repository) IsProtectedBranch(branchName string) (bool, error) {
68+
protectedBranch := &ProtectedBranch{
69+
RepoID: repo.ID,
70+
BranchName: branchName,
71+
}
72+
73+
has, err := x.Get(protectedBranch)
74+
if err != nil {
75+
return true, err
76+
} else if has {
77+
return true, nil
78+
}
79+
80+
return false, nil
81+
}
82+
6683
// AddProtectedBranch add protection to branch
6784
func (repo *Repository) AddProtectedBranch(branchName string, canPush bool) error {
6885
protectedBranch := &ProtectedBranch{

modules/context/repo.go

+10
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ func (r *Repository) CanEnableEditor() bool {
7575
return r.Repository.CanEnableEditor() && r.IsViewBranch && r.IsWriter()
7676
}
7777

78+
// CanCommitToBranch returns true if repository is editable and user has proper access level
79+
// and branch is not protected
80+
func (r *Repository) CanCommitToBranch() (bool, error) {
81+
protectedBranch, err := r.Repository.IsProtectedBranch(r.BranchName)
82+
if err != nil {
83+
return false, err
84+
}
85+
return r.CanEnableEditor() && !protectedBranch, nil
86+
}
87+
7888
// GetEditorconfig returns the .editorconfig definition if found in the
7989
// HEAD of the default repo branch.
8090
func (r *Repository) GetEditorconfig() (*editorconfig.Editorconfig, error) {

options/locale/locale_en-US.ini

+1
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ editor.fail_to_update_file = Failed to update/create file '%s' with error: %v
560560
editor.add_subdir = Add subdirectory...
561561
editor.unable_to_upload_files = Failed to upload files to '%s' with error: %v
562562
editor.upload_files_to_dir = Upload files to '%s'
563+
editor.cannot_commit_to_protected_branch = Can not commit to protected branch '%s'.
563564

564565
commits.commits = Commits
565566
commits.search = Search commits

routers/repo/editor.go

+53-6
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,26 @@ const (
2626
tplEditDiffPreview base.TplName = "repo/editor/diff_preview"
2727
tplDeleteFile base.TplName = "repo/editor/delete"
2828
tplUploadFile base.TplName = "repo/editor/upload"
29+
30+
frmCommitChoiceDirect string = "direct"
31+
frmCommitChoiceNewBranch string = "commit-to-new-branch"
2932
)
3033

34+
func renderCommitRights(ctx *context.Context) bool {
35+
canCommit, err := ctx.Repo.CanCommitToBranch()
36+
if err != nil {
37+
log.Error(4, "CanCommitToBranch: %v", err)
38+
}
39+
ctx.Data["CanCommitToBranch"] = canCommit
40+
return canCommit
41+
}
42+
3143
func editFile(ctx *context.Context, isNewFile bool) {
3244
ctx.Data["PageIsEdit"] = true
3345
ctx.Data["IsNewFile"] = isNewFile
3446
ctx.Data["RequireHighlightJS"] = true
3547
ctx.Data["RequireSimpleMDE"] = true
48+
canCommit := renderCommitRights(ctx)
3649

3750
var treeNames []string
3851
if len(ctx.Repo.TreePath) > 0 {
@@ -90,7 +103,11 @@ func editFile(ctx *context.Context, isNewFile bool) {
90103
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchName
91104
ctx.Data["commit_summary"] = ""
92105
ctx.Data["commit_message"] = ""
93-
ctx.Data["commit_choice"] = "direct"
106+
if canCommit {
107+
ctx.Data["commit_choice"] = frmCommitChoiceDirect
108+
} else {
109+
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
110+
}
94111
ctx.Data["new_branch_name"] = ""
95112
ctx.Data["last_commit"] = ctx.Repo.Commit.ID
96113
ctx.Data["MarkdownFileExts"] = strings.Join(setting.Markdown.FileExtensions, ",")
@@ -116,14 +133,15 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo
116133
ctx.Data["IsNewFile"] = isNewFile
117134
ctx.Data["RequireHighlightJS"] = true
118135
ctx.Data["RequireSimpleMDE"] = true
136+
canCommit := renderCommitRights(ctx)
119137

120138
oldBranchName := ctx.Repo.BranchName
121139
branchName := oldBranchName
122140
oldTreePath := ctx.Repo.TreePath
123141
lastCommit := form.LastCommit
124142
form.LastCommit = ctx.Repo.Commit.ID.String()
125143

126-
if form.CommitChoice == "commit-to-new-branch" {
144+
if form.CommitChoice == frmCommitChoiceNewBranch {
127145
branchName = form.NewBranchName
128146
}
129147

@@ -164,6 +182,11 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo
164182
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchName), tplEditFile, &form)
165183
return
166184
}
185+
} else if !canCommit {
186+
ctx.Data["Err_NewBranchName"] = true
187+
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
188+
ctx.RenderWithErr(ctx.Tr("repo.editor.cannot_commit_to_protected_branch", branchName), tplEditFile, &form)
189+
return
167190
}
168191

169192
var newTreePath string
@@ -317,10 +340,17 @@ func DeleteFile(ctx *context.Context) {
317340
ctx.Data["PageIsDelete"] = true
318341
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchName
319342
ctx.Data["TreePath"] = ctx.Repo.TreePath
343+
canCommit := renderCommitRights(ctx)
344+
320345
ctx.Data["commit_summary"] = ""
321346
ctx.Data["commit_message"] = ""
322-
ctx.Data["commit_choice"] = "direct"
347+
if canCommit {
348+
ctx.Data["commit_choice"] = frmCommitChoiceDirect
349+
} else {
350+
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
351+
}
323352
ctx.Data["new_branch_name"] = ""
353+
324354
ctx.HTML(200, tplDeleteFile)
325355
}
326356

@@ -329,11 +359,12 @@ func DeleteFilePost(ctx *context.Context, form auth.DeleteRepoFileForm) {
329359
ctx.Data["PageIsDelete"] = true
330360
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchName
331361
ctx.Data["TreePath"] = ctx.Repo.TreePath
362+
canCommit := renderCommitRights(ctx)
332363

333364
oldBranchName := ctx.Repo.BranchName
334365
branchName := oldBranchName
335366

336-
if form.CommitChoice == "commit-to-new-branch" {
367+
if form.CommitChoice == frmCommitChoiceNewBranch {
337368
branchName = form.NewBranchName
338369
}
339370
ctx.Data["commit_summary"] = form.CommitSummary
@@ -352,6 +383,11 @@ func DeleteFilePost(ctx *context.Context, form auth.DeleteRepoFileForm) {
352383
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchName), tplDeleteFile, &form)
353384
return
354385
}
386+
} else if !canCommit {
387+
ctx.Data["Err_NewBranchName"] = true
388+
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
389+
ctx.RenderWithErr(ctx.Tr("repo.editor.cannot_commit_to_protected_branch", branchName), tplDeleteFile, &form)
390+
return
355391
}
356392

357393
message := strings.TrimSpace(form.CommitSummary)
@@ -390,6 +426,7 @@ func renderUploadSettings(ctx *context.Context) {
390426
func UploadFile(ctx *context.Context) {
391427
ctx.Data["PageIsUpload"] = true
392428
renderUploadSettings(ctx)
429+
canCommit := renderCommitRights(ctx)
393430

394431
// We must at least have one element for user to input.
395432
treeNames := []string{""}
@@ -401,7 +438,11 @@ func UploadFile(ctx *context.Context) {
401438
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchName
402439
ctx.Data["commit_summary"] = ""
403440
ctx.Data["commit_message"] = ""
404-
ctx.Data["commit_choice"] = "direct"
441+
if canCommit {
442+
ctx.Data["commit_choice"] = frmCommitChoiceDirect
443+
} else {
444+
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
445+
}
405446
ctx.Data["new_branch_name"] = ""
406447

407448
ctx.HTML(200, tplUploadFile)
@@ -411,11 +452,12 @@ func UploadFile(ctx *context.Context) {
411452
func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) {
412453
ctx.Data["PageIsUpload"] = true
413454
renderUploadSettings(ctx)
455+
canCommit := renderCommitRights(ctx)
414456

415457
oldBranchName := ctx.Repo.BranchName
416458
branchName := oldBranchName
417459

418-
if form.CommitChoice == "commit-to-new-branch" {
460+
if form.CommitChoice == frmCommitChoiceNewBranch {
419461
branchName = form.NewBranchName
420462
}
421463

@@ -446,6 +488,11 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) {
446488
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchName), tplUploadFile, &form)
447489
return
448490
}
491+
} else if !canCommit {
492+
ctx.Data["Err_NewBranchName"] = true
493+
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
494+
ctx.RenderWithErr(ctx.Tr("repo.editor.cannot_commit_to_protected_branch", branchName), tplUploadFile, &form)
495+
return
449496
}
450497

451498
var newTreePath string

templates/repo/editor/commit_form.tmpl

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</div>
1111
<div class="quick-pull-choice js-quick-pull-choice">
1212
<div class="field">
13-
<div class="ui radio checkbox">
13+
<div class="ui radio checkbox {{if not .CanCommitToBranch}}disabled{{end}}">
1414
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="direct" {{if eq .commit_choice "direct"}}checked{{end}}>
1515
<label>
1616
<i class="octicon octicon-git-commit" height="16" width="14"></i>
@@ -40,4 +40,4 @@
4040
{{.i18n.Tr "repo.editor.commit_changes"}}
4141
</button>
4242
<a class="ui button red" href="{{EscapePound $.BranchLink}}/{{EscapePound .TreePath}}">{{.i18n.Tr "repo.editor.cancel"}}</a>
43-
</div>
43+
</div>

0 commit comments

Comments
 (0)