summaryrefslogtreecommitdiffstats
path: root/modules/repofiles
diff options
context:
space:
mode:
authorJimmy Praet <jimmy.praet@telenet.be>2021-09-11 16:21:17 +0200
committerGitHub <noreply@github.com>2021-09-11 16:21:17 +0200
commit3d6cb25e315c0d4249c5c749a2eb8c64ec463aad (patch)
treebf9ba30a34e0e97b6a52584caffa1d3d9fe2506d /modules/repofiles
parenteb03e819d323f6374d0a99a5b80d4674a18fa957 (diff)
downloadgitea-3d6cb25e315c0d4249c5c749a2eb8c64ec463aad.tar.gz
gitea-3d6cb25e315c0d4249c5c749a2eb8c64ec463aad.zip
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
Diffstat (limited to 'modules/repofiles')
-rw-r--r--modules/repofiles/delete.go33
-rw-r--r--modules/repofiles/update.go73
2 files changed, 44 insertions, 62 deletions
diff --git a/modules/repofiles/delete.go b/modules/repofiles/delete.go
index 2b8ddf3cc2..5ae418b7f6 100644
--- a/modules/repofiles/delete.go
+++ b/modules/repofiles/delete.go
@@ -56,37 +56,8 @@ func DeleteRepoFile(repo *models.Repository, doer *models.User, opts *DeleteRepo
BranchName: opts.NewBranch,
}
}
- } else {
- protectedBranch, err := repo.GetBranchProtection(opts.OldBranch)
- if err != nil {
- return nil, err
- }
- if protectedBranch != nil {
- if !protectedBranch.CanUserPush(doer.ID) {
- return nil, models.ErrUserCannotCommit{
- UserName: doer.LowerName,
- }
- }
- if protectedBranch.RequireSignedCommits {
- _, _, _, err := repo.SignCRUDAction(doer, repo.RepoPath(), opts.OldBranch)
- if err != nil {
- if !models.IsErrWontSign(err) {
- return nil, err
- }
- return nil, models.ErrUserCannotCommit{
- UserName: doer.LowerName,
- }
- }
- }
- patterns := protectedBranch.GetProtectedFilePatterns()
- for _, pat := range patterns {
- if pat.Match(strings.ToLower(opts.TreePath)) {
- return nil, models.ErrFilePathProtected{
- Path: opts.TreePath,
- }
- }
- }
- }
+ } else if err := VerifyBranchProtection(repo, doer, opts.OldBranch, opts.TreePath); err != nil {
+ return nil, err
}
// Check that the path given in opts.treeName is valid (not a git path)
diff --git a/modules/repofiles/update.go b/modules/repofiles/update.go
index ad984c465a..dc2893cb1c 100644
--- a/modules/repofiles/update.go
+++ b/modules/repofiles/update.go
@@ -148,37 +148,8 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
if err != nil && !git.IsErrBranchNotExist(err) {
return nil, err
}
- } else {
- protectedBranch, err := repo.GetBranchProtection(opts.OldBranch)
- if err != nil {
- return nil, err
- }
- if protectedBranch != nil {
- if !protectedBranch.CanUserPush(doer.ID) {
- return nil, models.ErrUserCannotCommit{
- UserName: doer.LowerName,
- }
- }
- if protectedBranch.RequireSignedCommits {
- _, _, _, err := repo.SignCRUDAction(doer, repo.RepoPath(), opts.OldBranch)
- if err != nil {
- if !models.IsErrWontSign(err) {
- return nil, err
- }
- return nil, models.ErrUserCannotCommit{
- UserName: doer.LowerName,
- }
- }
- }
- patterns := protectedBranch.GetProtectedFilePatterns()
- for _, pat := range patterns {
- if pat.Match(strings.ToLower(opts.TreePath)) {
- return nil, models.ErrFilePathProtected{
- Path: opts.TreePath,
- }
- }
- }
- }
+ } else if err := VerifyBranchProtection(repo, doer, opts.OldBranch, opts.TreePath); err != nil {
+ return nil, err
}
// If FromTreePath is not set, set it to the opts.TreePath
@@ -465,3 +436,43 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
}
return file, nil
}
+
+// VerifyBranchProtection verify the branch protection for modifying the given treePath on the given branch
+func VerifyBranchProtection(repo *models.Repository, doer *models.User, branchName string, treePath string) error {
+ protectedBranch, err := repo.GetBranchProtection(branchName)
+ if err != nil {
+ return err
+ }
+ if protectedBranch != nil {
+ isUnprotectedFile := false
+ glob := protectedBranch.GetUnprotectedFilePatterns()
+ if len(glob) != 0 {
+ isUnprotectedFile = protectedBranch.IsUnprotectedFile(glob, treePath)
+ }
+ if !protectedBranch.CanUserPush(doer.ID) && !isUnprotectedFile {
+ return models.ErrUserCannotCommit{
+ UserName: doer.LowerName,
+ }
+ }
+ if protectedBranch.RequireSignedCommits {
+ _, _, _, err := repo.SignCRUDAction(doer, repo.RepoPath(), branchName)
+ if err != nil {
+ if !models.IsErrWontSign(err) {
+ return err
+ }
+ return models.ErrUserCannotCommit{
+ UserName: doer.LowerName,
+ }
+ }
+ }
+ patterns := protectedBranch.GetProtectedFilePatterns()
+ for _, pat := range patterns {
+ if pat.Match(strings.ToLower(treePath)) {
+ return models.ErrFilePathProtected{
+ Path: treePath,
+ }
+ }
+ }
+ }
+ return nil
+}