"code.gitea.io/gitea/modules/pprof"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
"github.com/Unknwon/com"
"github.com/dgrijalva/jwt-go"
},
}
-func setup(logPath string) error {
+func setup(logPath string) {
setting.NewContext()
log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
- models.LoadConfigs()
-
- if setting.UseSQLite3 || setting.UseTiDB {
- workPath := setting.AppWorkPath
- if err := os.Chdir(workPath); err != nil {
- log.GitLogger.Fatal(4, "Failed to change directory %s: %v", workPath, err)
- }
- }
-
- setting.NewXORMLogService(true)
- return models.SetEngine()
}
func parseCmd(cmd string) (string, string) {
if c.IsSet("config") {
setting.CustomConf = c.String("config")
}
-
- if err := setup("serv.log"); err != nil {
- fail("System init failed", fmt.Sprintf("setup: %v", err))
- }
+ setup("serv.log")
if setting.SSH.Disabled {
println("Gitea: SSH has been disabled")
}
os.Setenv(models.EnvRepoName, reponame)
- repo, err := models.GetRepositoryByOwnerAndName(username, reponame)
+ repo, err := private.GetRepositoryByOwnerAndName(username, reponame)
if err != nil {
- if models.IsErrRepoNotExist(err) {
+ 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)
fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
}
- key, err := models.GetPublicKeyByID(com.StrTo(keys[1]).MustInt64())
+ 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)
}
if key.Mode < requestedMode {
fail("Key permission denied", "Cannot push with deployment key: %d", key.ID)
}
+
// Check if this deploy key belongs to current repository.
- if !models.HasDeployKey(key.ID, repo.ID) {
+ has, err := private.HasDeployKey(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 !has {
fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
}
// Update deploy key activity.
- deployKey, err := models.GetDeployKeyByRepo(key.ID, repo.ID)
- if err != nil {
- fail("Internal error", "GetDeployKey: %v", err)
- }
-
- deployKey.UpdatedUnix = util.TimeStampNow()
- if err = models.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil {
+ if err = private.UpdateDeployKeyUpdated(key.ID, repo.ID); err != nil {
fail("Internal error", "UpdateDeployKey: %v", err)
}
} else {
- user, err = models.GetUserByKeyID(key.ID)
+ user, err = private.GetUserByKeyID(key.ID)
if err != nil {
fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err)
}
user.Name, repoPath)
}
- mode, err := models.AccessLevel(user.ID, repo)
+ mode, err := private.AccessLevel(user.ID, repo.ID)
if err != nil {
fail("Internal error", "Failed to check access: %v", err)
- } else if mode < requestedMode {
+ } else if *mode < requestedMode {
clientMessage := accessDenied
- if mode >= models.AccessModeRead {
+ if *mode >= models.AccessModeRead {
clientMessage = "You do not have sufficient authorization for this action"
}
fail(clientMessage,
user.Name, requestedMode, repoPath)
}
- if !repo.CheckUnitUser(user.ID, user.IsAdmin, unitType) {
+ check, err := private.CheckUnitUser(user.ID, repo.ID, user.IsAdmin, unitType)
+ if err != nil {
+ fail("You do not have allowed for this action", "Failed to access internal api: [user.Name: %s, repoPath: %s]", user.Name, repoPath)
+ }
+ if !check {
fail("You do not have allowed for this action",
"User %s does not have allowed access to repository %s 's code",
user.Name, repoPath)
} else {
gitcmd = exec.Command(verb, repoPath)
}
-
if isWiki {
if err = repo.InitWiki(); err != nil {
fail("Internal error", "Failed to init wiki repo: %v", err)
// 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 nil, fmt.Errorf("Failed to get protected branch: %s", decodeJSONError(resp).Err)
}
return &branch, nil
"net"
"net/http"
+ "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
return req
}
-// UpdatePublicKeyUpdated update publick key updates
-func UpdatePublicKeyUpdated(keyID 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)
+// CheckUnitUser check whether user could visit the unit of this repository
+func CheckUnitUser(userID, repoID int64, isAdmin bool, unitType models.UnitType) (bool, error) {
+ reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/user/%d/checkunituser?isAdmin=%t&unitType=%d", repoID, userID, isAdmin, unitType)
+ log.GitLogger.Trace("AccessLevel: %s", reqURL)
- resp, err := newInternalRequest(reqURL, "POST").Response()
+ resp, err := newInternalRequest(reqURL, "GET").Response()
if err != nil {
- return err
+ return false, err
}
+ defer resp.Body.Close()
+
+ if resp.StatusCode == 200 {
+ return true, nil
+ }
+ return false, nil
+}
+
+// AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
+// user does not have access.
+func AccessLevel(userID, repoID int64) (*models.AccessMode, error) {
+ reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/user/%d/accesslevel", repoID, userID)
+ log.GitLogger.Trace("AccessLevel: %s", reqURL)
+ resp, err := newInternalRequest(reqURL, "GET").Response()
+ if 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 fmt.Errorf("Failed to update public key: %s", decodeJSONError(resp).Err)
+ if resp.StatusCode != 200 {
+ return nil, fmt.Errorf("Failed to get user access level: %s", decodeJSONError(resp).Err)
+ }
+
+ var a models.AccessMode
+ if err := json.NewDecoder(resp.Body).Decode(&a); err != nil {
+ return nil, err
}
- return nil
+
+ 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", ownerName, 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
}
--- /dev/null
+// 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"
+
+ "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
+}
+
+// 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 {
+ // 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)
+
+ 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 public key: %s", decodeJSONError(resp).Err)
+ }
+ return nil
+}
}
}
-// UpdatePublicKey update publick key updates
-func UpdatePublicKey(ctx *macaron.Context) {
- keyID := ctx.ParamsInt64(":id")
- if err := models.UpdatePublicKeyUpdated(keyID); err != nil {
+//GetRepositoryByOwnerAndName chainload to models.GetRepositoryByOwnerAndName
+func GetRepositoryByOwnerAndName(ctx *macaron.Context) {
+ //TODO use repo.Get(ctx *context.APIContext) ?
+ ownerName := ctx.Params(":owner")
+ repoName := ctx.Params(":repo")
+ repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName)
+ if err != nil {
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
return
}
+ ctx.JSON(200, repo)
+}
+
+//AccessLevel chainload to models.AccessLevel
+func AccessLevel(ctx *macaron.Context) {
+ repoID := ctx.ParamsInt64(":repoid")
+ userID := ctx.ParamsInt64(":userid")
+ repo, err := models.GetRepositoryByID(repoID)
+ if err != nil {
+ ctx.JSON(500, map[string]interface{}{
+ "err": err.Error(),
+ })
+ return
+ }
+ al, err := models.AccessLevel(userID, repo)
+ if err != nil {
+ ctx.JSON(500, map[string]interface{}{
+ "err": err.Error(),
+ })
+ return
+ }
+ ctx.JSON(200, al)
+}
- ctx.PlainText(200, []byte("success"))
+//CheckUnitUser chainload to models.CheckUnitUser
+func CheckUnitUser(ctx *macaron.Context) {
+ repoID := ctx.ParamsInt64(":repoid")
+ userID := ctx.ParamsInt64(":userid")
+ repo, err := models.GetRepositoryByID(repoID)
+ if err != nil {
+ ctx.JSON(500, map[string]interface{}{
+ "err": err.Error(),
+ })
+ return
+ }
+ if repo.CheckUnitUser(userID, ctx.QueryBool("isAdmin"), models.UnitType(ctx.QueryInt("unitType"))) {
+ ctx.PlainText(200, []byte("success"))
+ return
+ }
+ ctx.PlainText(404, []byte("no access"))
}
// RegisterRoutes registers all internal APIs routes to web application.
// 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/accesslevel", AccessLevel)
+ m.Get("/repositories/:repoid/user/:userid/checkunituser", CheckUnitUser)
+ m.Get("/repositories/:repoid/has-keys/:keyid", HasDeployKey)
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)
--- /dev/null
+// 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 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 (
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/util"
+
+ macaron "gopkg.in/macaron.v1"
+)
+
+// UpdateDeployKey update deploy key updates
+func UpdateDeployKey(ctx *macaron.Context) {
+ repoID := ctx.ParamsInt64(":repoid")
+ keyID := ctx.ParamsInt64(":keyid")
+ deployKey, err := models.GetDeployKeyByRepo(keyID, repoID)
+ if err != nil {
+ ctx.JSON(500, map[string]interface{}{
+ "err": err.Error(),
+ })
+ return
+ }
+ deployKey.UpdatedUnix = util.TimeStampNow()
+ if err = models.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil {
+ ctx.JSON(500, map[string]interface{}{
+ "err": err.Error(),
+ })
+ 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)
+}
+
+//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"))
+}