aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/hook.go60
-rw-r--r--models/update.go42
-rw-r--r--modules/private/branch.go43
-rw-r--r--modules/private/internal.go4
-rw-r--r--modules/private/push_update.go43
-rw-r--r--routers/private/branch.go30
-rw-r--r--routers/private/internal.go3
-rw-r--r--routers/private/push_update.go60
8 files changed, 225 insertions, 60 deletions
diff --git a/cmd/hook.go b/cmd/hook.go
index d120f21b20..06250181d3 100644
--- a/cmd/hook.go
+++ b/cmd/hook.go
@@ -7,20 +7,18 @@ package cmd
import (
"bufio"
"bytes"
- "crypto/tls"
"fmt"
"os"
+ "path/filepath"
"strconv"
"strings"
"code.gitea.io/git"
"code.gitea.io/gitea/models"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
- "github.com/Unknwon/com"
"github.com/urfave/cli"
)
@@ -64,6 +62,12 @@ var (
}
)
+func hookSetup(logPath string) {
+ setting.NewContext()
+ log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
+ models.LoadConfigs()
+}
+
func runHookPreReceive(c *cli.Context) error {
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
return nil
@@ -75,9 +79,7 @@ func runHookPreReceive(c *cli.Context) error {
setting.CustomConf = c.GlobalString("config")
}
- if err := setup("hooks/pre-receive.log"); err != nil {
- fail("Hook pre-receive init failed", fmt.Sprintf("setup: %v", err))
- }
+ hookSetup("hooks/pre-receive.log")
// the environment setted on serv command
repoID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchRepoID), 10, 64)
@@ -119,18 +121,20 @@ func runHookPreReceive(c *cli.Context) error {
}*/
branchName := strings.TrimPrefix(refFullName, git.BranchPrefix)
- protectBranch, err := models.GetProtectedBranchBy(repoID, branchName)
+ protectBranch, err := private.GetProtectedBranchBy(repoID, branchName)
if err != nil {
log.GitLogger.Fatal(2, "retrieve protected branches information failed")
}
if protectBranch != nil {
- // check and deletion
- if newCommitID == git.EmptySHA {
- fail(fmt.Sprintf("branch %s is protected from deletion", branchName), "")
- } else {
- fail(fmt.Sprintf("protected branch %s can not be pushed to", branchName), "")
- //fail(fmt.Sprintf("branch %s is protected from force push", branchName), "")
+ if !protectBranch.CanPush {
+ // check and deletion
+ if newCommitID == git.EmptySHA {
+ fail(fmt.Sprintf("branch %s is protected from deletion", branchName), "")
+ } else {
+ fail(fmt.Sprintf("protected branch %s can not be pushed to", branchName), "")
+ //fail(fmt.Sprintf("branch %s is protected from force push", branchName), "")
+ }
}
}
}
@@ -149,9 +153,7 @@ func runHookUpdate(c *cli.Context) error {
setting.CustomConf = c.GlobalString("config")
}
- if err := setup("hooks/update.log"); err != nil {
- fail("Hook update init failed", fmt.Sprintf("setup: %v", err))
- }
+ hookSetup("hooks/update.log")
return nil
}
@@ -167,13 +169,10 @@ func runHookPostReceive(c *cli.Context) error {
setting.CustomConf = c.GlobalString("config")
}
- if err := setup("hooks/post-receive.log"); err != nil {
- fail("Hook post-receive init failed", fmt.Sprintf("setup: %v", err))
- }
+ hookSetup("hooks/post-receive.log")
// the environment setted on serv command
repoUser := os.Getenv(models.EnvRepoUsername)
- repoUserSalt := os.Getenv(models.EnvRepoUserSalt)
isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true")
repoName := os.Getenv(models.EnvRepoName)
pusherID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
@@ -199,7 +198,7 @@ func runHookPostReceive(c *cli.Context) error {
newCommitID := string(fields[1])
refFullName := string(fields[2])
- if err := models.PushUpdate(models.PushUpdateOptions{
+ if err := private.PushUpdate(models.PushUpdateOptions{
RefFullName: refFullName,
OldCommitID: oldCommitID,
NewCommitID: newCommitID,
@@ -210,23 +209,6 @@ func runHookPostReceive(c *cli.Context) error {
}); err != nil {
log.GitLogger.Error(2, "Update: %v", err)
}
-
- // Ask for running deliver hook and test pull request tasks.
- reqURL := setting.LocalURL + repoUser + "/" + repoName + "/tasks/trigger?branch=" +
- strings.TrimPrefix(refFullName, git.BranchPrefix) + "&secret=" + base.EncodeMD5(repoUserSalt) + "&pusher=" + com.ToStr(pusherID)
- log.GitLogger.Trace("Trigger task: %s", reqURL)
-
- resp, err := httplib.Head(reqURL).SetTLSClientConfig(&tls.Config{
- InsecureSkipVerify: true,
- }).Response()
- if err == nil {
- resp.Body.Close()
- if resp.StatusCode/100 != 2 {
- log.GitLogger.Error(2, "Failed to trigger task: not 2xx response code")
- }
- } else {
- log.GitLogger.Error(2, "Failed to trigger task: %v", err)
- }
}
return nil
diff --git a/models/update.go b/models/update.go
index b3a8a1c9fb..7ee00f2c27 100644
--- a/models/update.go
+++ b/models/update.go
@@ -65,11 +65,11 @@ type PushUpdateOptions struct {
// PushUpdate must be called for any push actions in order to
// generates necessary push action history feeds.
-func PushUpdate(opts PushUpdateOptions) (err error) {
+func PushUpdate(opts PushUpdateOptions) (repo *Repository, err error) {
isNewRef := opts.OldCommitID == git.EmptySHA
isDelRef := opts.NewCommitID == git.EmptySHA
if isNewRef && isDelRef {
- return fmt.Errorf("Old and new revisions are both %s", git.EmptySHA)
+ return nil, fmt.Errorf("Old and new revisions are both %s", git.EmptySHA)
}
repoPath := RepoPath(opts.RepoUserName, opts.RepoName)
@@ -77,28 +77,28 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
gitUpdate := exec.Command("git", "update-server-info")
gitUpdate.Dir = repoPath
if err = gitUpdate.Run(); err != nil {
- return fmt.Errorf("Failed to call 'git update-server-info': %v", err)
+ return nil, fmt.Errorf("Failed to call 'git update-server-info': %v", err)
}
- if isDelRef {
- log.GitLogger.Info("Reference '%s' has been deleted from '%s/%s' by %s",
- opts.RefFullName, opts.RepoUserName, opts.RepoName, opts.PusherName)
- return nil
+ owner, err := GetUserByName(opts.RepoUserName)
+ if err != nil {
+ return nil, fmt.Errorf("GetUserByName: %v", err)
}
- gitRepo, err := git.OpenRepository(repoPath)
+ repo, err = GetRepositoryByName(owner.ID, opts.RepoName)
if err != nil {
- return fmt.Errorf("OpenRepository: %v", err)
+ return nil, fmt.Errorf("GetRepositoryByName: %v", err)
}
- owner, err := GetUserByName(opts.RepoUserName)
- if err != nil {
- return fmt.Errorf("GetUserByName: %v", err)
+ if isDelRef {
+ log.GitLogger.Info("Reference '%s' has been deleted from '%s/%s' by %s",
+ opts.RefFullName, opts.RepoUserName, opts.RepoName, opts.PusherName)
+ return repo, nil
}
- repo, err := GetRepositoryByName(owner.ID, opts.RepoName)
+ gitRepo, err := git.OpenRepository(repoPath)
if err != nil {
- return fmt.Errorf("GetRepositoryByName: %v", err)
+ return nil, fmt.Errorf("OpenRepository: %v", err)
}
if err = repo.UpdateSize(); err != nil {
@@ -116,14 +116,14 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
NewCommitID: opts.NewCommitID,
Commits: &PushCommits{},
}); err != nil {
- return fmt.Errorf("CommitRepoAction (tag): %v", err)
+ return nil, fmt.Errorf("CommitRepoAction (tag): %v", err)
}
- return nil
+ return repo, nil
}
newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
if err != nil {
- return fmt.Errorf("gitRepo.GetCommit: %v", err)
+ return nil, fmt.Errorf("gitRepo.GetCommit: %v", err)
}
// Push new branch.
@@ -131,12 +131,12 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
if isNewRef {
l, err = newCommit.CommitsBeforeLimit(10)
if err != nil {
- return fmt.Errorf("newCommit.CommitsBeforeLimit: %v", err)
+ return nil, fmt.Errorf("newCommit.CommitsBeforeLimit: %v", err)
}
} else {
l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID)
if err != nil {
- return fmt.Errorf("newCommit.CommitsBeforeUntil: %v", err)
+ return nil, fmt.Errorf("newCommit.CommitsBeforeUntil: %v", err)
}
}
@@ -149,7 +149,7 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
NewCommitID: opts.NewCommitID,
Commits: ListToPushCommits(l),
}); err != nil {
- return fmt.Errorf("CommitRepoAction (branch): %v", err)
+ return nil, fmt.Errorf("CommitRepoAction (branch): %v", err)
}
- return nil
+ return repo, nil
}
diff --git a/modules/private/branch.go b/modules/private/branch.go
new file mode 100644
index 0000000000..faee1c918a
--- /dev/null
+++ b/modules/private/branch.go
@@ -0,0 +1,43 @@
+// Copyright 2017 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package private
+
+import (
+ "crypto/tls"
+ "encoding/json"
+ "fmt"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+)
+
+// GetProtectedBranchBy get protected branch information
+func GetProtectedBranchBy(repoID int64, branchName string) (*models.ProtectedBranch, error) {
+ // Ask for running deliver hook and test pull request tasks.
+ reqURL := setting.LocalURL + fmt.Sprintf("api/internal/branch/%d/%s", repoID, branchName)
+ log.GitLogger.Trace("GetProtectedBranchBy: %s", reqURL)
+
+ resp, err := newRequest(reqURL, "GET").SetTLSClientConfig(&tls.Config{
+ InsecureSkipVerify: true,
+ }).Response()
+ if err != nil {
+ return nil, err
+ }
+
+ var branch models.ProtectedBranch
+ if err := json.NewDecoder(resp.Body).Decode(&branch); err != nil {
+ return nil, err
+ }
+
+ defer resp.Body.Close()
+
+ // All 2XX status codes are accepted and others will return an error
+ if resp.StatusCode/100 != 2 {
+ return nil, fmt.Errorf("Failed to update public key: %s", decodeJSONError(resp).Err)
+ }
+
+ return &branch, nil
+}
diff --git a/modules/private/internal.go b/modules/private/internal.go
index 017e265b7c..fbf9d6a011 100644
--- a/modules/private/internal.go
+++ b/modules/private/internal.go
@@ -1,3 +1,7 @@
+// Copyright 2017 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
package private
import (
diff --git a/modules/private/push_update.go b/modules/private/push_update.go
new file mode 100644
index 0000000000..348a40e0a2
--- /dev/null
+++ b/modules/private/push_update.go
@@ -0,0 +1,43 @@
+// Copyright 2017 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package private
+
+import (
+ "crypto/tls"
+ "encoding/json"
+ "fmt"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+)
+
+// PushUpdate update publick key updates
+func PushUpdate(opt models.PushUpdateOptions) error {
+ // Ask for running deliver hook and test pull request tasks.
+ reqURL := setting.LocalURL + "api/internal/push/update"
+ log.GitLogger.Trace("PushUpdate: %s", reqURL)
+
+ body, err := json.Marshal(&opt)
+ if err != nil {
+ return err
+ }
+
+ resp, err := newRequest(reqURL, "POST").Body(body).SetTLSClientConfig(&tls.Config{
+ InsecureSkipVerify: true,
+ }).Response()
+ if err != nil {
+ return err
+ }
+
+ defer resp.Body.Close()
+
+ // All 2XX status codes are accepted and others will return an error
+ if resp.StatusCode/100 != 2 {
+ return fmt.Errorf("Failed to update public key: %s", decodeJSONError(resp).Err)
+ }
+
+ return nil
+}
diff --git a/routers/private/branch.go b/routers/private/branch.go
new file mode 100644
index 0000000000..e74087950e
--- /dev/null
+++ b/routers/private/branch.go
@@ -0,0 +1,30 @@
+// Copyright 2017 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package private
+
+import (
+ "code.gitea.io/gitea/models"
+
+ macaron "gopkg.in/macaron.v1"
+)
+
+// GetProtectedBranchBy get protected branch information
+func GetProtectedBranchBy(ctx *macaron.Context) {
+ repoID := ctx.ParamsInt64(":id")
+ branchName := ctx.Params(":branch")
+ protectBranch, err := models.GetProtectedBranchBy(repoID, branchName)
+ if err != nil {
+ ctx.JSON(500, map[string]interface{}{
+ "err": err.Error(),
+ })
+ return
+ } else if protectBranch != nil {
+ ctx.JSON(200, protectBranch)
+ } else {
+ ctx.JSON(200, &models.ProtectedBranch{
+ CanPush: true,
+ })
+ }
+}
diff --git a/routers/private/internal.go b/routers/private/internal.go
index d662aa2c76..f663306e92 100644
--- a/routers/private/internal.go
+++ b/routers/private/internal.go
@@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/setting"
+
macaron "gopkg.in/macaron.v1"
)
@@ -40,5 +41,7 @@ func UpdatePublicKey(ctx *macaron.Context) {
func RegisterRoutes(m *macaron.Macaron) {
m.Group("/", func() {
m.Post("/ssh/:id/update", UpdatePublicKey)
+ m.Post("/push/update", PushUpdate)
+ m.Get("/branch/:id/:branch", GetProtectedBranchBy)
}, CheckInternalToken)
}
diff --git a/routers/private/push_update.go b/routers/private/push_update.go
new file mode 100644
index 0000000000..3008ef0e7a
--- /dev/null
+++ b/routers/private/push_update.go
@@ -0,0 +1,60 @@
+// Copyright 2017 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package private
+
+import (
+ "encoding/json"
+ "strings"
+
+ "code.gitea.io/git"
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/log"
+
+ macaron "gopkg.in/macaron.v1"
+)
+
+// PushUpdate update public key updates
+func PushUpdate(ctx *macaron.Context) {
+ var opt models.PushUpdateOptions
+ if err := json.NewDecoder(ctx.Req.Request.Body).Decode(&opt); err != nil {
+ ctx.JSON(500, map[string]interface{}{
+ "err": err.Error(),
+ })
+ return
+ }
+
+ branch := strings.TrimPrefix(opt.RefFullName, git.BranchPrefix)
+ if len(branch) == 0 || opt.PusherID <= 0 {
+ ctx.Error(404)
+ log.Trace("PushUpdate: branch or secret is empty, or pusher ID is not valid")
+ return
+ }
+
+ repo, err := models.PushUpdate(opt)
+ if err != nil {
+ ctx.JSON(500, map[string]interface{}{
+ "err": err.Error(),
+ })
+ return
+ }
+
+ pusher, err := models.GetUserByID(opt.PusherID)
+ if err != nil {
+ if models.IsErrUserNotExist(err) {
+ ctx.Error(404)
+ } else {
+ ctx.JSON(500, map[string]interface{}{
+ "err": err.Error(),
+ })
+ }
+ return
+ }
+
+ log.Trace("TriggerTask '%s/%s' by %s", repo.Name, branch, pusher.Name)
+
+ go models.HookQueue.Add(repo.ID)
+ go models.AddTestPullRequestTask(pusher, repo.ID, branch, true)
+ ctx.Status(202)
+}