mirror of
https://codeberg.org/davrot/forgejo.git
synced 2025-05-28 12:00:01 +02:00
Branch protection: Possibility to not use whitelist but allow anyone with write access (#9055)
* Possibility to not use whitelist but allow anyone with write access * fix existing test * rename migration function * Try to give a better name for migration step * Clear settings if higher level setting is not set * Move official reviews to db instead of counting approvals each time * migration * fix * fix migration * fix migration * Remove NOT NULL from EnableWhitelist as migration isn't possible * Fix migration, reviews are connected to issues. * Fix SQL query issues in GetReviewersByPullID. * Simplify function GetReviewersByIssueID * Handle reviewers that has been deleted * Ensure reviews for test is in a well defined order * Only clear and set official reviews when it is an approve or reject.
This commit is contained in:
parent
6460284085
commit
bac4b78e09
20 changed files with 389 additions and 171 deletions
|
@ -39,6 +39,7 @@ type ProtectedBranch struct {
|
|||
MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
|
||||
EnableStatusCheck bool `xorm:"NOT NULL DEFAULT false"`
|
||||
StatusCheckContexts []string `xorm:"JSON TEXT"`
|
||||
EnableApprovalsWhitelist bool `xorm:"NOT NULL DEFAULT false"`
|
||||
ApprovalsWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
|
||||
ApprovalsWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
|
||||
RequiredApprovals int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
|
@ -53,10 +54,25 @@ func (protectBranch *ProtectedBranch) IsProtected() bool {
|
|||
|
||||
// CanUserPush returns if some user could push to this protected branch
|
||||
func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool {
|
||||
if !protectBranch.EnableWhitelist {
|
||||
if !protectBranch.CanPush {
|
||||
return false
|
||||
}
|
||||
|
||||
if !protectBranch.EnableWhitelist {
|
||||
if user, err := GetUserByID(userID); err != nil {
|
||||
log.Error("GetUserByID: %v", err)
|
||||
return false
|
||||
} else if repo, err := GetRepositoryByID(protectBranch.RepoID); err != nil {
|
||||
log.Error("GetRepositoryByID: %v", err)
|
||||
return false
|
||||
} else if writeAccess, err := HasAccessUnit(user, repo, UnitTypeCode, AccessModeWrite); err != nil {
|
||||
log.Error("HasAccessUnit: %v", err)
|
||||
return false
|
||||
} else {
|
||||
return writeAccess
|
||||
}
|
||||
}
|
||||
|
||||
if base.Int64sContains(protectBranch.WhitelistUserIDs, userID) {
|
||||
return true
|
||||
}
|
||||
|
@ -95,6 +111,38 @@ func (protectBranch *ProtectedBranch) CanUserMerge(userID int64) bool {
|
|||
return in
|
||||
}
|
||||
|
||||
// IsUserOfficialReviewer check if user is official reviewer for the branch (counts towards required approvals)
|
||||
func (protectBranch *ProtectedBranch) IsUserOfficialReviewer(user *User) (bool, error) {
|
||||
return protectBranch.isUserOfficialReviewer(x, user)
|
||||
}
|
||||
|
||||
func (protectBranch *ProtectedBranch) isUserOfficialReviewer(e Engine, user *User) (bool, error) {
|
||||
repo, err := getRepositoryByID(e, protectBranch.RepoID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !protectBranch.EnableApprovalsWhitelist {
|
||||
// Anyone with write access is considered official reviewer
|
||||
writeAccess, err := hasAccessUnit(e, user, repo, UnitTypeCode, AccessModeWrite)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return writeAccess, nil
|
||||
}
|
||||
|
||||
if base.Int64sContains(protectBranch.ApprovalsWhitelistUserIDs, user.ID) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
inTeam, err := isUserInTeams(e, user.ID, protectBranch.ApprovalsWhitelistTeamIDs)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return inTeam, nil
|
||||
}
|
||||
|
||||
// HasEnoughApprovals returns true if pr has enough granted approvals.
|
||||
func (protectBranch *ProtectedBranch) HasEnoughApprovals(pr *PullRequest) bool {
|
||||
if protectBranch.RequiredApprovals == 0 {
|
||||
|
@ -105,30 +153,16 @@ func (protectBranch *ProtectedBranch) HasEnoughApprovals(pr *PullRequest) bool {
|
|||
|
||||
// GetGrantedApprovalsCount returns the number of granted approvals for pr. A granted approval must be authored by a user in an approval whitelist.
|
||||
func (protectBranch *ProtectedBranch) GetGrantedApprovalsCount(pr *PullRequest) int64 {
|
||||
reviews, err := GetReviewersByPullID(pr.IssueID)
|
||||
approvals, err := x.Where("issue_id = ?", pr.Issue.ID).
|
||||
And("type = ?", ReviewTypeApprove).
|
||||
And("official = ?", true).
|
||||
Count(new(Review))
|
||||
if err != nil {
|
||||
log.Error("GetReviewersByPullID: %v", err)
|
||||
log.Error("GetGrantedApprovalsCount: %v", err)
|
||||
return 0
|
||||
}
|
||||
|
||||
approvals := int64(0)
|
||||
userIDs := make([]int64, 0)
|
||||
for _, review := range reviews {
|
||||
if review.Type != ReviewTypeApprove {
|
||||
continue
|
||||
}
|
||||
if base.Int64sContains(protectBranch.ApprovalsWhitelistUserIDs, review.ID) {
|
||||
approvals++
|
||||
continue
|
||||
}
|
||||
userIDs = append(userIDs, review.ID)
|
||||
}
|
||||
approvalTeamCount, err := UsersInTeamsCount(userIDs, protectBranch.ApprovalsWhitelistTeamIDs)
|
||||
if err != nil {
|
||||
log.Error("UsersInTeamsCount: %v", err)
|
||||
return 0
|
||||
}
|
||||
return approvalTeamCount + approvals
|
||||
return approvals
|
||||
}
|
||||
|
||||
// GetProtectedBranchByRepoID getting protected branch by repo ID
|
||||
|
@ -139,8 +173,12 @@ func GetProtectedBranchByRepoID(repoID int64) ([]*ProtectedBranch, error) {
|
|||
|
||||
// GetProtectedBranchBy getting protected branch by ID/Name
|
||||
func GetProtectedBranchBy(repoID int64, branchName string) (*ProtectedBranch, error) {
|
||||
return getProtectedBranchBy(x, repoID, branchName)
|
||||
}
|
||||
|
||||
func getProtectedBranchBy(e Engine, repoID int64, branchName string) (*ProtectedBranch, error) {
|
||||
rel := &ProtectedBranch{RepoID: repoID, BranchName: branchName}
|
||||
has, err := x.Get(rel)
|
||||
has, err := e.Get(rel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue