]> source.dussan.org Git - gitea.git/commitdiff
Properly enforce gitea environment for pushes (#9501)
authorzeripath <art27@cantab.net>
Fri, 27 Dec 2019 21:15:04 +0000 (21:15 +0000)
committerGitHub <noreply@github.com>
Fri, 27 Dec 2019 21:15:04 +0000 (21:15 +0000)
#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!

cmd/hook.go
models/helper_environment.go
models/repo.go
models/repo_generate.go
models/update.go
services/pull/pull.go

index ebd230999a5318a30f947dbde42e78105b624ddf..aabd9637c2a0a1e4b27a00f3cc002dfb1dad08ce 100644 (file)
@@ -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")
index 2095205db3184271fc9f9e6828f16af188d753b3..35af17adb1025212da45eb0df8fca0d2092edd41 100644 (file)
@@ -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)
index 53a9196aa701fafba7b405f1c53d041995b57055..0dbdcc11b5b6a1460660e38a99251f148583d4d2 100644 (file)
@@ -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)
                }
        }
index 98ef0ea00081bd4762ab49d3cf144717ff56e8a9..556a5fc2f72b9b959ccb46fefc2c95f94971c328 100644 (file)
@@ -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
index b6c04bd515ceee1a3febc1e9a803239e3ecb868a..212f22cfc1ac4f26bf184c1e70b50b9e51b4fbe2 100644 (file)
@@ -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.
index fb47df1c3a6a72372f8e0a8d517df8918c17d9fb..6be9c2da176c06bb1abaa85084173128f60c6fbf 100644 (file)
@@ -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)
        }