Add an option to protected branches to add writing deploy keys to the whitelist for pushing.
Please note this is technically a breaking change: previously if the owner of a repository was on the whitelist then any writing deploy key was effectively on the whitelist. This option will now need to be set if that is desired.
Closes #8472
Details:
* Allow Protected Branches to Whitelist Deploy Keys
* Add migration
* Ensure that IsDeployKey is set to false on the http pushes
* add not null default false
reponame := os.Getenv(models.EnvRepoName)
userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
prID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchPRID), 10, 64)
+ isDeployKey, _ := strconv.ParseBool(os.Getenv(models.EnvIsDeployKey))
buf := bytes.NewBuffer(nil)
scanner := bufio.NewScanner(os.Stdin)
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
ProtectedBranchID: prID,
+ IsDeployKey: isDeployKey,
})
switch statusCode {
case http.StatusInternalServerError:
os.Setenv(models.EnvPusherID, strconv.FormatInt(results.UserID, 10))
os.Setenv(models.ProtectedBranchRepoID, strconv.FormatInt(results.RepoID, 10))
os.Setenv(models.ProtectedBranchPRID, fmt.Sprintf("%d", 0))
+ os.Setenv(models.EnvIsDeployKey, fmt.Sprintf("%t", results.IsDeployKey))
+ os.Setenv(models.EnvKeyID, fmt.Sprintf("%d", results.KeyID))
//LFS token authentication
if verb == lfsAuthenticateVerb {
WhitelistUserIDs []int64 `xorm:"JSON TEXT"`
WhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
EnableMergeWhitelist bool `xorm:"NOT NULL DEFAULT false"`
+ WhitelistDeployKeys bool `xorm:"NOT NULL DEFAULT false"`
MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
EnableStatusCheck bool `xorm:"NOT NULL DEFAULT false"`
NewMigration("change length of some external login users columns", changeSomeColumnsLengthOfExternalLoginUser),
// v102 -> v103
NewMigration("update migration repositories' service type", dropColumnHeadUserNameOnPullRequest),
+ // v103 -> v104
+ NewMigration("Add WhitelistDeployKeys to protected branch", addWhitelistDeployKeysToBranches),
}
// Migrate database to current version
--- /dev/null
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+ "xorm.io/xorm"
+)
+
+func addWhitelistDeployKeysToBranches(x *xorm.Engine) error {
+ type ProtectedBranch struct {
+ ID int64
+ WhitelistDeployKeys bool `xorm:"NOT NULL DEFAULT false"`
+ }
+
+ return x.Sync2(new(ProtectedBranch))
+}
EnvPusherName = "GITEA_PUSHER_NAME"
EnvPusherEmail = "GITEA_PUSHER_EMAIL"
EnvPusherID = "GITEA_PUSHER_ID"
+ EnvKeyID = "GITEA_KEY_ID"
+ EnvIsDeployKey = "GITEA_IS_DEPLOY_KEY"
)
// CommitToPushCommit transforms a git.Commit to PushCommit type.
EnableWhitelist bool
WhitelistUsers string
WhitelistTeams string
+ WhitelistDeployKeys bool
EnableMergeWhitelist bool
MergeWhitelistUsers string
MergeWhitelistTeams string
GitAlternativeObjectDirectories string
GitQuarantinePath string
ProtectedBranchID int64
+ IsDeployKey bool
}
// HookPreReceive check whether the provided commits are allowed
func HookPreReceive(ownerName, repoName string, opts HookOptions) (int, string) {
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s?old=%s&new=%s&ref=%s&userID=%d&gitObjectDirectory=%s&gitAlternativeObjectDirectories=%s&gitQuarantinePath=%s&prID=%d",
+ reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s?old=%s&new=%s&ref=%s&userID=%d&gitObjectDirectory=%s&gitAlternativeObjectDirectories=%s&gitQuarantinePath=%s&prID=%d&isDeployKey=%t",
url.PathEscape(ownerName),
url.PathEscape(repoName),
url.QueryEscape(opts.OldCommitID),
url.QueryEscape(opts.GitAlternativeObjectDirectories),
url.QueryEscape(opts.GitQuarantinePath),
opts.ProtectedBranchID,
+ opts.IsDeployKey,
)
resp, err := newInternalRequest(reqURL, "GET").Response()
settings.protect_this_branch_desc = Prevent deletion and disable any Git pushing to the branch.
settings.protect_whitelist_committers = Enable Push Whitelist
settings.protect_whitelist_committers_desc = Allow whitelisted users or teams to push to this branch (but not force push).
+settings.protect_whitelist_deploy_keys = Whitelist deploy keys with write access to push
settings.protect_whitelist_users = Whitelisted users for pushing:
settings.protect_whitelist_search_users = Search users…
settings.protect_whitelist_teams = Whitelisted teams for pushing:
gitAlternativeObjectDirectories := ctx.QueryTrim("gitAlternativeObjectDirectories")
gitQuarantinePath := ctx.QueryTrim("gitQuarantinePath")
prID := ctx.QueryInt64("prID")
+ isDeployKey := ctx.QueryBool("isDeployKey")
branchName := strings.TrimPrefix(refFullName, git.BranchPrefix)
repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName)
}
}
- canPush := protectBranch.CanUserPush(userID)
+ canPush := false
+ if isDeployKey {
+ canPush = protectBranch.WhitelistDeployKeys
+ } else {
+ canPush = protectBranch.CanUserPush(userID)
+ }
if !canPush && prID > 0 {
pr, err := models.GetPullRequestByID(prID)
if err != nil {
models.EnvPusherName + "=" + authUser.Name,
models.EnvPusherID + fmt.Sprintf("=%d", authUser.ID),
models.ProtectedBranchRepoID + fmt.Sprintf("=%d", repo.ID),
+ models.EnvIsDeployKey + "=false",
}
if !authUser.KeepEmailPrivate {
protectBranch.EnableStatusCheck = f.EnableStatusCheck
protectBranch.StatusCheckContexts = f.StatusCheckContexts
+ protectBranch.WhitelistDeployKeys = f.WhitelistDeployKeys
protectBranch.RequiredApprovals = f.RequiredApprovals
if strings.TrimSpace(f.ApprovalsWhitelistUsers) != "" {
</div>
</div>
{{end}}
+ <br>
+ <div class="whitelist field">
+ <div class="ui checkbox">
+ <input type="checkbox" name="whitelist_deploy_keys" {{if .Branch.WhitelistDeployKeys}}checked{{end}}>
+ <label for="whitelist_deploy_keys">{{.i18n.Tr "repo.settings.protect_whitelist_deploy_keys"}}</label>
+ </div>
+ </div>
</div>
<div class="field">