* 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)
 | 
			
		||||
	reponame := os.Getenv(models.EnvRepoName)
 | 
			
		||||
	userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
 | 
			
		||||
	prID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchPRID), 10, 64)
 | 
			
		||||
 | 
			
		||||
	buf := bytes.NewBuffer(nil)
 | 
			
		||||
	scanner := bufio.NewScanner(os.Stdin)
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +96,7 @@ func runHookPreReceive(c *cli.Context) error {
 | 
			
		|||
				UserID:                          userID,
 | 
			
		||||
				GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
 | 
			
		||||
				GitObjectDirectory:              os.Getenv(private.GitObjectDirectory),
 | 
			
		||||
				ProtectedBranchID:               prID,
 | 
			
		||||
			})
 | 
			
		||||
			switch statusCode {
 | 
			
		||||
			case http.StatusInternalServerError:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -191,6 +191,7 @@ func runServ(c *cli.Context) error {
 | 
			
		|||
	os.Setenv(models.EnvPusherName, results.UserName)
 | 
			
		||||
	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))
 | 
			
		||||
 | 
			
		||||
	//LFS token authentication
 | 
			
		||||
	if verb == lfsAuthenticateVerb {
 | 
			
		||||
| 
						 | 
				
			
			@ -239,8 +240,6 @@ func runServ(c *cli.Context) error {
 | 
			
		|||
		gitcmd = exec.Command(verb, repoPath)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	os.Setenv(models.ProtectedBranchRepoID, fmt.Sprintf("%d", results.RepoID))
 | 
			
		||||
 | 
			
		||||
	gitcmd.Dir = setting.RepoRootPath
 | 
			
		||||
	gitcmd.Stdout = os.Stdout
 | 
			
		||||
	gitcmd.Stdin = os.Stdin
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,8 @@ import (
 | 
			
		|||
const (
 | 
			
		||||
	// ProtectedBranchRepoID protected Repo ID
 | 
			
		||||
	ProtectedBranchRepoID = "GITEA_REPO_ID"
 | 
			
		||||
	// ProtectedBranchPRID protected Repo PR ID
 | 
			
		||||
	ProtectedBranchPRID = "GITEA_PR_ID"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ProtectedBranch struct
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,26 +12,34 @@ import (
 | 
			
		|||
 | 
			
		||||
// PushingEnvironment returns an os environment to allow hooks to work on push
 | 
			
		||||
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"
 | 
			
		||||
	if strings.HasSuffix(repo.Name, ".wiki") {
 | 
			
		||||
		isWiki = "true"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sig := doer.NewGitSig()
 | 
			
		||||
	authorSig := author.NewGitSig()
 | 
			
		||||
	committerSig := committer.NewGitSig()
 | 
			
		||||
 | 
			
		||||
	// We should add "SSH_ORIGINAL_COMMAND=gitea-internal",
 | 
			
		||||
	// once we have hook and pushing infrastructure working correctly
 | 
			
		||||
	return append(os.Environ(),
 | 
			
		||||
		"GIT_AUTHOR_NAME="+sig.Name,
 | 
			
		||||
		"GIT_AUTHOR_EMAIL="+sig.Email,
 | 
			
		||||
		"GIT_COMMITTER_NAME="+sig.Name,
 | 
			
		||||
		"GIT_COMMITTER_EMAIL="+sig.Email,
 | 
			
		||||
		"GIT_AUTHOR_NAME="+authorSig.Name,
 | 
			
		||||
		"GIT_AUTHOR_EMAIL="+authorSig.Email,
 | 
			
		||||
		"GIT_COMMITTER_NAME="+committerSig.Name,
 | 
			
		||||
		"GIT_COMMITTER_EMAIL="+committerSig.Email,
 | 
			
		||||
		EnvRepoName+"="+repo.Name,
 | 
			
		||||
		EnvRepoUsername+"="+repo.MustOwnerName(),
 | 
			
		||||
		EnvRepoIsWiki+"="+isWiki,
 | 
			
		||||
		EnvPusherName+"="+doer.Name,
 | 
			
		||||
		EnvPusherID+"="+fmt.Sprintf("%d", doer.ID),
 | 
			
		||||
		EnvPusherName+"="+committer.Name,
 | 
			
		||||
		EnvPusherID+"="+fmt.Sprintf("%d", committer.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 {
 | 
			
		||||
		return fmt.Errorf("GetHeadRepo: %v", err)
 | 
			
		||||
	} 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
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,11 +29,12 @@ type HookOptions struct {
 | 
			
		|||
	UserName                        string
 | 
			
		||||
	GitObjectDirectory              string
 | 
			
		||||
	GitAlternativeObjectDirectories string
 | 
			
		||||
	ProtectedBranchID               int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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",
 | 
			
		||||
	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(repoName),
 | 
			
		||||
		url.QueryEscape(opts.OldCommitID),
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +43,7 @@ func HookPreReceive(ownerName, repoName string, opts HookOptions) (int, string)
 | 
			
		|||
		opts.UserID,
 | 
			
		||||
		url.QueryEscape(opts.GitObjectDirectory),
 | 
			
		||||
		url.QueryEscape(opts.GitAlternativeObjectDirectories),
 | 
			
		||||
		opts.ProtectedBranchID,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	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.
 | 
			
		||||
	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")
 | 
			
		||||
	gitObjectDirectory := ctx.QueryTrim("gitObjectDirectory")
 | 
			
		||||
	gitAlternativeObjectDirectories := ctx.QueryTrim("gitAlternativeObjectDirectories")
 | 
			
		||||
	prID := ctx.QueryInt64("prID")
 | 
			
		||||
 | 
			
		||||
	branchName := strings.TrimPrefix(refFullName, git.BranchPrefix)
 | 
			
		||||
	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)
 | 
			
		||||
			ctx.JSON(http.StatusForbidden, map[string]interface{}{
 | 
			
		||||
				"err": fmt.Sprintf("protected branch %s can not be pushed to", branchName),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue