mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 19:06:18 +01:00 
			
		
		
		
	Added checks for protected branches in pull requests (#3544)
* Added checks for protected branches in pull requests Signed-off-by: Christian Wulff <NChris@posteo.net> * Moved check for protected branch into new function CheckUserAllowedToMerge Signed-off-by: Christian Wulff <NChris@posteo.net> * Removed merge conflict lines from last commit Signed-off-by: Christian Wulff <NChris@posteo.net> * Explicit check for error type in ViewIssue Signed-off-by: Christian Wulff <NChris@posteo.net>
This commit is contained in:
		| @@ -785,6 +785,21 @@ func (err ErrBranchNameConflict) Error() string { | |||||||
| 	return fmt.Sprintf("branch conflicts with existing branch [name: %s]", err.BranchName) | 	return fmt.Sprintf("branch conflicts with existing branch [name: %s]", err.BranchName) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ErrNotAllowedToMerge represents an error that a branch is protected and the current user is not allowed to modify it | ||||||
|  | type ErrNotAllowedToMerge struct { | ||||||
|  | 	Reason string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsErrNotAllowedToMerge checks if an error is an ErrNotAllowedToMerge. | ||||||
|  | func IsErrNotAllowedToMerge(err error) bool { | ||||||
|  | 	_, ok := err.(ErrNotAllowedToMerge) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (err ErrNotAllowedToMerge) Error() string { | ||||||
|  | 	return fmt.Sprintf("not allowed to merge [reason: %s]", err.Reason) | ||||||
|  | } | ||||||
|  |  | ||||||
| // ErrTagAlreadyExists represents an error that tag with such name already exists | // ErrTagAlreadyExists represents an error that tag with such name already exists | ||||||
| type ErrTagAlreadyExists struct { | type ErrTagAlreadyExists struct { | ||||||
| 	TagName string | 	TagName string | ||||||
|   | |||||||
| @@ -272,6 +272,31 @@ const ( | |||||||
| 	MergeStyleSquash MergeStyle = "squash" | 	MergeStyleSquash MergeStyle = "squash" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // CheckUserAllowedToMerge checks whether the user is allowed to merge | ||||||
|  | func (pr *PullRequest) CheckUserAllowedToMerge(doer *User) (err error) { | ||||||
|  | 	if doer == nil { | ||||||
|  | 		return ErrNotAllowedToMerge{ | ||||||
|  | 			"Not signed in", | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if pr.BaseRepo == nil { | ||||||
|  | 		if err = pr.GetBaseRepo(); err != nil { | ||||||
|  | 			return fmt.Errorf("GetBaseRepo: %v", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if protected, err := pr.BaseRepo.IsProtectedBranch(pr.BaseBranch, doer); err != nil { | ||||||
|  | 		return fmt.Errorf("IsProtectedBranch: %v", err) | ||||||
|  | 	} else if protected { | ||||||
|  | 		return ErrNotAllowedToMerge{ | ||||||
|  | 			"The branch is protected", | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // Merge merges pull request to base repository. | // Merge merges pull request to base repository. | ||||||
| // FIXME: add repoWorkingPull make sure two merges does not happen at same time. | // FIXME: add repoWorkingPull make sure two merges does not happen at same time. | ||||||
| func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle MergeStyle, message string) (err error) { | func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle MergeStyle, message string) (err error) { | ||||||
| @@ -287,6 +312,10 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle | |||||||
| 	} | 	} | ||||||
| 	prConfig := prUnit.PullRequestsConfig() | 	prConfig := prUnit.PullRequestsConfig() | ||||||
|  |  | ||||||
|  | 	if err := pr.CheckUserAllowedToMerge(doer); err != nil { | ||||||
|  | 		return fmt.Errorf("CheckUserAllowedToMerge: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Check if merge style is correct and allowed | 	// Check if merge style is correct and allowed | ||||||
| 	if !prConfig.IsMergeStyleAllowed(mergeStyle) { | 	if !prConfig.IsMergeStyleAllowed(mergeStyle) { | ||||||
| 		return ErrInvalidMergeStyle{pr.BaseRepo.ID, mergeStyle} | 		return ErrInvalidMergeStyle{pr.BaseRepo.ID, mergeStyle} | ||||||
|   | |||||||
| @@ -734,6 +734,15 @@ func ViewIssue(ctx *context.Context) { | |||||||
| 		} | 		} | ||||||
| 		prConfig := prUnit.PullRequestsConfig() | 		prConfig := prUnit.PullRequestsConfig() | ||||||
|  |  | ||||||
|  | 		ctx.Data["AllowMerge"] = ctx.Data["IsRepositoryWriter"] | ||||||
|  | 		if err := pull.CheckUserAllowedToMerge(ctx.User); err != nil { | ||||||
|  | 			if !models.IsErrNotAllowedToMerge(err) { | ||||||
|  | 				ctx.ServerError("CheckUserAllowedToMerge", err) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			ctx.Data["AllowMerge"] = false | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		// Check correct values and select default | 		// Check correct values and select default | ||||||
| 		if ms, ok := ctx.Data["MergeStyle"].(models.MergeStyle); !ok || | 		if ms, ok := ctx.Data["MergeStyle"].(models.MergeStyle); !ok || | ||||||
| 			!prConfig.IsMergeStyleAllowed(ms) { | 			!prConfig.IsMergeStyleAllowed(ms) { | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ | |||||||
| 					<span class="octicon octicon-check"></span> | 					<span class="octicon octicon-check"></span> | ||||||
| 					{{$.i18n.Tr "repo.pulls.can_auto_merge_desc"}} | 					{{$.i18n.Tr "repo.pulls.can_auto_merge_desc"}} | ||||||
| 				</div> | 				</div> | ||||||
| 				{{if .IsRepositoryWriter}} | 				{{if .AllowMerge}} | ||||||
| 					{{$prUnit := .Repository.MustGetUnit $.UnitTypePullRequests}} | 					{{$prUnit := .Repository.MustGetUnit $.UnitTypePullRequests}} | ||||||
| 					{{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowSquash}} | 					{{if or $prUnit.PullRequestsConfig.AllowMerge $prUnit.PullRequestsConfig.AllowRebase $prUnit.PullRequestsConfig.AllowSquash}} | ||||||
| 						<div class="ui divider"></div> | 						<div class="ui divider"></div> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user