mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-22 12:54:53 -05:00
* Fix #6946 by checking PullRequest ID on pushing * Ensure we have the owner name, the pr attributes and the the issue * Fix TestSearchRepo by waiting till indexing is done * Update integrations/repo_search_test.go * changes as per @mrsdizzie * missing comma * Spelling mistake * Fix full pushing environment
This commit is contained in:
parent
e5a4d784e8
commit
3563650bdb
8 changed files with 54 additions and 13 deletions
|
@ -65,6 +65,7 @@ func runHookPreReceive(c *cli.Context) error {
|
||||||
username := os.Getenv(models.EnvRepoUsername)
|
username := os.Getenv(models.EnvRepoUsername)
|
||||||
reponame := os.Getenv(models.EnvRepoName)
|
reponame := os.Getenv(models.EnvRepoName)
|
||||||
userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
|
userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
|
||||||
|
prID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchPRID), 10, 64)
|
||||||
|
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
scanner := bufio.NewScanner(os.Stdin)
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
@ -95,6 +96,7 @@ func runHookPreReceive(c *cli.Context) error {
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
|
GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
|
||||||
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
|
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
|
||||||
|
ProtectedBranchID: prID,
|
||||||
})
|
})
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
|
|
|
@ -191,6 +191,7 @@ func runServ(c *cli.Context) error {
|
||||||
os.Setenv(models.EnvPusherName, results.UserName)
|
os.Setenv(models.EnvPusherName, results.UserName)
|
||||||
os.Setenv(models.EnvPusherID, strconv.FormatInt(results.UserID, 10))
|
os.Setenv(models.EnvPusherID, strconv.FormatInt(results.UserID, 10))
|
||||||
os.Setenv(models.ProtectedBranchRepoID, strconv.FormatInt(results.RepoID, 10))
|
os.Setenv(models.ProtectedBranchRepoID, strconv.FormatInt(results.RepoID, 10))
|
||||||
|
os.Setenv(models.ProtectedBranchPRID, fmt.Sprintf("%d", 0))
|
||||||
|
|
||||||
//LFS token authentication
|
//LFS token authentication
|
||||||
if verb == lfsAuthenticateVerb {
|
if verb == lfsAuthenticateVerb {
|
||||||
|
@ -239,8 +240,6 @@ func runServ(c *cli.Context) error {
|
||||||
gitcmd = exec.Command(verb, repoPath)
|
gitcmd = exec.Command(verb, repoPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Setenv(models.ProtectedBranchRepoID, fmt.Sprintf("%d", results.RepoID))
|
|
||||||
|
|
||||||
gitcmd.Dir = setting.RepoRootPath
|
gitcmd.Dir = setting.RepoRootPath
|
||||||
gitcmd.Stdout = os.Stdout
|
gitcmd.Stdout = os.Stdout
|
||||||
gitcmd.Stdin = os.Stdin
|
gitcmd.Stdin = os.Stdin
|
||||||
|
|
|
@ -19,6 +19,8 @@ import (
|
||||||
const (
|
const (
|
||||||
// ProtectedBranchRepoID protected Repo ID
|
// ProtectedBranchRepoID protected Repo ID
|
||||||
ProtectedBranchRepoID = "GITEA_REPO_ID"
|
ProtectedBranchRepoID = "GITEA_REPO_ID"
|
||||||
|
// ProtectedBranchPRID protected Repo PR ID
|
||||||
|
ProtectedBranchPRID = "GITEA_PR_ID"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProtectedBranch struct
|
// ProtectedBranch struct
|
||||||
|
|
|
@ -12,26 +12,34 @@ import (
|
||||||
|
|
||||||
// PushingEnvironment returns an os environment to allow hooks to work on push
|
// PushingEnvironment returns an os environment to allow hooks to work on push
|
||||||
func PushingEnvironment(doer *User, repo *Repository) []string {
|
func PushingEnvironment(doer *User, repo *Repository) []string {
|
||||||
|
return FullPushingEnvironment(doer, doer, repo, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FullPushingEnvironment returns an os environment to allow hooks to work on push
|
||||||
|
func FullPushingEnvironment(author, committer *User, repo *Repository, prID int64) []string {
|
||||||
isWiki := "false"
|
isWiki := "false"
|
||||||
if strings.HasSuffix(repo.Name, ".wiki") {
|
if strings.HasSuffix(repo.Name, ".wiki") {
|
||||||
isWiki = "true"
|
isWiki = "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
sig := doer.NewGitSig()
|
authorSig := author.NewGitSig()
|
||||||
|
committerSig := committer.NewGitSig()
|
||||||
|
|
||||||
// We should add "SSH_ORIGINAL_COMMAND=gitea-internal",
|
// We should add "SSH_ORIGINAL_COMMAND=gitea-internal",
|
||||||
// once we have hook and pushing infrastructure working correctly
|
// once we have hook and pushing infrastructure working correctly
|
||||||
return append(os.Environ(),
|
return append(os.Environ(),
|
||||||
"GIT_AUTHOR_NAME="+sig.Name,
|
"GIT_AUTHOR_NAME="+authorSig.Name,
|
||||||
"GIT_AUTHOR_EMAIL="+sig.Email,
|
"GIT_AUTHOR_EMAIL="+authorSig.Email,
|
||||||
"GIT_COMMITTER_NAME="+sig.Name,
|
"GIT_COMMITTER_NAME="+committerSig.Name,
|
||||||
"GIT_COMMITTER_EMAIL="+sig.Email,
|
"GIT_COMMITTER_EMAIL="+committerSig.Email,
|
||||||
EnvRepoName+"="+repo.Name,
|
EnvRepoName+"="+repo.Name,
|
||||||
EnvRepoUsername+"="+repo.MustOwnerName(),
|
EnvRepoUsername+"="+repo.MustOwnerName(),
|
||||||
EnvRepoIsWiki+"="+isWiki,
|
EnvRepoIsWiki+"="+isWiki,
|
||||||
EnvPusherName+"="+doer.Name,
|
EnvPusherName+"="+committer.Name,
|
||||||
EnvPusherID+"="+fmt.Sprintf("%d", doer.ID),
|
EnvPusherID+"="+fmt.Sprintf("%d", committer.ID),
|
||||||
ProtectedBranchRepoID+"="+fmt.Sprintf("%d", repo.ID),
|
ProtectedBranchRepoID+"="+fmt.Sprintf("%d", repo.ID),
|
||||||
|
ProtectedBranchPRID+"="+fmt.Sprintf("%d", prID),
|
||||||
|
"SSH_ORIGINAL_COMMAND=gitea-internal",
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -876,7 +876,7 @@ func (pr *PullRequest) UpdatePatch() (err error) {
|
||||||
if err = pr.GetHeadRepo(); err != nil {
|
if err = pr.GetHeadRepo(); err != nil {
|
||||||
return fmt.Errorf("GetHeadRepo: %v", err)
|
return fmt.Errorf("GetHeadRepo: %v", err)
|
||||||
} else if pr.HeadRepo == nil {
|
} else if pr.HeadRepo == nil {
|
||||||
log.Trace("PullRequest[%d].UpdatePatch: ignored cruppted data", pr.ID)
|
log.Trace("PullRequest[%d].UpdatePatch: ignored corrupted data", pr.ID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,12 @@ type HookOptions struct {
|
||||||
UserName string
|
UserName string
|
||||||
GitObjectDirectory string
|
GitObjectDirectory string
|
||||||
GitAlternativeObjectDirectories string
|
GitAlternativeObjectDirectories string
|
||||||
|
ProtectedBranchID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// HookPreReceive check whether the provided commits are allowed
|
// HookPreReceive check whether the provided commits are allowed
|
||||||
func HookPreReceive(ownerName, repoName string, opts HookOptions) (int, string) {
|
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",
|
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s?old=%s&new=%s&ref=%s&userID=%d&gitObjectDirectory=%s&gitAlternativeObjectDirectories=%s&prID=%d",
|
||||||
url.PathEscape(ownerName),
|
url.PathEscape(ownerName),
|
||||||
url.PathEscape(repoName),
|
url.PathEscape(repoName),
|
||||||
url.QueryEscape(opts.OldCommitID),
|
url.QueryEscape(opts.OldCommitID),
|
||||||
|
@ -42,6 +43,7 @@ func HookPreReceive(ownerName, repoName string, opts HookOptions) (int, string)
|
||||||
opts.UserID,
|
opts.UserID,
|
||||||
url.QueryEscape(opts.GitObjectDirectory),
|
url.QueryEscape(opts.GitObjectDirectory),
|
||||||
url.QueryEscape(opts.GitAlternativeObjectDirectories),
|
url.QueryEscape(opts.GitAlternativeObjectDirectories),
|
||||||
|
opts.ProtectedBranchID,
|
||||||
)
|
)
|
||||||
|
|
||||||
resp, err := newInternalRequest(reqURL, "GET").Response()
|
resp, err := newInternalRequest(reqURL, "GET").Response()
|
||||||
|
|
|
@ -231,7 +231,17 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
env := models.PushingEnvironment(doer, pr.BaseRepo)
|
headUser, err := models.GetUserByName(pr.HeadUserName)
|
||||||
|
if err != nil {
|
||||||
|
if !models.IsErrUserNotExist(err) {
|
||||||
|
log.Error("Can't find user: %s for head repository - %v", pr.HeadUserName, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Error("Can't find user: %s for head repository - defaulting to doer: %s - %v", pr.HeadUserName, doer.Name, err)
|
||||||
|
headUser = doer
|
||||||
|
}
|
||||||
|
|
||||||
|
env := models.FullPushingEnvironment(headUser, doer, pr.BaseRepo, pr.ID)
|
||||||
|
|
||||||
// Push back to upstream.
|
// Push back to upstream.
|
||||||
if err := git.NewCommand("push", "origin", pr.BaseBranch).RunInDirTimeoutEnvPipeline(env, -1, tmpBasePath, nil, &errbuf); err != nil {
|
if err := git.NewCommand("push", "origin", pr.BaseBranch).RunInDirTimeoutEnvPipeline(env, -1, tmpBasePath, nil, &errbuf); err != nil {
|
||||||
|
|
|
@ -31,6 +31,7 @@ func HookPreReceive(ctx *macaron.Context) {
|
||||||
userID := ctx.QueryInt64("userID")
|
userID := ctx.QueryInt64("userID")
|
||||||
gitObjectDirectory := ctx.QueryTrim("gitObjectDirectory")
|
gitObjectDirectory := ctx.QueryTrim("gitObjectDirectory")
|
||||||
gitAlternativeObjectDirectories := ctx.QueryTrim("gitAlternativeObjectDirectories")
|
gitAlternativeObjectDirectories := ctx.QueryTrim("gitAlternativeObjectDirectories")
|
||||||
|
prID := ctx.QueryInt64("prID")
|
||||||
|
|
||||||
branchName := strings.TrimPrefix(refFullName, git.BranchPrefix)
|
branchName := strings.TrimPrefix(refFullName, git.BranchPrefix)
|
||||||
repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName)
|
repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName)
|
||||||
|
@ -85,7 +86,24 @@ func HookPreReceive(ctx *macaron.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !protectBranch.CanUserPush(userID) {
|
canPush := protectBranch.CanUserPush(userID)
|
||||||
|
if !canPush && prID > 0 {
|
||||||
|
pr, err := models.GetPullRequestByID(prID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to get PullRequest %d Error: %v", prID, err)
|
||||||
|
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||||
|
"err": fmt.Sprintf("Unable to get PullRequest %d Error: %v", prID, err),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !protectBranch.HasEnoughApprovals(pr) {
|
||||||
|
log.Warn("Forbidden: User %d cannot push to protected branch: %s in %-v and pr #%d does not have enough approvals", userID, branchName, repo, pr.Index)
|
||||||
|
ctx.JSON(http.StatusForbidden, map[string]interface{}{
|
||||||
|
"err": fmt.Sprintf("protected branch %s can not be pushed to and pr #%d does not have enough approvals", branchName, prID),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if !canPush {
|
||||||
log.Warn("Forbidden: User %d cannot push to protected branch: %s in %-v", userID, branchName, repo)
|
log.Warn("Forbidden: User %d cannot push to protected branch: %s in %-v", userID, branchName, repo)
|
||||||
ctx.JSON(http.StatusForbidden, map[string]interface{}{
|
ctx.JSON(http.StatusForbidden, map[string]interface{}{
|
||||||
"err": fmt.Sprintf("protected branch %s can not be pushed to", branchName),
|
"err": fmt.Sprintf("protected branch %s can not be pushed to", branchName),
|
||||||
|
|
Loading…
Reference in a new issue