summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2021-12-10 16:14:24 +0800
committerGitHub <noreply@github.com>2021-12-10 16:14:24 +0800
commit3ca5dc7e32b372d14ff80d96f14b8f6a805862f1 (patch)
tree50d193ed0dacf2888d57b193a9b0d36065aff205 /models
parent0a9fcf63a49799ad3b0f146c54879161bac61e10 (diff)
downloadgitea-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 'models')
-rw-r--r--models/asymkey/error.go248
-rw-r--r--models/asymkey/gpg_key.go (renamed from models/gpg_key.go)11
-rw-r--r--models/asymkey/gpg_key_add.go (renamed from models/gpg_key_add.go)2
-rw-r--r--models/asymkey/gpg_key_commit_verification.go (renamed from models/gpg_key_commit_verification.go)24
-rw-r--r--models/asymkey/gpg_key_common.go (renamed from models/gpg_key_common.go)2
-rw-r--r--models/asymkey/gpg_key_import.go (renamed from models/gpg_key_import.go)2
-rw-r--r--models/asymkey/gpg_key_test.go (renamed from models/gpg_key_test.go)2
-rw-r--r--models/asymkey/gpg_key_verify.go (renamed from models/gpg_key_verify.go)2
-rw-r--r--models/asymkey/main_test.go29
-rw-r--r--models/asymkey/ssh_key.go (renamed from models/ssh_key.go)45
-rw-r--r--models/asymkey/ssh_key_authorized_keys.go (renamed from models/ssh_key_authorized_keys.go)8
-rw-r--r--models/asymkey/ssh_key_authorized_principals.go (renamed from models/ssh_key_authorized_principals.go)2
-rw-r--r--models/asymkey/ssh_key_deploy.go (renamed from models/ssh_key_deploy.go)82
-rw-r--r--models/asymkey/ssh_key_fingerprint.go (renamed from models/ssh_key_fingerprint.go)2
-rw-r--r--models/asymkey/ssh_key_parse.go (renamed from models/ssh_key_parse.go)5
-rw-r--r--models/asymkey/ssh_key_principals.go (renamed from models/ssh_key_principals.go)4
-rw-r--r--models/asymkey/ssh_key_test.go (renamed from models/ssh_key_test.go)7
-rw-r--r--models/commit.go8
-rw-r--r--models/commit_status.go5
-rw-r--r--models/db/error.go13
-rw-r--r--models/error.go277
-rw-r--r--models/main_test.go6
-rw-r--r--models/pull_sign.go133
-rw-r--r--models/repo.go61
-rw-r--r--models/repo_sign.go251
-rw-r--r--models/statistic.go3
-rw-r--r--models/user.go9
-rw-r--r--models/user_test.go69
28 files changed, 412 insertions, 900 deletions
diff --git a/models/asymkey/error.go b/models/asymkey/error.go
new file mode 100644
index 0000000000..7add553bd6
--- /dev/null
+++ b/models/asymkey/error.go
@@ -0,0 +1,248 @@
+// 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"
+
+// ErrKeyUnableVerify represents a "KeyUnableVerify" kind of error.
+type ErrKeyUnableVerify struct {
+ Result string
+}
+
+// IsErrKeyUnableVerify checks if an error is a ErrKeyUnableVerify.
+func IsErrKeyUnableVerify(err error) bool {
+ _, ok := err.(ErrKeyUnableVerify)
+ return ok
+}
+
+func (err ErrKeyUnableVerify) Error() string {
+ return fmt.Sprintf("Unable to verify key content [result: %s]", err.Result)
+}
+
+// ErrKeyNotExist represents a "KeyNotExist" kind of error.
+type ErrKeyNotExist struct {
+ ID int64
+}
+
+// IsErrKeyNotExist checks if an error is a ErrKeyNotExist.
+func IsErrKeyNotExist(err error) bool {
+ _, ok := err.(ErrKeyNotExist)
+ return ok
+}
+
+func (err ErrKeyNotExist) Error() string {
+ return fmt.Sprintf("public key does not exist [id: %d]", err.ID)
+}
+
+// ErrKeyAlreadyExist represents a "KeyAlreadyExist" kind of error.
+type ErrKeyAlreadyExist struct {
+ OwnerID int64
+ Fingerprint string
+ Content string
+}
+
+// IsErrKeyAlreadyExist checks if an error is a ErrKeyAlreadyExist.
+func IsErrKeyAlreadyExist(err error) bool {
+ _, ok := err.(ErrKeyAlreadyExist)
+ return ok
+}
+
+func (err ErrKeyAlreadyExist) Error() string {
+ return fmt.Sprintf("public key already exists [owner_id: %d, finger_print: %s, content: %s]",
+ err.OwnerID, err.Fingerprint, err.Content)
+}
+
+// ErrKeyNameAlreadyUsed represents a "KeyNameAlreadyUsed" kind of error.
+type ErrKeyNameAlreadyUsed struct {
+ OwnerID int64
+ Name string
+}
+
+// IsErrKeyNameAlreadyUsed checks if an error is a ErrKeyNameAlreadyUsed.
+func IsErrKeyNameAlreadyUsed(err error) bool {
+ _, ok := err.(ErrKeyNameAlreadyUsed)
+ return ok
+}
+
+func (err ErrKeyNameAlreadyUsed) Error() string {
+ return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name)
+}
+
+// ErrGPGNoEmailFound represents a "ErrGPGNoEmailFound" kind of error.
+type ErrGPGNoEmailFound struct {
+ FailedEmails []string
+ ID string
+}
+
+// IsErrGPGNoEmailFound checks if an error is a ErrGPGNoEmailFound.
+func IsErrGPGNoEmailFound(err error) bool {
+ _, ok := err.(ErrGPGNoEmailFound)
+ return ok
+}
+
+func (err ErrGPGNoEmailFound) Error() string {
+ return fmt.Sprintf("none of the emails attached to the GPG key could be found: %v", err.FailedEmails)
+}
+
+// ErrGPGInvalidTokenSignature represents a "ErrGPGInvalidTokenSignature" kind of error.
+type ErrGPGInvalidTokenSignature struct {
+ Wrapped error
+ ID string
+}
+
+// IsErrGPGInvalidTokenSignature checks if an error is a ErrGPGInvalidTokenSignature.
+func IsErrGPGInvalidTokenSignature(err error) bool {
+ _, ok := err.(ErrGPGInvalidTokenSignature)
+ return ok
+}
+
+func (err ErrGPGInvalidTokenSignature) Error() string {
+ return "the provided signature does not sign the token with the provided key"
+}
+
+// ErrGPGKeyParsing represents a "ErrGPGKeyParsing" kind of error.
+type ErrGPGKeyParsing struct {
+ ParseError error
+}
+
+// IsErrGPGKeyParsing checks if an error is a ErrGPGKeyParsing.
+func IsErrGPGKeyParsing(err error) bool {
+ _, ok := err.(ErrGPGKeyParsing)
+ return ok
+}
+
+func (err ErrGPGKeyParsing) Error() string {
+ return fmt.Sprintf("failed to parse gpg key %s", err.ParseError.Error())
+}
+
+// ErrGPGKeyNotExist represents a "GPGKeyNotExist" kind of error.
+type ErrGPGKeyNotExist struct {
+ ID int64
+}
+
+// IsErrGPGKeyNotExist checks if an error is a ErrGPGKeyNotExist.
+func IsErrGPGKeyNotExist(err error) bool {
+ _, ok := err.(ErrGPGKeyNotExist)
+ return ok
+}
+
+func (err ErrGPGKeyNotExist) Error() string {
+ return fmt.Sprintf("public gpg key does not exist [id: %d]", err.ID)
+}
+
+// ErrGPGKeyImportNotExist represents a "GPGKeyImportNotExist" kind of error.
+type ErrGPGKeyImportNotExist struct {
+ ID string
+}
+
+// IsErrGPGKeyImportNotExist checks if an error is a ErrGPGKeyImportNotExist.
+func IsErrGPGKeyImportNotExist(err error) bool {
+ _, ok := err.(ErrGPGKeyImportNotExist)
+ return ok
+}
+
+func (err ErrGPGKeyImportNotExist) Error() string {
+ return fmt.Sprintf("public gpg key import does not exist [id: %s]", err.ID)
+}
+
+// ErrGPGKeyIDAlreadyUsed represents a "GPGKeyIDAlreadyUsed" kind of error.
+type ErrGPGKeyIDAlreadyUsed struct {
+ KeyID string
+}
+
+// IsErrGPGKeyIDAlreadyUsed checks if an error is a ErrKeyNameAlreadyUsed.
+func IsErrGPGKeyIDAlreadyUsed(err error) bool {
+ _, ok := err.(ErrGPGKeyIDAlreadyUsed)
+ return ok
+}
+
+func (err ErrGPGKeyIDAlreadyUsed) Error() string {
+ return fmt.Sprintf("public key already exists [key_id: %s]", err.KeyID)
+}
+
+// ErrGPGKeyAccessDenied represents a "GPGKeyAccessDenied" kind of Error.
+type ErrGPGKeyAccessDenied struct {
+ UserID int64
+ KeyID int64
+}
+
+// IsErrGPGKeyAccessDenied checks if an error is a ErrGPGKeyAccessDenied.
+func IsErrGPGKeyAccessDenied(err error) bool {
+ _, ok := err.(ErrGPGKeyAccessDenied)
+ return ok
+}
+
+// Error pretty-prints an error of type ErrGPGKeyAccessDenied.
+func (err ErrGPGKeyAccessDenied) Error() string {
+ return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d]",
+ err.UserID, err.KeyID)
+}
+
+// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
+type ErrKeyAccessDenied struct {
+ UserID int64
+ KeyID int64
+ Note string
+}
+
+// IsErrKeyAccessDenied checks if an error is a ErrKeyAccessDenied.
+func IsErrKeyAccessDenied(err error) bool {
+ _, ok := err.(ErrKeyAccessDenied)
+ return ok
+}
+
+func (err ErrKeyAccessDenied) Error() string {
+ return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d, note: %s]",
+ err.UserID, err.KeyID, err.Note)
+}
+
+// ErrDeployKeyNotExist represents a "DeployKeyNotExist" kind of error.
+type ErrDeployKeyNotExist struct {
+ ID int64
+ KeyID int64
+ RepoID int64
+}
+
+// IsErrDeployKeyNotExist checks if an error is a ErrDeployKeyNotExist.
+func IsErrDeployKeyNotExist(err error) bool {
+ _, ok := err.(ErrDeployKeyNotExist)
+ return ok
+}
+
+func (err ErrDeployKeyNotExist) Error() string {
+ return fmt.Sprintf("Deploy key does not exist [id: %d, key_id: %d, repo_id: %d]", err.ID, err.KeyID, err.RepoID)
+}
+
+// ErrDeployKeyAlreadyExist represents a "DeployKeyAlreadyExist" kind of error.
+type ErrDeployKeyAlreadyExist struct {
+ KeyID int64
+ RepoID int64
+}
+
+// IsErrDeployKeyAlreadyExist checks if an error is a ErrDeployKeyAlreadyExist.
+func IsErrDeployKeyAlreadyExist(err error) bool {
+ _, ok := err.(ErrDeployKeyAlreadyExist)
+ return ok
+}
+
+func (err ErrDeployKeyAlreadyExist) Error() string {
+ return fmt.Sprintf("public key already exists [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID)
+}
+
+// ErrDeployKeyNameAlreadyUsed represents a "DeployKeyNameAlreadyUsed" kind of error.
+type ErrDeployKeyNameAlreadyUsed struct {
+ RepoID int64
+ Name string
+}
+
+// IsErrDeployKeyNameAlreadyUsed checks if an error is a ErrDeployKeyNameAlreadyUsed.
+func IsErrDeployKeyNameAlreadyUsed(err error) bool {
+ _, ok := err.(ErrDeployKeyNameAlreadyUsed)
+ return ok
+}
+
+func (err ErrDeployKeyNameAlreadyUsed) Error() string {
+ return fmt.Sprintf("public key with name already exists [repo_id: %d, name: %s]", err.RepoID, err.Name)
+}
diff --git a/models/gpg_key.go b/models/asymkey/gpg_key.go
index ce27a9237e..ced6ca37a3 100644
--- a/models/gpg_key.go
+++ b/models/asymkey/gpg_key.go
@@ -2,9 +2,10 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
+ "context"
"fmt"
"strings"
"time"
@@ -63,12 +64,8 @@ func (key *GPGKey) AfterLoad(session *xorm.Session) {
}
// ListGPGKeys returns a list of public keys belongs to given user.
-func ListGPGKeys(uid int64, listOptions db.ListOptions) ([]*GPGKey, error) {
- return listGPGKeys(db.GetEngine(db.DefaultContext), uid, listOptions)
-}
-
-func listGPGKeys(e db.Engine, uid int64, listOptions db.ListOptions) ([]*GPGKey, error) {
- sess := e.Table(&GPGKey{}).Where("owner_id=? AND primary_key_id=''", uid)
+func ListGPGKeys(ctx context.Context, uid int64, listOptions db.ListOptions) ([]*GPGKey, error) {
+ sess := db.GetEngine(ctx).Table(&GPGKey{}).Where("owner_id=? AND primary_key_id=''", uid)
if listOptions.Page != 0 {
sess = db.SetSessionPagination(sess, &listOptions)
}
diff --git a/models/gpg_key_add.go b/models/asymkey/gpg_key_add.go
index 711fc86dee..8f84bba1df 100644
--- a/models/gpg_key_add.go
+++ b/models/asymkey/gpg_key_add.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"strings"
diff --git a/models/gpg_key_commit_verification.go b/models/asymkey/gpg_key_commit_verification.go
index 48f58c07b6..5ec4e335d5 100644
--- a/models/gpg_key_commit_verification.go
+++ b/models/asymkey/gpg_key_commit_verification.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"fmt"
@@ -70,7 +70,7 @@ const (
)
// ParseCommitsWithSignature checks if signaute of commits are corresponding to users gpg keys.
-func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repository *repo_model.Repository) []*SignCommit {
+func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repoTrustModel repo_model.TrustModelType, isCodeReader func(*user_model.User) (bool, error)) []*SignCommit {
newCommits := make([]*SignCommit, 0, len(oldCommits))
keyMap := map[string]bool{}
@@ -80,7 +80,7 @@ func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repository *
Verification: ParseCommitWithSignature(c.Commit),
}
- _ = CalculateTrustStatus(signCommit.Verification, repository, &keyMap)
+ _ = CalculateTrustStatus(signCommit.Verification, repoTrustModel, isCodeReader, &keyMap)
newCommits = append(newCommits, signCommit)
}
@@ -159,7 +159,7 @@ func ParseCommitWithSignature(c *git.Commit) *CommitVerification {
// Now try to associate the signature with the committer, if present
if committer.ID != 0 {
- keys, err := ListGPGKeys(committer.ID, db.ListOptions{})
+ keys, err := ListGPGKeys(db.DefaultContext, committer.ID, db.ListOptions{})
if err != nil { // Skipping failed to get gpg keys of user
log.Error("ListGPGKeys: %v", err)
return &CommitVerification{
@@ -448,18 +448,16 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *use
}
// CalculateTrustStatus will calculate the TrustStatus for a commit verification within a repository
-func CalculateTrustStatus(verification *CommitVerification, repository *repo_model.Repository, keyMap *map[string]bool) (err error) {
+// There are several trust models in Gitea
+func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_model.TrustModelType, isCodeReader func(*user_model.User) (bool, error), keyMap *map[string]bool) (err error) {
if !verification.Verified {
return
}
- // There are several trust models in Gitea
- trustModel := repository.GetTrustModel()
-
// In the Committer trust model a signature is trusted if it matches the committer
// - it doesn't matter if they're a collaborator, the owner, Gitea or Github
// NB: This model is commit verification only
- if trustModel == repo_model.CommitterTrustModel {
+ if repoTrustModel == repo_model.CommitterTrustModel {
// default to "unmatched"
verification.TrustStatus = "unmatched"
@@ -482,7 +480,7 @@ func CalculateTrustStatus(verification *CommitVerification, repository *repo_mod
// However in the repo_model.CollaboratorCommitterTrustModel we cannot mark this as trusted
// unless the default key matches the email of a non-user.
- if trustModel == repo_model.CollaboratorCommitterTrustModel && (verification.CommittingUser.ID != 0 ||
+ if repoTrustModel == repo_model.CollaboratorCommitterTrustModel && (verification.CommittingUser.ID != 0 ||
verification.SigningUser.Email != verification.CommittingUser.Email) {
verification.TrustStatus = "untrusted"
}
@@ -494,11 +492,11 @@ func CalculateTrustStatus(verification *CommitVerification, repository *repo_mod
var has bool
isMember, has = (*keyMap)[verification.SigningKey.KeyID]
if !has {
- isMember, err = IsOwnerMemberCollaborator(repository, verification.SigningUser.ID)
+ isMember, err = isCodeReader(verification.SigningUser)
(*keyMap)[verification.SigningKey.KeyID] = isMember
}
} else {
- isMember, err = IsOwnerMemberCollaborator(repository, verification.SigningUser.ID)
+ isMember, err = isCodeReader(verification.SigningUser)
}
if !isMember {
@@ -508,7 +506,7 @@ func CalculateTrustStatus(verification *CommitVerification, repository *repo_mod
// This should be marked as questionable unless the signing user is a collaborator/team member etc.
verification.TrustStatus = "unmatched"
}
- } else if trustModel == repo_model.CollaboratorCommitterTrustModel && verification.CommittingUser.ID != verification.SigningUser.ID {
+ } else if repoTrustModel == repo_model.CollaboratorCommitterTrustModel && verification.CommittingUser.ID != verification.SigningUser.ID {
// The committing user and the signing user are not the same and our trustmodel states that they must match
verification.TrustStatus = "unmatched"
}
diff --git a/models/gpg_key_common.go b/models/asymkey/gpg_key_common.go
index 72803625ee..1ea510c45f 100644
--- a/models/gpg_key_common.go
+++ b/models/asymkey/gpg_key_common.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"bytes"
diff --git a/models/gpg_key_import.go b/models/asymkey/gpg_key_import.go
index 1eed929627..210c4b835b 100644
--- a/models/gpg_key_import.go
+++ b/models/asymkey/gpg_key_import.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import "code.gitea.io/gitea/models/db"
diff --git a/models/gpg_key_test.go b/models/asymkey/gpg_key_test.go
index 8f51c146aa..07bb77bdf4 100644
--- a/models/gpg_key_test.go
+++ b/models/asymkey/gpg_key_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"testing"
diff --git a/models/gpg_key_verify.go b/models/asymkey/gpg_key_verify.go
index 1824086021..152765cc3a 100644
--- a/models/gpg_key_verify.go
+++ b/models/asymkey/gpg_key_verify.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"strconv"
diff --git a/models/asymkey/main_test.go b/models/asymkey/main_test.go
new file mode 100644
index 0000000000..1c4f7752e2
--- /dev/null
+++ b/models/asymkey/main_test.go
@@ -0,0 +1,29 @@
+// 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 (
+ "path/filepath"
+ "testing"
+
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/setting"
+)
+
+func init() {
+ setting.SetCustomPathAndConf("", "", "")
+ setting.LoadForTest()
+}
+
+func TestMain(m *testing.M) {
+ unittest.MainTest(m, filepath.Join("..", ".."),
+ "gpg_key.yml",
+ "public_key.yml",
+ "deploy_key.yml",
+ "gpg_key_import.yml",
+ "user.yml",
+ "email_address.yml",
+ )
+}
diff --git a/models/ssh_key.go b/models/asymkey/ssh_key.go
index 0d97096149..cc63663221 100644
--- a/models/ssh_key.go
+++ b/models/asymkey/ssh_key.go
@@ -3,9 +3,10 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
+ "context"
"fmt"
"strings"
"time"
@@ -247,13 +248,13 @@ func UpdatePublicKeyUpdated(id int64) error {
return nil
}
-// deletePublicKeys does the actual key deletion but does not update authorized_keys file.
-func deletePublicKeys(e db.Engine, keyIDs ...int64) error {
+// DeletePublicKeys does the actual key deletion but does not update authorized_keys file.
+func DeletePublicKeys(ctx context.Context, keyIDs ...int64) error {
if len(keyIDs) == 0 {
return nil
}
- _, err := e.In("id", keyIDs).Delete(new(PublicKey))
+ _, err := db.GetEngine(ctx).In("id", keyIDs).Delete(new(PublicKey))
return err
}
@@ -325,40 +326,6 @@ func PublicKeyIsExternallyManaged(id int64) (bool, error) {
return false, nil
}
-// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
-func DeletePublicKey(doer *user_model.User, id int64) (err error) {
- key, err := GetPublicKeyByID(id)
- if err != nil {
- return err
- }
-
- // Check if user has access to delete this key.
- if !doer.IsAdmin && doer.ID != key.OwnerID {
- return ErrKeyAccessDenied{doer.ID, key.ID, "public"}
- }
-
- ctx, committer, err := db.TxContext()
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if err = deletePublicKeys(db.GetEngine(ctx), id); err != nil {
- return err
- }
-
- if err = committer.Commit(); err != nil {
- return err
- }
- committer.Close()
-
- if key.Type == KeyTypePrincipal {
- return RewriteAllPrincipalKeys()
- }
-
- return RewriteAllPublicKeys()
-}
-
// deleteKeysMarkedForDeletion returns true if ssh keys needs update
func deleteKeysMarkedForDeletion(keys []string) (bool, error) {
// Start session
@@ -377,7 +344,7 @@ func deleteKeysMarkedForDeletion(keys []string) (bool, error) {
log.Error("SearchPublicKeyByContent: %v", err)
continue
}
- if err = deletePublicKeys(sess, key.ID); err != nil {
+ if err = DeletePublicKeys(ctx, key.ID); err != nil {
log.Error("deletePublicKeys: %v", err)
continue
}
diff --git a/models/ssh_key_authorized_keys.go b/models/asymkey/ssh_key_authorized_keys.go
index 7843390ffc..dd058f5d11 100644
--- a/models/ssh_key_authorized_keys.go
+++ b/models/asymkey/ssh_key_authorized_keys.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"bufio"
@@ -118,10 +118,6 @@ func appendAuthorizedKeysToFile(keys ...*PublicKey) error {
// Note: db.GetEngine(db.DefaultContext).Iterate does not get latest data after insert/delete, so we have to call this function
// outside any session scope independently.
func RewriteAllPublicKeys() error {
- return rewriteAllPublicKeys(db.GetEngine(db.DefaultContext))
-}
-
-func rewriteAllPublicKeys(e db.Engine) error {
// Don't rewrite key if internal server
if setting.SSH.StartBuiltinServer || !setting.SSH.CreateAuthorizedKeysFile {
return nil
@@ -169,7 +165,7 @@ func rewriteAllPublicKeys(e db.Engine) error {
}
}
- if err := regeneratePublicKeys(e, t); err != nil {
+ if err := RegeneratePublicKeys(t); err != nil {
return err
}
diff --git a/models/ssh_key_authorized_principals.go b/models/asymkey/ssh_key_authorized_principals.go
index c053b4b6d5..a8c48c50aa 100644
--- a/models/ssh_key_authorized_principals.go
+++ b/models/asymkey/ssh_key_authorized_principals.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"bufio"
diff --git a/models/ssh_key_deploy.go b/models/asymkey/ssh_key_deploy.go
index 672974afb3..fc6324792a 100644
--- a/models/ssh_key_deploy.go
+++ b/models/asymkey/ssh_key_deploy.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"context"
@@ -11,8 +11,6 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/builder"
@@ -169,13 +167,9 @@ func AddDeployKey(repoID int64, name, content string, readOnly bool) (*DeployKey
}
// GetDeployKeyByID returns deploy key by given ID.
-func GetDeployKeyByID(id int64) (*DeployKey, error) {
- return getDeployKeyByID(db.GetEngine(db.DefaultContext), id)
-}
-
-func getDeployKeyByID(e db.Engine, id int64) (*DeployKey, error) {
+func GetDeployKeyByID(ctx context.Context, id int64) (*DeployKey, error) {
key := new(DeployKey)
- has, err := e.ID(id).Get(key)
+ has, err := db.GetEngine(ctx).ID(id).Get(key)
if err != nil {
return nil, err
} else if !has {
@@ -215,68 +209,6 @@ func UpdateDeployKey(key *DeployKey) error {
return err
}
-// 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 := deleteDeployKey(ctx, doer, id); err != nil {
- return err
- }
- return committer.Commit()
-}
-
-func deleteDeployKey(ctx context.Context, doer *user_model.User, id int64) error {
- sess := db.GetEngine(ctx)
- key, err := getDeployKeyByID(sess, id)
- if err != nil {
- if IsErrDeployKeyNotExist(err) {
- return nil
- }
- return fmt.Errorf("GetDeployKeyByID: %v", err)
- }
-
- // Check if user has access to delete this key.
- if !doer.IsAdmin {
- repo, err := repo_model.GetRepositoryByIDCtx(ctx, key.RepoID)
- if err != nil {
- return fmt.Errorf("repo_model.GetRepositoryByID: %v", err)
- }
- has, err := isUserRepoAdmin(sess, repo, doer)
- if err != nil {
- return fmt.Errorf("GetUserRepoPermission: %v", err)
- } else if !has {
- return ErrKeyAccessDenied{doer.ID, key.ID, "deploy"}
- }
- }
-
- if _, err = sess.ID(key.ID).Delete(new(DeployKey)); err != nil {
- return fmt.Errorf("delete deploy key [%d]: %v", key.ID, err)
- }
-
- // Check if this is the last reference to same key content.
- has, err := sess.
- Where("key_id = ?", key.KeyID).
- Get(new(DeployKey))
- if err != nil {
- return err
- } else if !has {
- if err = deletePublicKeys(sess, key.KeyID); err != nil {
- return err
- }
-
- // after deleted the public keys, should rewrite the public keys file
- if err = rewriteAllPublicKeys(sess); err != nil {
- return err
- }
- }
-
- return nil
-}
-
// ListDeployKeysOptions are options for ListDeployKeys
type ListDeployKeysOptions struct {
db.ListOptions
@@ -300,12 +232,8 @@ func (opt ListDeployKeysOptions) toCond() builder.Cond {
}
// ListDeployKeys returns a list of deploy keys matching the provided arguments.
-func ListDeployKeys(opts *ListDeployKeysOptions) ([]*DeployKey, error) {
- return listDeployKeys(db.GetEngine(db.DefaultContext), opts)
-}
-
-func listDeployKeys(e db.Engine, opts *ListDeployKeysOptions) ([]*DeployKey, error) {
- sess := e.Where(opts.toCond())
+func ListDeployKeys(ctx context.Context, opts *ListDeployKeysOptions) ([]*DeployKey, error) {
+ sess := db.GetEngine(ctx).Where(opts.toCond())
if opts.Page != 0 {
sess = db.SetSessionPagination(sess, opts)
diff --git a/models/ssh_key_fingerprint.go b/models/asymkey/ssh_key_fingerprint.go
index 85296c961c..437f283bfa 100644
--- a/models/ssh_key_fingerprint.go
+++ b/models/asymkey/ssh_key_fingerprint.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"errors"
diff --git a/models/ssh_key_parse.go b/models/asymkey/ssh_key_parse.go
index 748c66da7d..734bd4ccab 100644
--- a/models/ssh_key_parse.go
+++ b/models/asymkey/ssh_key_parse.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"crypto/rsa"
@@ -18,6 +18,7 @@ import (
"strconv"
"strings"
+ "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting"
@@ -157,7 +158,7 @@ func parseKeyString(content string) (string, error) {
// It returns the actual public key line on success.
func CheckPublicKeyString(content string) (_ string, err error) {
if setting.SSH.Disabled {
- return "", ErrSSHDisabled{}
+ return "", db.ErrSSHDisabled{}
}
content, err = parseKeyString(content)
diff --git a/models/ssh_key_principals.go b/models/asymkey/ssh_key_principals.go
index 9a17a56f1a..19fc6644cb 100644
--- a/models/ssh_key_principals.go
+++ b/models/asymkey/ssh_key_principals.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"errors"
@@ -76,7 +76,7 @@ func addPrincipalKey(e db.Engine, key *PublicKey) (err error) {
// CheckPrincipalKeyString strips spaces and returns an error if the given principal contains newlines
func CheckPrincipalKeyString(user *user_model.User, content string) (_ string, err error) {
if setting.SSH.Disabled {
- return "", ErrSSHDisabled{}
+ return "", db.ErrSSHDisabled{}
}
content = strings.TrimSpace(content)
diff --git a/models/ssh_key_test.go b/models/asymkey/ssh_key_test.go
index b52a36bdbd..62c07c6035 100644
--- a/models/ssh_key_test.go
+++ b/models/asymkey/ssh_key_test.go
@@ -3,7 +3,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"strings"
@@ -14,11 +14,6 @@ import (
"github.com/stretchr/testify/assert"
)
-func init() {
- setting.SetCustomPathAndConf("", "", "")
- setting.LoadForTest()
-}
-
func Test_SSHParsePublicKey(t *testing.T) {
testCases := []struct {
name string
diff --git a/models/commit.go b/models/commit.go
index 8de71da1b3..5df6964a1d 100644
--- a/models/commit.go
+++ b/models/commit.go
@@ -5,6 +5,7 @@
package models
import (
+ 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"
@@ -13,9 +14,12 @@ import (
// ConvertFromGitCommit converts git commits into SignCommitWithStatuses
func ConvertFromGitCommit(commits []*git.Commit, repo *repo_model.Repository) []*SignCommitWithStatuses {
return ParseCommitsWithStatus(
- ParseCommitsWithSignature(
+ asymkey_model.ParseCommitsWithSignature(
user_model.ValidateCommitsWithEmails(commits),
- repo,
+ repo.GetTrustModel(),
+ func(user *user_model.User) (bool, error) {
+ return IsUserRepoAdmin(repo, user)
+ },
),
repo,
)
diff --git a/models/commit_status.go b/models/commit_status.go
index e0942d2028..93b6f93f96 100644
--- a/models/commit_status.go
+++ b/models/commit_status.go
@@ -12,6 +12,7 @@ import (
"strings"
"time"
+ 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"
@@ -328,11 +329,11 @@ func NewCommitStatus(opts NewCommitStatusOptions) error {
type SignCommitWithStatuses struct {
Status *CommitStatus
Statuses []*CommitStatus
- *SignCommit
+ *asymkey_model.SignCommit
}
// ParseCommitsWithStatus checks commits latest statuses and calculates its worst status state
-func ParseCommitsWithStatus(oldCommits []*SignCommit, repo *repo_model.Repository) []*SignCommitWithStatuses {
+func ParseCommitsWithStatus(oldCommits []*asymkey_model.SignCommit, repo *repo_model.Repository) []*SignCommitWithStatuses {
newCommits := make([]*SignCommitWithStatuses, 0, len(oldCommits))
for _, c := range oldCommits {
diff --git a/models/db/error.go b/models/db/error.go
index adaeedcc09..f20cc9b4cb 100644
--- a/models/db/error.go
+++ b/models/db/error.go
@@ -29,3 +29,16 @@ func ErrCancelledf(format string, args ...interface{}) error {
fmt.Sprintf(format, args...),
}
}
+
+// ErrSSHDisabled represents an "SSH disabled" error.
+type ErrSSHDisabled struct{}
+
+// IsErrSSHDisabled checks if an error is a ErrSSHDisabled.
+func IsErrSSHDisabled(err error) bool {
+ _, ok := err.(ErrSSHDisabled)
+ return ok
+}
+
+func (err ErrSSHDisabled) Error() string {
+ return "SSH is disabled"
+}
diff --git a/models/error.go b/models/error.go
index 20ed7f90e1..54556fd787 100644
--- a/models/error.go
+++ b/models/error.go
@@ -28,19 +28,6 @@ func (err ErrNotExist) Error() string {
return fmt.Sprintf("record does not exist [id: %d]", err.ID)
}
-// ErrSSHDisabled represents an "SSH disabled" error.
-type ErrSSHDisabled struct{}
-
-// IsErrSSHDisabled checks if an error is a ErrSSHDisabled.
-func IsErrSSHDisabled(err error) bool {
- _, ok := err.(ErrSSHDisabled)
- return ok
-}
-
-func (err ErrSSHDisabled) Error() string {
- return "SSH is disabled"
-}
-
// ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
type ErrUserOwnRepos struct {
UID int64
@@ -151,254 +138,6 @@ func (err ErrWikiInvalidFileName) Error() string {
return fmt.Sprintf("Invalid wiki filename: %s", err.FileName)
}
-// __________ ___. .__ .__ ____ __.
-// \______ \__ _\_ |__ | | |__| ____ | |/ _|____ ___.__.
-// | ___/ | \ __ \| | | |/ ___\ | <_/ __ < | |
-// | | | | / \_\ \ |_| \ \___ | | \ ___/\___ |
-// |____| |____/|___ /____/__|\___ > |____|__ \___ > ____|
-// \/ \/ \/ \/\/
-
-// ErrKeyUnableVerify represents a "KeyUnableVerify" kind of error.
-type ErrKeyUnableVerify struct {
- Result string
-}
-
-// IsErrKeyUnableVerify checks if an error is a ErrKeyUnableVerify.
-func IsErrKeyUnableVerify(err error) bool {
- _, ok := err.(ErrKeyUnableVerify)
- return ok
-}
-
-func (err ErrKeyUnableVerify) Error() string {
- return fmt.Sprintf("Unable to verify key content [result: %s]", err.Result)
-}
-
-// ErrKeyNotExist represents a "KeyNotExist" kind of error.
-type ErrKeyNotExist struct {
- ID int64
-}
-
-// IsErrKeyNotExist checks if an error is a ErrKeyNotExist.
-func IsErrKeyNotExist(err error) bool {
- _, ok := err.(ErrKeyNotExist)
- return ok
-}
-
-func (err ErrKeyNotExist) Error() string {
- return fmt.Sprintf("public key does not exist [id: %d]", err.ID)
-}
-
-// ErrKeyAlreadyExist represents a "KeyAlreadyExist" kind of error.
-type ErrKeyAlreadyExist struct {
- OwnerID int64
- Fingerprint string
- Content string
-}
-
-// IsErrKeyAlreadyExist checks if an error is a ErrKeyAlreadyExist.
-func IsErrKeyAlreadyExist(err error) bool {
- _, ok := err.(ErrKeyAlreadyExist)
- return ok
-}
-
-func (err ErrKeyAlreadyExist) Error() string {
- return fmt.Sprintf("public key already exists [owner_id: %d, finger_print: %s, content: %s]",
- err.OwnerID, err.Fingerprint, err.Content)
-}
-
-// ErrKeyNameAlreadyUsed represents a "KeyNameAlreadyUsed" kind of error.
-type ErrKeyNameAlreadyUsed struct {
- OwnerID int64
- Name string
-}
-
-// IsErrKeyNameAlreadyUsed checks if an error is a ErrKeyNameAlreadyUsed.
-func IsErrKeyNameAlreadyUsed(err error) bool {
- _, ok := err.(ErrKeyNameAlreadyUsed)
- return ok
-}
-
-func (err ErrKeyNameAlreadyUsed) Error() string {
- return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name)
-}
-
-// ErrGPGNoEmailFound represents a "ErrGPGNoEmailFound" kind of error.
-type ErrGPGNoEmailFound struct {
- FailedEmails []string
- ID string
-}
-
-// IsErrGPGNoEmailFound checks if an error is a ErrGPGNoEmailFound.
-func IsErrGPGNoEmailFound(err error) bool {
- _, ok := err.(ErrGPGNoEmailFound)
- return ok
-}
-
-func (err ErrGPGNoEmailFound) Error() string {
- return fmt.Sprintf("none of the emails attached to the GPG key could be found: %v", err.FailedEmails)
-}
-
-// ErrGPGInvalidTokenSignature represents a "ErrGPGInvalidTokenSignature" kind of error.
-type ErrGPGInvalidTokenSignature struct {
- Wrapped error
- ID string
-}
-
-// IsErrGPGInvalidTokenSignature checks if an error is a ErrGPGInvalidTokenSignature.
-func IsErrGPGInvalidTokenSignature(err error) bool {
- _, ok := err.(ErrGPGInvalidTokenSignature)
- return ok
-}
-
-func (err ErrGPGInvalidTokenSignature) Error() string {
- return "the provided signature does not sign the token with the provided key"
-}
-
-// ErrGPGKeyParsing represents a "ErrGPGKeyParsing" kind of error.
-type ErrGPGKeyParsing struct {
- ParseError error
-}
-
-// IsErrGPGKeyParsing checks if an error is a ErrGPGKeyParsing.
-func IsErrGPGKeyParsing(err error) bool {
- _, ok := err.(ErrGPGKeyParsing)
- return ok
-}
-
-func (err ErrGPGKeyParsing) Error() string {
- return fmt.Sprintf("failed to parse gpg key %s", err.ParseError.Error())
-}
-
-// ErrGPGKeyNotExist represents a "GPGKeyNotExist" kind of error.
-type ErrGPGKeyNotExist struct {
- ID int64
-}
-
-// IsErrGPGKeyNotExist checks if an error is a ErrGPGKeyNotExist.
-func IsErrGPGKeyNotExist(err error) bool {
- _, ok := err.(ErrGPGKeyNotExist)
- return ok
-}
-
-func (err ErrGPGKeyNotExist) Error() string {
- return fmt.Sprintf("public gpg key does not exist [id: %d]", err.ID)
-}
-
-// ErrGPGKeyImportNotExist represents a "GPGKeyImportNotExist" kind of error.
-type ErrGPGKeyImportNotExist struct {
- ID string
-}
-
-// IsErrGPGKeyImportNotExist checks if an error is a ErrGPGKeyImportNotExist.
-func IsErrGPGKeyImportNotExist(err error) bool {
- _, ok := err.(ErrGPGKeyImportNotExist)
- return ok
-}
-
-func (err ErrGPGKeyImportNotExist) Error() string {
- return fmt.Sprintf("public gpg key import does not exist [id: %s]", err.ID)
-}
-
-// ErrGPGKeyIDAlreadyUsed represents a "GPGKeyIDAlreadyUsed" kind of error.
-type ErrGPGKeyIDAlreadyUsed struct {
- KeyID string
-}
-
-// IsErrGPGKeyIDAlreadyUsed checks if an error is a ErrKeyNameAlreadyUsed.
-func IsErrGPGKeyIDAlreadyUsed(err error) bool {
- _, ok := err.(ErrGPGKeyIDAlreadyUsed)
- return ok
-}
-
-func (err ErrGPGKeyIDAlreadyUsed) Error() string {
- return fmt.Sprintf("public key already exists [key_id: %s]", err.KeyID)
-}
-
-// ErrGPGKeyAccessDenied represents a "GPGKeyAccessDenied" kind of Error.
-type ErrGPGKeyAccessDenied struct {
- UserID int64
- KeyID int64
-}
-
-// IsErrGPGKeyAccessDenied checks if an error is a ErrGPGKeyAccessDenied.
-func IsErrGPGKeyAccessDenied(err error) bool {
- _, ok := err.(ErrGPGKeyAccessDenied)
- return ok
-}
-
-// Error pretty-prints an error of type ErrGPGKeyAccessDenied.
-func (err ErrGPGKeyAccessDenied) Error() string {
- return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d]",
- err.UserID, err.KeyID)
-}
-
-// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
-type ErrKeyAccessDenied struct {
- UserID int64
- KeyID int64
- Note string
-}
-
-// IsErrKeyAccessDenied checks if an error is a ErrKeyAccessDenied.
-func IsErrKeyAccessDenied(err error) bool {
- _, ok := err.(ErrKeyAccessDenied)
- return ok
-}
-
-func (err ErrKeyAccessDenied) Error() string {
- return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d, note: %s]",
- err.UserID, err.KeyID, err.Note)
-}
-
-// ErrDeployKeyNotExist represents a "DeployKeyNotExist" kind of error.
-type ErrDeployKeyNotExist struct {
- ID int64
- KeyID int64
- RepoID int64
-}
-
-// IsErrDeployKeyNotExist checks if an error is a ErrDeployKeyNotExist.
-func IsErrDeployKeyNotExist(err error) bool {
- _, ok := err.(ErrDeployKeyNotExist)
- return ok
-}
-
-func (err ErrDeployKeyNotExist) Error() string {
- return fmt.Sprintf("Deploy key does not exist [id: %d, key_id: %d, repo_id: %d]", err.ID, err.KeyID, err.RepoID)
-}
-
-// ErrDeployKeyAlreadyExist represents a "DeployKeyAlreadyExist" kind of error.
-type ErrDeployKeyAlreadyExist struct {
- KeyID int64
- RepoID int64
-}
-
-// IsErrDeployKeyAlreadyExist checks if an error is a ErrDeployKeyAlreadyExist.
-func IsErrDeployKeyAlreadyExist(err error) bool {
- _, ok := err.(ErrDeployKeyAlreadyExist)
- return ok
-}
-
-func (err ErrDeployKeyAlreadyExist) Error() string {
- return fmt.Sprintf("public key already exists [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID)
-}
-
-// ErrDeployKeyNameAlreadyUsed represents a "DeployKeyNameAlreadyUsed" kind of error.
-type ErrDeployKeyNameAlreadyUsed struct {
- RepoID int64
- Name string
-}
-
-// IsErrDeployKeyNameAlreadyUsed checks if an error is a ErrDeployKeyNameAlreadyUsed.
-func IsErrDeployKeyNameAlreadyUsed(err error) bool {
- _, ok := err.(ErrDeployKeyNameAlreadyUsed)
- return ok
-}
-
-func (err ErrDeployKeyNameAlreadyUsed) Error() string {
- return fmt.Sprintf("public key with name already exists [repo_id: %d, name: %s]", err.RepoID, err.Name)
-}
-
// _____ ___________ __
// / _ \ ____ ____ ____ ______ _____\__ ___/___ | | __ ____ ____
// / /_\ \_/ ___\/ ___\/ __ \ / ___// ___/ | | / _ \| |/ // __ \ / \
@@ -878,22 +617,6 @@ func (err ErrUserDoesNotHaveAccessToRepo) Error() string {
return fmt.Sprintf("user doesn't have access to repo [user_id: %d, repo_name: %s]", err.UserID, err.RepoName)
}
-// 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
-}
-
// __________ .__
// \______ \____________ ____ ____ | |__
// | | _/\_ __ \__ \ / \_/ ___\| | \
diff --git a/models/main_test.go b/models/main_test.go
index 20107eab1e..8d5291a8aa 100644
--- a/models/main_test.go
+++ b/models/main_test.go
@@ -10,10 +10,16 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
+func init() {
+ setting.SetCustomPathAndConf("", "", "")
+ setting.LoadForTest()
+}
+
// TestFixturesAreConsistent assert that test fixtures are consistent
func TestFixturesAreConsistent(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
diff --git a/models/pull_sign.go b/models/pull_sign.go
deleted file mode 100644
index 269e8e06d2..0000000000
--- a/models/pull_sign.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// 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 models
-
-import (
- "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/setting"
-)
-
-// SignMerge determines if we should sign a PR merge commit to the base repository
-func (pr *PullRequest) SignMerge(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 := ListGPGKeys(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 := 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 := 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 := 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 := 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 := ParseCommitWithSignature(commit)
- if !verification.Verified {
- return false, "", nil, &ErrWontSign{commitsSigned}
- }
- }
- }
- }
- return true, signingKey, signer, nil
-}
diff --git a/models/repo.go b/models/repo.go
index 6bdc4c20d2..adc62c9528 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -20,6 +20,7 @@ import (
_ "image/jpeg" // Needed for jpeg support
admin_model "code.gitea.io/gitea/models/admin"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
@@ -856,12 +857,13 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
}
// Delete Deploy Keys
- deployKeys, err := listDeployKeys(sess, &ListDeployKeysOptions{RepoID: repoID})
+ deployKeys, err := asymkey_model.ListDeployKeys(ctx, &asymkey_model.ListDeployKeysOptions{RepoID: repoID})
if err != nil {
return fmt.Errorf("listDeployKeys: %v", err)
}
+ var needRewriteKeysFile = len(deployKeys) > 0
for _, dKey := range deployKeys {
- if err := deleteDeployKey(ctx, doer, dKey.ID); err != nil {
+ if err := DeleteDeployKey(ctx, doer, dKey.ID); err != nil {
return fmt.Errorf("deleteDeployKeys: %v", err)
}
}
@@ -1049,6 +1051,12 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
committer.Close()
+ if needRewriteKeysFile {
+ if err := asymkey_model.RewriteAllPublicKeys(); err != nil {
+ log.Error("RewriteAllPublicKeys failed: %v", err)
+ }
+ }
+
// We should always delete the files after the database transaction succeed. If
// we delete the file but the database rollback, the repository will be broken.
@@ -1407,3 +1415,52 @@ func LinkedRepository(a *repo_model.Attachment) (*repo_model.Repository, unit.Ty
}
return nil, -1, nil
}
+
+// DeleteDeployKey delete deploy keys
+func DeleteDeployKey(ctx context.Context, doer *user_model.User, id int64) error {
+ key, err := asymkey_model.GetDeployKeyByID(ctx, id)
+ if err != nil {
+ if asymkey_model.IsErrDeployKeyNotExist(err) {
+ return nil
+ }
+ return fmt.Errorf("GetDeployKeyByID: %v", err)
+ }
+
+ sess := db.GetEngine(ctx)
+
+ // Check if user has access to delete this key.
+ if !doer.IsAdmin {
+ repo, err := repo_model.GetRepositoryByIDCtx(ctx, key.RepoID)
+ if err != nil {
+ return fmt.Errorf("GetRepositoryByID: %v", err)
+ }
+ has, err := isUserRepoAdmin(sess, repo, doer)
+ if err != nil {
+ return fmt.Errorf("GetUserRepoPermission: %v", err)
+ } else if !has {
+ return asymkey_model.ErrKeyAccessDenied{
+ UserID: doer.ID,
+ KeyID: key.ID,
+ Note: "deploy",
+ }
+ }
+ }
+
+ if _, err = sess.ID(key.ID).Delete(new(asymkey_model.DeployKey)); err != nil {
+ return fmt.Errorf("delete deploy key [%d]: %v", key.ID, err)
+ }
+
+ // Check if this is the last reference to same key content.
+ has, err := sess.
+ Where("key_id = ?", key.KeyID).
+ Get(new(asymkey_model.DeployKey))
+ if err != nil {
+ return err
+ } else if !has {
+ if err = asymkey_model.DeletePublicKeys(ctx, key.KeyID); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/models/repo_sign.go b/models/repo_sign.go
deleted file mode 100644
index 1c736a62da..0000000000
--- a/models/repo_sign.go
+++ /dev/null
@@ -1,251 +0,0 @@
-// 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 models
-
-import (
- "strings"
-
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/login"
- repo_model "code.gitea.io/gitea/models/repo"
- 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
-}
-
-// 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 := ListGPGKeys(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(repo *repo_model.Repository, u *user_model.User) (bool, string, *git.Signature, error) {
- rules := signingModeFromStrings(setting.Repository.Signing.Wiki)
- signingKey, sig := SigningKey(repo.WikiPath())
- 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 := ListGPGKeys(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(repo.WikiPath())
- 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 := 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(repo *repo_model.Repository, u *user_model.User, tmpBasePath, parentCommit string) (bool, string, *git.Signature, error) {
- rules := signingModeFromStrings(setting.Repository.Signing.CRUDActions)
- signingKey, sig := SigningKey(repo.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 := ListGPGKeys(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 := ParseCommitWithSignature(commit)
- if !verification.Verified {
- return false, "", nil, &ErrWontSign{parentSigned}
- }
- }
- }
- return true, signingKey, sig, nil
-}
diff --git a/models/statistic.go b/models/statistic.go
index 055f312c11..175815081f 100644
--- a/models/statistic.go
+++ b/models/statistic.go
@@ -5,6 +5,7 @@
package models
import (
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/login"
repo_model "code.gitea.io/gitea/models/repo"
@@ -47,7 +48,7 @@ func GetStatistic() (stats Statistic) {
e := db.GetEngine(db.DefaultContext)
stats.Counter.User = user_model.CountUsers()
stats.Counter.Org = CountOrganizations()
- stats.Counter.PublicKey, _ = e.Count(new(PublicKey))
+ stats.Counter.PublicKey, _ = e.Count(new(asymkey_model.PublicKey))
stats.Counter.Repo = repo_model.CountRepositories(true)
stats.Counter.Watch, _ = e.Count(new(Watch))
stats.Counter.Star, _ = e.Count(new(Star))
diff --git a/models/user.go b/models/user.go
index 1427833e21..2a727dd124 100644
--- a/models/user.go
+++ b/models/user.go
@@ -12,6 +12,7 @@ import (
_ "image/jpeg" // Needed for jpeg support
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
@@ -234,23 +235,23 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {
}
// ***** START: PublicKey *****
- if _, err = e.Delete(&PublicKey{OwnerID: u.ID}); err != nil {
+ if _, err = e.Delete(&asymkey_model.PublicKey{OwnerID: u.ID}); err != nil {
return fmt.Errorf("deletePublicKeys: %v", err)
}
// ***** END: PublicKey *****
// ***** START: GPGPublicKey *****
- keys, err := listGPGKeys(e, u.ID, db.ListOptions{})
+ keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{})
if err != nil {
return fmt.Errorf("ListGPGKeys: %v", err)
}
// Delete GPGKeyImport(s).
for _, key := range keys {
- if _, err = e.Delete(&GPGKeyImport{KeyID: key.KeyID}); err != nil {
+ if _, err = e.Delete(&asymkey_model.GPGKeyImport{KeyID: key.KeyID}); err != nil {
return fmt.Errorf("deleteGPGKeyImports: %v", err)
}
}
- if _, err = e.Delete(&GPGKey{OwnerID: u.ID}); err != nil {
+ if _, err = e.Delete(&asymkey_model.GPGKey{OwnerID: u.ID}); err != nil {
return fmt.Errorf("deleteGPGKeys: %v", err)
}
// ***** END: GPGPublicKey *****
diff --git a/models/user_test.go b/models/user_test.go
index d3c7718d69..4749a3af73 100644
--- a/models/user_test.go
+++ b/models/user_test.go
@@ -8,7 +8,6 @@ import (
"fmt"
"testing"
- "code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -121,71 +120,3 @@ func TestGetOrgRepositoryIDs(t *testing.T) {
// User 5's team has no access to any repo
assert.Len(t, accessibleRepos, 0)
}
-
-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
- AddPublicKeysBySource(user, s, []string{kase.keyString})
- keys, err := 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)
- }
- }
-}