From 7e019b1705132e7e2c1947d7489c7a5279c6bb2c Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Thu, 6 Sep 2018 17:57:21 +0200 Subject: [PATCH 01/14] Start to move to internal/private --- cmd/serv.go | 42 ++++++++++++++++++++----------------- modules/private/branch.go | 2 +- modules/private/internal.go | 25 ++++++++++++++++++++++ routers/private/internal.go | 17 +++++++++++++++ 4 files changed, 66 insertions(+), 20 deletions(-) diff --git a/cmd/serv.go b/cmd/serv.go index b532b95494e50..b0ad918b0e3b9 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -52,17 +52,21 @@ var CmdServ = cli.Command{ func setup(logPath string) error { 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) + return nil + //TODO clean this + /* + 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() + setting.NewXORMLogService(true) + return models.SetEngine() + */ } func parseCmd(cmd string) (string, string) { @@ -175,8 +179,8 @@ func runServ(c *cli.Context) error { } os.Setenv(models.EnvRepoName, reponame) - repo, err := models.GetRepositoryByOwnerAndName(username, reponame) - if err != nil { + repo, err := private.GetRepositoryByOwnerAndName(username, reponame) + if err != nil { //TODO manage error with internal api if models.IsErrRepoNotExist(err) { fail(accessDenied, "Repository does not exist: %s/%s", username, reponame) } @@ -214,7 +218,7 @@ func runServ(c *cli.Context) error { 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) } @@ -226,22 +230,22 @@ func runServ(c *cli.Context) error { 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) { + if !private.HasDeployKey(key.ID, repo.ID) { 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) + deployKey, err := private.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.UpdateDeployKeyCols(deployKey, "updated_unix"); 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) } @@ -252,7 +256,7 @@ func runServ(c *cli.Context) error { user.Name, repoPath) } - mode, err := models.AccessLevel(user.ID, repo) + mode, err := private.AccessLevel(user.ID, repo) if err != nil { fail("Internal error", "Failed to check access: %v", err) } else if mode < requestedMode { @@ -264,7 +268,7 @@ func runServ(c *cli.Context) error { "User %s does not have level %v access to repository %s", user.Name, requestedMode, repoPath) } - + //TODO verify that it doesn't need access to DB if !repo.CheckUnitUser(user.ID, user.IsAdmin, unitType) { fail("You do not have allowed for this action", "User %s does not have allowed access to repository %s 's code", @@ -325,7 +329,7 @@ func runServ(c *cli.Context) error { } else { gitcmd = exec.Command(verb, repoPath) } - + //TODO check if need access to database if isWiki { if err = repo.InitWiki(); err != nil { fail("Internal error", "Failed to init wiki repo: %v", err) diff --git a/modules/private/branch.go b/modules/private/branch.go index fed66d29ffb39..cadbf6c88c2a6 100644 --- a/modules/private/branch.go +++ b/modules/private/branch.go @@ -33,7 +33,7 @@ func GetProtectedBranchBy(repoID int64, branchName string) (*models.ProtectedBra // 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 diff --git a/modules/private/internal.go b/modules/private/internal.go index ac2fe56b871e7..05acb818b591c 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -11,6 +11,7 @@ import ( "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" @@ -49,6 +50,30 @@ func newInternalRequest(url, method string) *httplib.Request { return req } +//TODO move on specific file +func GetRepositoryByOwnerAndName(ownerName, repoName string) (*models.Repository, error) { + // Ask for running deliver hook and test pull request tasks. + 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 + } + var repo models.Repository + if err := json.NewDecoder(resp.Body).Decode(&repo); 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) + } + + return &repo, nil +} + // UpdatePublicKeyUpdated update publick key updates func UpdatePublicKeyUpdated(keyID int64) error { // Ask for running deliver hook and test pull request tasks. diff --git a/routers/private/internal.go b/routers/private/internal.go index 96021d8feb7a4..4dd9cc98f4295 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -36,6 +36,22 @@ func UpdatePublicKey(ctx *macaron.Context) { ctx.PlainText(200, []byte("success")) } +//TODO move on specific file +//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.APIFormat(models.AccessModeAdmin)) //TODO verify only use for internal but maybe a lower access is enough +} + // 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) { @@ -43,6 +59,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/ssh/:id/update", UpdatePublicKey) 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) From fe79ba339ca26d429890970f982a921b05f4b96f Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Thu, 6 Sep 2018 18:37:17 +0200 Subject: [PATCH 02/14] Add GetPublicKeyByID --- cmd/serv.go | 1 + modules/private/internal.go | 34 ++++++++++++++++++++++++++++------ routers/private/internal.go | 17 ++++++++++++++++- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/cmd/serv.go b/cmd/serv.go index b0ad918b0e3b9..72e4fa8f94143 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -54,6 +54,7 @@ func setup(logPath string) error { log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath)) return nil //TODO clean this + //TODO add tests /* models.LoadConfigs() diff --git a/modules/private/internal.go b/modules/private/internal.go index 05acb818b591c..6a21e2eba1bba 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -51,26 +51,48 @@ func newInternalRequest(url, method string) *httplib.Request { } //TODO move on specific file -func GetRepositoryByOwnerAndName(ownerName, repoName string) (*models.Repository, error) { - // Ask for running deliver hook and test pull request tasks. - reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repo/%s/%s", ownerName, repoName) - log.GitLogger.Trace("GetRepositoryByOwnerAndName: %s", reqURL) + +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 } - var repo models.Repository - if err := json.NewDecoder(resp.Body).Decode(&repo); err != nil { + + 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 +} +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 } diff --git a/routers/private/internal.go b/routers/private/internal.go index 4dd9cc98f4295..8919a9d6e38d2 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" + "code.gitea.io/gitea/routers/api/v1/convert" macaron "gopkg.in/macaron.v1" ) @@ -37,7 +38,7 @@ func UpdatePublicKey(ctx *macaron.Context) { } //TODO move on specific file -//GetRepositoryByOwnerAndName +//GetRepositoryByOwnerAndName chainload to models.GetRepositoryByOwnerAndName func GetRepositoryByOwnerAndName(ctx *macaron.Context) { //TODO use repo.Get(ctx *context.APIContext) ? ownerName := ctx.Params(":owner") @@ -52,10 +53,24 @@ func GetRepositoryByOwnerAndName(ctx *macaron.Context) { ctx.JSON(200, repo.APIFormat(models.AccessModeAdmin)) //TODO verify only use for internal but maybe a lower access is enough } +//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, convert.ToPublicKey("", key)) //TODO check if api link is needed +} + // 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.Post("/ssh/:id/update", UpdatePublicKey) m.Post("/push/update", PushUpdate) m.Get("/protectedbranch/:pbid/:userid", CanUserPush) From 806eb9c39c10408d52c0f20be9a007ba833400a7 Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Thu, 6 Sep 2018 19:09:51 +0200 Subject: [PATCH 03/14] Add HasDeployKey --- cmd/serv.go | 6 +++++- modules/private/internal.go | 14 ++++++++++++++ routers/private/internal.go | 11 +++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/cmd/serv.go b/cmd/serv.go index 72e4fa8f94143..5854442e6f05a 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -231,7 +231,11 @@ func runServ(c *cli.Context) error { fail("Key permission denied", "Cannot push with deployment key: %d", key.ID) } // Check if this deploy key belongs to current repository. - if !private.HasDeployKey(key.ID, repo.ID) { + b, 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 !b { fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID) } diff --git a/modules/private/internal.go b/modules/private/internal.go index 6a21e2eba1bba..2e3b4fd31d580 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -52,6 +52,20 @@ func newInternalRequest(url, method string) *httplib.Request { //TODO move on specific file +func HasDeployKey(keyID, repoID int64) (bool, error) { + reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/has-keys/%d", repoID, keyID) + 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 +} + func GetPublicKeyByID(keyID int64) (*models.PublicKey, error) { reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/%d", keyID) log.GitLogger.Trace("GetPublicKeyByID: %s", reqURL) diff --git a/routers/private/internal.go b/routers/private/internal.go index 8919a9d6e38d2..5485611f50b69 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -66,12 +66,23 @@ func GetPublicKeyByID(ctx *macaron.Context) { ctx.JSON(200, convert.ToPublicKey("", key)) //TODO check if api link is needed } +//HasDeployKey chainload to models.HasDeployKey +func HasDeployKey(ctx *macaron.Context) { + repoID := ctx.ParamsInt64(":repoid") + keyID := ctx.ParamsInt64(":keyid") + if models.HasDeployKey(repoID, keyID) { + ctx.PlainText(200, []byte("success")) + } + ctx.PlainText(404, []byte("not found")) +} + // 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.Post("/ssh/:id/update", UpdatePublicKey) + 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) From 0fda01019d63f40a61949cb4d605491645c48283 Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Thu, 6 Sep 2018 20:15:43 +0200 Subject: [PATCH 04/14] Add private.UpdateDeployKeyUpdated --- cmd/serv.go | 14 ++++-------- modules/private/internal.go | 40 +++++++++++++++++++++++++++++++++ routers/private/internal.go | 45 ++++++++++++++++++++++++++++++++++--- 3 files changed, 86 insertions(+), 13 deletions(-) diff --git a/cmd/serv.go b/cmd/serv.go index 5854442e6f05a..1fd5f3a3a0b69 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -19,7 +19,6 @@ import ( "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" @@ -230,23 +229,18 @@ func runServ(c *cli.Context) error { 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. + + // Check if this deploy key belongs to current repository. //TODO maybe not needed anymore b, 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) + fail("Key access denied", "Failed to access internal api: [key_id: %d, repo_id: %d]", key.ID, repo.ID) } if !b { fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID) } // Update deploy key activity. - deployKey, err := private.GetDeployKeyByRepo(key.ID, repo.ID) - if err != nil { - fail("Internal error", "GetDeployKey: %v", err) - } - - deployKey.UpdatedUnix = util.TimeStampNow() - if err = private.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil { + if err = private.UpdateDeployKeyUpdated(key.ID, repo.ID); err != nil { fail("Internal error", "UpdateDeployKey: %v", err) } } else { diff --git a/modules/private/internal.go b/modules/private/internal.go index 2e3b4fd31d580..c0c51cc6fb516 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -52,6 +52,46 @@ func newInternalRequest(url, method string) *httplib.Request { //TODO move on specific file +// UpdatePublicKeyUpdated update publick key updates +func UpdateDeployKeyUpdated(keyID int64, repoID int64) error { + // Ask for running deliver hook and test pull request tasks. + reqURL := setting.LocalURL + fmt.Sprintf("/repositories/%d/keys/%d/update", keyID, repoID) + 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 +} + +/* +func GetDeployKeyByRepo(keyID, repoID int64) (*models.DeployKey, error) { + reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/keys/%d", repoID, keyID) + 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 key models.DeployKey + if err := json.NewDecoder(resp.Body).Decode(&key); err != nil { + return nil, err + } + return &key, nil +} +*/ func HasDeployKey(keyID, repoID int64) (bool, error) { reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/has-keys/%d", repoID, keyID) resp, err := newInternalRequest(reqURL, "GET").Response() diff --git a/routers/private/internal.go b/routers/private/internal.go index 5485611f50b69..de093c2466a69 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/routers/api/v1/convert" + "code.gitea.io/gitea/modules/util" macaron "gopkg.in/macaron.v1" ) @@ -24,6 +24,27 @@ func CheckInternalToken(ctx *macaron.Context) { } } +// 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") @@ -50,7 +71,7 @@ func GetRepositoryByOwnerAndName(ctx *macaron.Context) { }) return } - ctx.JSON(200, repo.APIFormat(models.AccessModeAdmin)) //TODO verify only use for internal but maybe a lower access is enough + ctx.JSON(200, repo) } //GetPublicKeyByID chainload to models.GetPublicKeyByID @@ -63,7 +84,7 @@ func GetPublicKeyByID(ctx *macaron.Context) { }) return } - ctx.JSON(200, convert.ToPublicKey("", key)) //TODO check if api link is needed + ctx.JSON(200, key) } //HasDeployKey chainload to models.HasDeployKey @@ -76,12 +97,30 @@ func HasDeployKey(ctx *macaron.Context) { ctx.PlainText(404, []byte("not found")) } +/* +//GetDeployKeyByRepo chainload to models.GetDeployKeyByRepo +func GetDeployKeyByRepo(ctx *macaron.Context) { + repoID := ctx.ParamsInt64(":repoid") + keyID := ctx.ParamsInt64(":keyid") + key, err := models.GetDeployKeyByRepo(repoID, keyID) + if err != nil { + ctx.JSON(500, map[string]interface{}{ + "err": err.Error(), + }) + return + } + ctx.JSON(200, key) +} +*/ + // 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.Post("/ssh/:id/update", UpdatePublicKey) + m.Post("/repositories/:repoid/keys/:keyid/update", UpdateDeployKey) + //m.Get("/repositories/:repoid/keys/:keyid", GetDeployKeyByRepo) m.Get("/repositories/:repoid/has-keys/:keyid", HasDeployKey) m.Post("/push/update", PushUpdate) m.Get("/protectedbranch/:pbid/:userid", CanUserPush) From 363d806ebae69c0068748da280bc8f4c0007a97a Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Thu, 6 Sep 2018 20:25:02 +0200 Subject: [PATCH 05/14] Add private.GetUserByKeyID --- cmd/serv.go | 2 +- modules/private/internal.go | 24 ++++++++++++++++++++++++ routers/private/internal.go | 14 ++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/cmd/serv.go b/cmd/serv.go index 1fd5f3a3a0b69..3ca470f6bb1e5 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -267,7 +267,7 @@ func runServ(c *cli.Context) error { "User %s does not have level %v access to repository %s", user.Name, requestedMode, repoPath) } - //TODO verify that it doesn't need access to DB + //TODO use private if !repo.CheckUnitUser(user.ID, user.IsAdmin, unitType) { fail("You do not have allowed for this action", "User %s does not have allowed access to repository %s 's code", diff --git a/modules/private/internal.go b/modules/private/internal.go index c0c51cc6fb516..ebcf95bd6697d 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -94,6 +94,8 @@ func GetDeployKeyByRepo(keyID, repoID int64) (*models.DeployKey, error) { */ 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 @@ -128,6 +130,28 @@ func GetPublicKeyByID(keyID int64) (*models.PublicKey, error) { return &pKey, nil } +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 +} + 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) diff --git a/routers/private/internal.go b/routers/private/internal.go index de093c2466a69..11648009a8d71 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -87,6 +87,19 @@ func GetPublicKeyByID(ctx *macaron.Context) { 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") @@ -118,6 +131,7 @@ func GetDeployKeyByRepo(ctx *macaron.Context) { 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/keys/:keyid", GetDeployKeyByRepo) From f7093b4e24e9b471566c6a690c61d06998200fcf Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Thu, 6 Sep 2018 20:38:38 +0200 Subject: [PATCH 06/14] Add private.AccessLevel --- cmd/serv.go | 24 +++++------------------- modules/private/internal.go | 22 ++++++++++++++++++++++ routers/private/internal.go | 22 ++++++++++++++++++++++ 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/cmd/serv.go b/cmd/serv.go index 3ca470f6bb1e5..7943139acde76 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -25,6 +25,8 @@ import ( "github.com/urfave/cli" ) +//TODO add tests + const ( accessDenied = "Repository does not exist or you do not have access" lfsAuthenticateVerb = "git-lfs-authenticate" @@ -52,21 +54,6 @@ func setup(logPath string) error { setting.NewContext() log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath)) return nil - //TODO clean this - //TODO add tests - /* - 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) { @@ -255,12 +242,12 @@ func runServ(c *cli.Context) error { user.Name, repoPath) } - mode, err := private.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, @@ -328,7 +315,6 @@ func runServ(c *cli.Context) error { } else { gitcmd = exec.Command(verb, repoPath) } - //TODO check if need access to database if isWiki { if err = repo.InitWiki(); err != nil { fail("Internal error", "Failed to init wiki repo: %v", err) diff --git a/modules/private/internal.go b/modules/private/internal.go index ebcf95bd6697d..2e747cf0d8ee9 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -130,6 +130,28 @@ func GetPublicKeyByID(keyID int64) (*models.PublicKey, error) { return &pKey, nil } +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() + + 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 &a, nil +} + func GetUserByKeyID(keyID int64) (*models.User, error) { reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/%d/user", keyID) log.GitLogger.Trace("GetUserByKeyID: %s", reqURL) diff --git a/routers/private/internal.go b/routers/private/internal.go index 11648009a8d71..946b907d94019 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -110,6 +110,27 @@ func HasDeployKey(ctx *macaron.Context) { ctx.PlainText(404, []byte("not found")) } +//GetUserByKeyID chainload to models.GetUserByKeyID +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) +} + /* //GetDeployKeyByRepo chainload to models.GetDeployKeyByRepo func GetDeployKeyByRepo(ctx *macaron.Context) { @@ -134,6 +155,7 @@ func RegisterRoutes(m *macaron.Macaron) { 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/keys/:keyid", GetDeployKeyByRepo) m.Get("/repositories/:repoid/has-keys/:keyid", HasDeployKey) m.Post("/push/update", PushUpdate) From 0249192131f2422603a98ea9a11cfa6ad868934f Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Fri, 7 Sep 2018 00:29:20 +0200 Subject: [PATCH 07/14] Add private.CheckUnitUser --- cmd/serv.go | 12 ++++++++---- modules/private/internal.go | 16 ++++++++++++++++ routers/private/internal.go | 22 +++++++++++++++++++++- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/cmd/serv.go b/cmd/serv.go index 7943139acde76..db4760e6595ad 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -218,11 +218,11 @@ func runServ(c *cli.Context) error { } // Check if this deploy key belongs to current repository. //TODO maybe not needed anymore - b, err := private.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 !b { + if !has { fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID) } @@ -254,8 +254,12 @@ func runServ(c *cli.Context) error { "User %s does not have level %v access to repository %s", user.Name, requestedMode, repoPath) } - //TODO use private - if !repo.CheckUnitUser(user.ID, user.IsAdmin, unitType) { + + check, err := private.CheckUnitUser(repo.ID, user.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) diff --git a/modules/private/internal.go b/modules/private/internal.go index 2e747cf0d8ee9..b635a7480113d 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -130,6 +130,22 @@ func GetPublicKeyByID(keyID int64) (*models.PublicKey, error) { return &pKey, nil } +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, "GET").Response() + if err != nil { + return false, err + } + defer resp.Body.Close() + + if resp.StatusCode == 200 { + return true, nil + } + return false, nil +} + 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) diff --git a/routers/private/internal.go b/routers/private/internal.go index 946b907d94019..40af0c17e2814 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -106,11 +106,12 @@ func HasDeployKey(ctx *macaron.Context) { keyID := ctx.ParamsInt64(":keyid") if models.HasDeployKey(repoID, keyID) { ctx.PlainText(200, []byte("success")) + return } ctx.PlainText(404, []byte("not found")) } -//GetUserByKeyID chainload to models.GetUserByKeyID +//AccessLevel chainload to models.AccessLevel func AccessLevel(ctx *macaron.Context) { repoID := ctx.ParamsInt64(":repoid") userID := ctx.ParamsInt64(":userid") @@ -131,6 +132,24 @@ func AccessLevel(ctx *macaron.Context) { ctx.JSON(200, al) } +//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")) +} + /* //GetDeployKeyByRepo chainload to models.GetDeployKeyByRepo func GetDeployKeyByRepo(ctx *macaron.Context) { @@ -156,6 +175,7 @@ func RegisterRoutes(m *macaron.Macaron) { 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/keys/:keyid", GetDeployKeyByRepo) m.Get("/repositories/:repoid/has-keys/:keyid", HasDeployKey) m.Post("/push/update", PushUpdate) From 4c81d3ed36846cccfa86b671bdbcda56d58ee3ed Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Fri, 7 Sep 2018 00:54:26 +0200 Subject: [PATCH 08/14] Fix mistakes I made --- modules/private/internal.go | 3 +-- routers/private/internal.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/private/internal.go b/modules/private/internal.go index b635a7480113d..0f4b8b1a1bbfc 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -54,8 +54,7 @@ func newInternalRequest(url, method string) *httplib.Request { // UpdatePublicKeyUpdated update publick key updates func UpdateDeployKeyUpdated(keyID int64, repoID int64) error { - // Ask for running deliver hook and test pull request tasks. - reqURL := setting.LocalURL + fmt.Sprintf("/repositories/%d/keys/%d/update", keyID, repoID) + 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() diff --git a/routers/private/internal.go b/routers/private/internal.go index 40af0c17e2814..adaa553bb1102 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -104,7 +104,7 @@ func GetUserByKeyID(ctx *macaron.Context) { func HasDeployKey(ctx *macaron.Context) { repoID := ctx.ParamsInt64(":repoid") keyID := ctx.ParamsInt64(":keyid") - if models.HasDeployKey(repoID, keyID) { + if models.HasDeployKey(keyID, repoID) { ctx.PlainText(200, []byte("success")) return } From 899499cb59e6b9f01e1a6807f1c08eedce8ef6a7 Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Fri, 7 Sep 2018 01:03:53 +0200 Subject: [PATCH 09/14] Some cleaning + moving code to separate files --- cmd/serv.go | 4 +- modules/private/internal.go | 121 ------------------------------------ modules/private/key.go | 115 ++++++++++++++++++++++++++++++++++ routers/private/internal.go | 90 --------------------------- routers/private/key.go | 84 +++++++++++++++++++++++++ 5 files changed, 200 insertions(+), 214 deletions(-) create mode 100644 modules/private/key.go create mode 100644 routers/private/key.go diff --git a/cmd/serv.go b/cmd/serv.go index db4760e6595ad..4e9040d9095af 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -25,8 +25,6 @@ import ( "github.com/urfave/cli" ) -//TODO add tests - const ( accessDenied = "Repository does not exist or you do not have access" lfsAuthenticateVerb = "git-lfs-authenticate" @@ -217,7 +215,7 @@ func runServ(c *cli.Context) error { fail("Key permission denied", "Cannot push with deployment key: %d", key.ID) } - // Check if this deploy key belongs to current repository. //TODO maybe not needed anymore + // Check if this deploy key belongs to current repository. 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) diff --git a/modules/private/internal.go b/modules/private/internal.go index 0f4b8b1a1bbfc..c21e87067d6ef 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -50,85 +50,6 @@ func newInternalRequest(url, method string) *httplib.Request { return req } -//TODO move on specific file - -// UpdatePublicKeyUpdated update publick 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 -} - -/* -func GetDeployKeyByRepo(keyID, repoID int64) (*models.DeployKey, error) { - reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/keys/%d", repoID, keyID) - 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 key models.DeployKey - if err := json.NewDecoder(resp.Body).Decode(&key); err != nil { - return nil, err - } - return &key, nil -} -*/ -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 -} - -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 -} - 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) @@ -167,28 +88,6 @@ func AccessLevel(userID, repoID int64) (*models.AccessMode, error) { return &a, nil } -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 -} - 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) @@ -210,23 +109,3 @@ func GetRepositoryByOwnerAndName(ownerName, repoName string) (*models.Repository return &repo, nil } - -// 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) - - 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 -} diff --git a/modules/private/key.go b/modules/private/key.go new file mode 100644 index 0000000000000..78bacbb2da60e --- /dev/null +++ b/modules/private/key.go @@ -0,0 +1,115 @@ +// 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" +) + +// UpdatePublicKeyUpdated update publick 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 +} + +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 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) + + 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 +} diff --git a/routers/private/internal.go b/routers/private/internal.go index adaa553bb1102..23e0122642b37 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -10,7 +10,6 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" macaron "gopkg.in/macaron.v1" ) @@ -24,41 +23,6 @@ func CheckInternalToken(ctx *macaron.Context) { } } -// 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")) -} - -//TODO move on specific file //GetRepositoryByOwnerAndName chainload to models.GetRepositoryByOwnerAndName func GetRepositoryByOwnerAndName(ctx *macaron.Context) { //TODO use repo.Get(ctx *context.APIContext) ? @@ -74,43 +38,6 @@ func GetRepositoryByOwnerAndName(ctx *macaron.Context) { ctx.JSON(200, repo) } -//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")) -} - //AccessLevel chainload to models.AccessLevel func AccessLevel(ctx *macaron.Context) { repoID := ctx.ParamsInt64(":repoid") @@ -150,22 +77,6 @@ func CheckUnitUser(ctx *macaron.Context) { ctx.PlainText(404, []byte("no access")) } -/* -//GetDeployKeyByRepo chainload to models.GetDeployKeyByRepo -func GetDeployKeyByRepo(ctx *macaron.Context) { - repoID := ctx.ParamsInt64(":repoid") - keyID := ctx.ParamsInt64(":keyid") - key, err := models.GetDeployKeyByRepo(repoID, keyID) - if err != nil { - ctx.JSON(500, map[string]interface{}{ - "err": err.Error(), - }) - return - } - ctx.JSON(200, key) -} -*/ - // 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) { @@ -176,7 +87,6 @@ func RegisterRoutes(m *macaron.Macaron) { 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/keys/:keyid", GetDeployKeyByRepo) m.Get("/repositories/:repoid/has-keys/:keyid", HasDeployKey) m.Post("/push/update", PushUpdate) m.Get("/protectedbranch/:pbid/:userid", CanUserPush) diff --git a/routers/private/key.go b/routers/private/key.go new file mode 100644 index 0000000000000..9cc11657807dc --- /dev/null +++ b/routers/private/key.go @@ -0,0 +1,84 @@ +// 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")) +} From f8f07de88009632135cf08d4b044208b69797600 Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Fri, 7 Sep 2018 01:12:56 +0200 Subject: [PATCH 10/14] Fix error handling --- cmd/serv.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/serv.go b/cmd/serv.go index 4e9040d9095af..fb157fde5024e 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -165,8 +165,8 @@ func runServ(c *cli.Context) error { os.Setenv(models.EnvRepoName, reponame) repo, err := private.GetRepositoryByOwnerAndName(username, reponame) - if err != nil { //TODO manage error with internal api - if models.IsErrRepoNotExist(err) { + 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) From 60ead514b6662bff94295e9453ea5487e7840b51 Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Fri, 7 Sep 2018 01:15:09 +0200 Subject: [PATCH 11/14] Remove useless error handling for setup --- cmd/serv.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/cmd/serv.go b/cmd/serv.go index fb157fde5024e..bc73f60ad78db 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -48,10 +48,9 @@ var CmdServ = cli.Command{ }, } -func setup(logPath string) error { +func setup(logPath string) { setting.NewContext() log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath)) - return nil } func parseCmd(cmd string) (string, string) { @@ -90,10 +89,7 @@ func runServ(c *cli.Context) error { 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") From 5162dd4a484278c59afdb8db0d0db2a1198c273b Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Fri, 7 Sep 2018 01:20:00 +0200 Subject: [PATCH 12/14] lint: fix comment on exported func --- modules/private/internal.go | 4 ++++ modules/private/key.go | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/private/internal.go b/modules/private/internal.go index c21e87067d6ef..f4ac1c515a4bf 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -50,6 +50,7 @@ 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) (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) @@ -66,6 +67,8 @@ func CheckUnitUser(userID, repoID int64, isAdmin bool, unitType models.UnitType) 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) @@ -88,6 +91,7 @@ func AccessLevel(userID, repoID int64) (*models.AccessMode, error) { 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) diff --git a/modules/private/key.go b/modules/private/key.go index 78bacbb2da60e..6b85a43a9f803 100644 --- a/modules/private/key.go +++ b/modules/private/key.go @@ -13,7 +13,7 @@ import ( "code.gitea.io/gitea/modules/setting" ) -// UpdatePublicKeyUpdated update publick key updates +// 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) @@ -72,6 +72,7 @@ func GetPublicKeyByID(keyID int64) (*models.PublicKey, error) { 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) @@ -94,7 +95,7 @@ func GetUserByKeyID(keyID int64) (*models.User, error) { return &user, nil } -// UpdatePublicKeyUpdated update publick key updates +// 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) From 3c3ff1108c5a3084de862080a223f4e7ffe3c08b Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Tue, 23 Oct 2018 15:15:57 +0200 Subject: [PATCH 13/14] fix copyright header --- modules/private/key.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/private/key.go b/modules/private/key.go index 6b85a43a9f803..86d0a730d16c5 100644 --- a/modules/private/key.go +++ b/modules/private/key.go @@ -1,4 +1,4 @@ -// Copyright 2017 The Gitea Authors. All rights reserved. +// 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. From 5e6ae2b81225121dd7d51d84d64db42cf8073cec Mon Sep 17 00:00:00 2001 From: Antoine GIRARD Date: Tue, 23 Oct 2018 18:39:12 +0200 Subject: [PATCH 14/14] Fix order of args --- cmd/serv.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/serv.go b/cmd/serv.go index bc73f60ad78db..ca042e2b2b70d 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -249,7 +249,7 @@ func runServ(c *cli.Context) error { user.Name, requestedMode, repoPath) } - check, err := private.CheckUnitUser(repo.ID, 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) }