Skip to content

Commit 4acca9d

Browse files
authored
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!
1 parent f2d03cd commit 4acca9d

File tree

6 files changed

+36
-8
lines changed

6 files changed

+36
-8
lines changed

cmd/hook.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ var (
5959
)
6060

6161
func runHookPreReceive(c *cli.Context) error {
62+
if os.Getenv(models.EnvIsInternal) == "true" {
63+
return nil
64+
}
65+
66+
setup("hooks/pre-receive.log", false)
67+
6268
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
6369
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
6470
fail(`Rejecting changes as Gitea environment not set.
@@ -69,8 +75,6 @@ Gitea or set your environment appropriately.`, "")
6975
}
7076
}
7177

72-
setup("hooks/pre-receive.log", false)
73-
7478
// the environment setted on serv command
7579
isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true")
7680
username := os.Getenv(models.EnvRepoUsername)
@@ -186,6 +190,12 @@ func runHookUpdate(c *cli.Context) error {
186190
}
187191

188192
func runHookPostReceive(c *cli.Context) error {
193+
if os.Getenv(models.EnvIsInternal) == "true" {
194+
return nil
195+
}
196+
197+
setup("hooks/post-receive.log", false)
198+
189199
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
190200
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
191201
fail(`Rejecting changes as Gitea environment not set.
@@ -196,8 +206,6 @@ Gitea or set your environment appropriately.`, "")
196206
}
197207
}
198208

199-
setup("hooks/post-receive.log", false)
200-
201209
// the environment setted on serv command
202210
repoUser := os.Getenv(models.EnvRepoUsername)
203211
isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true")

models/helper_environment.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ import (
1010
"strings"
1111
)
1212

13+
// InternalPushingEnvironment returns an os environment to switch off hooks on push
14+
// It is recommended to avoid using this unless you are pushing within a transaction
15+
// or if you absolutely are sure that post-receive and pre-receive will do nothing
16+
// We provide the full pushing-environment for other hook providers
17+
func InternalPushingEnvironment(doer *User, repo *Repository) []string {
18+
return append(PushingEnvironment(doer, repo),
19+
EnvIsInternal+"=true",
20+
)
21+
}
22+
1323
// PushingEnvironment returns an os environment to allow hooks to work on push
1424
func PushingEnvironment(doer *User, repo *Repository) []string {
1525
return FullPushingEnvironment(doer, doer, repo, repo.Name, 0)

models/repo.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ func createDelegateHooks(repoPath string) (err error) {
10121012
}
10131013

10141014
// initRepoCommit temporarily changes with work directory.
1015-
func initRepoCommit(tmpPath string, u *User) (err error) {
1015+
func initRepoCommit(tmpPath string, repo *Repository, u *User) (err error) {
10161016
commitTimeStr := time.Now().Format(time.RFC3339)
10171017

10181018
sig := u.NewGitSig()
@@ -1061,7 +1061,7 @@ func initRepoCommit(tmpPath string, u *User) (err error) {
10611061

10621062
if stdout, err := git.NewCommand("push", "origin", "master").
10631063
SetDescription(fmt.Sprintf("initRepoCommit (git push): %s", tmpPath)).
1064-
RunInDir(tmpPath); err != nil {
1064+
RunInDirWithEnv(tmpPath, InternalPushingEnvironment(u, repo)); err != nil {
10651065
log.Error("Failed to push back to master: Stdout: %s\nError: %v", stdout, err)
10661066
return fmt.Errorf("git push: %v", err)
10671067
}
@@ -1219,7 +1219,7 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts C
12191219
}
12201220

12211221
// Apply changes and commit.
1222-
if err = initRepoCommit(tmpDir, u); err != nil {
1222+
if err = initRepoCommit(tmpDir, repo, u); err != nil {
12231223
return fmt.Errorf("initRepoCommit: %v", err)
12241224
}
12251225
}

models/repo_generate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ func generateRepoCommit(e Engine, repo, templateRepo, generateRepo *Repository,
174174
return fmt.Errorf("git remote add: %v", err)
175175
}
176176

177-
return initRepoCommit(tmpDir, repo.Owner)
177+
return initRepoCommit(tmpDir, repo, repo.Owner)
178178
}
179179

180180
// generateRepository initializes repository from template

models/update.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const (
2424
EnvPusherID = "GITEA_PUSHER_ID"
2525
EnvKeyID = "GITEA_KEY_ID"
2626
EnvIsDeployKey = "GITEA_IS_DEPLOY_KEY"
27+
EnvIsInternal = "GITEA_INTERNAL_PUSH"
2728
)
2829

2930
// CommitToPushCommit transforms a git.Commit to PushCommit type.

services/pull/pull.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,19 @@ func PushToBaseRepo(pr *models.PullRequest) (err error) {
242242

243243
_ = os.Remove(file)
244244

245+
if err = pr.LoadIssue(); err != nil {
246+
return fmt.Errorf("unable to load issue %d for pr %d: %v", pr.IssueID, pr.ID, err)
247+
}
248+
if err = pr.Issue.LoadPoster(); err != nil {
249+
return fmt.Errorf("unable to load poster %d for pr %d: %v", pr.Issue.PosterID, pr.ID, err)
250+
}
251+
245252
if err = git.Push(headRepoPath, git.PushOptions{
246253
Remote: tmpRemoteName,
247254
Branch: fmt.Sprintf("%s:%s", pr.HeadBranch, headFile),
248255
Force: true,
256+
// Use InternalPushingEnvironment here because we know that pre-receive and post-receive do not run on a refs/pulls/...
257+
Env: models.InternalPushingEnvironment(pr.Issue.Poster, pr.BaseRepo),
249258
}); err != nil {
250259
return fmt.Errorf("Push: %v", err)
251260
}

0 commit comments

Comments
 (0)