From 3d6cb25e315c0d4249c5c749a2eb8c64ec463aad Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Sat, 11 Sep 2021 16:21:17 +0200 Subject: Support unprotected file patterns (#16395) Fixes #16381 Note that changes to unprotected files via the web editor still cannot be pushed directly to the protected branch. I could easily add such support for edits and deletes if needed. But for adding, uploading or renaming unprotected files, it is not trivial. * Extract & Move GetAffectedFiles to modules/git --- routers/api/v1/repo/branch.go | 5 +++++ routers/private/hook.go | 17 +++++++++++++++++ routers/web/repo/setting_protected_branch.go | 1 + 3 files changed, 23 insertions(+) (limited to 'routers') diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 8653b0bc80..c57075e3b8 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -498,6 +498,7 @@ func CreateBranchProtection(ctx *context.APIContext) { DismissStaleApprovals: form.DismissStaleApprovals, RequireSignedCommits: form.RequireSignedCommits, ProtectedFilePatterns: form.ProtectedFilePatterns, + UnprotectedFilePatterns: form.UnprotectedFilePatterns, BlockOnOutdatedBranch: form.BlockOnOutdatedBranch, } @@ -643,6 +644,10 @@ func EditBranchProtection(ctx *context.APIContext) { protectBranch.ProtectedFilePatterns = *form.ProtectedFilePatterns } + if form.UnprotectedFilePatterns != nil { + protectBranch.UnprotectedFilePatterns = *form.UnprotectedFilePatterns + } + if form.BlockOnOutdatedBranch != nil { protectBranch.BlockOnOutdatedBranch = *form.BlockOnOutdatedBranch } diff --git a/routers/private/hook.go b/routers/private/hook.go index 40edcd9c5a..d928dc421c 100644 --- a/routers/private/hook.go +++ b/routers/private/hook.go @@ -343,6 +343,23 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) { return } + // Allow commits that only touch unprotected files + globs := protectBranch.GetUnprotectedFilePatterns() + if len(globs) > 0 { + unprotectedFilesOnly, err := pull_service.CheckUnprotectedFiles(oldCommitID, newCommitID, globs, env, gitRepo) + if err != nil { + log.Error("Unable to check file protection for commits from %s to %s in %-v: %v", oldCommitID, newCommitID, repo, err) + ctx.JSON(http.StatusInternalServerError, private.Response{ + Err: fmt.Sprintf("Unable to check file protection for commits from %s to %s: %v", oldCommitID, newCommitID, err), + }) + return + } + if unprotectedFilesOnly { + // Commit only touches unprotected files, this is allowed + continue + } + } + // Or we're simply not able to push to this protected branch log.Warn("Forbidden: User %d is not allowed to push to protected branch: %s in %-v", opts.UserID, branchName, repo) ctx.JSON(http.StatusForbidden, private.Response{ diff --git a/routers/web/repo/setting_protected_branch.go b/routers/web/repo/setting_protected_branch.go index 30c7d81b8e..c48ab9471a 100644 --- a/routers/web/repo/setting_protected_branch.go +++ b/routers/web/repo/setting_protected_branch.go @@ -253,6 +253,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) { protectBranch.DismissStaleApprovals = f.DismissStaleApprovals protectBranch.RequireSignedCommits = f.RequireSignedCommits protectBranch.ProtectedFilePatterns = f.ProtectedFilePatterns + protectBranch.UnprotectedFilePatterns = f.UnprotectedFilePatterns protectBranch.BlockOnOutdatedBranch = f.BlockOnOutdatedBranch err = models.UpdateProtectBranch(ctx.Repo.Repository, protectBranch, models.WhitelistOptions{ -- cgit v1.2.3