mirror of https://github.com/go-gitea/gitea
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 * mergepull/17941/head
parent
0a9fcf63a4
commit
3ca5dc7e32
@ -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) |
||||||
|
} |
@ -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", |
||||||
|
) |
||||||
|
} |
@ -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 |
|
||||||
} |
|
@ -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() |
||||||
|
} |
@ -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("..", "..")) |
||||||
|
} |
@ -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() |
||||||
|
} |
@ -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) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue