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 "/"
This commit is contained in:
zeripath 2019-06-01 16:00:21 +01:00 committed by Lunny Xiao
parent 8a343dda39
commit 356854fc5f
25 changed files with 806 additions and 982 deletions

View file

@ -5,7 +5,6 @@
package routers
import (
"path"
"strings"
"time"
@ -99,7 +98,6 @@ func GlobalInit() {
models.InitSyncMirrors()
models.InitDeliverHooks()
models.InitTestPullRequests()
log.NewGitLogger(path.Join(setting.LogRootPath, "http.log"))
}
if models.EnableSQLite3 {
log.Info("SQLite3 Supported")

View file

@ -1,52 +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 (
"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("*")
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{
ID: 0,
})
}
}
// CanUserPush returns if user push
func CanUserPush(ctx *macaron.Context) {
pbID := ctx.ParamsInt64(":pbid")
userID := ctx.ParamsInt64(":userid")
protectBranch, err := models.GetProtectedBranchByID(pbID)
if err != nil {
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
return
} else if protectBranch != nil {
ctx.JSON(200, map[string]interface{}{
"can_push": protectBranch.CanUserPush(userID),
})
} else {
ctx.JSON(200, map[string]interface{}{
"can_push": false,
})
}
}

209
routers/private/hook.go Normal file
View file

