diff options
author | Jimmy Praet <jimmy.praet@telenet.be> | 2021-09-11 16:21:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-11 16:21:17 +0200 |
commit | 3d6cb25e315c0d4249c5c749a2eb8c64ec463aad (patch) | |
tree | bf9ba30a34e0e97b6a52584caffa1d3d9fe2506d /modules/repofiles | |
parent | eb03e819d323f6374d0a99a5b80d4674a18fa957 (diff) | |
download | gitea-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.go | 33 | ||||
-rw-r--r-- | modules/repofiles/update.go | 73 |
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 +} |