Skip to content

Commit 617a243

Browse files
sapklunny
authored andcommitted
Make gitea serv use api/internal (#4886)
* Start to move to internal/private * Add GetPublicKeyByID * Add HasDeployKey * Add private.UpdateDeployKeyUpdated * Add private.GetUserByKeyID * Add private.AccessLevel * Add private.CheckUnitUser * Fix mistakes I made * Some cleaning + moving code to separate files * Fix error handling * Remove useless error handling for setup * lint: fix comment on exported func * fix copyright header * Fix order of args
1 parent aefeb8c commit 617a243

File tree

6 files changed

+331
-51
lines changed

6 files changed

+331
-51
lines changed

cmd/serv.go

+21-34
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"code.gitea.io/gitea/modules/pprof"
2020
"code.gitea.io/gitea/modules/private"
2121
"code.gitea.io/gitea/modules/setting"
22-
"code.gitea.io/gitea/modules/util"
2322

2423
"github.com/Unknwon/com"
2524
"github.com/dgrijalva/jwt-go"
@@ -49,20 +48,9 @@ var CmdServ = cli.Command{
4948
},
5049
}
5150

52-
func setup(logPath string) error {
51+
func setup(logPath string) {
5352
setting.NewContext()
5453
log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
55-
models.LoadConfigs()
56-
57-
if setting.UseSQLite3 || setting.UseTiDB {
58-
workPath := setting.AppWorkPath
59-
if err := os.Chdir(workPath); err != nil {
60-
log.GitLogger.Fatal(4, "Failed to change directory %s: %v", workPath, err)
61-
}
62-
}
63-
64-
setting.NewXORMLogService(true)
65-
return models.SetEngine()
6654
}
6755

6856
func parseCmd(cmd string) (string, string) {
@@ -101,10 +89,7 @@ func runServ(c *cli.Context) error {
10189
if c.IsSet("config") {
10290
setting.CustomConf = c.String("config")
10391
}
104-
105-
if err := setup("serv.log"); err != nil {
106-
fail("System init failed", fmt.Sprintf("setup: %v", err))
107-
}
92+
setup("serv.log")
10893

10994
if setting.SSH.Disabled {
11095
println("Gitea: SSH has been disabled")
@@ -175,9 +160,9 @@ func runServ(c *cli.Context) error {
175160
}
176161
os.Setenv(models.EnvRepoName, reponame)
177162

178-
repo, err := models.GetRepositoryByOwnerAndName(username, reponame)
163+
repo, err := private.GetRepositoryByOwnerAndName(username, reponame)
179164
if err != nil {
180-
if models.IsErrRepoNotExist(err) {
165+
if strings.Contains(err.Error(), "Failed to get repository: repository does not exist") {
181166
fail(accessDenied, "Repository does not exist: %s/%s", username, reponame)
182167
}
183168
fail("Internal error", "Failed to get repository: %v", err)
@@ -214,7 +199,7 @@ func runServ(c *cli.Context) error {
214199
fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
215200
}
216201

217-
key, err := models.GetPublicKeyByID(com.StrTo(keys[1]).MustInt64())
202+
key, err := private.GetPublicKeyByID(com.StrTo(keys[1]).MustInt64())
218203
if err != nil {
219204
fail("Invalid key ID", "Invalid key ID[%s]: %v", c.Args()[0], err)
220205
}
@@ -225,23 +210,22 @@ func runServ(c *cli.Context) error {
225210
if key.Mode < requestedMode {
226211
fail("Key permission denied", "Cannot push with deployment key: %d", key.ID)
227212
}
213+
228214
// Check if this deploy key belongs to current repository.
229-
if !models.HasDeployKey(key.ID, repo.ID) {
215+
has, err := private.HasDeployKey(key.ID, repo.ID)
216+
if err != nil {
217+
fail("Key access denied", "Failed to access internal api: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
218+
}
219+
if !has {
230220
fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
231221
}
232222

233223
// Update deploy key activity.
234-
deployKey, err := models.GetDeployKeyByRepo(key.ID, repo.ID)
235-
if err != nil {
236-
fail("Internal error", "GetDeployKey: %v", err)
237-
}
238-
239-
deployKey.UpdatedUnix = util.TimeStampNow()
240-
if err = models.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil {
224+
if err = private.UpdateDeployKeyUpdated(key.ID, repo.ID); err != nil {
241225
fail("Internal error", "UpdateDeployKey: %v", err)
242226
}
243227
} else {
244-
user, err = models.GetUserByKeyID(key.ID)
228+
user, err = private.GetUserByKeyID(key.ID)
245229
if err != nil {
246230
fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err)
247231
}
@@ -252,20 +236,24 @@ func runServ(c *cli.Context) error {
252236
user.Name, repoPath)
253237
}
254238

255-
mode, err := models.AccessLevel(user.ID, repo)
239+
mode, err := private.AccessLevel(user.ID, repo.ID)
256240
if err != nil {
257241
fail("Internal error", "Failed to check access: %v", err)
258-
} else if mode < requestedMode {
242+
} else if *mode < requestedMode {
259243
clientMessage := accessDenied
260-
if mode >= models.AccessModeRead {
244+
if *mode >= models.AccessModeRead {
261245
clientMessage = "You do not have sufficient authorization for this action"
262246
}
263247
fail(clientMessage,
264248
"User %s does not have level %v access to repository %s",
265249
user.Name, requestedMode, repoPath)
266250
}
267251

268-
if !repo.CheckUnitUser(user.ID, user.IsAdmin, unitType) {
252+
check, err := private.CheckUnitUser(user.ID, repo.ID, user.IsAdmin, unitType)
253+
if err != nil {
254+
fail("You do not have allowed for this action", "Failed to access internal api: [user.Name: %s, repoPath: %s]", user.Name, repoPath)
255+
}
256+
if !check {
269257
fail("You do not have allowed for this action",
270258
"User %s does not have allowed access to repository %s 's code",
271259
user.Name, repoPath)
@@ -325,7 +313,6 @@ func runServ(c *cli.Context) error {
325313
} else {
326314
gitcmd = exec.Command(verb, repoPath)
327315
}
328-
329316
if isWiki {
330317
if err = repo.InitWiki(); err != nil {
331318
fail("Internal error", "Failed to init wiki repo: %v", err)

modules/private/branch.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func GetProtectedBranchBy(repoID int64, branchName string) (*models.ProtectedBra
3333

3434
// All 2XX status codes are accepted and others will return an error
3535
if resp.StatusCode/100 != 2 {
36-
return nil, fmt.Errorf("Failed to update public key: %s", decodeJSONError(resp).Err)
36+
return nil, fmt.Errorf("Failed to get protected branch: %s", decodeJSONError(resp).Err)
3737
}
3838

3939
return &branch, nil

modules/private/internal.go

+56-11
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"net"
1212
"net/http"
1313

14+
"code.gitea.io/gitea/models"
1415
"code.gitea.io/gitea/modules/httplib"
1516
"code.gitea.io/gitea/modules/log"
1617
"code.gitea.io/gitea/modules/setting"
@@ -49,22 +50,66 @@ func newInternalRequest(url, method string) *httplib.Request {
4950
return req
5051
}
5152

52-
// UpdatePublicKeyUpdated update publick key updates
53-
func UpdatePublicKeyUpdated(keyID int64) error {
54-
// Ask for running deliver hook and test pull request tasks.
55-
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/%d/update", keyID)
56-
log.GitLogger.Trace("UpdatePublicKeyUpdated: %s", reqURL)
53+
// CheckUnitUser check whether user could visit the unit of this repository
54+
func CheckUnitUser(userID, repoID int64, isAdmin bool, unitType models.UnitType) (bool, error) {
55+
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/user/%d/checkunituser?isAdmin=%t&unitType=%d", repoID, userID, isAdmin, unitType)
56+
log.GitLogger.Trace("AccessLevel: %s", reqURL)
5757

58-
resp, err := newInternalRequest(reqURL, "POST").Response()
58+
resp, err := newInternalRequest(reqURL, "GET").Response()
5959
if err != nil {
60-
return err
60+
return false, err
6161
}
62+
defer resp.Body.Close()
63+
64+
if resp.StatusCode == 200 {
65+
return true, nil
66+
}
67+
return false, nil
68+
}
69+
70+
// AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
71+
// user does not have access.
72+
func AccessLevel(userID, repoID int64) (*models.AccessMode, error) {
73+
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/user/%d/accesslevel", repoID, userID)
74+
log.GitLogger.Trace("AccessLevel: %s", reqURL)
6275

76+
resp, err := newInternalRequest(reqURL, "GET").Response()
77+
if err != nil {
78+
return nil, err
79+
}
6380
defer resp.Body.Close()
6481

65-
// All 2XX status codes are accepted and others will return an error
66-
if resp.StatusCode/100 != 2 {
67-
return fmt.Errorf("Failed to update public key: %s", decodeJSONError(resp).Err)
82+
if resp.StatusCode != 200 {
83+
return nil, fmt.Errorf("Failed to get user access level: %s", decodeJSONError(resp).Err)
84+
}
85+
86+
var a models.AccessMode
87+
if err := json.NewDecoder(resp.Body).Decode(&a); err != nil {
88+
return nil, err
6889
}
69-
return nil
90+
91+
return &a, nil
92+
}
93+
94+
// GetRepositoryByOwnerAndName returns the repository by given ownername and reponame.
95+
func GetRepositoryByOwnerAndName(ownerName, repoName string) (*models.Repository, error) {
96+
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repo/%s/%s", ownerName, repoName)
97+
log.GitLogger.Trace("GetRepositoryByOwnerAndName: %s", reqURL)
98+
99+
resp, err := newInternalRequest(reqURL, "GET").Response()
100+
if err != nil {
101+
return nil, err
102+
}
103+
defer resp.Body.Close()
104+
105+
if resp.StatusCode != 200 {
106+
return nil, fmt.Errorf("Failed to get repository: %s", decodeJSONError(resp).Err)
107+
}
108+
109+
var repo models.Repository
110+
if err := json.NewDecoder(resp.Body).Decode(&repo); err != nil {
111+
return nil, err
112+
}
113+
114+
return &repo, nil
70115
}

modules/private/key.go

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright 2018 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package private
6+
7+
import (
8+
"encoding/json"
9+
"fmt"
10+
11+
"code.gitea.io/gitea/models"
12+
"code.gitea.io/gitea/modules/log"
13+
"code.gitea.io/gitea/modules/setting"
14+
)
15+
16+
// UpdateDeployKeyUpdated update deploy key updates
17+
func UpdateDeployKeyUpdated(keyID int64, repoID int64) error {
18+
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/keys/%d/update", repoID, keyID)
19+
log.GitLogger.Trace("UpdateDeployKeyUpdated: %s", reqURL)
20+
21+
resp, err := newInternalRequest(reqURL, "POST").Response()
22+
if err != nil {
23+
return err
24+
}
25+
26+
defer resp.Body.Close()
27+
28+
// All 2XX status codes are accepted and others will return an error
29+
if resp.StatusCode/100 != 2 {
30+
return fmt.Errorf("Failed to update deploy key: %s", decodeJSONError(resp).Err)
31+
}
32+
return nil
33+
}
34+
35+
// HasDeployKey check if repo has deploy key
36+
func HasDeployKey(keyID, repoID int64) (bool, error) {
37+
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/has-keys/%d", repoID, keyID)
38+
log.GitLogger.Trace("HasDeployKey: %s", reqURL)
39+
40+
resp, err := newInternalRequest(reqURL, "GET").Response()
41+
if err != nil {
42+
return false, err
43+
}
44+
defer resp.Body.Close()
45+
46+
if resp.StatusCode == 200 {
47+
return true, nil
48+
}
49+
return false, nil
50+
}
51+
52+
// GetPublicKeyByID get public ssh key by his ID
53+
func GetPublicKeyByID(keyID int64) (*models.PublicKey, error) {
54+
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/%d", keyID)
55+
log.GitLogger.Trace("GetPublicKeyByID: %s", reqURL)
56+
57+
resp, err := newInternalRequest(reqURL, "GET").Response()
58+
if err != nil {
59+
return nil, err
60+
}
61+
62+
defer resp.Body.Close()
63+
64+
if resp.StatusCode != 200 {
65+
return nil, fmt.Errorf("Failed to get repository: %s", decodeJSONError(resp).Err)
66+
}
67+
68+
var pKey models.PublicKey
69+
if err := json.NewDecoder(resp.Body).Decode(&pKey); err != nil {
70+
return nil, err
71+
}
72+
return &pKey, nil
73+
}
74+
75+
// GetUserByKeyID get user attached to key
76+
func GetUserByKeyID(keyID int64) (*models.User, error) {
77+
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/%d/user", keyID)
78+
log.GitLogger.Trace("GetUserByKeyID: %s", reqURL)
79+
80+
resp, err := newInternalRequest(reqURL, "GET").Response()
81+
if err != nil {
82+
return nil, err
83+
}
84+
defer resp.Body.Close()
85+
86+
if resp.StatusCode != 200 {
87+
return nil, fmt.Errorf("Failed to get user: %s", decodeJSONError(resp).Err)
88+
}
89+
90+
var user models.User
91+
if err := json.NewDecoder(resp.Body).Decode(&user); err != nil {
92+
return nil, err
93+
}
94+
95+
return &user, nil
96+
}
97+
98+
// UpdatePublicKeyUpdated update public key updates
99+
func UpdatePublicKeyUpdated(keyID int64) error {
100+
// Ask for running deliver hook and test pull request tasks.
101+
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/ssh/%d/update", keyID)
102+
log.GitLogger.Trace("UpdatePublicKeyUpdated: %s", reqURL)
103+
104+
resp, err := newInternalRequest(reqURL, "POST").Response()
105+
if err != nil {
106+
return err
107+
}
108+
109+
defer resp.Body.Close()
110+
111+
// All 2XX status codes are accepted and others will return an error
112+
if resp.StatusCode/100 != 2 {
113+
return fmt.Errorf("Failed to update public key: %s", decodeJSONError(resp).Err)
114+
}
115+
return nil
116+
}

0 commit comments

Comments
 (0)