@ -0,0 +1,209 @@
// 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 includes all internal routes. The package name internal is ideal but Golang is not allowed, so we use private as package name instead.
package private
import (
"fmt"
"net/http"
"os"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/util"
macaron "gopkg.in/macaron.v1"
)
// HookPreReceive checks whether a individual commit is acceptable
func HookPreReceive(ctx *macaron.Context) {
ownerName := ctx.Params(":owner")
repoName := ctx.Params(":repo")
oldCommitID := ctx.QueryTrim("old")
newCommitID := ctx.QueryTrim("new")
refFullName := ctx.QueryTrim("ref")
userID := ctx.QueryInt64("userID")
gitObjectDirectory := ctx.QueryTrim("gitObjectDirectory")
gitAlternativeObjectDirectories := ctx.QueryTrim("gitAlternativeObjectDirectories")
branchName := strings.TrimPrefix(refFullName, git.BranchPrefix)
repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName)
if err != nil {
log.Error("Unable to get repository: %s/%s Error: %v", ownerName, repoName, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": err.Error(),
})
return
}
repo.OwnerName = ownerName
protectBranch, err := models.GetProtectedBranchBy(repo.ID, branchName)
if err != nil {
log.Error("Unable to get protected branch: %s in %-v Error: %v", branchName, repo, err)
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
return
}
if protectBranch != nil && protectBranch.IsProtected() {
// check and deletion
if newCommitID == git.EmptySHA {
log.Warn("Forbidden: Branch: %s in %-v is protected from deletion", branchName, repo)
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"err": fmt.Sprintf("branch %s is protected from deletion", branchName),
})
return
}
// detect force push
if git.EmptySHA != oldCommitID {
env := append(os.Environ(),
private.GitAlternativeObjectDirectories+"="+gitAlternativeObjectDirectories,
private.GitObjectDirectory+"="+gitObjectDirectory,
private.GitQuarantinePath+"="+gitObjectDirectory,
)
output, err := git.NewCommand("rev-list", "--max-count=1", oldCommitID, "^"+newCommitID).RunInDirWithEnv(repo.RepoPath(), env)
if err != nil {
log.Error("Unable to detect force push between: %s and %s in %-v Error: %v", oldCommitID, newCommitID, repo, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": fmt.Sprintf("Fail to detect force push: %v", err),
})
return
} else if len(output) > 0 {
log.Warn("Forbidden: Branch: %s in %-v is protected from force push", branchName, repo)
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"err": fmt.Sprintf("branch %s is protected from force push", branchName),
})
return
}
}
if !protectBranch.CanUserPush(userID) {
log.Warn("Forbidden: User %d cannot push to protected branch: %s in %-v", userID, branchName, repo)
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"err": fmt.Sprintf("protected branch %s can not be pushed to", branchName),
})
return
}
}
ctx.PlainText(http.StatusOK, []byte("ok"))
}
// HookPostReceive updates services and users
func HookPostReceive(ctx *macaron.Context) {
ownerName := ctx.Params(":owner")
repoName := ctx.Params(":repo")
oldCommitID := ctx.Query("old")
newCommitID := ctx.Query("new")
refFullName := ctx.Query("ref")
userID := ctx.QueryInt64("userID")
userName := ctx.Query("username")
branch := refFullName
if strings.HasPrefix(refFullName, git.BranchPrefix) {
branch = strings.TrimPrefix(refFullName, git.BranchPrefix)
} else if strings.HasPrefix(refFullName, git.TagPrefix) {
branch = strings.TrimPrefix(refFullName, git.TagPrefix)
}
// Only trigger activity updates for changes to branches or
// tags. Updates to other refs (eg, refs/notes, refs/changes,
// or other less-standard refs spaces are ignored since there
// may be a very large number of them).
if strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) {
if err := models.PushUpdate(branch, models.PushUpdateOptions{
RefFullName: refFullName,
OldCommitID: oldCommitID,
NewCommitID: newCommitID,
PusherID: userID,
PusherName: userName,
RepoUserName: ownerName,
RepoName: repoName,
}); err != nil {
log.Error("Failed to Update: %s/%s Branch: %s Error: %v", ownerName, repoName, branch, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": fmt.Sprintf("Failed to Update: %s/%s Branch: %s Error: %v", ownerName, repoName, branch, err),
})
return
}
}
if newCommitID != git.EmptySHA && strings.HasPrefix(refFullName, git.BranchPrefix) {
repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName)
if err != nil {
log.Error("Failed to get repository: %s/%s Error: %v", ownerName, repoName, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": fmt.Sprintf("Failed to get repository: %s/%s Error: %v", ownerName, repoName, err),
})
return
}
repo.OwnerName = ownerName
pullRequestAllowed := repo.AllowsPulls()
if !pullRequestAllowed {
ctx.JSON(http.StatusOK, map[string]interface{}{
"message": false,
})
return
}
baseRepo := repo
if repo.IsFork {
if err := repo.GetBaseRepo(); err != nil {
log.Error("Failed to get Base Repository of Forked repository: %-v Error: %v", repo, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": fmt.Sprintf("Failed to get Base Repository of Forked repository: %-v Error: %v", repo, err),
})
return
}
baseRepo = repo.BaseRepo
}
if !repo.IsFork && branch == baseRepo.DefaultBranch {
ctx.JSON(http.StatusOK, map[string]interface{}{
"message": false,
})
return
}
pr, err := models.GetUnmergedPullRequest(repo.ID, baseRepo.ID, branch, baseRepo.DefaultBranch)
if err != nil && !models.IsErrPullRequestNotExist(err) {
log.Error("Failed to get active PR in: %-v Branch: %s to: %-v Branch: %s Error: %v", repo, branch, baseRepo, baseRepo.DefaultBranch, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": fmt.Sprintf(
"Failed to get active PR in: %-v Branch: %s to: %-v Branch: %s Error: %v", repo, branch, baseRepo, baseRepo.DefaultBranch, err),
})
return
}
if pr == nil {
if repo.IsFork {
branch = fmt.Sprintf("%s:%s", repo.OwnerName, branch)
}
ctx.JSON(http.StatusOK, map[string]interface{}{
"message": true,
"create": true,
"branch": branch,
"url": fmt.Sprintf("%s/compare/%s...%s", baseRepo.HTMLURL(), util.PathEscapeSegments(baseRepo.DefaultBranch), util.PathEscapeSegments(branch)),
})
} else {
ctx.JSON(http.StatusOK, map[string]interface{}{
"message": true,
"create": false,
"branch": branch,
"url": fmt.Sprintf("%s/pulls/%d", baseRepo.HTMLURL(), pr.Index),
})
}
return
}
ctx.JSON(http.StatusOK, map[string]interface{}{
"message": false,
})
return
}

View file

