Properly enforce gitea environment for pushes (#9501)
#8982 attempted to enforce the gitea environment for pushes - unfortunately it tested the settings before they were actually read in - and therefore does not do that!
This commit is contained in:
		
							parent
							
								
									f2d03cda96
								
							
						
					
					
						commit
						4acca9d2e8
					
				
					 6 changed files with 36 additions and 8 deletions
				
			
		
							
								
								
									
										16
									
								
								cmd/hook.go
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								cmd/hook.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -59,6 +59,12 @@ var (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
func runHookPreReceive(c *cli.Context) error {
 | 
			
		||||
	if os.Getenv(models.EnvIsInternal) == "true" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup("hooks/pre-receive.log", false)
 | 
			
		||||
 | 
			
		||||
	if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
 | 
			
		||||
		if setting.OnlyAllowPushIfGiteaEnvironmentSet {
 | 
			
		||||
			fail(`Rejecting changes as Gitea environment not set.
 | 
			
		||||
| 
						 | 
				
			
			@ -69,8 +75,6 @@ Gitea or set your environment appropriately.`, "")
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup("hooks/pre-receive.log", false)
 | 
			
		||||
 | 
			
		||||
	// the environment setted on serv command
 | 
			
		||||
	isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true")
 | 
			
		||||
	username := os.Getenv(models.EnvRepoUsername)
 | 
			
		||||
| 
						 | 
				
			
			@ -186,6 +190,12 @@ func runHookUpdate(c *cli.Context) error {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func runHookPostReceive(c *cli.Context) error {
 | 
			
		||||
	if os.Getenv(models.EnvIsInternal) == "true" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup("hooks/post-receive.log", false)
 | 
			
		||||
 | 
			
		||||
	if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
 | 
			
		||||
		if setting.OnlyAllowPushIfGiteaEnvironmentSet {
 | 
			
		||||
			fail(`Rejecting changes as Gitea environment not set.
 | 
			
		||||
| 
						 | 
				
			
			@ -196,8 +206,6 @@ Gitea or set your environment appropriately.`, "")
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup("hooks/post-receive.log", false)
 | 
			
		||||
 | 
			
		||||
	// the environment setted on serv command
 | 
			
		||||
	repoUser := os.Getenv(models.EnvRepoUsername)
 | 
			
		||||
	isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,16 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// InternalPushingEnvironment returns an os environment to switch off hooks on push
 | 
			
		||||
// It is recommended to avoid using this unless you are pushing within a transaction
 | 
			
		||||
// or if you absolutely are sure that post-receive and pre-receive will do nothing
 | 
			
		||||
// We provide the full pushing-environment for other hook providers
 | 
			
		||||
func InternalPushingEnvironment(doer *User, repo *Repository) []string {
 | 
			
		||||
	return append(PushingEnvironment(doer, repo),
 | 
			
		||||
		EnvIsInternal+"=true",
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PushingEnvironment returns an os environment to allow hooks to work on push
 | 
			
		||||
func PushingEnvironment(doer *User, repo *Repository) []string {
 | 
			
		||||
	return FullPushingEnvironment(doer, doer, repo, repo.Name, 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1012,7 +1012,7 @@ func createDelegateHooks(repoPath string) (err error) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// initRepoCommit temporarily changes with work directory.
 | 
			
		||||
func initRepoCommit(tmpPath string, u *User) (err error) {
 | 
			
		||||
func initRepoCommit(tmpPath string, repo *Repository, u *User) (err error) {
 | 
			
		||||
	commitTimeStr := time.Now().Format(time.RFC3339)
 | 
			
		||||
 | 
			
		||||
	sig := u.NewGitSig()
 | 
			
		||||
| 
						 | 
				
			
			@ -1061,7 +1061,7 @@ func initRepoCommit(tmpPath string, u *User) (err error) {
 | 
			
		|||
 | 
			
		||||
	if stdout, err := git.NewCommand("push", "origin", "master").
 | 
			
		||||
		SetDescription(fmt.Sprintf("initRepoCommit (git push): %s", tmpPath)).
 | 
			
		||||
		RunInDir(tmpPath); err != nil {
 | 
			
		||||
		RunInDirWithEnv(tmpPath, InternalPushingEnvironment(u, repo)); err != nil {
 | 
			
		||||
		log.Error("Failed to push back to master: Stdout: %s\nError: %v", stdout, err)
 | 
			
		||||
		return fmt.Errorf("git push: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1219,7 +1219,7 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts C
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		// Apply changes and commit.
 | 
			
		||||
		if err = initRepoCommit(tmpDir, u); err != nil {
 | 
			
		||||
		if err = initRepoCommit(tmpDir, repo, u); err != nil {
 | 
			
		||||
			return fmt.Errorf("initRepoCommit: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -174,7 +174,7 @@ func generateRepoCommit(e Engine, repo, templateRepo, generateRepo *Repository,
 | 
			
		|||
		return fmt.Errorf("git remote add: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return initRepoCommit(tmpDir, repo.Owner)
 | 
			
		||||
	return initRepoCommit(tmpDir, repo, repo.Owner)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// generateRepository initializes repository from template
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,7 @@ const (
 | 
			
		|||
	EnvPusherID     = "GITEA_PUSHER_ID"
 | 
			
		||||
	EnvKeyID        = "GITEA_KEY_ID"
 | 
			
		||||
	EnvIsDeployKey  = "GITEA_IS_DEPLOY_KEY"
 | 
			
		||||
	EnvIsInternal   = "GITEA_INTERNAL_PUSH"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CommitToPushCommit transforms a git.Commit to PushCommit type.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -242,10 +242,19 @@ func PushToBaseRepo(pr *models.PullRequest) (err error) {
 | 
			
		|||
 | 
			
		||||
	_ = os.Remove(file)
 | 
			
		||||
 | 
			
		||||
	if err = pr.LoadIssue(); err != nil {
 | 
			
		||||
		return fmt.Errorf("unable to load issue %d for pr %d: %v", pr.IssueID, pr.ID, err)
 | 
			
		||||
	}
 | 
			
		||||
	if err = pr.Issue.LoadPoster(); err != nil {
 | 
			
		||||
		return fmt.Errorf("unable to load poster %d for pr %d: %v", pr.Issue.PosterID, pr.ID, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = git.Push(headRepoPath, git.PushOptions{
 | 
			
		||||
		Remote: tmpRemoteName,
 | 
			
		||||
		Branch: fmt.Sprintf("%s:%s", pr.HeadBranch, headFile),
 | 
			
		||||
		Force:  true,
 | 
			
		||||
		// Use InternalPushingEnvironment here because we know that pre-receive and post-receive do not run on a refs/pulls/...
 | 
			
		||||
		Env: models.InternalPushingEnvironment(pr.Issue.Poster, pr.BaseRepo),
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		return fmt.Errorf("Push: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue