summaryrefslogtreecommitdiffstats
path: root/modules/private
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2019-06-01 16:00:21 +0100
committerLunny Xiao <xiaolunwen@gmail.com>2019-06-01 23:00:21 +0800
commit356854fc5f8d7d1a7e4d68c9e00929e9ce8aa867 (patch)
treebc250740ffe65de5cd9ce3389e004ca7723d5643 /modules/private
parent8a343dda39b187627db6ffb4c24a6e0ae615867b (diff)
downloadgitea-356854fc5f8d7d1a7e4d68c9e00929e9ce8aa867.tar.gz
gitea-356854fc5f8d7d1a7e4d68c9e00929e9ce8aa867.zip
Move serv hook functionality & drop GitLogger (#6993)
* Move hook functionality internally * Internalise serv logic * Remove old internal paths * finally remove the gitlogger * Disallow push on archived repositories * fix lint error * Update modules/private/key.go * Update routers/private/hook.go * Update routers/private/hook.go * Update routers/private/hook.go * Updated routers/private/serv.go * Fix LFS Locks over SSH * rev-list needs to be run by the hook process * fixup * Improve git test * Ensure that the lfs files are created with a different prefix * Reduce the replication in git_test.go * slight refactor * Remove unnecessary "/" * Restore ensureAnonymousClone * Restore ensureAnonymousClone * Run rev-list on server side * Try passing in the alternative directories instead * Mark test as skipped * Improve git test * Ensure that the lfs files are created with a different prefix * Reduce the replication in git_test.go * Remove unnecessary "/"
Diffstat (limited to 'modules/private')
-rw-r--r--modules/private/branch.go67
-rw-r--r--modules/private/hook.go84
-rw-r--r--modules/private/internal.go49
-rw-r--r--modules/private/key.go118
-rw-r--r--modules/private/push_update.go40
-rw-r--r--modules/private/repository.go68
-rw-r--r--modules/private/serv.go106
-rw-r--r--modules/private/wiki.go33
8 files changed, 193 insertions, 372 deletions
diff --git a/modules/private/branch.go b/modules/private/branch.go
deleted file mode 100644
index bbd0d4b697..0000000000
--- a/modules/private/branch.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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"
- "fmt"
-
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
-)
-
-// 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, util.PathEscapeSegments(branchName))
- log.GitLogger.Trace("GetProtectedBranchBy: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "GET").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 get protected branch: %s", decodeJSONError(resp).Err)
- }
-
- return &branch, nil
-}
-
-// CanUserPush returns if user can push
-func CanUserPush(protectedBranchID, userID int64) (bool, error) {
- // Ask for running deliver hook and test pull request tasks.
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/protectedbranch/%d/%d", protectedBranchID, userID)
- log.GitLogger.Trace("CanUserPush: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "GET").Response()
- if err != nil {
- return false, err
- }
-
- var canPush = make(map[string]interface{})
- if err := json.NewDecoder(resp.Body).Decode(&canPush); err != nil {
- return false, err
- }
-
- defer resp.Body.Close()
-
- // All 2XX status codes are accepted and others will return an error
- if resp.StatusCode/100 != 2 {
- return false, fmt.Errorf("Failed to retrieve push user: %s", decodeJSONError(resp).Err)
- }
-
- return canPush["can_push"].(bool), nil
-}
diff --git a/modules/private/hook.go b/modules/private/hook.go
new file mode 100644
index 0000000000..7e2a475d4b
--- /dev/null
+++ b/modules/private/hook.go
@@ -0,0 +1,84 @@
+// Copyright 2019 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"
+ "fmt"
+ "net/http"
+ "net/url"
+
+ "code.gitea.io/gitea/modules/setting"
+)
+
+// Git environment variables
+const (
+ GitAlternativeObjectDirectories = "GIT_ALTERNATE_OBJECT_DIRECTORIES"
+ GitObjectDirectory = "GIT_OBJECT_DIRECTORY"
+ GitQuarantinePath = "GIT_QUARANTINE_PATH"
+)
+
+// HookOptions represents the options for the Hook calls
+type HookOptions struct {
+ OldCommitID string
+ NewCommitID string
+ RefFullName string
+ UserID int64
+ UserName string
+ GitObjectDirectory string
+ GitAlternativeObjectDirectories string
+}
+
+// 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",
+ url.PathEscape(ownerName),
+ url.PathEscape(repoName),
+ url.QueryEscape(opts.OldCommitID),
+ url.QueryEscape(opts.NewCommitID),
+ url.QueryEscape(opts.RefFullName),
+ opts.UserID,
+ url.QueryEscape(opts.GitObjectDirectory),
+ url.QueryEscape(opts.GitAlternativeObjectDirectories),
+ )
+
+ resp, err := newInternalRequest(reqURL, "GET").Response()
+ if err != nil {
+ return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ return resp.StatusCode, decodeJSONError(resp).Err
+ }
+
+ return http.StatusOK, ""
+}
+
+// HookPostReceive updates services and users
+func HookPostReceive(ownerName, repoName string, opts HookOptions) (map[string]interface{}, string) {
+ reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/post-receive/%s/%s?old=%s&new=%s&ref=%s&userID=%d&username=%s",
+ url.PathEscape(ownerName),
+ url.PathEscape(repoName),
+ url.QueryEscape(opts.OldCommitID),
+ url.QueryEscape(opts.NewCommitID),
+ url.QueryEscape(opts.RefFullName),
+ opts.UserID,
+ url.QueryEscape(opts.UserName))
+
+ resp, err := newInternalRequest(reqURL, "GET").Response()
+ if err != nil {
+ return nil, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ return nil, decodeJSONError(resp).Err
+ }
+ res := map[string]interface{}{}
+ _ = json.NewDecoder(resp.Body).Decode(&res)
+
+ return res, ""
+}
diff --git a/modules/private/internal.go b/modules/private/internal.go
index 56852ce63c..b4fee2680f 100644
--- a/modules/private/internal.go
+++ b/modules/private/internal.go
@@ -10,11 +10,8 @@ import (
"fmt"
"net"
"net/http"
- "net/url"
- "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/httplib"
- "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
@@ -51,49 +48,3 @@ func newInternalRequest(url, method string) *httplib.Request {
}
return req
}
-
-// CheckUnitUser check whether user could visit the unit of this repository
-func CheckUnitUser(userID, repoID int64, isAdmin bool, unitType models.UnitType) (*models.AccessMode, error) {
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/user/%d/checkunituser?isAdmin=%t&unitType=%d", repoID, userID, isAdmin, unitType)
- log.GitLogger.Trace("CheckUnitUser: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "GET").Response()
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("Failed to CheckUnitUser: %s", decodeJSONError(resp).Err)
- }
-
- var a models.AccessMode
- if err := json.NewDecoder(resp.Body).Decode(&a); err != nil {
- return nil, err
- }
-
- return &a, nil
-}
-
-// GetRepositoryByOwnerAndName returns the repository by given ownername and reponame.
-func GetRepositoryByOwnerAndName(ownerName, repoName string) (*models.Repository, error) {
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repo/%s/%s", url.PathEscape(ownerName), url.PathEscape(repoName))
- log.GitLogger.Trace("GetRepositoryByOwnerAndName: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "GET").Response()
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("Failed to get repository: %s", decodeJSONError(resp).Err)
- }
-
- var repo models.Repository
- if err := json.NewDecoder(resp.Body).Decode(&repo); err != nil {
- return nil, err
- }
-
- return &repo, nil
-}
diff --git a/modules/private/key.go b/modules/private/key.go
index 1c6511846b..ebc28eb871 100644
--- a/modules/private/key.go
+++ b/modules/private/key.go
@@ -5,127 +5,15 @@
package private
import (
- "encoding/json"
"fmt"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
-// UpdateDeployKeyUpdated update deploy key updates
-func UpdateDeployKeyUpdated(keyID int64, repoID int64) error {
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/keys/%d/update", repoID, keyID)
- log.GitLogger.Trace("UpdateDeployKeyUpdated: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "POST").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 deploy key: %s", decodeJSONError(resp).Err)
- }
- return nil
-}
-
-// GetDeployKey check if repo has deploy key
-func GetDeployKey(keyID, repoID int64) (*models.DeployKey, error) {
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/keys/%d", repoID, keyID)
- log.GitLogger.Trace("GetDeployKey: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "GET").Response()
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- switch resp.StatusCode {
- case 404:
- return nil, nil
- case 200:
- var dKey models.DeployKey
- if err := json.NewDecoder(resp.Body).Decode(&dKey); err != nil {
- return nil, err
- }
- return &dKey, nil
- default:
- return nil, fmt.Errorf("Failed to get deploy key: %s", decodeJSONError(resp).Err)
- }
-}
-
-// HasDeployKey check if repo has deploy key
-func HasDeployKey(keyID, repoID int64) (bool, error) {
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/has-keys/%d", repoID, keyID)
- log.GitLogger.Trace("HasDeployKey: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "GET").Response()
- if err != nil {
- return false, err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode == 200 {
- return true, nil
- }
- return false, nil
-}
-
-// GetPublicKeyByID get public ssh key by his ID
-func GetPublicKeyByID(keyID int64) (*models.PublicKey, error) {
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/%d", keyID)
- log.GitLogger.Trace("GetPublicKeyByID: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "GET").Response()
- if err != nil {
- return nil, err
- }
-
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("Failed to get repository: %s", decodeJSONError(resp).Err)
- }
-
- var pKey models.PublicKey
- if err := json.NewDecoder(resp.Body).Decode(&pKey); err != nil {
- return nil, err
- }
- return &pKey, nil
-}
-
-// GetUserByKeyID get user attached to key
-func GetUserByKeyID(keyID int64) (*models.User, error) {
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/%d/user", keyID)
- log.GitLogger.Trace("GetUserByKeyID: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "GET").Response()
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("Failed to get user: %s", decodeJSONError(resp).Err)
- }
-
- var user models.User
- if err := json.NewDecoder(resp.Body).Decode(&user); err != nil {
- return nil, err
- }
-
- return &user, nil
-}
-
-// UpdatePublicKeyUpdated update public key updates
-func UpdatePublicKeyUpdated(keyID int64) error {
+// UpdatePublicKeyInRepo update public key and if necessary deploy key updates
+func UpdatePublicKeyInRepo(keyID, repoID int64) error {
// Ask for running deliver hook and test pull request tasks.
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/%d/update", keyID)
- log.GitLogger.Trace("UpdatePublicKeyUpdated: %s", reqURL)
-
+ reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/%d/update/%d", keyID, repoID)
resp, err := newInternalRequest(reqURL, "POST").Response()
if err != nil {
return err
diff --git a/modules/private/push_update.go b/modules/private/push_update.go
deleted file mode 100644
index f3071b63ad..0000000000
--- a/modules/private/push_update.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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"
- "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 := newInternalRequest(reqURL, "POST").Body(body).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/modules/private/repository.go b/modules/private/repository.go
deleted file mode 100644
index cf8ae68409..0000000000
--- a/modules/private/repository.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2018 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"
- "fmt"
- "net/url"
-
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
-)
-
-// GetRepository return the repository by its ID and a bool about if it's allowed to have PR
-func GetRepository(repoID int64) (*models.Repository, bool, error) {
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repository/%d", repoID)
- log.GitLogger.Trace("GetRepository: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "GET").Response()
- if err != nil {
- return nil, false, err
- }
-
- var repoInfo struct {
- Repository *models.Repository
- AllowPullRequest bool
- }
- if err := json.NewDecoder(resp.Body).Decode(&repoInfo); err != nil {
- return nil, false, err
- }
-
- defer resp.Body.Close()
-
- // All 2XX status codes are accepted and others will return an error
- if resp.StatusCode/100 != 2 {
- return nil, false, fmt.Errorf("failed to retrieve repository: %s", decodeJSONError(resp).Err)
- }
-
- return repoInfo.Repository, repoInfo.AllowPullRequest, nil
-}
-
-// ActivePullRequest returns an active pull request if it exists
-func ActivePullRequest(baseRepoID int64, headRepoID int64, baseBranch, headBranch string) (*models.PullRequest, error) {
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/active-pull-request?baseRepoID=%d&headRepoID=%d&baseBranch=%s&headBranch=%s", baseRepoID, headRepoID, url.QueryEscape(baseBranch), url.QueryEscape(headBranch))
- log.GitLogger.Trace("ActivePullRequest: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "GET").Response()
- if err != nil {
- return nil, err
- }
-
- var pr *models.PullRequest
- if err := json.NewDecoder(resp.Body).Decode(&pr); 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 retrieve pull request: %s", decodeJSONError(resp).Err)
- }
-
- return pr, nil
-}
diff --git a/modules/private/serv.go b/modules/private/serv.go
new file mode 100644
index 0000000000..5b4a27f116
--- /dev/null
+++ b/modules/private/serv.go
@@ -0,0 +1,106 @@
+// Copyright 2019 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"
+ "fmt"
+ "net/http"
+ "net/url"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/setting"
+)
+
+// KeyAndOwner is the response from ServNoCommand
+type KeyAndOwner struct {
+ Key *models.PublicKey `json:"key"`
+ Owner *models.User `json:"user"`
+}
+
+// ServNoCommand returns information about the provided key
+func ServNoCommand(keyID int64) (*models.PublicKey, *models.User, error) {
+ reqURL := setting.LocalURL + fmt.Sprintf("api/internal/serv/none/%d",
+ keyID)
+ resp, err := newInternalRequest(reqURL, "GET").Response()
+ if err != nil {
+ return nil, nil, err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ return nil, nil, fmt.Errorf("%s", decodeJSONError(resp).Err)
+ }
+
+ var keyAndOwner KeyAndOwner
+ if err := json.NewDecoder(resp.Body).Decode(&keyAndOwner); err != nil {
+ return nil, nil, err
+ }
+ return keyAndOwner.Key, keyAndOwner.Owner, nil
+}
+
+// ServCommandResults are the results of a call to the private route serv
+type ServCommandResults struct {
+ IsWiki bool
+ IsDeployKey bool
+ KeyID int64
+ KeyName string
+ UserName string
+ UserID int64
+ OwnerName string
+ RepoName string
+ RepoID int64
+}
+
+// ErrServCommand is an error returned from ServCommmand.
+type ErrServCommand struct {
+ Results ServCommandResults
+ Type string
+ Err string
+ StatusCode int
+}
+
+func (err ErrServCommand) Error() string {
+ return err.Err
+}
+
+// IsErrServCommand checks if an error is a ErrServCommand.
+func IsErrServCommand(err error) bool {
+ _, ok := err.(ErrServCommand)
+ return ok
+}
+
+// ServCommand preps for a serv call
+func ServCommand(keyID int64, ownerName, repoName string, mode models.AccessMode, verbs ...string) (*ServCommandResults, error) {
+ reqURL := setting.LocalURL + fmt.Sprintf("api/internal/serv/command/%d/%s/%s?mode=%d",
+ keyID,
+ url.PathEscape(ownerName),
+ url.PathEscape(repoName),
+ mode)
+ for _, verb := range verbs {
+ if verb != "" {
+ reqURL += fmt.Sprintf("&verb=%s", url.QueryEscape(verb))
+ }
+ }
+
+ resp, err := newInternalRequest(reqURL, "GET").Response()
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ var errServCommand ErrServCommand
+ if err := json.NewDecoder(resp.Body).Decode(&errServCommand); err != nil {
+ return nil, err
+ }
+ errServCommand.StatusCode = resp.StatusCode
+ return nil, errServCommand
+ }
+ var results ServCommandResults
+ if err := json.NewDecoder(resp.Body).Decode(&results); err != nil {
+ return nil, err
+ }
+ return &results, nil
+
+}
diff --git a/modules/private/wiki.go b/modules/private/wiki.go
deleted file mode 100644
index 4ad0cc7c4e..0000000000
--- a/modules/private/wiki.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 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 (
- "fmt"
-
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
-)
-
-// InitWiki initwiki via repo id
-func InitWiki(repoID int64) error {
- // Ask for running deliver hook and test pull request tasks.
- reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/wiki/init", repoID)
- log.GitLogger.Trace("InitWiki: %s", reqURL)
-
- resp, err := newInternalRequest(reqURL, "GET").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 init wiki: %s", decodeJSONError(resp).Err)
- }
-
- return nil
-}