@ -76,19 +76,10 @@ func CheckUnitUser(ctx *macaron.Context) {
// These APIs will be invoked by internal commands for example `gitea serv` and etc.
func RegisterRoutes(m *macaron.Macaron) {
m.Group("/", func() {
m.Get("/ssh/:id", GetPublicKeyByID)
m.Get("/ssh/:id/user", GetUserByKeyID)
m.Post("/ssh/:id/update", UpdatePublicKey)
m.Post("/repositories/:repoid/keys/:keyid/update", UpdateDeployKey)
m.Get("/repositories/:repoid/user/:userid/checkunituser", CheckUnitUser)
m.Get("/repositories/:repoid/has-keys/:keyid", HasDeployKey)
m.Get("/repositories/:repoid/keys/:keyid", GetDeployKey)
m.Get("/repositories/:repoid/wiki/init", InitWiki)
m.Post("/push/update", PushUpdate)
m.Get("/protectedbranch/:pbid/:userid", CanUserPush)
m.Get("/repo/:owner/:repo", GetRepositoryByOwnerAndName)
m.Get("/branch/:id/*", GetProtectedBranchBy)
m.Get("/repository/:rid", GetRepository)
m.Get("/active-pull-request", GetActivePullRequest)
m.Post("/ssh/:id/update/:repoid", UpdatePublicKeyInRepo)
m.Get("/hook/pre-receive/:owner/:repo", HookPreReceive)
m.Get("/hook/post-receive/:owner/:repo", HookPostReceive)
m.Get("/serv/none/:keyid", ServNoCommand)
m.Get("/serv/command/:keyid/:owner/:repo", ServCommand)
}, CheckInternalToken)
}

View file

@ -12,12 +12,23 @@ import (
macaron "gopkg.in/macaron.v1"
)
// UpdateDeployKey update deploy key updates
func UpdateDeployKey(ctx *macaron.Context) {
// UpdatePublicKeyInRepo update public key and deploy key updates
func UpdatePublicKeyInRepo(ctx *macaron.Context) {
keyID := ctx.ParamsInt64(":id")
repoID := ctx.ParamsInt64(":repoid")
keyID := ctx.ParamsInt64(":keyid")
if err := models.UpdatePublicKeyUpdated(keyID); err != nil {
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
return
}
deployKey, err := models.GetDeployKeyByRepo(keyID, repoID)
if err != nil {
if models.IsErrDeployKeyNotExist(err) {
ctx.PlainText(200, []byte("success"))
return
}
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
@ -30,73 +41,6 @@ func UpdateDeployKey(ctx *macaron.Context) {
})
return
}
ctx.PlainText(200, []byte("success"))
}
// UpdatePublicKey update publick key updates
func UpdatePublicKey(ctx *macaron.Context) {
keyID := ctx.ParamsInt64(":id")
if err := models.UpdatePublicKeyUpdated(keyID); err != nil {
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
return
}
ctx.PlainText(200, []byte("success"))
}
//GetPublicKeyByID chainload to models.GetPublicKeyByID
func GetPublicKeyByID(ctx *macaron.Context) {
keyID := ctx.ParamsInt64(":id")
key, err := models.GetPublicKeyByID(keyID)
if err != nil {
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
return
}
ctx.JSON(200, key)
}
//GetUserByKeyID chainload to models.GetUserByKeyID
func GetUserByKeyID(ctx *macaron.Context) {
keyID := ctx.ParamsInt64(":id")
user, err := models.GetUserByKeyID(keyID)
if err != nil {
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
return
}
ctx.JSON(200, user)
}
//GetDeployKey chainload to models.GetDeployKey
func GetDeployKey(ctx *macaron.Context) {
repoID := ctx.ParamsInt64(":repoid")
keyID := ctx.ParamsInt64(":keyid")
dKey, err := models.GetDeployKeyByRepo(keyID, repoID)
if err != nil {
if models.IsErrDeployKeyNotExist(err) {
ctx.JSON(404, []byte("not found"))
return
}
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
return
}
ctx.JSON(200, dKey)
}
//HasDeployKey chainload to models.HasDeployKey
func HasDeployKey(ctx *macaron.Context) {
repoID := ctx.ParamsInt64(":repoid")
keyID := ctx.ParamsInt64(":keyid")
if models.HasDeployKey(keyID, repoID) {
ctx.PlainText(200, []byte("success"))
return
}
ctx.PlainText(404, []byte("not found"))
}

View file

@ -1,47 +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"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"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
}
err := models.PushUpdate(branch, opt)
if err != nil {
if models.IsErrUserNotExist(err) {
ctx.Error(404)
} else {
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
}
return
}
ctx.Status(202)
}

View file

