Protect default branch against deletion ()

Although default branch is not offered for deletion in the templates, we need to prevent it both at the router level and in the pre-receive hook.

Co-authored-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
6543
2020-05-06 13:08:45 +02:00
committed by GitHub
parent a1f11a05e9
commit 505e456f26
3 changed files with 14 additions and 1 deletions
options/locale
routers
private
repo

@ -1683,6 +1683,7 @@ branch.deleted_by = Deleted by %s
branch.restore_success = Branch '%s' has been restored. branch.restore_success = Branch '%s' has been restored.
branch.restore_failed = Failed to restore branch '%s'. branch.restore_failed = Failed to restore branch '%s'.
branch.protected_deletion_failed = Branch '%s' is protected. It cannot be deleted. branch.protected_deletion_failed = Branch '%s' is protected. It cannot be deleted.
branch.default_deletion_failed = Branch '%s' is the default branch. It cannot be deleted.
branch.restore = Restore Branch '%s' branch.restore = Restore Branch '%s'
branch.download = Download Branch '%s' branch.download = Download Branch '%s'
branch.included_desc = This branch is part of the default branch branch.included_desc = This branch is part of the default branch

@ -206,6 +206,14 @@ func HookPreReceive(ctx *macaron.Context, opts private.HookOptions) {
refFullName := opts.RefFullNames[i] refFullName := opts.RefFullNames[i]
branchName := strings.TrimPrefix(refFullName, git.BranchPrefix) branchName := strings.TrimPrefix(refFullName, git.BranchPrefix)
if branchName == repo.DefaultBranch && newCommitID == git.EmptySHA {
log.Warn("Forbidden: Branch: %s is the default branch in %-v and cannot be deleted", branchName, repo)
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"err": fmt.Sprintf("branch %s is the default branch and cannot be deleted", branchName),
})
return
}
protectBranch, err := models.GetProtectedBranchBy(repo.ID, branchName) protectBranch, err := models.GetProtectedBranchBy(repo.ID, branchName)
if err != nil { if err != nil {
log.Error("Unable to get protected branch: %s in %-v Error: %v", branchName, repo, err) log.Error("Unable to get protected branch: %s in %-v Error: %v", branchName, repo, err)

@ -57,8 +57,12 @@ func Branches(ctx *context.Context) {
// DeleteBranchPost responses for delete merged branch // DeleteBranchPost responses for delete merged branch
func DeleteBranchPost(ctx *context.Context) { func DeleteBranchPost(ctx *context.Context) {
defer redirect(ctx) defer redirect(ctx)
branchName := ctx.Query("name") branchName := ctx.Query("name")
if branchName == ctx.Repo.Repository.DefaultBranch {
ctx.Flash.Error(ctx.Tr("repo.branch.default_deletion_failed", branchName))
return
}
isProtected, err := ctx.Repo.Repository.IsProtectedBranch(branchName, ctx.User) isProtected, err := ctx.Repo.Repository.IsProtectedBranch(branchName, ctx.User)
if err != nil { if err != nil {
log.Error("DeleteBranch: %v", err) log.Error("DeleteBranch: %v", err)