Skip to content

Commit f29d916

Browse files
committed
Fix Deploy Key and Public Key Semantics
1 parent f7c46df commit f29d916

File tree

8 files changed

+81
-28
lines changed

8 files changed

+81
-28
lines changed

cmd/serv.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -234,19 +234,20 @@ func runServ(c *cli.Context) error {
234234

235235
// Check deploy key or user key.
236236
if key.Type == models.KeyTypeDeploy {
237-
if key.Mode < requestedMode {
238-
fail("Key permission denied", "Cannot push with deployment key: %d", key.ID)
239-
}
240-
241-
// Check if this deploy key belongs to current repository.
242-
has, err := private.HasDeployKey(key.ID, repo.ID)
237+
// Now we have to get the deploy key for this repo
238+
deployKey, err := private.GetDeployKey(key.ID, repo.ID)
243239
if err != nil {
244240
fail("Key access denied", "Failed to access internal api: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
245241
}
246-
if !has {
242+
243+
if deployKey == nil {
247244
fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
248245
}
249246

247+
if deployKey.Mode < requestedMode {
248+
fail("Key permission denied", "Cannot push with deployment key: %d to repo_id: %d", key.ID, repo.ID)
249+
}
250+
250251
// Update deploy key activity.
251252
if err = private.UpdateDeployKeyUpdated(key.ID, repo.ID); err != nil {
252253
fail("Internal error", "UpdateDeployKey: %v", err)

models/ssh_key.go

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,6 @@ func appendAuthorizedKeysToFile(keys ...*PublicKey) error {
350350
func checkKeyFingerprint(e Engine, fingerprint string) error {
351351
has, err := e.Get(&PublicKey{
352352
Fingerprint: fingerprint,
353-
Type: KeyTypeUser,
354353
})
355354
if err != nil {
356355
return err
@@ -401,12 +400,18 @@ func AddPublicKey(ownerID int64, name, content string, LoginSourceID int64) (*Pu
401400
return nil, err
402401
}
403402

404-
if err := checkKeyFingerprint(x, fingerprint); err != nil {
403+
sess := x.NewSession()
404+
defer sess.Close()
405+
if err = sess.Begin(); err != nil {
406+
return nil, err
407+
}
408+
409+
if err := checkKeyFingerprint(sess, fingerprint); err != nil {
405410
return nil, err
406411
}
407412

408413
// Key name of same user cannot be duplicated.
409-
has, err := x.
414+
has, err := sess.
410415
Where("owner_id = ? AND name = ?", ownerID, name).
411416
Get(new(PublicKey))
412417
if err != nil {
@@ -415,12 +420,6 @@ func AddPublicKey(ownerID int64, name, content string, LoginSourceID int64) (*Pu
415420
return nil, ErrKeyNameAlreadyUsed{ownerID, name}
416421
}
417422

418-
sess := x.NewSession()
419-
defer sess.Close()
420-
if err = sess.Begin(); err != nil {
421-
return nil, err
422-
}
423-
424423
key := &PublicKey{
425424
OwnerID: ownerID,
426425
Name: name,
@@ -728,24 +727,28 @@ func AddDeployKey(repoID int64, name, content string, readOnly bool) (*DeployKey
728727
accessMode = AccessModeWrite
729728
}
730729

730+
sess := x.NewSession()
731+
defer sess.Close()
732+
if err = sess.Begin(); err != nil {
733+
return nil, err
734+
}
735+
731736
pkey := &PublicKey{
732737
Fingerprint: fingerprint,
733-
Mode: accessMode,
734-
Type: KeyTypeDeploy,
735738
}
736-
has, err := x.Get(pkey)
739+
has, err := sess.Get(pkey)
737740
if err != nil {
738741
return nil, err
739742
}
740743

741-
sess := x.NewSession()
742-
defer sess.Close()
743-
if err = sess.Begin(); err != nil {
744-
return nil, err
745-
}
746-
747-
// First time use this deploy key.
748-
if !has {
744+
if has {
745+
if pkey.Type != KeyTypeDeploy {
746+
return nil, ErrKeyAlreadyExist{0, fingerprint, ""}
747+
}
748+
} else {
749+
// First time use this deploy key.
750+
pkey.Mode = accessMode
751+
pkey.Type = KeyTypeDeploy
749752
pkey.Content = content
750753
pkey.Name = name
751754
if err = addKey(sess, pkey); err != nil {

modules/private/key.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,31 @@ func UpdateDeployKeyUpdated(keyID int64, repoID int64) error {
3232
return nil
3333
}
3434

35+
// GetDeployKey check if repo has deploy key
36+
func GetDeployKey(keyID, repoID int64) (*models.DeployKey, error) {
37+
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/keys/%d", repoID, keyID)
38+
log.GitLogger.Trace("GetDeployKey: %s", reqURL)
39+
40+
resp, err := newInternalRequest(reqURL, "GET").Response()
41+
if err != nil {
42+
return nil, err
43+
}
44+
defer resp.Body.Close()
45+
46+
switch resp.StatusCode {
47+
case 404:
48+
return nil, nil
49+
case 200:
50+
var dKey models.DeployKey
51+
if err := json.NewDecoder(resp.Body).Decode(&dKey); err != nil {
52+
return nil, err
53+
}
54+
return &dKey, nil
55+
default:
56+
return nil, fmt.Errorf("Failed to get deploy key: %s", decodeJSONError(resp).Err)
57+
}
58+
}
59+
3560
// HasDeployKey check if repo has deploy key
3661
func HasDeployKey(keyID, repoID int64) (bool, error) {
3762
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/has-keys/%d", repoID, keyID)

options/locale/locale_en-US.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ ssh_helper = <strong>Need help?</strong> Have a look at GitHub's guide to <a hre
419419
gpg_helper = <strong>Need help?</strong> Have a look at GitHub's guide <a href="%s">about GPG</a>.
420420
add_new_key = Add SSH Key
421421
add_new_gpg_key = Add GPG Key
422-
ssh_key_been_used = This SSH key is already added to your account.
422+
ssh_key_been_used = This SSH key has already been added to the server.
423423
ssh_key_name_used = An SSH key with same name is already added to your account.
424424
gpg_key_id_used = A public GPG key with same ID already exists.
425425
gpg_no_key_email_found = This GPG key is not usable with any email address associated with your account.

routers/api/v1/repo/key.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ func HandleCheckKeyStringError(ctx *context.APIContext, err error) {
159159
// HandleAddKeyError handle add key error
160160
func HandleAddKeyError(ctx *context.APIContext, err error) {
161161
switch {
162+
case models.IsErrDeployKeyAlreadyExist(err):
163+
ctx.Error(422, "", "This key has already been added to this repository")
162164
case models.IsErrKeyAlreadyExist(err):
163165
ctx.Error(422, "", "Key content has been used as non-deploy key")
164166
case models.IsErrKeyNameAlreadyUsed(err):

routers/private/internal.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ func RegisterRoutes(m *macaron.Macaron) {
8282
m.Post("/repositories/:repoid/keys/:keyid/update", UpdateDeployKey)
8383
m.Get("/repositories/:repoid/user/:userid/checkunituser", CheckUnitUser)
8484
m.Get("/repositories/:repoid/has-keys/:keyid", HasDeployKey)
85+
m.Get("/repositories/:repoid/keys/:keyid", GetDeployKey)
8586
m.Get("/repositories/:repoid/wiki/init", InitUncyclo)
8687
m.Post("/push/update", PushUpdate)
8788
m.Get("/protectedbranch/:pbid/:userid", CanUserPush)

routers/private/key.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,24 @@ func GetUserByKeyID(ctx *macaron.Context) {
7272
ctx.JSON(200, user)
7373
}
7474

75+
//GetDeployKey chainload to models.GetDeployKey
76+
func GetDeployKey(ctx *macaron.Context) {
77+
repoID := ctx.ParamsInt64(":repoid")
78+
keyID := ctx.ParamsInt64(":keyid")
79+
dKey, err := models.GetDeployKeyByRepo(keyID, repoID)
80+
if err != nil {
81+
if models.IsErrDeployKeyNotExist(err) {
82+
ctx.JSON(404, []byte("not found"))
83+
return
84+
}
85+
ctx.JSON(500, map[string]interface{}{
86+
"err": err.Error(),
87+
})
88+
return
89+
}
90+
ctx.JSON(200, dKey)
91+
}
92+
7593
//HasDeployKey chainload to models.HasDeployKey
7694
func HasDeployKey(ctx *macaron.Context) {
7795
repoID := ctx.ParamsInt64(":repoid")

routers/repo/setting.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,9 @@ func DeployKeysPost(ctx *context.Context, form auth.AddKeyForm) {
622622
case models.IsErrDeployKeyAlreadyExist(err):
623623
ctx.Data["Err_Content"] = true
624624
ctx.RenderWithErr(ctx.Tr("repo.settings.key_been_used"), tplDeployKeys, &form)
625+
case models.IsErrKeyAlreadyExist(err):
626+
ctx.Data["Err_Content"] = true
627+
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_been_used"), tplDeployKeys, &form)
625628
case models.IsErrKeyNameAlreadyUsed(err):
626629
ctx.Data["Err_Title"] = true
627630
ctx.RenderWithErr(ctx.Tr("repo.settings.key_name_used"), tplDeployKeys, &form)

0 commit comments

Comments
 (0)