@ -1,83 +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 (
"net/http"
"code.gitea.io/gitea/models"
macaron "gopkg.in/macaron.v1"
)
// GetRepository return the default branch of a repository
func GetRepository(ctx *macaron.Context) {
repoID := ctx.ParamsInt64(":rid")
repository, err := models.GetRepositoryByID(repoID)
repository.MustOwnerName()
allowPulls := repository.AllowsPulls()
// put it back to nil because json unmarshal can't unmarshal it
repository.Units = nil
if err != nil {
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": err.Error(),
})
return
}
if repository.IsFork {
repository.GetBaseRepo()
if err != nil {
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": err.Error(),
})
return
}
repository.BaseRepo.MustOwnerName()
allowPulls = repository.BaseRepo.AllowsPulls()
// put it back to nil because json unmarshal can't unmarshal it
repository.BaseRepo.Units = nil
}
ctx.JSON(http.StatusOK, struct {
Repository *models.Repository
AllowPullRequest bool
}{
Repository: repository,
AllowPullRequest: allowPulls,
})
}
// GetActivePullRequest return an active pull request when it exists or an empty object
func GetActivePullRequest(ctx *macaron.Context) {
baseRepoID := ctx.QueryInt64("baseRepoID")
headRepoID := ctx.QueryInt64("headRepoID")
baseBranch := ctx.QueryTrim("baseBranch")
if len(baseBranch) == 0 {
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": "QueryTrim failed",
})
return
}
headBranch := ctx.QueryTrim("headBranch")
if len(headBranch) == 0 {
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": "QueryTrim failed",
})
return
}
pr, err := models.GetUnmergedPullRequest(headRepoID, baseRepoID, headBranch, baseBranch)
if err != nil && !models.IsErrPullRequestNotExist(err) {
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": err.Error(),
})
return
}
ctx.JSON(http.StatusOK, pr)
}

286
routers/private/serv.go Normal file
View file

