diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2021-12-10 16:14:24 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-10 16:14:24 +0800 |
commit | 3ca5dc7e32b372d14ff80d96f14b8f6a805862f1 (patch) | |
tree | 50d193ed0dacf2888d57b193a9b0d36065aff205 /services | |
parent | 0a9fcf63a49799ad3b0f146c54879161bac61e10 (diff) | |
download | gitea-3ca5dc7e32b372d14ff80d96f14b8f6a805862f1.tar.gz gitea-3ca5dc7e32b372d14ff80d96f14b8f6a805862f1.zip |
Move keys to models/asymkey (#17917)
* Move keys to models/keys
* Rename models/keys -> models/asymkey
* change the missed package name
* Fix package alias
* Fix test
* Fix docs
* Fix test
* Fix test
* merge
Diffstat (limited to 'services')
-rw-r--r-- | services/asymkey/deploy_key.go | 30 | ||||
-rw-r--r-- | services/asymkey/main_test.go | 16 | ||||
-rw-r--r-- | services/asymkey/sign.go | 388 | ||||
-rw-r--r-- | services/asymkey/ssh_key.go | 49 | ||||
-rw-r--r-- | services/asymkey/ssh_key_test.go | 83 | ||||
-rw-r--r-- | services/auth/source/ldap/source_authenticate.go | 10 | ||||
-rw-r--r-- | services/auth/source/ldap/source_sync.go | 10 | ||||
-rw-r--r-- | services/cron/tasks_extended.go | 5 | ||||
-rw-r--r-- | services/pull/merge.go | 5 | ||||
-rw-r--r-- | services/repository/archiver/archiver.go | 3 | ||||
-rw-r--r-- | services/repository/files/commit.go | 3 | ||||
-rw-r--r-- | services/repository/files/temp_repo.go | 3 | ||||
-rw-r--r-- | services/repository/files/update.go | 5 | ||||
-rw-r--r-- | services/repository/repository.go | 8 | ||||
-rw-r--r-- | services/user/user.go | 12 | ||||
-rw-r--r-- | services/wiki/wiki.go | 5 |
16 files changed, 605 insertions, 30 deletions
diff --git a/services/asymkey/deploy_key.go b/services/asymkey/deploy_key.go new file mode 100644 index 0000000000..aa0925ab13 --- /dev/null +++ b/services/asymkey/deploy_key.go @@ -0,0 +1,30 @@ +// Copyright 2021 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 asymkey + +import ( + "code.gitea.io/gitea/models" + asymkey_model "code.gitea.io/gitea/models/asymkey" + "code.gitea.io/gitea/models/db" + user_model "code.gitea.io/gitea/models/user" +) + +// DeleteDeployKey deletes deploy key from its repository authorized_keys file if needed. +func DeleteDeployKey(doer *user_model.User, id int64) error { + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + if err := models.DeleteDeployKey(ctx, doer, id); err != nil { + return err + } + if err := committer.Commit(); err != nil { + return err + } + + return asymkey_model.RewriteAllPublicKeys() +} diff --git a/services/asymkey/main_test.go b/services/asymkey/main_test.go new file mode 100644 index 0000000000..a891a10cf6 --- /dev/null +++ b/services/asymkey/main_test.go @@ -0,0 +1,16 @@ +// Copyright 2019 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 asymkey + +import ( + "path/filepath" + "testing" + + "code.gitea.io/gitea/models/unittest" +) + +func TestMain(m *testing.M) { + unittest.MainTest(m, filepath.Join("..", "..")) +} diff --git a/services/asymkey/sign.go b/services/asymkey/sign.go new file mode 100644 index 0000000000..4ccc581803 --- /dev/null +++ b/services/asymkey/sign.go @@ -0,0 +1,388 @@ +// Copyright 2021 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 asymkey + +import ( + "fmt" + "strings" + + "code.gitea.io/gitea/models" + asymkey_model "code.gitea.io/gitea/models/asymkey" + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/login" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/process" + "code.gitea.io/gitea/modules/setting" +) + +type signingMode string + +const ( + never signingMode = "never" + always signingMode = "always" + pubkey signingMode = "pubkey" + twofa signingMode = "twofa" + parentSigned signingMode = "parentsigned" + baseSigned signingMode = "basesigned" + headSigned signingMode = "headsigned" + commitsSigned signingMode = "commitssigned" + approved signingMode = "approved" + noKey signingMode = "nokey" +) + +func signingModeFromStrings(modeStrings []string) []signingMode { + returnable := make([]signingMode, 0, len(modeStrings)) + for _, mode := range modeStrings { + signMode := signingMode(strings.ToLower(strings.TrimSpace(mode))) + switch signMode { + case never: + return []signingMode{never} + case always: + return []signingMode{always} + case pubkey: + fallthrough + case twofa: + fallthrough + case parentSigned: + fallthrough + case baseSigned: + fallthrough + case headSigned: + fallthrough + case approved: + fallthrough + case commitsSigned: + returnable = append(returnable, signMode) + } + } + if len(returnable) == 0 { + return []signingMode{never} + } + return returnable +} + +// ErrWontSign explains the first reason why a commit would not be signed +// There may be other reasons - this is just the first reason found +type ErrWontSign struct { + Reason signingMode +} + +func (e *ErrWontSign) Error() string { + return fmt.Sprintf("wont sign: %s", e.Reason) +} + +// IsErrWontSign checks if an error is a ErrWontSign +func IsErrWontSign(err error) bool { + _, ok := err.(*ErrWontSign) + return ok +} + +// SigningKey returns the KeyID and git Signature for the repo +func SigningKey(repoPath string) (string, *git.Signature) { + if setting.Repository.Signing.SigningKey == "none" { + return "", nil + } + + if setting.Repository.Signing.SigningKey == "default" || setting.Repository.Signing.SigningKey == "" { + // Can ignore the error here as it means that commit.gpgsign is not set + value, _ := git.NewCommand("config", "--get", "commit.gpgsign").RunInDir(repoPath) + sign, valid := git.ParseBool(strings.TrimSpace(value)) + if !sign || !valid { + return "", nil + } + + signingKey, _ := git.NewCommand("config", "--get", "user.signingkey").RunInDir(repoPath) + signingName, _ := git.NewCommand("config", "--get", "user.name").RunInDir(repoPath) + signingEmail, _ := git.NewCommand("config", "--get", "user.email").RunInDir(repoPath) + return strings.TrimSpace(signingKey), &git.Signature{ + Name: strings.TrimSpace(signingName), + Email: strings.TrimSpace(signingEmail), + } + } + + return setting.Repository.Signing.SigningKey, &git.Signature{ + Name: setting.Repository.Signing.SigningName, + Email: setting.Repository.Signing.SigningEmail, + } +} + +// PublicSigningKey gets the public signing key within a provided repository directory +func PublicSigningKey(repoPath string) (string, error) { + signingKey, _ := SigningKey(repoPath) + if signingKey == "" { + return "", nil + } + + content, stderr, err := process.GetManager().ExecDir(-1, repoPath, + "gpg --export -a", "gpg", "--export", "-a", signingKey) + if err != nil { + log.Error("Unable to get default signing key in %s: %s, %s, %v", repoPath, signingKey, stderr, err) + return "", err + } + return content, nil +} + +// SignInitialCommit determines if we should sign the initial commit to this repository +func SignInitialCommit(repoPath string, u *user_model.User) (bool, string, *git.Signature, error) { + rules := signingModeFromStrings(setting.Repository.Signing.InitialCommit) + signingKey, sig := SigningKey(repoPath) + if signingKey == "" { + return false, "", nil, &ErrWontSign{noKey} + } + +Loop: + for _, rule := range rules { + switch rule { + case never: + return false, "", nil, &ErrWontSign{never} + case always: + break Loop + case pubkey: + keys, err := asymkey_model.ListGPGKeys(db.DefaultContext, u.ID, db.ListOptions{}) + if err != nil { + return false, "", nil, err + } + if len(keys) == 0 { + return false, "", nil, &ErrWontSign{pubkey} + } + case twofa: + twofaModel, err := login.GetTwoFactorByUID(u.ID) + if err != nil && !login.IsErrTwoFactorNotEnrolled(err) { + return false, "", nil, err + } + if twofaModel == nil { + return false, "", nil, &ErrWontSign{twofa} + } + } + } + return true, signingKey, sig, nil +} + +// SignWikiCommit determines if we should sign the commits to this repository wiki +func SignWikiCommit(repoWikiPath string, u *user_model.User) (bool, string, *git.Signature, error) { + rules := signingModeFromStrings(setting.Repository.Signing.Wiki) + signingKey, sig := SigningKey(repoWikiPath) + if signingKey == "" { + return false, "", nil, &ErrWontSign{noKey} + } + +Loop: + for _, rule := range rules { + switch rule { + case never: + return false, "", nil, &ErrWontSign{never} + case always: + break Loop + case pubkey: + keys, err := asymkey_model.ListGPGKeys(db.DefaultContext, u.ID, db.ListOptions{}) + if err != nil { + return false, "", nil, err + } + if len(keys) == 0 { + return false, "", nil, &ErrWontSign{pubkey} + } + case twofa: + twofaModel, err := login.GetTwoFactorByUID(u.ID) + if err != nil && !login.IsErrTwoFactorNotEnrolled(err) { + return false, "", nil, err + } + if twofaModel == nil { + return false, "", nil, &ErrWontSign{twofa} + } + case parentSigned: + gitRepo, err := git.OpenRepository(repoWikiPath) + if err != nil { + return false, "", nil, err + } + defer gitRepo.Close() + commit, err := gitRepo.GetCommit("HEAD") + if err != nil { + return false, "", nil, err + } + if commit.Signature == nil { + return false, "", nil, &ErrWontSign{parentSigned} + } + verification := asymkey_model.ParseCommitWithSignature(commit) + if !verification.Verified { + return false, "", nil, &ErrWontSign{parentSigned} + } + } + } + return true, signingKey, sig, nil +} + +// SignCRUDAction determines if we should sign a CRUD commit to this repository +func SignCRUDAction(repoPath string, u *user_model.User, tmpBasePath, parentCommit string) (bool, string, *git.Signature, error) { + rules := signingModeFromStrings(setting.Repository.Signing.CRUDActions) + signingKey, sig := SigningKey(repoPath) + if signingKey == "" { + return false, "", nil, &ErrWontSign{noKey} + } + +Loop: + for _, rule := range rules { + switch rule { + case never: + return false, "", nil, &ErrWontSign{never} + case always: + break Loop + case pubkey: + keys, err := asymkey_model.ListGPGKeys(db.DefaultContext, u.ID, db.ListOptions{}) + if err != nil { + return false, "", nil, err + } + if len(keys) == 0 { + return false, "", nil, &ErrWontSign{pubkey} + } + case twofa: + twofaModel, err := login.GetTwoFactorByUID(u.ID) + if err != nil && !login.IsErrTwoFactorNotEnrolled(err) { + return false, "", nil, err + } + if twofaModel == nil { + return false, "", nil, &ErrWontSign{twofa} + } + case parentSigned: + gitRepo, err := git.OpenRepository(tmpBasePath) + if err != nil { + return false, "", nil, err + } + defer gitRepo.Close() + commit, err := gitRepo.GetCommit(parentCommit) + if err != nil { + return false, "", nil, err + } + if commit.Signature == nil { + return false, "", nil, &ErrWontSign{parentSigned} + } + verification := asymkey_model.ParseCommitWithSignature(commit) + if !verification.Verified { + return false, "", nil, &ErrWontSign{parentSigned} + } + } + } + return true, signingKey, sig, nil +} + +// SignMerge determines if we should sign a PR merge commit to the base repository +func SignMerge(pr *models.PullRequest, u *user_model.User, tmpBasePath, baseCommit, headCommit string) (bool, string, *git.Signature, error) { + if err := pr.LoadBaseRepo(); err != nil { + log.Error("Unable to get Base Repo for pull request") + return false, "", nil, err + } + repo := pr.BaseRepo + + signingKey, signer := SigningKey(repo.RepoPath()) + if signingKey == "" { + return false, "", nil, &ErrWontSign{noKey} + } + rules := signingModeFromStrings(setting.Repository.Signing.Merges) + + var gitRepo *git.Repository + var err error + +Loop: + for _, rule := range rules { + switch rule { + case never: + return false, "", nil, &ErrWontSign{never} + case always: + break Loop + case pubkey: + keys, err := asymkey_model.ListGPGKeys(db.DefaultContext, u.ID, db.ListOptions{}) + if err != nil { + return false, "", nil, err + } + if len(keys) == 0 { + return false, "", nil, &ErrWontSign{pubkey} + } + case twofa: + twofaModel, err := login.GetTwoFactorByUID(u.ID) + if err != nil && !login.IsErrTwoFactorNotEnrolled(err) { + return false, "", nil, err + } + if twofaModel == nil { + return false, "", nil, &ErrWontSign{twofa} + } + case approved: + protectedBranch, err := models.GetProtectedBranchBy(repo.ID, pr.BaseBranch) + if err != nil { + return false, "", nil, err + } + if protectedBranch == nil { + return false, "", nil, &ErrWontSign{approved} + } + if protectedBranch.GetGrantedApprovalsCount(pr) < 1 { + return false, "", nil, &ErrWontSign{approved} + } + case baseSigned: + if gitRepo == nil { + gitRepo, err = git.OpenRepository(tmpBasePath) + if err != nil { + return false, "", nil, err + } + defer gitRepo.Close() + } + commit, err := gitRepo.GetCommit(baseCommit) + if err != nil { + return false, "", nil, err + } + verification := asymkey_model.ParseCommitWithSignature(commit) + if !verification.Verified { + return false, "", nil, &ErrWontSign{baseSigned} + } + case headSigned: + if gitRepo == nil { + gitRepo, err = git.OpenRepository(tmpBasePath) + if err != nil { + return false, "", nil, err + } + defer gitRepo.Close() + } + commit, err := gitRepo.GetCommit(headCommit) + if err != nil { + return false, "", nil, err + } + verification := asymkey_model.ParseCommitWithSignature(commit) + if !verification.Verified { + return false, "", nil, &ErrWontSign{headSigned} + } + case commitsSigned: + if gitRepo == nil { + gitRepo, err = git.OpenRepository(tmpBasePath) + if err != nil { + return false, "", nil, err + } + defer gitRepo.Close() + } + commit, err := gitRepo.GetCommit(headCommit) + if err != nil { + return false, "", nil, err + } + verification := asymkey_model.ParseCommitWithSignature(commit) + if !verification.Verified { + return false, "", nil, &ErrWontSign{commitsSigned} + } + // need to work out merge-base + mergeBaseCommit, _, err := gitRepo.GetMergeBase("", baseCommit, headCommit) + if err != nil { + return false, "", nil, err + } + commitList, err := commit.CommitsBeforeUntil(mergeBaseCommit) + if err != nil { + return false, "", nil, err + } + for _, commit := range commitList { + verification := asymkey_model.ParseCommitWithSignature(commit) + if !verification.Verified { + return false, "", nil, &ErrWontSign{commitsSigned} + } + } + } + } + return true, signingKey, signer, nil +} diff --git a/services/asymkey/ssh_key.go b/services/asymkey/ssh_key.go new file mode 100644 index 0000000000..1f6b93eb24 --- /dev/null +++ b/services/asymkey/ssh_key.go @@ -0,0 +1,49 @@ +// Copyright 2021 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 asymkey + +import ( + asymkey_model "code.gitea.io/gitea/models/asymkey" + "code.gitea.io/gitea/models/db" + user_model "code.gitea.io/gitea/models/user" +) + +// DeletePublicKey deletes SSH key information both in database and authorized_keys file. +func DeletePublicKey(doer *user_model.User, id int64) (err error) { + key, err := asymkey_model.GetPublicKeyByID(id) + if err != nil { + return err + } + + // Check if user has access to delete this key. + if !doer.IsAdmin && doer.ID != key.OwnerID { + return asymkey_model.ErrKeyAccessDenied{ + UserID: doer.ID, + KeyID: key.ID, + Note: "public", + } + } + + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + if err = asymkey_model.DeletePublicKeys(ctx, id); err != nil { + return err + } + + if err = committer.Commit(); err != nil { + return err + } + committer.Close() + + if key.Type == asymkey_model.KeyTypePrincipal { + return asymkey_model.RewriteAllPrincipalKeys() + } + + return asymkey_model.RewriteAllPublicKeys() +} diff --git a/services/asymkey/ssh_key_test.go b/services/asymkey/ssh_key_test.go new file mode 100644 index 0000000000..0ce235f7f6 --- /dev/null +++ b/services/asymkey/ssh_key_test.go @@ -0,0 +1,83 @@ +// Copyright 2021 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 asymkey + +import ( + "testing" + + asymkey_model "code.gitea.io/gitea/models/asymkey" + "code.gitea.io/gitea/models/login" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + "github.com/stretchr/testify/assert" +) + +func TestAddLdapSSHPublicKeys(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + s := &login.Source{ID: 1} + + testCases := []struct { + keyString string + number int + keyContents []string + }{ + { + keyString: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n", + number: 1, + keyContents: []string{ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=", + }, + }, + { + keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment +ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`, + number: 2, + keyContents: []string{ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=", + "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=", + }, + }, + { + keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment +# comment asmdna,ndp +ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`, + number: 2, + keyContents: []string{ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=", + "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=", + }, + }, + { + keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment +382488320jasdj1lasmva/vasodifipi4193-fksma.cm +ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`, + number: 2, + keyContents: []string{ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=", + "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=", + }, + }, + } + + for i, kase := range testCases { + s.ID = int64(i) + 20 + asymkey_model.AddPublicKeysBySource(user, s, []string{kase.keyString}) + keys, err := asymkey_model.ListPublicKeysBySource(user.ID, s.ID) + assert.NoError(t, err) + if err != nil { + continue + } + assert.Len(t, keys, kase.number) + + for _, key := range keys { + assert.Contains(t, kase.keyContents, key.Content) + } + for _, key := range keys { + DeletePublicKey(user, key.ID) + } + } +} diff --git a/services/auth/source/ldap/source_authenticate.go b/services/auth/source/ldap/source_authenticate.go index 9bb07d244f..9938525c0e 100644 --- a/services/auth/source/ldap/source_authenticate.go +++ b/services/auth/source/ldap/source_authenticate.go @@ -8,7 +8,7 @@ import ( "fmt" "strings" - "code.gitea.io/gitea/models" + asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/login" user_model "code.gitea.io/gitea/models/user" @@ -59,8 +59,8 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str } if user != nil { - if isAttributeSSHPublicKeySet && models.SynchronizePublicKeys(user, source.loginSource, sr.SSHPublicKey) { - return user, models.RewriteAllPublicKeys() + if isAttributeSSHPublicKeySet && asymkey_model.SynchronizePublicKeys(user, source.loginSource, sr.SSHPublicKey) { + return user, asymkey_model.RewriteAllPublicKeys() } return user, nil @@ -95,8 +95,8 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str mailer.SendRegisterNotifyMail(user) - if isAttributeSSHPublicKeySet && models.AddPublicKeysBySource(user, source.loginSource, sr.SSHPublicKey) { - err = models.RewriteAllPublicKeys() + if isAttributeSSHPublicKeySet && asymkey_model.AddPublicKeysBySource(user, source.loginSource, sr.SSHPublicKey) { + err = asymkey_model.RewriteAllPublicKeys() } if err == nil && len(source.AttributeAvatar) > 0 { diff --git a/services/auth/source/ldap/source_sync.go b/services/auth/source/ldap/source_sync.go index 9c504476c0..fb15b2f046 100644 --- a/services/auth/source/ldap/source_sync.go +++ b/services/auth/source/ldap/source_sync.go @@ -10,7 +10,7 @@ import ( "sort" "strings" - "code.gitea.io/gitea/models" + asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -68,7 +68,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { log.Warn("SyncExternalUsers: Cancelled at update of %s before completed update of users", source.loginSource.Name) // Rewrite authorized_keys file if LDAP Public SSH Key attribute is set and any key was added or removed if sshKeysNeedUpdate { - err = models.RewriteAllPublicKeys() + err = asymkey_model.RewriteAllPublicKeys() if err != nil { log.Error("RewriteAllPublicKeys: %v", err) } @@ -119,7 +119,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { if err == nil && isAttributeSSHPublicKeySet { log.Trace("SyncExternalUsers[%s]: Adding LDAP Public SSH Keys for user %s", source.loginSource.Name, usr.Name) - if models.AddPublicKeysBySource(usr, source.loginSource, su.SSHPublicKey) { + if asymkey_model.AddPublicKeysBySource(usr, source.loginSource, su.SSHPublicKey) { sshKeysNeedUpdate = true } } @@ -129,7 +129,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { } } else if updateExisting { // Synchronize SSH Public Key if that attribute is set - if isAttributeSSHPublicKeySet && models.SynchronizePublicKeys(usr, source.loginSource, su.SSHPublicKey) { + if isAttributeSSHPublicKeySet && asymkey_model.SynchronizePublicKeys(usr, source.loginSource, su.SSHPublicKey) { sshKeysNeedUpdate = true } @@ -171,7 +171,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { // Rewrite authorized_keys file if LDAP Public SSH Key attribute is set and any key was added or removed if sshKeysNeedUpdate { - err = models.RewriteAllPublicKeys() + err = asymkey_model.RewriteAllPublicKeys() if err != nil { log.Error("RewriteAllPublicKeys: %v", err) } diff --git a/services/cron/tasks_extended.go b/services/cron/tasks_extended.go index bc6add090b..90b391474f 100644 --- a/services/cron/tasks_extended.go +++ b/services/cron/tasks_extended.go @@ -9,6 +9,7 @@ import ( "time" "code.gitea.io/gitea/models" + asymkey_model "code.gitea.io/gitea/models/asymkey" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/updatechecker" @@ -67,7 +68,7 @@ func registerRewriteAllPublicKeys() { RunAtStart: false, Schedule: "@every 72h", }, func(_ context.Context, _ *user_model.User, _ Config) error { - return models.RewriteAllPublicKeys() + return asymkey_model.RewriteAllPublicKeys() }) } @@ -77,7 +78,7 @@ func registerRewriteAllPrincipalKeys() { RunAtStart: false, Schedule: "@every 72h", }, func(_ context.Context, _ *user_model.User, _ Config) error { - return models.RewriteAllPrincipalKeys() + return asymkey_model.RewriteAllPrincipalKeys() }) } diff --git a/services/pull/merge.go b/services/pull/merge.go index 49050d6bee..ab1f43a50a 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -27,6 +27,7 @@ import ( "code.gitea.io/gitea/modules/references" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + asymkey_service "code.gitea.io/gitea/services/asymkey" issue_service "code.gitea.io/gitea/services/issue" ) @@ -218,7 +219,7 @@ func rawMerge(pr *models.PullRequest, doer *user_model.User, mergeStyle repo_mod // Determine if we should sign signArg := "" if git.CheckGitVersionAtLeast("1.7.9") == nil { - sign, keyID, signer, _ := pr.SignMerge(doer, tmpBasePath, "HEAD", trackingBranch) + sign, keyID, signer, _ := asymkey_service.SignMerge(pr, doer, tmpBasePath, "HEAD", trackingBranch) if sign { signArg = "-S" + keyID if pr.BaseRepo.GetTrustModel() == repo_model.CommitterTrustModel || pr.BaseRepo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel { @@ -553,7 +554,7 @@ func IsSignedIfRequired(pr *models.PullRequest, doer *user_model.User) (bool, er return true, nil } - sign, _, _, err := pr.SignMerge(doer, pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName()) + sign, _, _, err := asymkey_service.SignMerge(pr, doer, pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName()) return sign, err } diff --git a/services/repository/archiver/archiver.go b/services/repository/archiver/archiver.go index 7e886d79cb..fb40c3383d 100644 --- a/services/repository/archiver/archiver.go +++ b/services/repository/archiver/archiver.go @@ -14,7 +14,6 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/git" @@ -171,7 +170,7 @@ func doArchive(r *ArchiveRequest) (*repo_model.RepoArchiver, error) { rd.Close() }() var done = make(chan error) - repo, err := models.LoadArchiverRepo(archiver) + repo, err := repo_model.GetRepositoryByID(archiver.RepoID) if err != nil { return nil, fmt.Errorf("archiver.LoadRepo failed: %v", err) } diff --git a/services/repository/files/commit.go b/services/repository/files/commit.go index 6bff1bb97f..4e391ff343 100644 --- a/services/repository/files/commit.go +++ b/services/repository/files/commit.go @@ -8,6 +8,7 @@ import ( "fmt" "code.gitea.io/gitea/models" + asymkey_model "code.gitea.io/gitea/models/asymkey" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -55,7 +56,7 @@ func CountDivergingCommits(repo *repo_model.Repository, branch string) (*git.Div // GetPayloadCommitVerification returns the verification information of a commit func GetPayloadCommitVerification(commit *git.Commit) *structs.PayloadCommitVerification { verification := &structs.PayloadCommitVerification{} - commitVerification := models.ParseCommitWithSignature(commit) + commitVerification := asymkey_model.ParseCommitWithSignature(commit) if commit.Signature != nil { verification.Signature = commit.Signature.Signature verification.Payload = commit.Signature.Payload diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go index 815aa2c69f..52879dd3b0 100644 --- a/services/repository/files/temp_repo.go +++ b/services/repository/files/temp_repo.go @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + asymkey_service "code.gitea.io/gitea/services/asymkey" "code.gitea.io/gitea/services/gitdiff" ) @@ -217,7 +218,7 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *user_m // Determine if we should sign if git.CheckGitVersionAtLeast("1.7.9") == nil { - sign, keyID, signer, _ := models.SignCRUDAction(t.repo, author, t.basePath, "HEAD") + sign, keyID, signer, _ := asymkey_service.SignCRUDAction(t.repo.RepoPath(), author, t.basePath, "HEAD") if sign { args = append(args, "-S"+keyID) if t.repo.GetTrustModel() == repo_model.CommitterTrustModel || t.repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel { diff --git a/services/repository/files/update.go b/services/repository/files/update.go index 9a069acbfc..4bafa62cc1 100644 --- a/services/repository/files/update.go +++ b/services/repository/files/update.go @@ -21,6 +21,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + asymkey_service "code.gitea.io/gitea/services/asymkey" repo_service "code.gitea.io/gitea/services/repository" stdcharset "golang.org/x/net/html/charset" @@ -458,9 +459,9 @@ func VerifyBranchProtection(repo *repo_model.Repository, doer *user_model.User, } } if protectedBranch.RequireSignedCommits { - _, _, _, err := models.SignCRUDAction(repo, doer, repo.RepoPath(), branchName) + _, _, _, err := asymkey_service.SignCRUDAction(repo.RepoPath(), doer, repo.RepoPath(), branchName) if err != nil { - if !models.IsErrWontSign(err) { + if !asymkey_service.IsErrWontSign(err) { return err } return models.ErrUserCannotCommit{ diff --git a/services/repository/repository.go b/services/repository/repository.go index 0b97148f66..17fab57e19 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -31,13 +31,15 @@ func CreateRepository(doer, owner *user_model.User, opts models.CreateRepoOption } // DeleteRepository deletes a repository for a user or organization. -func DeleteRepository(doer *user_model.User, repo *repo_model.Repository) error { +func DeleteRepository(doer *user_model.User, repo *repo_model.Repository, notify bool) error { if err := pull_service.CloseRepoBranchesPulls(doer, repo); err != nil { log.Error("CloseRepoBranchesPulls failed: %v", err) } - // If the repo itself has webhooks, we need to trigger them before deleting it... - notification.NotifyDeleteRepository(doer, repo) + if notify { + // If the repo itself has webhooks, we need to trigger them before deleting it... + notification.NotifyDeleteRepository(doer, repo) + } err := models.DeleteRepository(doer, repo.OwnerID, repo.ID) return err diff --git a/services/user/user.go b/services/user/user.go index 72052f4ec9..21f1a74f62 100644 --- a/services/user/user.go +++ b/services/user/user.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models" admin_model "code.gitea.io/gitea/models/admin" + asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -31,11 +32,11 @@ func DeleteUser(u *user_model.User) error { return fmt.Errorf("%s is an organization not a user", u.Name) } - ctx, commiter, err := db.TxContext() + ctx, committer, err := db.TxContext() if err != nil { return err } - defer commiter.Close() + defer committer.Close() // Note: A user owns any repository or belongs to any organization // cannot perform delete operation. @@ -60,14 +61,15 @@ func DeleteUser(u *user_model.User) error { return fmt.Errorf("DeleteUser: %v", err) } - if err := commiter.Commit(); err != nil { + if err := committer.Commit(); err != nil { return err } + committer.Close() - if err = models.RewriteAllPublicKeys(); err != nil { + if err = asymkey_model.RewriteAllPublicKeys(); err != nil { return err } - if err = models.RewriteAllPrincipalKeys(); err != nil { + if err = asymkey_model.RewriteAllPrincipalKeys(); err != nil { return err } diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go index 18e9b26d81..aa683dd44f 100644 --- a/services/wiki/wiki.go +++ b/services/wiki/wiki.go @@ -22,6 +22,7 @@ import ( repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/util" + asymkey_service "code.gitea.io/gitea/services/asymkey" ) var ( @@ -225,7 +226,7 @@ func updateWikiPage(doer *user_model.User, repo *repo_model.Repository, oldWikiN committer := doer.NewGitSig() - sign, signingKey, signer, _ := models.SignWikiCommit(repo, doer) + sign, signingKey, signer, _ := asymkey_service.SignWikiCommit(repo.WikiPath(), doer) if sign { commitTreeOpts.KeyID = signingKey if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel { @@ -343,7 +344,7 @@ func DeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, wikiName committer := doer.NewGitSig() - sign, signingKey, signer, _ := models.SignWikiCommit(repo, doer) + sign, signingKey, signer, _ := asymkey_service.SignWikiCommit(repo.WikiPath(), doer) if sign { commitTreeOpts.KeyID = signingKey if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel { |