summaryrefslogtreecommitdiffstats
path: root/cmd/serv.go
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 /cmd/serv.go
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 'cmd/serv.go')
-rw-r--r--cmd/serv.go173
1 files changed, 49 insertions, 124 deletions
diff --git a/cmd/serv.go b/cmd/serv.go
index a30e02e7a2..aa068d4cf6 100644
--- a/cmd/serv.go
+++ b/cmd/serv.go
@@ -8,9 +8,11 @@ package cmd
import (
"encoding/json"
"fmt"
+ "net/http"
+ "net/url"
"os"
"os/exec"
- "path/filepath"
+ "strconv"
"strings"
"time"
@@ -68,7 +70,6 @@ func setup(logPath string) {
log.DelLogger("console")
setting.NewContext()
checkLFSVersion()
- log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
}
func parseCmd(cmd string) (string, string) {
@@ -95,15 +96,14 @@ func fail(userMessage, logMessage string, args ...interface{}) {
if !setting.ProdMode {
fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
}
- log.GitLogger.Fatal(logMessage, args...)
return
}
- log.GitLogger.Close()
os.Exit(1)
}
func runServ(c *cli.Context) error {
+ // FIXME: This needs to internationalised
setup("serv.log")
if setting.SSH.Disabled {
@@ -116,9 +116,23 @@ func runServ(c *cli.Context) error {
return nil
}
+ keys := strings.Split(c.Args()[0], "-")
+ if len(keys) != 2 || keys[0] != "key" {
+ fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
+ }
+ keyID := com.StrTo(keys[1]).MustInt64()
+
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
if len(cmd) == 0 {
- println("Hi there, You've successfully authenticated, but Gitea does not provide shell access.")
+ key, user, err := private.ServNoCommand(keyID)
+ if err != nil {
+ fail("Internal error", "Failed to check provided key: %v", err)
+ }
+ if key.Type == models.KeyTypeDeploy {
+ println("Hi there! You've successfully authenticated with the deploy key named " + key.Name + ", but Gitea does not provide shell access.")
+ } else {
+ println("Hi there: " + user.Name + "! You've successfully authenticated with the key named " + key.Name + ", but Gitea does not provide shell access.")
+ }
println("If this is unexpected, please log in with password and setup Gitea under another user.")
return nil
}
@@ -152,41 +166,19 @@ func runServ(c *cli.Context) error {
fail("Error while trying to create PPROF_DATA_PATH", "Error while trying to create PPROF_DATA_PATH: %v", err)
}
- stopCPUProfiler := pprof.DumpCPUProfileForUsername(setting.PprofDataPath, username)
+ stopCPUProfiler, err := pprof.DumpCPUProfileForUsername(setting.PprofDataPath, username)
+ if err != nil {
+ fail("Internal Server Error", "Unable to start CPU profile: %v", err)
+ }
defer func() {
stopCPUProfiler()
- pprof.DumpMemProfileForUsername(setting.PprofDataPath, username)
+ err := pprof.DumpMemProfileForUsername(setting.PprofDataPath, username)
+ if err != nil {
+ fail("Internal Server Error", "Unable to dump Mem Profile: %v", err)
+ }
}()
}
- var (
- isWiki bool
- unitType = models.UnitTypeCode
- unitName = "code"
- )
- if strings.HasSuffix(reponame, ".wiki") {
- isWiki = true
- unitType = models.UnitTypeWiki
- unitName = "wiki"
- reponame = reponame[:len(reponame)-5]
- }
-
- os.Setenv(models.EnvRepoUsername, username)
- if isWiki {
- os.Setenv(models.EnvRepoIsWiki, "true")
- } else {
- os.Setenv(models.EnvRepoIsWiki, "false")
- }
- os.Setenv(models.EnvRepoName, reponame)
-
- repo, err := private.GetRepositoryByOwnerAndName(username, reponame)
- if err != nil {
- if strings.Contains(err.Error(), "Failed to get repository: repository does not exist") {
- fail(accessDenied, "Repository does not exist: %s/%s", username, reponame)
- }
- fail("Internal error", "Failed to get repository: %v", err)
- }
-
requestedMode, has := allowedCommands[verb]
if !has {
fail("Unknown git command", "Unknown git command %s", verb)
@@ -202,97 +194,36 @@ func runServ(c *cli.Context) error {
}
}
- // Prohibit push to mirror repositories.
- if requestedMode > models.AccessModeRead && repo.IsMirror {
- fail("mirror repository is read-only", "")
- }
-
- // Allow anonymous clone for public repositories.
- var (
- keyID int64
- user *models.User
- )
- if requestedMode == models.AccessModeWrite || repo.IsPrivate || setting.Service.RequireSignInView {
- keys := strings.Split(c.Args()[0], "-")
- if len(keys) != 2 {
- fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
- }
-
- key, err := private.GetPublicKeyByID(com.StrTo(keys[1]).MustInt64())
- if err != nil {
- fail("Invalid key ID", "Invalid key ID[%s]: %v", c.Args()[0], err)
- }
- keyID = key.ID
-
- // Check deploy key or user key.
- if key.Type == models.KeyTypeDeploy {
- // Now we have to get the deploy key for this repo
- deployKey, err := private.GetDeployKey(key.ID, repo.ID)
- if err != nil {
- fail("Key access denied", "Failed to access internal api: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
- }
-
- if deployKey == nil {
- fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
- }
-
- if deployKey.Mode < requestedMode {
- fail("Key permission denied", "Cannot push with read-only deployment key: %d to repo_id: %d", key.ID, repo.ID)
- }
-
- // Update deploy key activity.
- if err = private.UpdateDeployKeyUpdated(key.ID, repo.ID); err != nil {
- fail("Internal error", "UpdateDeployKey: %v", err)
- }
-
- // FIXME: Deploy keys aren't really the owner of the repo pushing changes
- // however we don't have good way of representing deploy keys in hook.go
- // so for now use the owner
- os.Setenv(models.EnvPusherName, username)
- os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", repo.OwnerID))
- } else {
- user, err = private.GetUserByKeyID(key.ID)
- if err != nil {
- fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err)
- }
-
- if !user.IsActive || user.ProhibitLogin {
- fail("Your account is not active or has been disabled by Administrator",
- "User %s is disabled and have no access to repository %s",
- user.Name, repoPath)
- }
-
- mode, err := private.CheckUnitUser(user.ID, repo.ID, user.IsAdmin, unitType)
- if err != nil {
- fail("Internal error", "Failed to check access: %v", err)
- } else if *mode < requestedMode {
- clientMessage := accessDenied
- if *mode >= models.AccessModeRead {
- clientMessage = "You do not have sufficient authorization for this action"
- }
- fail(clientMessage,
- "User %s does not have level %v access to repository %s's "+unitName,
- user.Name, requestedMode, repoPath)
+ results, err := private.ServCommand(keyID, username, reponame, requestedMode, verb, lfsVerb)
+ if err != nil {
+ if private.IsErrServCommand(err) {
+ errServCommand := err.(private.ErrServCommand)
+ if errServCommand.StatusCode != http.StatusInternalServerError {
+ fail("Unauthorized", errServCommand.Error())
+ } else {
+ fail("Internal Server Error", errServCommand.Error())
}
-
- os.Setenv(models.EnvPusherName, user.Name)
- os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", user.ID))
}
+ fail("Internal Server Error", err.Error())
}
+ os.Setenv(models.EnvRepoIsWiki, strconv.FormatBool(results.IsWiki))
+ os.Setenv(models.EnvRepoName, results.RepoName)
+ os.Setenv(models.EnvRepoUsername, results.OwnerName)
+ os.Setenv(models.EnvPusherName, username)
+ os.Setenv(models.EnvPusherID, strconv.FormatInt(results.UserID, 10))
+ os.Setenv(models.ProtectedBranchRepoID, strconv.FormatInt(results.RepoID, 10))
//LFS token authentication
if verb == lfsAuthenticateVerb {
- url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, username, repo.Name)
+ url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, url.PathEscape(results.OwnerName), url.PathEscape(results.RepoName))
now := time.Now()
claims := jwt.MapClaims{
- "repo": repo.ID,
+ "repo": results.RepoID,
"op": lfsVerb,
"exp": now.Add(setting.LFS.HTTPAuthExpiry).Unix(),
"nbf": now.Unix(),
- }
- if user != nil {
- claims["user"] = user.ID
+ "user": results.UserID,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
@@ -313,7 +244,6 @@ func runServ(c *cli.Context) error {
if err != nil {
fail("Internal error", "Failed to encode LFS json response: %v", err)
}
-
return nil
}
@@ -329,13 +259,8 @@ func runServ(c *cli.Context) error {
} else {
gitcmd = exec.Command(verb, repoPath)
}
- if isWiki {
- if err = private.InitWiki(repo.ID); err != nil {
- fail("Internal error", "Failed to init wiki repo: %v", err)
- }
- }
- os.Setenv(models.ProtectedBranchRepoID, fmt.Sprintf("%d", repo.ID))
+ os.Setenv(models.ProtectedBranchRepoID, fmt.Sprintf("%d", results.RepoID))
gitcmd.Dir = setting.RepoRootPath
gitcmd.Stdout = os.Stdout
@@ -346,9 +271,9 @@ func runServ(c *cli.Context) error {
}
// Update user key activity.
- if keyID > 0 {
- if err = private.UpdatePublicKeyUpdated(keyID); err != nil {
- fail("Internal error", "UpdatePublicKey: %v", err)
+ if results.KeyID > 0 {
+ if err = private.UpdatePublicKeyInRepo(results.KeyID, results.RepoID); err != nil {
+ fail("Internal error", "UpdatePublicKeyInRepo: %v", err)
}
}