@ -0,0 +1,286 @@
// 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 includes all internal routes. The package name internal is ideal but Golang is not allowed, so we use private as package name instead.
package private
import (
"fmt"
"net/http"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
macaron "gopkg.in/macaron.v1"
)
// ServNoCommand returns information about the provided keyid
func ServNoCommand(ctx *macaron.Context) {
keyID := ctx.ParamsInt64(":keyid")
if keyID <= 0 {
ctx.JSON(http.StatusBadRequest, map[string]interface{}{
"err": fmt.Sprintf("Bad key id: %d", keyID),
})
}
results := private.KeyAndOwner{}
key, err := models.GetPublicKeyByID(keyID)
if err != nil {
if models.IsErrKeyNotExist(err) {
ctx.JSON(http.StatusUnauthorized, map[string]interface{}{
"err": fmt.Sprintf("Cannot find key: %d", keyID),
})
return
}
log.Error("Unable to get public key: %d Error: %v", keyID, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": err.Error(),
})
return
}
results.Key = key
if key.Type == models.KeyTypeUser {
user, err := models.GetUserByID(key.OwnerID)
if err != nil {
if models.IsErrUserNotExist(err) {
ctx.JSON(http.StatusUnauthorized, map[string]interface{}{
"err": fmt.Sprintf("Cannot find owner with id: %d for key: %d", key.OwnerID, keyID),
})
return
}
log.Error("Unable to get owner with id: %d for public key: %d Error: %v", key.OwnerID, keyID, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err": err.Error(),
})
return
}
results.Owner = user
}
ctx.JSON(http.StatusOK, &results)
return
}
// ServCommand returns information about the provided keyid
func ServCommand(ctx *macaron.Context) {
// Although we provide the verbs we don't need them at present they're just for logging purposes
keyID := ctx.ParamsInt64(":keyid")
ownerName := ctx.Params(":owner")
repoName := ctx.Params(":repo")
mode := models.AccessMode(ctx.QueryInt("mode"))
// Set the basic parts of the results to return
results := private.ServCommandResults{
RepoName: repoName,
OwnerName: ownerName,
KeyID: keyID,
}
// Now because we're not translating things properly let's just default some Engish strings here
modeString := "read"
if mode > models.AccessModeRead {
modeString = "write to"
}
// The default unit we're trying to look at is code
unitType := models.UnitTypeCode
// Unless we're a wiki...
if strings.HasSuffix(repoName, ".wiki") {
// in which case we need to look at the wiki
unitType = models.UnitTypeWiki
// And we'd better munge the reponame and tell downstream we're looking at a wiki
results.IsWiki = true
results.RepoName = repoName[:len(repoName)-5]
}
// Now get the Repository and set the results section
repo, err := models.GetRepositoryByOwnerAndName(results.OwnerName, results.RepoName)
if err != nil {
if models.IsErrRepoNotExist(err) {
ctx.JSON(http.StatusNotFound, map[string]interface{}{
"results": results,
"type": "ErrRepoNotExist",
"err": fmt.Sprintf("Cannot find repository %s/%s", results.OwnerName, results.RepoName),
})
return
}
log.Error("Unable to get repository: %s/%s Error: %v", results.OwnerName, results.RepoName, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"results": results,
"type": "InternalServerError",
"err": fmt.Sprintf("Unable to get repository: %s/%s %v", results.OwnerName, results.RepoName, err),
})
return
}
repo.OwnerName = ownerName
results.RepoID = repo.ID
// We can shortcut at this point if the repo is a mirror
if mode > models.AccessModeRead && repo.IsMirror {
ctx.JSON(http.StatusUnauthorized, map[string]interface{}{
"results": results,
"type": "ErrMirrorReadOnly",
"err": fmt.Sprintf("Mirror Repository %s/%s is read-only", results.OwnerName, results.RepoName),
})
return
}
// Get the Public Key represented by the keyID
key, err := models.GetPublicKeyByID(keyID)
if err != nil {
if models.IsErrKeyNotExist(err) {
ctx.JSON(http.StatusUnauthorized, map[string]interface{}{
"results": results,
"type": "ErrKeyNotExist",
"err": fmt.Sprintf("Cannot find key: %d", keyID),
})
return
}
log.Error("Unable to get public key: %d Error: %v", keyID, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"results": results,
"type": "InternalServerError",
"err": fmt.Sprintf("Unable to get key: %d Error: %v", keyID, err),
})
return
}
results.KeyName = key.Name
results.KeyID = key.ID
results.UserID = key.OwnerID
// Deploy Keys have ownerID set to 0 therefore we can't use the owner
// So now we need to check if the key is a deploy key
// We'll keep hold of the deploy key here for permissions checking
var deployKey *models.DeployKey
var user *models.User
if key.Type == models.KeyTypeDeploy {
results.IsDeployKey = true
var err error
deployKey, err = models.GetDeployKeyByRepo(key.ID, repo.ID)
if err != nil {
if models.IsErrDeployKeyNotExist(err) {
ctx.JSON(http.StatusUnauthorized, map[string]interface{}{
"results": results,
"type": "ErrDeployKeyNotExist",
"err": fmt.Sprintf("Public (Deploy) Key: %d:%s is not authorized to %s %s/%s.", key.ID, key.Name, modeString, results.OwnerName, results.RepoName),
})
return
}
log.Error("Unable to get deploy for public (deploy) key: %d in %-v Error: %v", key.ID, repo, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"results": results,
"type": "InternalServerError",
"err": fmt.Sprintf("Unable to get Deploy Key for Public Key: %d:%s in %s/%s.", key.ID, key.Name, results.OwnerName, results.RepoName),
})
return
}
results.KeyName = deployKey.Name
// 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 of the repository
results.UserName = results.OwnerName
results.UserID = repo.OwnerID
} else {
// Get the user represented by the Key
var err error
user, err = models.GetUserByID(key.OwnerID)
if err != nil {
if models.IsErrUserNotExist(err) {
ctx.JSON(http.StatusUnauthorized, map[string]interface{}{
"results": results,
"type": "ErrUserNotExist",
"err": fmt.Sprintf("Public Key: %d:%s owner %d does not exist.", key.ID, key.Name, key.OwnerID),
})
return
}
log.Error("Unable to get owner: %d for public key: %d:%s Error: %v", key.OwnerID, key.ID, key.Name, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"results": results,
"type": "InternalServerError",
"err": fmt.Sprintf("Unable to get Owner: %d for Deploy Key: %d:%s in %s/%s.", key.OwnerID, key.ID, key.Name, ownerName, repoName),
})
return
}
results.UserName = user.Name
}
// Don't allow pushing if the repo is archived
if mode > models.AccessModeRead && repo.IsArchived {
ctx.JSON(http.StatusUnauthorized, map[string]interface{}{
"results": results,
"type": "ErrRepoIsArchived",
"err": fmt.Sprintf("Repo: %s/%s is archived.", results.OwnerName, results.RepoName),
})
return
}
// Permissions checking:
if mode > models.AccessModeRead || repo.IsPrivate || setting.Service.RequireSignInView {
if key.Type == models.KeyTypeDeploy {
if deployKey.Mode < mode {
ctx.JSON(http.StatusUnauthorized, map[string]interface{}{
"results": results,
"type": "ErrUnauthorized",
"err": fmt.Sprintf("Deploy Key: %d:%s is not authorized to %s %s/%s.", key.ID, key.Name, modeString, results.OwnerName, results.RepoName),
})
return
}
} else {
perm, err := models.GetUserRepoPermission(repo, user)
if err != nil {
log.Error("Unable to get permissions for %-v with key %d in %-v Error: %v", user, key.ID, repo, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"results": results,
"type": "InternalServerError",
"err": fmt.Sprintf("Unable to get permissions for user %d:%s with key %d in %s/%s Error: %v", user.ID, user.Name, key.ID, results.OwnerName, results.RepoName, err),
})
return
}
userMode := perm.UnitAccessMode(unitType)
if userMode < mode {
ctx.JSON(http.StatusUnauthorized, map[string]interface{}{
"results": results,
"type": "ErrUnauthorized",
"err": fmt.Sprintf("User: %d:%s with Key: %d:%s is not authorized to %s %s/%s.", user.ID, user.Name, key.ID, key.Name, modeString, ownerName, repoName),
})
return
}
}
}
// Finally if we're trying to touch the wiki we should init it
if results.IsWiki {
if err = repo.InitWiki(); err != nil {
log.Error("Failed to initialize the wiki in %-v Error: %v", repo, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"results": results,
"type": "InternalServerError",
"err": fmt.Sprintf("Failed to initialize the wiki in %s/%s Error: %v", ownerName, repoName, err),
})
return
}
}
log.Debug("Serv Results:\nIsWiki: %t\nIsDeployKey: %t\nKeyID: %d\tKeyName: %s\nUserName: %s\nUserID: %d\nOwnerName: %s\nRepoName: %s\nRepoID: %d",
results.IsWiki,
results.IsDeployKey,
results.KeyID,
results.KeyName,
results.UserName,
results.UserID,
results.OwnerName,
results.RepoName,
results.RepoID)
ctx.JSON(http.StatusOK, results)
// We will update the keys in a different call.
return
}

