Skip to content

Commit f9f62b4

Browse files
authored
Move delete deploy keys into service layer (#32201)
1 parent e4c4629 commit f9f62b4

File tree

7 files changed

+61
-66
lines changed

7 files changed

+61
-66
lines changed

models/asymkey/error.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ func (err ErrGPGKeyAccessDenied) Unwrap() error {
217217
// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
218218
type ErrKeyAccessDenied struct {
219219
UserID int64
220+
RepoID int64
220221
KeyID int64
221222
Note string
222223
}
@@ -228,8 +229,8 @@ func IsErrKeyAccessDenied(err error) bool {
228229
}
229230

230231
func (err ErrKeyAccessDenied) Error() string {
231-
return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d, note: %s]",
232-
err.UserID, err.KeyID, err.Note)
232+
return fmt.Sprintf("user does not have access to the key [user_id: %d, repo_id: %d, key_id: %d, note: %s]",
233+
err.UserID, err.RepoID, err.KeyID, err.Note)
233234
}
234235

235236
func (err ErrKeyAccessDenied) Unwrap() error {

models/repo.go

-48
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,12 @@ package models
66

77
import (
88
"context"
9-
"fmt"
109
"strconv"
1110

1211
_ "image/jpeg" // Needed for jpeg support
1312

14-
asymkey_model "code.gitea.io/gitea/models/asymkey"
1513
"code.gitea.io/gitea/models/db"
1614
issues_model "code.gitea.io/gitea/models/issues"
17-
access_model "code.gitea.io/gitea/models/perm/access"
1815
repo_model "code.gitea.io/gitea/models/repo"
1916
"code.gitea.io/gitea/models/unit"
2017
user_model "code.gitea.io/gitea/models/user"
@@ -315,48 +312,3 @@ func DoctorUserStarNum(ctx context.Context) (err error) {
315312

316313
return err
317314
}
318-
319-
// DeleteDeployKey delete deploy keys
320-
func DeleteDeployKey(ctx context.Context, doer *user_model.User, id int64) error {
321-
key, err := asymkey_model.GetDeployKeyByID(ctx, id)
322-
if err != nil {
323-
if asymkey_model.IsErrDeployKeyNotExist(err) {
324-
return nil
325-
}
326-
return fmt.Errorf("GetDeployKeyByID: %w", err)
327-
}
328-
329-
// Check if user has access to delete this key.
330-
if !doer.IsAdmin {
331-
repo, err := repo_model.GetRepositoryByID(ctx, key.RepoID)
332-
if err != nil {
333-
return fmt.Errorf("GetRepositoryByID: %w", err)
334-
}
335-
has, err := access_model.IsUserRepoAdmin(ctx, repo, doer)
336-
if err != nil {
337-
return fmt.Errorf("GetUserRepoPermission: %w", err)
338-
} else if !has {
339-
return asymkey_model.ErrKeyAccessDenied{
340-
UserID: doer.ID,
341-
KeyID: key.ID,
342-
Note: "deploy",
343-
}
344-
}
345-
}
346-
347-
if _, err := db.DeleteByID[asymkey_model.DeployKey](ctx, key.ID); err != nil {
348-
return fmt.Errorf("delete deploy key [%d]: %w", key.ID, err)
349-
}
350-
351-
// Check if this is the last reference to same key content.
352-
has, err := asymkey_model.IsDeployKeyExistByKeyID(ctx, key.KeyID)
353-
if err != nil {
354-
return err
355-
} else if !has {
356-
if _, err = db.DeleteByID[asymkey_model.PublicKey](ctx, key.KeyID); err != nil {
357-
return err
358-
}
359-
}
360-
361-
return nil
362-
}

routers/api/v1/repo/key.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ func DeleteDeploykey(ctx *context.APIContext) {
279279
// "404":
280280
// "$ref": "#/responses/notFound"
281281

282-
if err := asymkey_service.DeleteDeployKey(ctx, ctx.Doer, ctx.PathParamInt64(":id")); err != nil {
282+
if err := asymkey_service.DeleteDeployKey(ctx, ctx.Repo.Repository, ctx.PathParamInt64(":id")); err != nil {
283283
if asymkey_model.IsErrKeyAccessDenied(err) {
284284
ctx.Error(http.StatusForbidden, "", "You do not have access to this key")
285285
} else {

routers/web/repo/setting/deploy_key.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func DeployKeysPost(ctx *context.Context) {
9999

100100
// DeleteDeployKey response for deleting a deploy key
101101
func DeleteDeployKey(ctx *context.Context) {
102-
if err := asymkey_service.DeleteDeployKey(ctx, ctx.Doer, ctx.FormInt64("id")); err != nil {
102+
if err := asymkey_service.DeleteDeployKey(ctx, ctx.Repo.Repository, ctx.FormInt64("id")); err != nil {
103103
ctx.Flash.Error("DeleteDeployKey: " + err.Error())
104104
} else {
105105
ctx.Flash.Success(ctx.Tr("repo.settings.deploy_key_deletion_success"))

services/asymkey/deploy_key.go

+52-4
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,69 @@ package asymkey
55

66
import (
77
"context"
8+
"fmt"
89

9-
"code.gitea.io/gitea/models"
10+
asymkey_model "code.gitea.io/gitea/models/asymkey"
1011
"code.gitea.io/gitea/models/db"
11-
user_model "code.gitea.io/gitea/models/user"
12+
repo_model "code.gitea.io/gitea/models/repo"
1213
)
1314

15+
// DeleteRepoDeployKeys deletes all deploy keys of a repository. permissions check should be done outside
16+
func DeleteRepoDeployKeys(ctx context.Context, repoID int64) (int, error) {
17+
deployKeys, err := db.Find[asymkey_model.DeployKey](ctx, asymkey_model.ListDeployKeysOptions{RepoID: repoID})
18+
if err != nil {
19+
return 0, fmt.Errorf("listDeployKeys: %w", err)
20+
}
21+
22+
for _, dKey := range deployKeys {
23+
if err := deleteDeployKeyFromDB(ctx, dKey); err != nil {
24+
return 0, fmt.Errorf("deleteDeployKeys: %w", err)
25+
}
26+
}
27+
return len(deployKeys), nil
28+
}
29+
30+
// deleteDeployKeyFromDB delete deploy keys from database
31+
func deleteDeployKeyFromDB(ctx context.Context, key *asymkey_model.DeployKey) error {
32+
if _, err := db.DeleteByID[asymkey_model.DeployKey](ctx, key.ID); err != nil {
33+
return fmt.Errorf("delete deploy key [%d]: %w", key.ID, err)
34+
}
35+
36+
// Check if this is the last reference to same key content.
37+
has, err := asymkey_model.IsDeployKeyExistByKeyID(ctx, key.KeyID)
38+
if err != nil {
39+
return err
40+
} else if !has {
41+
if _, err = db.DeleteByID[asymkey_model.PublicKey](ctx, key.KeyID); err != nil {
42+
return err
43+
}
44+
}
45+
46+
return nil
47+
}
48+
1449
// DeleteDeployKey deletes deploy key from its repository authorized_keys file if needed.
15-
func DeleteDeployKey(ctx context.Context, doer *user_model.User, id int64) error {
50+
// Permissions check should be done outside.
51+
func DeleteDeployKey(ctx context.Context, repo *repo_model.Repository, id int64) error {
1652
dbCtx, committer, err := db.TxContext(ctx)
1753
if err != nil {
1854
return err
1955
}
2056
defer committer.Close()
2157

22-
if err := models.DeleteDeployKey(dbCtx, doer, id); err != nil {
58+
key, err := asymkey_model.GetDeployKeyByID(ctx, id)
59+
if err != nil {
60+
if asymkey_model.IsErrDeployKeyNotExist(err) {
61+
return nil
62+
}
63+
return fmt.Errorf("GetDeployKeyByID: %w", err)
64+
}
65+
66+
if key.RepoID != repo.ID {
67+
return fmt.Errorf("deploy key %d does not belong to repository %d", id, repo.ID)
68+
}
69+
70+
if err := deleteDeployKeyFromDB(dbCtx, key); err != nil {
2371
return err
2472
}
2573
if err := committer.Commit(); err != nil {

services/asymkey/main_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"code.gitea.io/gitea/models/unittest"
1010

11+
_ "code.gitea.io/gitea/models"
1112
_ "code.gitea.io/gitea/models/actions"
1213
_ "code.gitea.io/gitea/models/activities"
1314
)

services/repository/delete.go

+3-10
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ import (
77
"context"
88
"fmt"
99

10-
"code.gitea.io/gitea/models"
1110
actions_model "code.gitea.io/gitea/models/actions"
1211
activities_model "code.gitea.io/gitea/models/activities"
1312
admin_model "code.gitea.io/gitea/models/admin"
14-
asymkey_model "code.gitea.io/gitea/models/asymkey"
1513
"code.gitea.io/gitea/models/db"
1614
git_model "code.gitea.io/gitea/models/git"
1715
issues_model "code.gitea.io/gitea/models/issues"
@@ -76,16 +74,11 @@ func DeleteRepositoryDirectly(ctx context.Context, doer *user_model.User, repoID
7674
}
7775

7876
// Delete Deploy Keys
79-
deployKeys, err := db.Find[asymkey_model.DeployKey](ctx, asymkey_model.ListDeployKeysOptions{RepoID: repoID})
77+
deleted, err := asymkey_service.DeleteRepoDeployKeys(ctx, repoID)
8078
if err != nil {
81-
return fmt.Errorf("listDeployKeys: %w", err)
82-
}
83-
needRewriteKeysFile := len(deployKeys) > 0
84-
for _, dKey := range deployKeys {
85-
if err := models.DeleteDeployKey(ctx, doer, dKey.ID); err != nil {
86-
return fmt.Errorf("deleteDeployKeys: %w", err)
87-
}
79+
return err
8880
}
81+
needRewriteKeysFile := deleted > 0
8982

9083
if cnt, err := sess.ID(repoID).Delete(&repo_model.Repository{}); err != nil {
9184
return err

0 commit comments

Comments
 (0)