View file

@ -1,34 +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 (
"code.gitea.io/gitea/models"
macaron "gopkg.in/macaron.v1"
)
// InitWiki initilizes wiki via repo id
func InitWiki(ctx *macaron.Context) {
repoID := ctx.ParamsInt64("repoid")
repo, err := models.GetRepositoryByID(repoID)
if err != nil {
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
return
}
err = repo.InitWiki()
if err != nil {
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
return
}
ctx.Status(202)
}

View file

@ -351,7 +351,7 @@ func gitCommand(dir string, args ...string) []byte {
cmd.Dir = dir
out, err := cmd.Output()
if err != nil {
log.GitLogger.Error(fmt.Sprintf("%v - %s", err, out))
log.Error("%v - %s", err, out)
}
return out
}
@ -409,7 +409,7 @@ func serviceRPC(h serviceHandler, service string) {
if h.r.Header.Get("Content-Encoding") == "gzip" {
reqBody, err = gzip.NewReader(reqBody)
if err != nil {
log.GitLogger.Error("Fail to create gzip reader: %v", err)
log.Error("Fail to create gzip reader: %v", err)
h.w.WriteHeader(http.StatusInternalServerError)
return
}
@ -428,7 +428,7 @@ func serviceRPC(h serviceHandler, service string) {
cmd.Stdin = reqBody
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
log.GitLogger.Error("Fail to serve RPC(%s): %v - %v", service, err, stderr)
log.Error("Fail to serve RPC(%s): %v - %v", service, err, stderr)
return
}
}
@ -541,7 +541,7 @@ func HTTPBackend(ctx *context.Context, cfg *serviceConfig) http.HandlerFunc {
file := strings.Replace(r.URL.Path, m[1]+"/", "", 1)
dir, err := getGitRepoPath(m[1])
if err != nil {
log.GitLogger.Error(err.Error())
log.Error(err.Error())
ctx.NotFound("HTTPBackend", err)
return
}