* 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 * mergetags/v1.16.0-rc1
@@ -14,6 +14,7 @@ import ( | |||
"text/tabwriter" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/db" | |||
"code.gitea.io/gitea/models/login" | |||
user_model "code.gitea.io/gitea/models/user" | |||
@@ -625,7 +626,7 @@ func runRegenerateKeys(_ *cli.Context) error { | |||
if err := initDB(ctx); err != nil { | |||
return err | |||
} | |||
return models.RewriteAllPublicKeys() | |||
return asymkey_model.RewriteAllPublicKeys() | |||
} | |||
func parseOAuth2Config(c *cli.Context) *oauth2.Source { |
@@ -17,6 +17,7 @@ import ( | |||
"time" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/perm" | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/json" | |||
@@ -129,9 +130,9 @@ func runServ(c *cli.Context) error { | |||
return fail("Internal error", "Failed to check provided key: %v", err) | |||
} | |||
switch key.Type { | |||
case models.KeyTypeDeploy: | |||
case asymkey_model.KeyTypeDeploy: | |||
println("Hi there! You've successfully authenticated with the deploy key named " + key.Name + ", but Gitea does not provide shell access.") | |||
case models.KeyTypePrincipal: | |||
case asymkey_model.KeyTypePrincipal: | |||
println("Hi there! You've successfully authenticated with the principal " + key.Content + ", but Gitea does not provide shell access.") | |||
default: | |||
println("Hi there, " + user.Name + "! You've successfully authenticated with the key named " + key.Name + ", but Gitea does not provide shell access.") |
@@ -277,7 +277,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a | |||
- `SSH_AUTHORIZED_PRINCIPALS_ALLOW`: **off** or **username, email**: \[off, username, email, anything\]: Specify the principals values that users are allowed to use as principal. When set to `anything` no checks are done on the principal string. When set to `off` authorized principal are not allowed to be set. | |||
- `SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE`: **false/true**: Gitea will create a authorized_principals file by default when it is not using the internal ssh server and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`. | |||
- `SSH_AUTHORIZED_PRINCIPALS_BACKUP`: **false/true**: Enable SSH Authorized Principals Backup when rewriting all keys, default is true if `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`. | |||
- `SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE`: **{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}**: Set the template for the command to passed on authorized keys. Possible keys are: AppPath, AppWorkPath, CustomConf, CustomPath, Key - where Key is a `models.PublicKey` and the others are strings which are shellquoted. | |||
- `SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE`: **{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}**: Set the template for the command to passed on authorized keys. Possible keys are: AppPath, AppWorkPath, CustomConf, CustomPath, Key - where Key is a `models/asymkey.PublicKey` and the others are strings which are shellquoted. | |||
- `SSH_SERVER_CIPHERS`: **aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128**: For the built-in SSH server, choose the ciphers to support for SSH connections, for system SSH this setting has no effect. | |||
- `SSH_SERVER_KEY_EXCHANGES`: **diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org**: For the built-in SSH server, choose the key exchange algorithms to support for SSH connections, for system SSH this setting has no effect. | |||
- `SSH_SERVER_MACS`: **hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1, hmac-sha1-96**: For the built-in SSH server, choose the MACs to support for SSH connections, for system SSH this setting has no effect |
@@ -9,7 +9,7 @@ import ( | |||
"net/http" | |||
"testing" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/unittest" | |||
user_model "code.gitea.io/gitea/models/user" | |||
"code.gitea.io/gitea/modules/json" | |||
@@ -34,7 +34,7 @@ func TestAPIAdminCreateAndDeleteSSHKey(t *testing.T) { | |||
var newPublicKey api.PublicKey | |||
DecodeJSON(t, resp, &newPublicKey) | |||
unittest.AssertExistsAndLoadBean(t, &models.PublicKey{ | |||
unittest.AssertExistsAndLoadBean(t, &asymkey_model.PublicKey{ | |||
ID: newPublicKey.ID, | |||
Name: newPublicKey.Title, | |||
Content: newPublicKey.Key, | |||
@@ -45,7 +45,7 @@ func TestAPIAdminCreateAndDeleteSSHKey(t *testing.T) { | |||
req = NewRequestf(t, "DELETE", "/api/v1/admin/users/%s/keys/%d?token=%s", | |||
keyOwner.Name, newPublicKey.ID, token) | |||
session.MakeRequest(t, req, http.StatusNoContent) | |||
unittest.AssertNotExistsBean(t, &models.PublicKey{ID: newPublicKey.ID}) | |||
unittest.AssertNotExistsBean(t, &asymkey_model.PublicKey{ID: newPublicKey.ID}) | |||
} | |||
func TestAPIAdminDeleteMissingSSHKey(t *testing.T) { |
@@ -10,7 +10,7 @@ import ( | |||
"net/url" | |||
"testing" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/perm" | |||
repo_model "code.gitea.io/gitea/models/repo" | |||
"code.gitea.io/gitea/models/unittest" | |||
@@ -65,7 +65,7 @@ func TestCreateReadOnlyDeployKey(t *testing.T) { | |||
var newDeployKey api.DeployKey | |||
DecodeJSON(t, resp, &newDeployKey) | |||
unittest.AssertExistsAndLoadBean(t, &models.DeployKey{ | |||
unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{ | |||
ID: newDeployKey.ID, | |||
Name: rawKeyBody.Title, | |||
Content: rawKeyBody.Key, | |||
@@ -90,7 +90,7 @@ func TestCreateReadWriteDeployKey(t *testing.T) { | |||
var newDeployKey api.DeployKey | |||
DecodeJSON(t, resp, &newDeployKey) | |||
unittest.AssertExistsAndLoadBean(t, &models.DeployKey{ | |||
unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{ | |||
ID: newDeployKey.ID, | |||
Name: rawKeyBody.Title, | |||
Content: rawKeyBody.Key, | |||
@@ -116,7 +116,7 @@ func TestCreateUserKey(t *testing.T) { | |||
var newPublicKey api.PublicKey | |||
DecodeJSON(t, resp, &newPublicKey) | |||
unittest.AssertExistsAndLoadBean(t, &models.PublicKey{ | |||
unittest.AssertExistsAndLoadBean(t, &asymkey_model.PublicKey{ | |||
ID: newPublicKey.ID, | |||
OwnerID: user.ID, | |||
Name: rawKeyBody.Title, |
@@ -9,7 +9,7 @@ import ( | |||
"net/url" | |||
"testing" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/perm" | |||
"code.gitea.io/gitea/modules/private" | |||
@@ -27,7 +27,7 @@ func TestAPIPrivateNoServ(t *testing.T) { | |||
assert.Equal(t, int64(1), key.ID) | |||
assert.Equal(t, "user2@localhost", key.Name) | |||
deployKey, err := models.AddDeployKey(1, "test-deploy", "sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGXEEzWmm1dxb+57RoK5KVCL0w2eNv9cqJX2AGGVlkFsVDhOXHzsadS3LTK4VlEbbrDMJdoti9yM8vclA8IeRacAAAAEc3NoOg== nocomment", false) | |||
deployKey, err := asymkey_model.AddDeployKey(1, "test-deploy", "sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGXEEzWmm1dxb+57RoK5KVCL0w2eNv9cqJX2AGGVlkFsVDhOXHzsadS3LTK4VlEbbrDMJdoti9yM8vclA8IeRacAAAAEc3NoOg== nocomment", false) | |||
assert.NoError(t, err) | |||
key, user, err = private.ServNoCommand(ctx, deployKey.KeyID) | |||
@@ -85,7 +85,7 @@ func TestAPIPrivateServ(t *testing.T) { | |||
assert.Empty(t, results) | |||
// Add reading deploy key | |||
deployKey, err := models.AddDeployKey(19, "test-deploy", "sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGXEEzWmm1dxb+57RoK5KVCL0w2eNv9cqJX2AGGVlkFsVDhOXHzsadS3LTK4VlEbbrDMJdoti9yM8vclA8IeRacAAAAEc3NoOg== nocomment", true) | |||
deployKey, err := asymkey_model.AddDeployKey(19, "test-deploy", "sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGXEEzWmm1dxb+57RoK5KVCL0w2eNv9cqJX2AGGVlkFsVDhOXHzsadS3LTK4VlEbbrDMJdoti9yM8vclA8IeRacAAAAEc3NoOg== nocomment", true) | |||
assert.NoError(t, err) | |||
// Can pull from repo we're a deploy key for | |||
@@ -117,7 +117,7 @@ func TestAPIPrivateServ(t *testing.T) { | |||
assert.Empty(t, results) | |||
// Add writing deploy key | |||
deployKey, err = models.AddDeployKey(20, "test-deploy", "sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGXEEzWmm1dxb+57RoK5KVCL0w2eNv9cqJX2AGGVlkFsVDhOXHzsadS3LTK4VlEbbrDMJdoti9yM8vclA8IeRacAAAAEc3NoOg== nocomment", false) | |||
deployKey, err = asymkey_model.AddDeployKey(20, "test-deploy", "sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGXEEzWmm1dxb+57RoK5KVCL0w2eNv9cqJX2AGGVlkFsVDhOXHzsadS3LTK4VlEbbrDMJdoti9yM8vclA8IeRacAAAAEc3NoOg== nocomment", false) | |||
assert.NoError(t, err) | |||
// Cannot push to a private repo with reading key |
@@ -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) | |||
} |
@@ -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) | |||
} |
@@ -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" |
@@ -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" | |||
} |
@@ -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" |
@@ -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" | |||
@@ -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" |
@@ -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" |
@@ -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", | |||
) | |||
} |
@@ -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 | |||
} |
@@ -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 | |||
} | |||
@@ -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" |
@@ -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) |
@@ -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" |
@@ -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) |
@@ -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) |
@@ -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 |
@@ -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, | |||
) |
@@ -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 { |
@@ -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" | |||
} |
@@ -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 | |||
} | |||
// __________ .__ | |||
// \______ \____________ ____ ____ | |__ | |||
// | | _/\_ __ \__ \ / \_/ ___\| | \ |
@@ -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()) |
@@ -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 | |||
} |
@@ -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 | |||
} |
@@ -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)) |
@@ -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 ***** |
@@ -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) | |||
} | |||
} | |||
} |
@@ -25,6 +25,7 @@ import ( | |||
"code.gitea.io/gitea/modules/setting" | |||
api "code.gitea.io/gitea/modules/structs" | |||
"code.gitea.io/gitea/modules/util" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
"github.com/editorconfig/editorconfig-core-go/v2" | |||
"github.com/unknwon/com" | |||
@@ -120,7 +121,7 @@ func (r *Repository) CanCommitToBranch(doer *user_model.User) (CanCommitToBranch | |||
requireSigned = protectedBranch.RequireSignedCommits | |||
} | |||
sign, keyID, _, err := models.SignCRUDAction(r.Repository, doer, r.Repository.RepoPath(), git.BranchPrefix+r.BranchName) | |||
sign, keyID, _, err := asymkey_service.SignCRUDAction(r.Repository.RepoPath(), doer, r.Repository.RepoPath(), git.BranchPrefix+r.BranchName) | |||
canCommit := r.CanEnableEditor() && userCanPush | |||
if requireSigned { | |||
@@ -128,8 +129,8 @@ func (r *Repository) CanCommitToBranch(doer *user_model.User) (CanCommitToBranch | |||
} | |||
wontSignReason := "" | |||
if err != nil { | |||
if models.IsErrWontSign(err) { | |||
wontSignReason = string(err.(*models.ErrWontSign).Reason) | |||
if asymkey_service.IsErrWontSign(err) { | |||
wontSignReason = string(err.(*asymkey_service.ErrWontSign).Reason) | |||
err = nil | |||
} else { | |||
wontSignReason = "error" |
@@ -12,6 +12,7 @@ import ( | |||
"time" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/login" | |||
"code.gitea.io/gitea/models/perm" | |||
repo_model "code.gitea.io/gitea/models/repo" | |||
@@ -152,7 +153,7 @@ func ToTag(repo *repo_model.Repository, t *git.Tag) *api.Tag { | |||
// ToVerification convert a git.Commit.Signature to an api.PayloadCommitVerification | |||
func ToVerification(c *git.Commit) *api.PayloadCommitVerification { | |||
verif := models.ParseCommitWithSignature(c) | |||
verif := asymkey_model.ParseCommitWithSignature(c) | |||
commitVerification := &api.PayloadCommitVerification{ | |||
Verified: verif.Verified, | |||
Reason: verif.Reason, | |||
@@ -170,8 +171,8 @@ func ToVerification(c *git.Commit) *api.PayloadCommitVerification { | |||
return commitVerification | |||
} | |||
// ToPublicKey convert models.PublicKey to api.PublicKey | |||
func ToPublicKey(apiLink string, key *models.PublicKey) *api.PublicKey { | |||
// ToPublicKey convert asymkey_model.PublicKey to api.PublicKey | |||
func ToPublicKey(apiLink string, key *asymkey_model.PublicKey) *api.PublicKey { | |||
return &api.PublicKey{ | |||
ID: key.ID, | |||
Key: key.Content, | |||
@@ -183,7 +184,7 @@ func ToPublicKey(apiLink string, key *models.PublicKey) *api.PublicKey { | |||
} | |||
// ToGPGKey converts models.GPGKey to api.GPGKey | |||
func ToGPGKey(key *models.GPGKey) *api.GPGKey { | |||
func ToGPGKey(key *asymkey_model.GPGKey) *api.GPGKey { | |||
subkeys := make([]*api.GPGKey, len(key.SubsKey)) | |||
for id, k := range key.SubsKey { | |||
subkeys[id] = &api.GPGKey{ | |||
@@ -264,8 +265,8 @@ func ToGitHook(h *git.Hook) *api.GitHook { | |||
} | |||
} | |||
// ToDeployKey convert models.DeployKey to api.DeployKey | |||
func ToDeployKey(apiLink string, key *models.DeployKey) *api.DeployKey { | |||
// ToDeployKey convert asymkey_model.DeployKey to api.DeployKey | |||
func ToDeployKey(apiLink string, key *asymkey_model.DeployKey) *api.DeployKey { | |||
return &api.DeployKey{ | |||
ID: key.ID, | |||
KeyID: key.KeyID, |
@@ -12,7 +12,7 @@ import ( | |||
"path/filepath" | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/modules/setting" | |||
) | |||
@@ -32,7 +32,7 @@ func checkAuthorizedKeys(logger log.Logger, autofix bool) error { | |||
return fmt.Errorf("Unable to open authorized_keys file. ERROR: %v", err) | |||
} | |||
logger.Warn("Unable to open authorized_keys. (ERROR: %v). Attempting to rewrite...", err) | |||
if err = models.RewriteAllPublicKeys(); err != nil { | |||
if err = asymkey_model.RewriteAllPublicKeys(); err != nil { | |||
logger.Critical("Unable to rewrite authorized_keys file. ERROR: %v", err) | |||
return fmt.Errorf("Unable to rewrite authorized_keys file. ERROR: %v", err) | |||
} | |||
@@ -53,7 +53,7 @@ func checkAuthorizedKeys(logger log.Logger, autofix bool) error { | |||
// now we regenerate and check if there are any lines missing | |||
regenerated := &bytes.Buffer{} | |||
if err := models.RegeneratePublicKeys(regenerated); err != nil { | |||
if err := asymkey_model.RegeneratePublicKeys(regenerated); err != nil { | |||
logger.Critical("Unable to regenerate authorized_keys file. ERROR: %v", err) | |||
return fmt.Errorf("Unable to regenerate authorized_keys file. ERROR: %v", err) | |||
} | |||
@@ -75,7 +75,7 @@ func checkAuthorizedKeys(logger log.Logger, autofix bool) error { | |||
return fmt.Errorf(`authorized_keys is out of date and should be regenerated with "gitea admin regenerate keys" or "gitea doctor --run authorized_keys --fix"`) | |||
} | |||
logger.Warn("authorized_keys is out of date. Attempting rewrite...") | |||
err = models.RewriteAllPublicKeys() | |||
err = asymkey_model.RewriteAllPublicKeys() | |||
if err != nil { | |||
logger.Critical("Unable to rewrite authorized_keys file. ERROR: %v", err) | |||
return fmt.Errorf("Unable to rewrite authorized_keys file. ERROR: %v", err) |
@@ -10,6 +10,7 @@ import ( | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
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" | |||
@@ -113,9 +114,11 @@ func (graph *Graph) LoadAndProcessCommits(repository *repo_model.Repository, git | |||
} | |||
} | |||
c.Verification = models.ParseCommitWithSignature(c.Commit) | |||
c.Verification = asymkey_model.ParseCommitWithSignature(c.Commit) | |||
_ = models.CalculateTrustStatus(c.Verification, repository, &keyMap) | |||
_ = asymkey_model.CalculateTrustStatus(c.Verification, repository.GetTrustModel(), func(user *user_model.User) (bool, error) { | |||
return models.IsUserRepoAdmin(repository, user) | |||
}, &keyMap) | |||
statuses, err := models.GetLatestCommitStatus(repository.ID, c.Commit.ID.String(), db.ListOptions{}) | |||
if err != nil { | |||
@@ -236,7 +239,7 @@ func newRefsFromRefNames(refNames []byte) []git.Reference { | |||
type Commit struct { | |||
Commit *git.Commit | |||
User *user_model.User | |||
Verification *models.CommitVerification | |||
Verification *asymkey_model.CommitVerification | |||
Status *models.CommitStatus | |||
Flow int64 | |||
Row int |
@@ -10,7 +10,7 @@ import ( | |||
"net/http" | |||
"net/url" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/perm" | |||
user_model "code.gitea.io/gitea/models/user" | |||
"code.gitea.io/gitea/modules/json" | |||
@@ -19,12 +19,12 @@ import ( | |||
// KeyAndOwner is the response from ServNoCommand | |||
type KeyAndOwner struct { | |||
Key *models.PublicKey `json:"key"` | |||
Owner *user_model.User `json:"user"` | |||
Key *asymkey_model.PublicKey `json:"key"` | |||
Owner *user_model.User `json:"user"` | |||
} | |||
// ServNoCommand returns information about the provided key | |||
func ServNoCommand(ctx context.Context, keyID int64) (*models.PublicKey, *user_model.User, error) { | |||
func ServNoCommand(ctx context.Context, keyID int64) (*asymkey_model.PublicKey, *user_model.User, error) { | |||
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/serv/none/%d", | |||
keyID) | |||
resp, err := newInternalRequest(ctx, reqURL, "GET").Response() |
@@ -20,6 +20,7 @@ import ( | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/util" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
"github.com/unknwon/com" | |||
) | |||
@@ -134,7 +135,7 @@ func initRepoCommit(tmpPath string, repo *repo_model.Repository, u *user_model.U | |||
} | |||
if git.CheckGitVersionAtLeast("1.7.9") == nil { | |||
sign, keyID, signer, _ := models.SignInitialCommit(tmpPath, u) | |||
sign, keyID, signer, _ := asymkey_service.SignInitialCommit(tmpPath, u) | |||
if sign { | |||
args = append(args, "-S"+keyID) | |||
@@ -22,7 +22,7 @@ import ( | |||
"sync" | |||
"syscall" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/util" | |||
@@ -172,9 +172,9 @@ func publicKeyHandler(ctx ssh.Context, key ssh.PublicKey) bool { | |||
// look for the exact principal | |||
principalLoop: | |||
for _, principal := range cert.ValidPrincipals { | |||
pkey, err := models.SearchPublicKeyByContentExact(principal) | |||
pkey, err := asymkey_model.SearchPublicKeyByContentExact(principal) | |||
if err != nil { | |||
if models.IsErrKeyNotExist(err) { | |||
if asymkey_model.IsErrKeyNotExist(err) { | |||
log.Debug("Principal Rejected: %s Unknown Principal: %s", ctx.RemoteAddr(), principal) | |||
continue principalLoop | |||
} | |||
@@ -232,9 +232,9 @@ func publicKeyHandler(ctx ssh.Context, key ssh.PublicKey) bool { | |||
log.Debug("Handle Public Key: %s Fingerprint: %s is not a certificate", ctx.RemoteAddr(), gossh.FingerprintSHA256(key)) | |||
} | |||
pkey, err := models.SearchPublicKeyByContent(strings.TrimSpace(string(gossh.MarshalAuthorizedKey(key)))) | |||
pkey, err := asymkey_model.SearchPublicKeyByContent(strings.TrimSpace(string(gossh.MarshalAuthorizedKey(key)))) | |||
if err != nil { | |||
if models.IsErrKeyNotExist(err) { | |||
if asymkey_model.IsErrKeyNotExist(err) { | |||
if log.IsWarn() { | |||
log.Warn("Unknown public key: %s from %s", gossh.FingerprintSHA256(key), ctx.RemoteAddr()) | |||
log.Warn("Failed authentication attempt from %s", ctx.RemoteAddr()) |
@@ -12,6 +12,7 @@ import ( | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/db" | |||
"code.gitea.io/gitea/models/login" | |||
user_model "code.gitea.io/gitea/models/user" | |||
@@ -23,6 +24,7 @@ import ( | |||
"code.gitea.io/gitea/modules/web" | |||
"code.gitea.io/gitea/routers/api/v1/user" | |||
"code.gitea.io/gitea/routers/api/v1/utils" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
"code.gitea.io/gitea/services/mailer" | |||
user_service "code.gitea.io/gitea/services/user" | |||
) | |||
@@ -381,10 +383,10 @@ func DeleteUserPublicKey(ctx *context.APIContext) { | |||
return | |||
} | |||
if err := models.DeletePublicKey(u, ctx.ParamsInt64(":id")); err != nil { | |||
if models.IsErrKeyNotExist(err) { | |||
if err := asymkey_service.DeletePublicKey(u, ctx.ParamsInt64(":id")); err != nil { | |||
if asymkey_model.IsErrKeyNotExist(err) { | |||
ctx.NotFound() | |||
} else if models.IsErrKeyAccessDenied(err) { | |||
} else if asymkey_model.IsErrKeyAccessDenied(err) { | |||
ctx.Error(http.StatusForbidden, "", "You do not have access to this key") | |||
} else { | |||
ctx.Error(http.StatusInternalServerError, "DeleteUserPublicKey", err) |
@@ -8,8 +8,8 @@ import ( | |||
"fmt" | |||
"net/http" | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/context" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
) | |||
// SigningKey returns the public key of the default signing key if it exists | |||
@@ -52,7 +52,7 @@ func SigningKey(ctx *context.APIContext) { | |||
path = ctx.Repo.Repository.RepoPath() | |||
} | |||
content, err := models.PublicSigningKey(path) | |||
content, err := asymkey_service.PublicSigningKey(path) | |||
if err != nil { | |||
ctx.Error(http.StatusInternalServerError, "gpg export", err) | |||
return |
@@ -10,7 +10,8 @@ import ( | |||
"net/http" | |||
"net/url" | |||
"code.gitea.io/gitea/models" | |||
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" | |||
"code.gitea.io/gitea/modules/context" | |||
@@ -19,10 +20,11 @@ import ( | |||
api "code.gitea.io/gitea/modules/structs" | |||
"code.gitea.io/gitea/modules/web" | |||
"code.gitea.io/gitea/routers/api/v1/utils" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
) | |||
// appendPrivateInformation appends the owner and key type information to api.PublicKey | |||
func appendPrivateInformation(apiKey *api.DeployKey, key *models.DeployKey, repository *repo_model.Repository) (*api.DeployKey, error) { | |||
func appendPrivateInformation(apiKey *api.DeployKey, key *asymkey_model.DeployKey, repository *repo_model.Repository) (*api.DeployKey, error) { | |||
apiKey.ReadOnly = key.Mode == perm.AccessModeRead | |||
if repository.ID == key.RepoID { | |||
apiKey.Repository = convert.ToRepo(repository, key.Mode) | |||
@@ -78,20 +80,20 @@ func ListDeployKeys(ctx *context.APIContext) { | |||
// "200": | |||
// "$ref": "#/responses/DeployKeyList" | |||
opts := &models.ListDeployKeysOptions{ | |||
opts := &asymkey_model.ListDeployKeysOptions{ | |||
ListOptions: utils.GetListOptions(ctx), | |||
RepoID: ctx.Repo.Repository.ID, | |||
KeyID: ctx.FormInt64("key_id"), | |||
Fingerprint: ctx.FormString("fingerprint"), | |||
} | |||
keys, err := models.ListDeployKeys(opts) | |||
keys, err := asymkey_model.ListDeployKeys(db.DefaultContext, opts) | |||
if err != nil { | |||
ctx.InternalServerError(err) | |||
return | |||
} | |||
count, err := models.CountDeployKeys(opts) | |||
count, err := asymkey_model.CountDeployKeys(opts) | |||
if err != nil { | |||
ctx.InternalServerError(err) | |||
return | |||
@@ -142,9 +144,9 @@ func GetDeployKey(ctx *context.APIContext) { | |||
// "200": | |||
// "$ref": "#/responses/DeployKey" | |||
key, err := models.GetDeployKeyByID(ctx.ParamsInt64(":id")) | |||
key, err := asymkey_model.GetDeployKeyByID(db.DefaultContext, ctx.ParamsInt64(":id")) | |||
if err != nil { | |||
if models.IsErrDeployKeyNotExist(err) { | |||
if asymkey_model.IsErrDeployKeyNotExist(err) { | |||
ctx.NotFound() | |||
} else { | |||
ctx.Error(http.StatusInternalServerError, "GetDeployKeyByID", err) | |||
@@ -167,9 +169,9 @@ func GetDeployKey(ctx *context.APIContext) { | |||
// HandleCheckKeyStringError handle check key error | |||
func HandleCheckKeyStringError(ctx *context.APIContext, err error) { | |||
if models.IsErrSSHDisabled(err) { | |||
if db.IsErrSSHDisabled(err) { | |||
ctx.Error(http.StatusUnprocessableEntity, "", "SSH is disabled") | |||
} else if models.IsErrKeyUnableVerify(err) { | |||
} else if asymkey_model.IsErrKeyUnableVerify(err) { | |||
ctx.Error(http.StatusUnprocessableEntity, "", "Unable to verify key content") | |||
} else { | |||
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid key content: %v", err)) | |||
@@ -179,13 +181,13 @@ func HandleCheckKeyStringError(ctx *context.APIContext, err error) { | |||
// HandleAddKeyError handle add key error | |||
func HandleAddKeyError(ctx *context.APIContext, err error) { | |||
switch { | |||
case models.IsErrDeployKeyAlreadyExist(err): | |||
case asymkey_model.IsErrDeployKeyAlreadyExist(err): | |||
ctx.Error(http.StatusUnprocessableEntity, "", "This key has already been added to this repository") | |||
case models.IsErrKeyAlreadyExist(err): | |||
case asymkey_model.IsErrKeyAlreadyExist(err): | |||
ctx.Error(http.StatusUnprocessableEntity, "", "Key content has been used as non-deploy key") | |||
case models.IsErrKeyNameAlreadyUsed(err): | |||
case asymkey_model.IsErrKeyNameAlreadyUsed(err): | |||
ctx.Error(http.StatusUnprocessableEntity, "", "Key title has been used") | |||
case models.IsErrDeployKeyNameAlreadyUsed(err): | |||
case asymkey_model.IsErrDeployKeyNameAlreadyUsed(err): | |||
ctx.Error(http.StatusUnprocessableEntity, "", "A key with the same name already exists") | |||
default: | |||
ctx.Error(http.StatusInternalServerError, "AddKey", err) | |||
@@ -223,13 +225,13 @@ func CreateDeployKey(ctx *context.APIContext) { | |||
// "$ref": "#/responses/validationError" | |||
form := web.GetForm(ctx).(*api.CreateKeyOption) | |||
content, err := models.CheckPublicKeyString(form.Key) | |||
content, err := asymkey_model.CheckPublicKeyString(form.Key) | |||
if err != nil { | |||
HandleCheckKeyStringError(ctx, err) | |||
return | |||
} | |||
key, err := models.AddDeployKey(ctx.Repo.Repository.ID, form.Title, content, form.ReadOnly) | |||
key, err := asymkey_model.AddDeployKey(ctx.Repo.Repository.ID, form.Title, content, form.ReadOnly) | |||
if err != nil { | |||
HandleAddKeyError(ctx, err) | |||
return | |||
@@ -268,8 +270,8 @@ func DeleteDeploykey(ctx *context.APIContext) { | |||
// "403": | |||
// "$ref": "#/responses/forbidden" | |||
if err := models.DeleteDeployKey(ctx.User, ctx.ParamsInt64(":id")); err != nil { | |||
if models.IsErrKeyAccessDenied(err) { | |||
if err := asymkey_service.DeleteDeployKey(ctx.User, ctx.ParamsInt64(":id")); err != nil { | |||
if asymkey_model.IsErrKeyAccessDenied(err) { | |||
ctx.Error(http.StatusForbidden, "", "You do not have access to this key") | |||
} else { | |||
ctx.Error(http.StatusInternalServerError, "DeleteDeployKey", err) |
@@ -26,6 +26,7 @@ import ( | |||
"code.gitea.io/gitea/modules/timeutil" | |||
"code.gitea.io/gitea/modules/web" | |||
"code.gitea.io/gitea/routers/api/v1/utils" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
"code.gitea.io/gitea/services/forms" | |||
issue_service "code.gitea.io/gitea/services/issue" | |||
pull_service "code.gitea.io/gitea/services/pull" | |||
@@ -810,7 +811,7 @@ func MergePullRequest(ctx *context.APIContext) { | |||
} | |||
if _, err := pull_service.IsSignedIfRequired(pr, ctx.User); err != nil { | |||
if !models.IsErrWontSign(err) { | |||
if !asymkey_service.IsErrWontSign(err) { | |||
ctx.Error(http.StatusInternalServerError, "IsSignedIfRequired", err) | |||
return | |||
} |
@@ -1023,7 +1023,7 @@ func Delete(ctx *context.APIContext) { | |||
ctx.Repo.GitRepo.Close() | |||
} | |||
if err := repo_service.DeleteRepository(ctx.User, repo); err != nil { | |||
if err := repo_service.DeleteRepository(ctx.User, repo, true); err != nil { | |||
ctx.Error(http.StatusInternalServerError, "DeleteRepository", err) | |||
return | |||
} |
@@ -8,7 +8,7 @@ import ( | |||
"fmt" | |||
"net/http" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/db" | |||
"code.gitea.io/gitea/modules/context" | |||
"code.gitea.io/gitea/modules/convert" | |||
@@ -18,7 +18,7 @@ import ( | |||
) | |||
func listGPGKeys(ctx *context.APIContext, uid int64, listOptions db.ListOptions) { | |||
keys, err := models.ListGPGKeys(uid, listOptions) | |||
keys, err := asymkey_model.ListGPGKeys(db.DefaultContext, uid, listOptions) | |||
if err != nil { | |||
ctx.Error(http.StatusInternalServerError, "ListGPGKeys", err) | |||
return | |||
@@ -29,7 +29,7 @@ func listGPGKeys(ctx *context.APIContext, uid int64, listOptions db.ListOptions) | |||
apiKeys[i] = convert.ToGPGKey(keys[i]) | |||
} | |||
total, err := models.CountUserGPGKeys(uid) | |||
total, err := asymkey_model.CountUserGPGKeys(uid) | |||
if err != nil { | |||
ctx.InternalServerError(err) | |||
return | |||
@@ -114,9 +114,9 @@ func GetGPGKey(ctx *context.APIContext) { | |||
// "404": | |||
// "$ref": "#/responses/notFound" | |||
key, err := models.GetGPGKeyByID(ctx.ParamsInt64(":id")) | |||
key, err := asymkey_model.GetGPGKeyByID(ctx.ParamsInt64(":id")) | |||
if err != nil { | |||
if models.IsErrGPGKeyNotExist(err) { | |||
if asymkey_model.IsErrGPGKeyNotExist(err) { | |||
ctx.NotFound() | |||
} else { | |||
ctx.Error(http.StatusInternalServerError, "GetGPGKeyByID", err) | |||
@@ -128,12 +128,12 @@ func GetGPGKey(ctx *context.APIContext) { | |||
// CreateUserGPGKey creates new GPG key to given user by ID. | |||
func CreateUserGPGKey(ctx *context.APIContext, form api.CreateGPGKeyOption, uid int64) { | |||
token := models.VerificationToken(ctx.User, 1) | |||
lastToken := models.VerificationToken(ctx.User, 0) | |||
token := asymkey_model.VerificationToken(ctx.User, 1) | |||
lastToken := asymkey_model.VerificationToken(ctx.User, 0) | |||
keys, err := models.AddGPGKey(uid, form.ArmoredKey, token, form.Signature) | |||
if err != nil && models.IsErrGPGInvalidTokenSignature(err) { | |||
keys, err = models.AddGPGKey(uid, form.ArmoredKey, lastToken, form.Signature) | |||
keys, err := asymkey_model.AddGPGKey(uid, form.ArmoredKey, token, form.Signature) | |||
if err != nil && asymkey_model.IsErrGPGInvalidTokenSignature(err) { | |||
keys, err = asymkey_model.AddGPGKey(uid, form.ArmoredKey, lastToken, form.Signature) | |||
} | |||
if err != nil { | |||
HandleAddGPGKeyError(ctx, err, token) | |||
@@ -156,7 +156,7 @@ func GetVerificationToken(ctx *context.APIContext) { | |||
// "404": | |||
// "$ref": "#/responses/notFound" | |||
token := models.VerificationToken(ctx.User, 1) | |||
token := asymkey_model.VerificationToken(ctx.User, 1) | |||
ctx.PlainText(http.StatusOK, []byte(token)) | |||
} | |||
@@ -178,25 +178,25 @@ func VerifyUserGPGKey(ctx *context.APIContext) { | |||
// "$ref": "#/responses/validationError" | |||
form := web.GetForm(ctx).(*api.VerifyGPGKeyOption) | |||
token := models.VerificationToken(ctx.User, 1) | |||
lastToken := models.VerificationToken(ctx.User, 0) | |||
token := asymkey_model.VerificationToken(ctx.User, 1) | |||
lastToken := asymkey_model.VerificationToken(ctx.User, 0) | |||
_, err := models.VerifyGPGKey(ctx.User.ID, form.KeyID, token, form.Signature) | |||
if err != nil && models.IsErrGPGInvalidTokenSignature(err) { | |||
_, err = models.VerifyGPGKey(ctx.User.ID, form.KeyID, lastToken, form.Signature) | |||
_, err := asymkey_model.VerifyGPGKey(ctx.User.ID, form.KeyID, token, form.Signature) | |||
if err != nil && asymkey_model.IsErrGPGInvalidTokenSignature(err) { | |||
_, err = asymkey_model.VerifyGPGKey(ctx.User.ID, form.KeyID, lastToken, form.Signature) | |||
} | |||
if err != nil { | |||
if models.IsErrGPGInvalidTokenSignature(err) { | |||
if asymkey_model.IsErrGPGInvalidTokenSignature(err) { | |||
ctx.Error(http.StatusUnprocessableEntity, "GPGInvalidSignature", fmt.Sprintf("The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: %s", token)) | |||
return | |||
} | |||
ctx.Error(http.StatusInternalServerError, "VerifyUserGPGKey", err) | |||
} | |||
key, err := models.GetGPGKeysByKeyID(form.KeyID) | |||
key, err := asymkey_model.GetGPGKeysByKeyID(form.KeyID) | |||
if err != nil { | |||
if models.IsErrGPGKeyNotExist(err) { | |||
if asymkey_model.IsErrGPGKeyNotExist(err) { | |||
ctx.NotFound() | |||
} else { | |||
ctx.Error(http.StatusInternalServerError, "GetGPGKeysByKeyID", err) | |||
@@ -255,8 +255,8 @@ func DeleteGPGKey(ctx *context.APIContext) { | |||
// "404": | |||
// "$ref": "#/responses/notFound" | |||
if err := models.DeleteGPGKey(ctx.User, ctx.ParamsInt64(":id")); err != nil { | |||
if models.IsErrGPGKeyAccessDenied(err) { | |||
if err := asymkey_model.DeleteGPGKey(ctx.User, ctx.ParamsInt64(":id")); err != nil { | |||
if asymkey_model.IsErrGPGKeyAccessDenied(err) { | |||
ctx.Error(http.StatusForbidden, "", "You do not have access to this key") | |||
} else { | |||
ctx.Error(http.StatusInternalServerError, "DeleteGPGKey", err) | |||
@@ -270,15 +270,15 @@ func DeleteGPGKey(ctx *context.APIContext) { | |||
// HandleAddGPGKeyError handle add GPGKey error | |||
func HandleAddGPGKeyError(ctx *context.APIContext, err error, token string) { | |||
switch { | |||
case models.IsErrGPGKeyAccessDenied(err): | |||
case asymkey_model.IsErrGPGKeyAccessDenied(err): | |||
ctx.Error(http.StatusUnprocessableEntity, "GPGKeyAccessDenied", "You do not have access to this GPG key") | |||
case models.IsErrGPGKeyIDAlreadyUsed(err): | |||
case asymkey_model.IsErrGPGKeyIDAlreadyUsed(err): | |||
ctx.Error(http.StatusUnprocessableEntity, "GPGKeyIDAlreadyUsed", "A key with the same id already exists") | |||
case models.IsErrGPGKeyParsing(err): | |||
case asymkey_model.IsErrGPGKeyParsing(err): | |||
ctx.Error(http.StatusUnprocessableEntity, "GPGKeyParsing", err) | |||
case models.IsErrGPGNoEmailFound(err): | |||
case asymkey_model.IsErrGPGNoEmailFound(err): | |||
ctx.Error(http.StatusNotFound, "GPGNoEmailFound", fmt.Sprintf("None of the emails attached to the GPG key could be found. It may still be added if you provide a valid signature for the token: %s", token)) | |||
case models.IsErrGPGInvalidTokenSignature(err): | |||
case asymkey_model.IsErrGPGInvalidTokenSignature(err): | |||
ctx.Error(http.StatusUnprocessableEntity, "GPGInvalidSignature", fmt.Sprintf("The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: %s", token)) | |||
default: | |||
ctx.Error(http.StatusInternalServerError, "AddGPGKey", err) |
@@ -7,7 +7,7 @@ package user | |||
import ( | |||
"net/http" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/perm" | |||
user_model "code.gitea.io/gitea/models/user" | |||
"code.gitea.io/gitea/modules/context" | |||
@@ -17,13 +17,14 @@ import ( | |||
"code.gitea.io/gitea/modules/web" | |||
"code.gitea.io/gitea/routers/api/v1/repo" | |||
"code.gitea.io/gitea/routers/api/v1/utils" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
) | |||
// appendPrivateInformation appends the owner and key type information to api.PublicKey | |||
func appendPrivateInformation(apiKey *api.PublicKey, key *models.PublicKey, defaultUser *user_model.User) (*api.PublicKey, error) { | |||
if key.Type == models.KeyTypeDeploy { | |||
func appendPrivateInformation(apiKey *api.PublicKey, key *asymkey_model.PublicKey, defaultUser *user_model.User) (*api.PublicKey, error) { | |||
if key.Type == asymkey_model.KeyTypeDeploy { | |||
apiKey.KeyType = "deploy" | |||
} else if key.Type == models.KeyTypeUser { | |||
} else if key.Type == asymkey_model.KeyTypeUser { | |||
apiKey.KeyType = "user" | |||
if defaultUser.ID == key.OwnerID { | |||
@@ -47,7 +48,7 @@ func composePublicKeysAPILink() string { | |||
} | |||
func listPublicKeys(ctx *context.APIContext, user *user_model.User) { | |||
var keys []*models.PublicKey | |||
var keys []*asymkey_model.PublicKey | |||
var err error | |||
var count int | |||
@@ -58,14 +59,14 @@ func listPublicKeys(ctx *context.APIContext, user *user_model.User) { | |||
// Querying not just listing | |||
if username != "" { | |||
// Restrict to provided uid | |||
keys, err = models.SearchPublicKey(user.ID, fingerprint) | |||
keys, err = asymkey_model.SearchPublicKey(user.ID, fingerprint) | |||
} else { | |||
// Unrestricted | |||
keys, err = models.SearchPublicKey(0, fingerprint) | |||
keys, err = asymkey_model.SearchPublicKey(0, fingerprint) | |||
} | |||
count = len(keys) | |||
} else { | |||
total, err2 := models.CountPublicKeys(user.ID) | |||
total, err2 := asymkey_model.CountPublicKeys(user.ID) | |||
if err2 != nil { | |||
ctx.InternalServerError(err) | |||
return | |||
@@ -73,7 +74,7 @@ func listPublicKeys(ctx *context.APIContext, user *user_model.User) { | |||
count = int(total) | |||
// Use ListPublicKeys | |||
keys, err = models.ListPublicKeys(user.ID, utils.GetListOptions(ctx)) | |||
keys, err = asymkey_model.ListPublicKeys(user.ID, utils.GetListOptions(ctx)) | |||
} | |||
if err != nil { | |||
@@ -177,9 +178,9 @@ func GetPublicKey(ctx *context.APIContext) { | |||
// "404": | |||
// "$ref": "#/responses/notFound" | |||
key, err := models.GetPublicKeyByID(ctx.ParamsInt64(":id")) | |||
key, err := asymkey_model.GetPublicKeyByID(ctx.ParamsInt64(":id")) | |||
if err != nil { | |||
if models.IsErrKeyNotExist(err) { | |||
if asymkey_model.IsErrKeyNotExist(err) { | |||
ctx.NotFound() | |||
} else { | |||
ctx.Error(http.StatusInternalServerError, "GetPublicKeyByID", err) | |||
@@ -197,13 +198,13 @@ func GetPublicKey(ctx *context.APIContext) { | |||
// CreateUserPublicKey creates new public key to given user by ID. | |||
func CreateUserPublicKey(ctx *context.APIContext, form api.CreateKeyOption, uid int64) { | |||
content, err := models.CheckPublicKeyString(form.Key) | |||
content, err := asymkey_model.CheckPublicKeyString(form.Key) | |||
if err != nil { | |||
repo.HandleCheckKeyStringError(ctx, err) | |||
return | |||
} | |||
key, err := models.AddPublicKey(uid, form.Title, content, 0) | |||
key, err := asymkey_model.AddPublicKey(uid, form.Title, content, 0) | |||
if err != nil { | |||
repo.HandleAddKeyError(ctx, err) | |||
return | |||
@@ -263,7 +264,7 @@ func DeletePublicKey(ctx *context.APIContext) { | |||
// "$ref": "#/responses/notFound" | |||
id := ctx.ParamsInt64(":id") | |||
externallyManaged, err := models.PublicKeyIsExternallyManaged(id) | |||
externallyManaged, err := asymkey_model.PublicKeyIsExternallyManaged(id) | |||
if err != nil { | |||
ctx.Error(http.StatusInternalServerError, "PublicKeyIsExternallyManaged", err) | |||
} | |||
@@ -271,10 +272,10 @@ func DeletePublicKey(ctx *context.APIContext) { | |||
ctx.Error(http.StatusForbidden, "", "SSH Key is externally managed for this user") | |||
} | |||
if err := models.DeletePublicKey(ctx.User, id); err != nil { | |||
if models.IsErrKeyNotExist(err) { | |||
if err := asymkey_service.DeletePublicKey(ctx.User, id); err != nil { | |||
if asymkey_model.IsErrKeyNotExist(err) { | |||
ctx.NotFound() | |||
} else if models.IsErrKeyAccessDenied(err) { | |||
} else if asymkey_model.IsErrKeyAccessDenied(err) { | |||
ctx.Error(http.StatusForbidden, "", "You do not have access to this key") | |||
} else { | |||
ctx.Error(http.StatusInternalServerError, "DeletePublicKey", err) |
@@ -13,6 +13,7 @@ import ( | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/modules/appstate" | |||
"code.gitea.io/gitea/modules/cache" | |||
"code.gitea.io/gitea/modules/eventsource" | |||
@@ -87,7 +88,7 @@ func syncAppPathForGit(ctx context.Context) error { | |||
mustInitCtx(ctx, repo_service.SyncRepositoryHooks) | |||
log.Info("re-write ssh public keys ...") | |||
mustInit(models.RewriteAllPublicKeys) | |||
mustInit(asymkey_model.RewriteAllPublicKeys) | |||
runtimeState.LastAppPath = setting.AppPath | |||
return appstate.AppState.Set(runtimeState) |
@@ -12,7 +12,7 @@ import ( | |||
"io" | |||
"os" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/log" | |||
) | |||
@@ -97,7 +97,7 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error { | |||
if err != nil { | |||
return err | |||
} | |||
verification := models.ParseCommitWithSignature(commit) | |||
verification := asymkey_model.ParseCommitWithSignature(commit) | |||
if !verification.Verified { | |||
cancel() | |||
return &errUnverifiedCommit{ |
@@ -8,7 +8,7 @@ package private | |||
import ( | |||
"net/http" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/modules/context" | |||
"code.gitea.io/gitea/modules/private" | |||
"code.gitea.io/gitea/modules/timeutil" | |||
@@ -18,16 +18,16 @@ import ( | |||
func UpdatePublicKeyInRepo(ctx *context.PrivateContext) { | |||
keyID := ctx.ParamsInt64(":id") | |||
repoID := ctx.ParamsInt64(":repoid") | |||
if err := models.UpdatePublicKeyUpdated(keyID); err != nil { | |||
if err := asymkey_model.UpdatePublicKeyUpdated(keyID); err != nil { | |||
ctx.JSON(http.StatusInternalServerError, private.Response{ | |||
Err: err.Error(), | |||
}) | |||
return | |||
} | |||
deployKey, err := models.GetDeployKeyByRepo(keyID, repoID) | |||
deployKey, err := asymkey_model.GetDeployKeyByRepo(keyID, repoID) | |||
if err != nil { | |||
if models.IsErrDeployKeyNotExist(err) { | |||
if asymkey_model.IsErrDeployKeyNotExist(err) { | |||
ctx.PlainText(http.StatusOK, []byte("success")) | |||
return | |||
} | |||
@@ -37,7 +37,7 @@ func UpdatePublicKeyInRepo(ctx *context.PrivateContext) { | |||
return | |||
} | |||
deployKey.UpdatedUnix = timeutil.TimeStampNow() | |||
if err = models.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil { | |||
if err = asymkey_model.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil { | |||
ctx.JSON(http.StatusInternalServerError, private.Response{ | |||
Err: err.Error(), | |||
}) | |||
@@ -52,7 +52,7 @@ func UpdatePublicKeyInRepo(ctx *context.PrivateContext) { | |||
func AuthorizedPublicKeyByContent(ctx *context.PrivateContext) { | |||
content := ctx.FormString("content") | |||
publicKey, err := models.SearchPublicKeyByContent(content) | |||
publicKey, err := asymkey_model.SearchPublicKeyByContent(content) | |||
if err != nil { | |||
ctx.JSON(http.StatusInternalServerError, private.Response{ | |||
Err: err.Error(), |
@@ -11,6 +11,7 @@ import ( | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/perm" | |||
repo_model "code.gitea.io/gitea/models/repo" | |||
"code.gitea.io/gitea/models/unit" | |||
@@ -34,9 +35,9 @@ func ServNoCommand(ctx *context.PrivateContext) { | |||
} | |||
results := private.KeyAndOwner{} | |||
key, err := models.GetPublicKeyByID(keyID) | |||
key, err := asymkey_model.GetPublicKeyByID(keyID) | |||
if err != nil { | |||
if models.IsErrKeyNotExist(err) { | |||
if asymkey_model.IsErrKeyNotExist(err) { | |||
ctx.JSON(http.StatusUnauthorized, private.Response{ | |||
Err: fmt.Sprintf("Cannot find key: %d", keyID), | |||
}) | |||
@@ -50,7 +51,7 @@ func ServNoCommand(ctx *context.PrivateContext) { | |||
} | |||
results.Key = key | |||
if key.Type == models.KeyTypeUser || key.Type == models.KeyTypePrincipal { | |||
if key.Type == asymkey_model.KeyTypeUser || key.Type == asymkey_model.KeyTypePrincipal { | |||
user, err := user_model.GetUserByID(key.OwnerID) | |||
if err != nil { | |||
if user_model.IsErrUserNotExist(err) { | |||
@@ -184,9 +185,9 @@ func ServCommand(ctx *context.PrivateContext) { | |||
} | |||
// Get the Public Key represented by the keyID | |||
key, err := models.GetPublicKeyByID(keyID) | |||
key, err := asymkey_model.GetPublicKeyByID(keyID) | |||
if err != nil { | |||
if models.IsErrKeyNotExist(err) { | |||
if asymkey_model.IsErrKeyNotExist(err) { | |||
ctx.JSON(http.StatusNotFound, private.ErrServCommand{ | |||
Results: results, | |||
Err: fmt.Sprintf("Cannot find key: %d", keyID), | |||
@@ -205,7 +206,7 @@ func ServCommand(ctx *context.PrivateContext) { | |||
results.UserID = key.OwnerID | |||
// If repo doesn't exist, deploy key doesn't make sense | |||
if !repoExist && key.Type == models.KeyTypeDeploy { | |||
if !repoExist && key.Type == asymkey_model.KeyTypeDeploy { | |||
ctx.JSON(http.StatusNotFound, private.ErrServCommand{ | |||
Results: results, | |||
Err: fmt.Sprintf("Cannot find repository %s/%s", results.OwnerName, results.RepoName), | |||
@@ -216,15 +217,15 @@ func ServCommand(ctx *context.PrivateContext) { | |||
// Deploy Keys have ownerID set to 0 therefore we can't use the owner | |||
// So now we need to check if the key is a deploy key | |||
// We'll keep hold of the deploy key here for permissions checking | |||
var deployKey *models.DeployKey | |||
var deployKey *asymkey_model.DeployKey | |||
var user *user_model.User | |||
if key.Type == models.KeyTypeDeploy { | |||
if key.Type == asymkey_model.KeyTypeDeploy { | |||
results.IsDeployKey = true | |||
var err error | |||
deployKey, err = models.GetDeployKeyByRepo(key.ID, repo.ID) | |||
deployKey, err = asymkey_model.GetDeployKeyByRepo(key.ID, repo.ID) | |||
if err != nil { | |||
if models.IsErrDeployKeyNotExist(err) { | |||
if asymkey_model.IsErrDeployKeyNotExist(err) { | |||
ctx.JSON(http.StatusNotFound, private.ErrServCommand{ | |||
Results: results, | |||
Err: fmt.Sprintf("Public (Deploy) Key: %d:%s is not authorized to %s %s/%s.", key.ID, key.Name, modeString, results.OwnerName, results.RepoName), | |||
@@ -297,7 +298,7 @@ func ServCommand(ctx *context.PrivateContext) { | |||
owner.Visibility.IsPrivate() || | |||
(user != nil && user.IsRestricted) || // user will be nil if the key is a deploykey | |||
setting.Service.RequireSignInView) { | |||
if key.Type == models.KeyTypeDeploy { | |||
if key.Type == asymkey_model.KeyTypeDeploy { | |||
if deployKey.Mode < mode { | |||
ctx.JSON(http.StatusUnauthorized, private.ErrServCommand{ | |||
Results: results, |
@@ -52,7 +52,7 @@ func DeleteRepo(ctx *context.Context) { | |||
ctx.Repo.GitRepo.Close() | |||
} | |||
if err := repo_service.DeleteRepository(ctx.User, repo); err != nil { | |||
if err := repo_service.DeleteRepository(ctx.User, repo, true); err != nil { | |||
ctx.ServerError("DeleteRepository", err) | |||
return | |||
} |
@@ -11,6 +11,7 @@ import ( | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
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" | |||
@@ -344,13 +345,15 @@ func Diff(ctx *context.Context) { | |||
ctx.Data["CommitStatus"] = models.CalcCommitStatus(statuses) | |||
ctx.Data["CommitStatuses"] = statuses | |||
verification := models.ParseCommitWithSignature(commit) | |||
verification := asymkey_model.ParseCommitWithSignature(commit) | |||
ctx.Data["Verification"] = verification | |||
ctx.Data["Author"] = user_model.ValidateCommitWithEmail(commit) | |||
ctx.Data["Parents"] = parents | |||
ctx.Data["DiffNotAvailable"] = diff.NumFiles == 0 | |||
if err := models.CalculateTrustStatus(verification, ctx.Repo.Repository, nil); err != nil { | |||
if err := asymkey_model.CalculateTrustStatus(verification, ctx.Repo.Repository.GetTrustModel(), func(user *user_model.User) (bool, error) { | |||
return models.IsUserRepoAdmin(ctx.Repo.Repository, user) | |||
}, nil); err != nil { | |||
ctx.ServerError("CalculateTrustStatus", err) | |||
return | |||
} |
@@ -34,6 +34,7 @@ import ( | |||
"code.gitea.io/gitea/modules/upload" | |||
"code.gitea.io/gitea/modules/util" | |||
"code.gitea.io/gitea/modules/web" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
comment_service "code.gitea.io/gitea/services/comments" | |||
"code.gitea.io/gitea/services/forms" | |||
issue_service "code.gitea.io/gitea/services/issue" | |||
@@ -1583,12 +1584,12 @@ func ViewIssue(ctx *context.Context) { | |||
} | |||
ctx.Data["WillSign"] = false | |||
if ctx.User != nil { | |||
sign, key, _, err := pull.SignMerge(ctx.User, pull.BaseRepo.RepoPath(), pull.BaseBranch, pull.GetGitRefName()) | |||
sign, key, _, err := asymkey_service.SignMerge(pull, ctx.User, pull.BaseRepo.RepoPath(), pull.BaseBranch, pull.GetGitRefName()) | |||
ctx.Data["WillSign"] = sign | |||
ctx.Data["SigningKey"] = key | |||
if err != nil { | |||
if models.IsErrWontSign(err) { | |||
ctx.Data["WontSignReason"] = err.(*models.ErrWontSign).Reason | |||
if asymkey_service.IsErrWontSign(err) { | |||
ctx.Data["WontSignReason"] = err.(*asymkey_service.ErrWontSign).Reason | |||
} else { | |||
ctx.Data["WontSignReason"] = "error" | |||
log.Error("Error whilst checking if could sign pr %d in repo %s. Error: %v", pull.ID, pull.BaseRepo.FullName(), err) |
@@ -15,6 +15,7 @@ import ( | |||
"time" | |||
"code.gitea.io/gitea/models" | |||
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" | |||
@@ -34,6 +35,7 @@ import ( | |||
"code.gitea.io/gitea/modules/validation" | |||
"code.gitea.io/gitea/modules/web" | |||
"code.gitea.io/gitea/routers/utils" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
"code.gitea.io/gitea/services/forms" | |||
"code.gitea.io/gitea/services/mailer" | |||
"code.gitea.io/gitea/services/migrations" | |||
@@ -62,7 +64,7 @@ func Settings(ctx *context.Context) { | |||
ctx.Data["DisableNewPushMirrors"] = setting.Mirror.DisableNewPush | |||
ctx.Data["DefaultMirrorInterval"] = setting.Mirror.DefaultInterval | |||
signing, _ := models.SigningKey(ctx.Repo.Repository.RepoPath()) | |||
signing, _ := asymkey_service.SigningKey(ctx.Repo.Repository.RepoPath()) | |||
ctx.Data["SigningKeyAvailable"] = len(signing) > 0 | |||
ctx.Data["SigningSettings"] = setting.Repository.Signing | |||
pushMirrors, err := repo_model.GetPushMirrorsByRepoID(ctx.Repo.Repository.ID) | |||
@@ -476,7 +478,6 @@ func SettingsPost(ctx *context.Context) { | |||
case "signing": | |||
changed := false | |||
trustModel := repo_model.ToTrustModel(form.TrustModel) | |||
if trustModel != repo.TrustModel { | |||
repo.TrustModel = trustModel | |||
@@ -673,7 +674,7 @@ func SettingsPost(ctx *context.Context) { | |||
ctx.Repo.GitRepo.Close() | |||
} | |||
if err := repo_service.DeleteRepository(ctx.User, ctx.Repo.Repository); err != nil { | |||
if err := repo_service.DeleteRepository(ctx.User, ctx.Repo.Repository, true); err != nil { | |||
ctx.ServerError("DeleteRepository", err) | |||
return | |||
} | |||
@@ -1029,7 +1030,7 @@ func DeployKeys(ctx *context.Context) { | |||
ctx.Data["PageIsSettingsKeys"] = true | |||
ctx.Data["DisableSSH"] = setting.SSH.Disabled | |||
keys, err := models.ListDeployKeys(&models.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID}) | |||
keys, err := asymkey_model.ListDeployKeys(db.DefaultContext, &asymkey_model.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID}) | |||
if err != nil { | |||
ctx.ServerError("ListDeployKeys", err) | |||
return | |||
@@ -1045,7 +1046,7 @@ func DeployKeysPost(ctx *context.Context) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.deploy_keys") | |||
ctx.Data["PageIsSettingsKeys"] = true | |||
keys, err := models.ListDeployKeys(&models.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID}) | |||
keys, err := asymkey_model.ListDeployKeys(db.DefaultContext, &asymkey_model.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID}) | |||
if err != nil { | |||
ctx.ServerError("ListDeployKeys", err) | |||
return | |||
@@ -1057,11 +1058,11 @@ func DeployKeysPost(ctx *context.Context) { | |||
return | |||
} | |||
content, err := models.CheckPublicKeyString(form.Content) | |||
content, err := asymkey_model.CheckPublicKeyString(form.Content) | |||
if err != nil { | |||
if models.IsErrSSHDisabled(err) { | |||
if db.IsErrSSHDisabled(err) { | |||
ctx.Flash.Info(ctx.Tr("settings.ssh_disabled")) | |||
} else if models.IsErrKeyUnableVerify(err) { | |||
} else if asymkey_model.IsErrKeyUnableVerify(err) { | |||
ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key")) | |||
} else { | |||
ctx.Data["HasError"] = true | |||
@@ -1072,20 +1073,20 @@ func DeployKeysPost(ctx *context.Context) { | |||
return | |||
} | |||
key, err := models.AddDeployKey(ctx.Repo.Repository.ID, form.Title, content, !form.IsWritable) | |||
key, err := asymkey_model.AddDeployKey(ctx.Repo.Repository.ID, form.Title, content, !form.IsWritable) | |||
if err != nil { | |||
ctx.Data["HasError"] = true | |||
switch { | |||
case models.IsErrDeployKeyAlreadyExist(err): | |||
case asymkey_model.IsErrDeployKeyAlreadyExist(err): | |||
ctx.Data["Err_Content"] = true | |||
ctx.RenderWithErr(ctx.Tr("repo.settings.key_been_used"), tplDeployKeys, &form) | |||
case models.IsErrKeyAlreadyExist(err): | |||
case asymkey_model.IsErrKeyAlreadyExist(err): | |||
ctx.Data["Err_Content"] = true | |||
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_been_used"), tplDeployKeys, &form) | |||
case models.IsErrKeyNameAlreadyUsed(err): | |||
case asymkey_model.IsErrKeyNameAlreadyUsed(err): | |||
ctx.Data["Err_Title"] = true | |||
ctx.RenderWithErr(ctx.Tr("repo.settings.key_name_used"), tplDeployKeys, &form) | |||
case models.IsErrDeployKeyNameAlreadyUsed(err): | |||
case asymkey_model.IsErrDeployKeyNameAlreadyUsed(err): | |||
ctx.Data["Err_Title"] = true | |||
ctx.RenderWithErr(ctx.Tr("repo.settings.key_name_used"), tplDeployKeys, &form) | |||
default: | |||
@@ -1101,7 +1102,7 @@ func DeployKeysPost(ctx *context.Context) { | |||
// DeleteDeployKey response for deleting a deploy key | |||
func DeleteDeployKey(ctx *context.Context) { | |||
if err := models.DeleteDeployKey(ctx.User, ctx.FormInt64("id")); err != nil { | |||
if err := asymkey_service.DeleteDeployKey(ctx.User, ctx.FormInt64("id")); err != nil { | |||
ctx.Flash.Error("DeleteDeployKey: " + err.Error()) | |||
} else { | |||
ctx.Flash.Success(ctx.Tr("repo.settings.deploy_key_deletion_success")) |
@@ -10,6 +10,7 @@ import ( | |||
"testing" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/perm" | |||
repo_model "code.gitea.io/gitea/models/repo" | |||
"code.gitea.io/gitea/models/unittest" | |||
@@ -61,7 +62,7 @@ func TestAddReadOnlyDeployKey(t *testing.T) { | |||
DeployKeysPost(ctx) | |||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status()) | |||
unittest.AssertExistsAndLoadBean(t, &models.DeployKey{ | |||
unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{ | |||
Name: addKeyForm.Title, | |||
Content: addKeyForm.Content, | |||
Mode: perm.AccessModeRead, | |||
@@ -91,7 +92,7 @@ func TestAddReadWriteOnlyDeployKey(t *testing.T) { | |||
DeployKeysPost(ctx) | |||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status()) | |||
unittest.AssertExistsAndLoadBean(t, &models.DeployKey{ | |||
unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{ | |||
Name: addKeyForm.Title, | |||
Content: addKeyForm.Content, | |||
Mode: perm.AccessModeWrite, |
@@ -20,6 +20,7 @@ import ( | |||
"time" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/db" | |||
repo_model "code.gitea.io/gitea/models/repo" | |||
unit_model "code.gitea.io/gitea/models/unit" | |||
@@ -777,9 +778,11 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri | |||
ctx.Data["LatestCommit"] = latestCommit | |||
if latestCommit != nil { | |||
verification := models.ParseCommitWithSignature(latestCommit) | |||
verification := asymkey_model.ParseCommitWithSignature(latestCommit) | |||
if err := models.CalculateTrustStatus(verification, ctx.Repo.Repository, nil); err != nil { | |||
if err := asymkey_model.CalculateTrustStatus(verification, ctx.Repo.Repository.GetTrustModel(), func(user *user_model.User) (bool, error) { | |||
return models.IsUserRepoAdmin(ctx.Repo.Repository, user) | |||
}, nil); err != nil { | |||
ctx.ServerError("CalculateTrustStatus", err) | |||
return nil | |||
} |
@@ -15,6 +15,7 @@ import ( | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
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" | |||
@@ -827,7 +828,7 @@ func repoIDMap(ctxUser *user_model.User, issueCountByRepo map[int64]int64, unitT | |||
// ShowSSHKeys output all the ssh keys of user by uid | |||
func ShowSSHKeys(ctx *context.Context, uid int64) { | |||
keys, err := models.ListPublicKeys(uid, db.ListOptions{}) | |||
keys, err := asymkey_model.ListPublicKeys(uid, db.ListOptions{}) | |||
if err != nil { | |||
ctx.ServerError("ListPublicKeys", err) | |||
return | |||
@@ -843,7 +844,7 @@ func ShowSSHKeys(ctx *context.Context, uid int64) { | |||
// ShowGPGKeys output all the public GPG keys of user by uid | |||
func ShowGPGKeys(ctx *context.Context, uid int64) { | |||
keys, err := models.ListGPGKeys(uid, db.ListOptions{}) | |||
keys, err := asymkey_model.ListGPGKeys(db.DefaultContext, uid, db.ListOptions{}) | |||
if err != nil { | |||
ctx.ServerError("ListGPGKeys", err) | |||
return | |||
@@ -851,9 +852,9 @@ func ShowGPGKeys(ctx *context.Context, uid int64) { | |||
entities := make([]*openpgp.Entity, 0) | |||
failedEntitiesID := make([]string, 0) | |||
for _, k := range keys { | |||
e, err := models.GPGKeyToEntity(k) | |||
e, err := asymkey_model.GPGKeyToEntity(k) | |||
if err != nil { | |||
if models.IsErrGPGKeyImportNotExist(err) { | |||
if asymkey_model.IsErrGPGKeyImportNotExist(err) { | |||
failedEntitiesID = append(failedEntitiesID, k.KeyID) | |||
continue //Skip previous import without backup of imported armored key | |||
} |
@@ -8,12 +8,13 @@ package setting | |||
import ( | |||
"net/http" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/db" | |||
"code.gitea.io/gitea/modules/base" | |||
"code.gitea.io/gitea/modules/context" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/web" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
"code.gitea.io/gitea/services/forms" | |||
) | |||
@@ -51,9 +52,9 @@ func KeysPost(ctx *context.Context) { | |||
} | |||
switch form.Type { | |||
case "principal": | |||
content, err := models.CheckPrincipalKeyString(ctx.User, form.Content) | |||
content, err := asymkey_model.CheckPrincipalKeyString(ctx.User, form.Content) | |||
if err != nil { | |||
if models.IsErrSSHDisabled(err) { | |||
if db.IsErrSSHDisabled(err) { | |||
ctx.Flash.Info(ctx.Tr("settings.ssh_disabled")) | |||
} else { | |||
ctx.Flash.Error(ctx.Tr("form.invalid_ssh_principal", err.Error())) | |||
@@ -61,10 +62,10 @@ func KeysPost(ctx *context.Context) { | |||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys") | |||
return | |||
} | |||
if _, err = models.AddPrincipalKey(ctx.User.ID, content, 0); err != nil { | |||
if _, err = asymkey_model.AddPrincipalKey(ctx.User.ID, content, 0); err != nil { | |||
ctx.Data["HasPrincipalError"] = true | |||
switch { | |||
case models.IsErrKeyAlreadyExist(err), models.IsErrKeyNameAlreadyUsed(err): | |||
case asymkey_model.IsErrKeyAlreadyExist(err), asymkey_model.IsErrKeyNameAlreadyUsed(err): | |||
loadKeysData(ctx) | |||
ctx.Data["Err_Content"] = true | |||
@@ -77,36 +78,36 @@ func KeysPost(ctx *context.Context) { | |||
ctx.Flash.Success(ctx.Tr("settings.add_principal_success", form.Content)) | |||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys") | |||
case "gpg": | |||
token := models.VerificationToken(ctx.User, 1) | |||
lastToken := models.VerificationToken(ctx.User, 0) | |||
token := asymkey_model.VerificationToken(ctx.User, 1) | |||
lastToken := asymkey_model.VerificationToken(ctx.User, 0) | |||
keys, err := models.AddGPGKey(ctx.User.ID, form.Content, token, form.Signature) | |||
if err != nil && models.IsErrGPGInvalidTokenSignature(err) { | |||
keys, err = models.AddGPGKey(ctx.User.ID, form.Content, lastToken, form.Signature) | |||
keys, err := asymkey_model.AddGPGKey(ctx.User.ID, form.Content, token, form.Signature) | |||
if err != nil && asymkey_model.IsErrGPGInvalidTokenSignature(err) { | |||
keys, err = asymkey_model.AddGPGKey(ctx.User.ID, form.Content, lastToken, form.Signature) | |||
} | |||
if err != nil { | |||
ctx.Data["HasGPGError"] = true | |||
switch { | |||
case models.IsErrGPGKeyParsing(err): | |||
case asymkey_model.IsErrGPGKeyParsing(err): | |||
ctx.Flash.Error(ctx.Tr("form.invalid_gpg_key", err.Error())) | |||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys") | |||
case models.IsErrGPGKeyIDAlreadyUsed(err): | |||
case asymkey_model.IsErrGPGKeyIDAlreadyUsed(err): | |||
loadKeysData(ctx) | |||
ctx.Data["Err_Content"] = true | |||
ctx.RenderWithErr(ctx.Tr("settings.gpg_key_id_used"), tplSettingsKeys, &form) | |||
case models.IsErrGPGInvalidTokenSignature(err): | |||
case asymkey_model.IsErrGPGInvalidTokenSignature(err): | |||
loadKeysData(ctx) | |||
ctx.Data["Err_Content"] = true | |||
ctx.Data["Err_Signature"] = true | |||
ctx.Data["KeyID"] = err.(models.ErrGPGInvalidTokenSignature).ID | |||
ctx.Data["KeyID"] = err.(asymkey_model.ErrGPGInvalidTokenSignature).ID | |||
ctx.RenderWithErr(ctx.Tr("settings.gpg_invalid_token_signature"), tplSettingsKeys, &form) | |||
case models.IsErrGPGNoEmailFound(err): | |||
case asymkey_model.IsErrGPGNoEmailFound(err): | |||
loadKeysData(ctx) | |||
ctx.Data["Err_Content"] = true | |||
ctx.Data["Err_Signature"] = true | |||
ctx.Data["KeyID"] = err.(models.ErrGPGNoEmailFound).ID | |||
ctx.Data["KeyID"] = err.(asymkey_model.ErrGPGNoEmailFound).ID | |||
ctx.RenderWithErr(ctx.Tr("settings.gpg_no_key_email_found"), tplSettingsKeys, &form) | |||
default: | |||
ctx.ServerError("AddPublicKey", err) | |||
@@ -124,21 +125,21 @@ func KeysPost(ctx *context.Context) { | |||
ctx.Flash.Success(ctx.Tr("settings.add_gpg_key_success", keyIDs)) | |||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys") | |||
case "verify_gpg": | |||
token := models.VerificationToken(ctx.User, 1) | |||
lastToken := models.VerificationToken(ctx.User, 0) | |||
token := asymkey_model.VerificationToken(ctx.User, 1) | |||
lastToken := asymkey_model.VerificationToken(ctx.User, 0) | |||
keyID, err := models.VerifyGPGKey(ctx.User.ID, form.KeyID, token, form.Signature) | |||
if err != nil && models.IsErrGPGInvalidTokenSignature(err) { | |||
keyID, err = models.VerifyGPGKey(ctx.User.ID, form.KeyID, lastToken, form.Signature) | |||
keyID, err := asymkey_model.VerifyGPGKey(ctx.User.ID, form.KeyID, token, form.Signature) | |||
if err != nil && asymkey_model.IsErrGPGInvalidTokenSignature(err) { | |||
keyID, err = asymkey_model.VerifyGPGKey(ctx.User.ID, form.KeyID, lastToken, form.Signature) | |||
} | |||
if err != nil { | |||
ctx.Data["HasGPGVerifyError"] = true | |||
switch { | |||
case models.IsErrGPGInvalidTokenSignature(err): | |||
case asymkey_model.IsErrGPGInvalidTokenSignature(err): | |||
loadKeysData(ctx) | |||
ctx.Data["VerifyingID"] = form.KeyID | |||
ctx.Data["Err_Signature"] = true | |||
ctx.Data["KeyID"] = err.(models.ErrGPGInvalidTokenSignature).ID | |||
ctx.Data["KeyID"] = err.(asymkey_model.ErrGPGInvalidTokenSignature).ID | |||
ctx.RenderWithErr(ctx.Tr("settings.gpg_invalid_token_signature"), tplSettingsKeys, &form) | |||
default: | |||
ctx.ServerError("VerifyGPG", err) | |||
@@ -147,11 +148,11 @@ func KeysPost(ctx *context.Context) { | |||
ctx.Flash.Success(ctx.Tr("settings.verify_gpg_key_success", keyID)) | |||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys") | |||
case "ssh": | |||
content, err := models.CheckPublicKeyString(form.Content) | |||
content, err := asymkey_model.CheckPublicKeyString(form.Content) | |||
if err != nil { | |||
if models.IsErrSSHDisabled(err) { | |||
if db.IsErrSSHDisabled(err) { | |||
ctx.Flash.Info(ctx.Tr("settings.ssh_disabled")) | |||
} else if models.IsErrKeyUnableVerify(err) { | |||
} else if asymkey_model.IsErrKeyUnableVerify(err) { | |||
ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key")) | |||
} else { | |||
ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error())) | |||
@@ -160,20 +161,20 @@ func KeysPost(ctx *context.Context) { | |||
return | |||
} | |||
if _, err = models.AddPublicKey(ctx.User.ID, form.Title, content, 0); err != nil { | |||
if _, err = asymkey_model.AddPublicKey(ctx.User.ID, form.Title, content, 0); err != nil { | |||
ctx.Data["HasSSHError"] = true | |||
switch { | |||
case models.IsErrKeyAlreadyExist(err): | |||
case asymkey_model.IsErrKeyAlreadyExist(err): | |||
loadKeysData(ctx) | |||
ctx.Data["Err_Content"] = true | |||
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_been_used"), tplSettingsKeys, &form) | |||
case models.IsErrKeyNameAlreadyUsed(err): | |||
case asymkey_model.IsErrKeyNameAlreadyUsed(err): | |||
loadKeysData(ctx) | |||
ctx.Data["Err_Title"] = true | |||
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_name_used"), tplSettingsKeys, &form) | |||
case models.IsErrKeyUnableVerify(err): | |||
case asymkey_model.IsErrKeyUnableVerify(err): | |||
ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key")) | |||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys") | |||
default: | |||
@@ -196,14 +197,14 @@ func DeleteKey(ctx *context.Context) { | |||
switch ctx.FormString("type") { | |||
case "gpg": | |||
if err := models.DeleteGPGKey(ctx.User, ctx.FormInt64("id")); err != nil { | |||
if err := asymkey_model.DeleteGPGKey(ctx.User, ctx.FormInt64("id")); err != nil { | |||
ctx.Flash.Error("DeleteGPGKey: " + err.Error()) | |||
} else { | |||
ctx.Flash.Success(ctx.Tr("settings.gpg_key_deletion_success")) | |||
} | |||
case "ssh": | |||
keyID := ctx.FormInt64("id") | |||
external, err := models.PublicKeyIsExternallyManaged(keyID) | |||
external, err := asymkey_model.PublicKeyIsExternallyManaged(keyID) | |||
if err != nil { | |||
ctx.ServerError("sshKeysExternalManaged", err) | |||
return | |||
@@ -213,13 +214,13 @@ func DeleteKey(ctx *context.Context) { | |||
ctx.Redirect(setting.AppSubURL + "/user/settings/keys") | |||
return | |||
} | |||
if err := models.DeletePublicKey(ctx.User, keyID); err != nil { | |||
if err := asymkey_service.DeletePublicKey(ctx.User, keyID); err != nil { | |||
ctx.Flash.Error("DeletePublicKey: " + err.Error()) | |||
} else { | |||
ctx.Flash.Success(ctx.Tr("settings.ssh_key_deletion_success")) | |||
} | |||
case "principal": | |||
if err := models.DeletePublicKey(ctx.User, ctx.FormInt64("id")); err != nil { | |||
if err := asymkey_service.DeletePublicKey(ctx.User, ctx.FormInt64("id")); err != nil { | |||
ctx.Flash.Error("DeletePublicKey: " + err.Error()) | |||
} else { | |||
ctx.Flash.Success(ctx.Tr("settings.ssh_principal_deletion_success")) | |||
@@ -234,32 +235,32 @@ func DeleteKey(ctx *context.Context) { | |||
} | |||
func loadKeysData(ctx *context.Context) { | |||
keys, err := models.ListPublicKeys(ctx.User.ID, db.ListOptions{}) | |||
keys, err := asymkey_model.ListPublicKeys(ctx.User.ID, db.ListOptions{}) | |||
if err != nil { | |||
ctx.ServerError("ListPublicKeys", err) | |||
return | |||
} | |||
ctx.Data["Keys"] = keys | |||
externalKeys, err := models.PublicKeysAreExternallyManaged(keys) | |||
externalKeys, err := asymkey_model.PublicKeysAreExternallyManaged(keys) | |||
if err != nil { | |||
ctx.ServerError("ListPublicKeys", err) | |||
return | |||
} | |||
ctx.Data["ExternalKeys"] = externalKeys | |||
gpgkeys, err := models.ListGPGKeys(ctx.User.ID, db.ListOptions{}) | |||
gpgkeys, err := asymkey_model.ListGPGKeys(db.DefaultContext, ctx.User.ID, db.ListOptions{}) | |||
if err != nil { | |||
ctx.ServerError("ListGPGKeys", err) | |||
return | |||
} | |||
ctx.Data["GPGKeys"] = gpgkeys | |||
tokenToSign := models.VerificationToken(ctx.User, 1) | |||
tokenToSign := asymkey_model.VerificationToken(ctx.User, 1) | |||
// generate a new aes cipher using the csrfToken | |||
ctx.Data["TokenToSign"] = tokenToSign | |||
principals, err := models.ListPrincipalKeys(ctx.User.ID, db.ListOptions{}) | |||
principals, err := asymkey_model.ListPrincipalKeys(ctx.User.ID, db.ListOptions{}) | |||
if err != nil { | |||
ctx.ServerError("ListPrincipalKeys", err) | |||
return |
@@ -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("..", "..")) | |||
} |
@@ -1,15 +1,17 @@ | |||
// Copyright 2019 The Gitea Authors. All rights reserved. | |||
// 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 models | |||
package asymkey | |||
import ( | |||
"fmt" | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/db" | |||
"code.gitea.io/gitea/models/login" | |||
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" | |||
@@ -63,6 +65,22 @@ func signingModeFromStrings(modeStrings []string) []signingMode { | |||
return returnable | |||
} | |||
// ErrWontSign explains the first reason why a commit would not be signed | |||
// There may be other reasons - this is just the first reason found | |||
type ErrWontSign struct { | |||
Reason signingMode | |||
} | |||
func (e *ErrWontSign) Error() string { | |||
return fmt.Sprintf("wont sign: %s", e.Reason) | |||
} | |||
// IsErrWontSign checks if an error is a ErrWontSign | |||
func IsErrWontSign(err error) bool { | |||
_, ok := err.(*ErrWontSign) | |||
return ok | |||
} | |||
// SigningKey returns the KeyID and git Signature for the repo | |||
func SigningKey(repoPath string) (string, *git.Signature) { | |||
if setting.Repository.Signing.SigningKey == "none" { | |||
@@ -124,7 +142,7 @@ Loop: | |||
case always: | |||
break Loop | |||
case pubkey: | |||
keys, err := ListGPGKeys(u.ID, db.ListOptions{}) | |||
keys, err := asymkey_model.ListGPGKeys(db.DefaultContext, u.ID, db.ListOptions{}) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
@@ -145,9 +163,9 @@ Loop: | |||
} | |||
// 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) { | |||
func SignWikiCommit(repoWikiPath string, u *user_model.User) (bool, string, *git.Signature, error) { | |||
rules := signingModeFromStrings(setting.Repository.Signing.Wiki) | |||
signingKey, sig := SigningKey(repo.WikiPath()) | |||
signingKey, sig := SigningKey(repoWikiPath) | |||
if signingKey == "" { | |||
return false, "", nil, &ErrWontSign{noKey} | |||
} | |||
@@ -160,7 +178,7 @@ Loop: | |||
case always: | |||
break Loop | |||
case pubkey: | |||
keys, err := ListGPGKeys(u.ID, db.ListOptions{}) | |||
keys, err := asymkey_model.ListGPGKeys(db.DefaultContext, u.ID, db.ListOptions{}) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
@@ -176,7 +194,7 @@ Loop: | |||
return false, "", nil, &ErrWontSign{twofa} | |||
} | |||
case parentSigned: | |||
gitRepo, err := git.OpenRepository(repo.WikiPath()) | |||
gitRepo, err := git.OpenRepository(repoWikiPath) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
@@ -188,7 +206,7 @@ Loop: | |||
if commit.Signature == nil { | |||
return false, "", nil, &ErrWontSign{parentSigned} | |||
} | |||
verification := ParseCommitWithSignature(commit) | |||
verification := asymkey_model.ParseCommitWithSignature(commit) | |||
if !verification.Verified { | |||
return false, "", nil, &ErrWontSign{parentSigned} | |||
} | |||
@@ -198,9 +216,9 @@ Loop: | |||
} | |||
// 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) { | |||
func SignCRUDAction(repoPath string, u *user_model.User, tmpBasePath, parentCommit string) (bool, string, *git.Signature, error) { | |||
rules := signingModeFromStrings(setting.Repository.Signing.CRUDActions) | |||
signingKey, sig := SigningKey(repo.RepoPath()) | |||
signingKey, sig := SigningKey(repoPath) | |||
if signingKey == "" { | |||
return false, "", nil, &ErrWontSign{noKey} | |||
} | |||
@@ -213,7 +231,7 @@ Loop: | |||
case always: | |||
break Loop | |||
case pubkey: | |||
keys, err := ListGPGKeys(u.ID, db.ListOptions{}) | |||
keys, err := asymkey_model.ListGPGKeys(db.DefaultContext, u.ID, db.ListOptions{}) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
@@ -241,7 +259,7 @@ Loop: | |||
if commit.Signature == nil { | |||
return false, "", nil, &ErrWontSign{parentSigned} | |||
} | |||
verification := ParseCommitWithSignature(commit) | |||
verification := asymkey_model.ParseCommitWithSignature(commit) | |||
if !verification.Verified { | |||
return false, "", nil, &ErrWontSign{parentSigned} | |||
} | |||
@@ -249,3 +267,122 @@ Loop: | |||
} | |||
return true, signingKey, sig, nil | |||
} | |||
// SignMerge determines if we should sign a PR merge commit to the base repository | |||
func SignMerge(pr *models.PullRequest, u *user_model.User, tmpBasePath, baseCommit, headCommit string) (bool, string, *git.Signature, error) { | |||
if err := pr.LoadBaseRepo(); err != nil { | |||
log.Error("Unable to get Base Repo for pull request") | |||
return false, "", nil, err | |||
} | |||
repo := pr.BaseRepo | |||
signingKey, signer := SigningKey(repo.RepoPath()) | |||
if signingKey == "" { | |||
return false, "", nil, &ErrWontSign{noKey} | |||
} | |||
rules := signingModeFromStrings(setting.Repository.Signing.Merges) | |||
var gitRepo *git.Repository | |||
var err error | |||
Loop: | |||
for _, rule := range rules { | |||
switch rule { | |||
case never: | |||
return false, "", nil, &ErrWontSign{never} | |||
case always: | |||
break Loop | |||
case pubkey: | |||
keys, err := asymkey_model.ListGPGKeys(db.DefaultContext, u.ID, db.ListOptions{}) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
if len(keys) == 0 { | |||
return false, "", nil, &ErrWontSign{pubkey} | |||
} | |||
case twofa: | |||
twofaModel, err := login.GetTwoFactorByUID(u.ID) | |||
if err != nil && !login.IsErrTwoFactorNotEnrolled(err) { | |||
return false, "", nil, err | |||
} | |||
if twofaModel == nil { | |||
return false, "", nil, &ErrWontSign{twofa} | |||
} | |||
case approved: | |||
protectedBranch, err := models.GetProtectedBranchBy(repo.ID, pr.BaseBranch) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
if protectedBranch == nil { | |||
return false, "", nil, &ErrWontSign{approved} | |||
} | |||
if protectedBranch.GetGrantedApprovalsCount(pr) < 1 { | |||
return false, "", nil, &ErrWontSign{approved} | |||
} | |||
case baseSigned: | |||
if gitRepo == nil { | |||
gitRepo, err = git.OpenRepository(tmpBasePath) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
defer gitRepo.Close() | |||
} | |||
commit, err := gitRepo.GetCommit(baseCommit) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
verification := asymkey_model.ParseCommitWithSignature(commit) | |||
if !verification.Verified { | |||
return false, "", nil, &ErrWontSign{baseSigned} | |||
} | |||
case headSigned: | |||
if gitRepo == nil { | |||
gitRepo, err = git.OpenRepository(tmpBasePath) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
defer gitRepo.Close() | |||
} | |||
commit, err := gitRepo.GetCommit(headCommit) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
verification := asymkey_model.ParseCommitWithSignature(commit) | |||
if !verification.Verified { | |||
return false, "", nil, &ErrWontSign{headSigned} | |||
} | |||
case commitsSigned: | |||
if gitRepo == nil { | |||
gitRepo, err = git.OpenRepository(tmpBasePath) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
defer gitRepo.Close() | |||
} | |||
commit, err := gitRepo.GetCommit(headCommit) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
verification := asymkey_model.ParseCommitWithSignature(commit) | |||
if !verification.Verified { | |||
return false, "", nil, &ErrWontSign{commitsSigned} | |||
} | |||
// need to work out merge-base | |||
mergeBaseCommit, _, err := gitRepo.GetMergeBase("", baseCommit, headCommit) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
commitList, err := commit.CommitsBeforeUntil(mergeBaseCommit) | |||
if err != nil { | |||
return false, "", nil, err | |||
} | |||
for _, commit := range commitList { | |||
verification := asymkey_model.ParseCommitWithSignature(commit) | |||
if !verification.Verified { | |||
return false, "", nil, &ErrWontSign{commitsSigned} | |||
} | |||
} | |||
} | |||
} | |||
return true, signingKey, signer, nil | |||
} |
@@ -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) | |||
} | |||
} | |||
} |
@@ -8,7 +8,7 @@ import ( | |||
"fmt" | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/db" | |||
"code.gitea.io/gitea/models/login" | |||
user_model "code.gitea.io/gitea/models/user" | |||
@@ -59,8 +59,8 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str | |||
} | |||
if user != nil { | |||
if isAttributeSSHPublicKeySet && models.SynchronizePublicKeys(user, source.loginSource, sr.SSHPublicKey) { | |||
return user, models.RewriteAllPublicKeys() | |||
if isAttributeSSHPublicKeySet && asymkey_model.SynchronizePublicKeys(user, source.loginSource, sr.SSHPublicKey) { | |||
return user, asymkey_model.RewriteAllPublicKeys() | |||
} | |||
return user, nil | |||
@@ -95,8 +95,8 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str | |||
mailer.SendRegisterNotifyMail(user) | |||
if isAttributeSSHPublicKeySet && models.AddPublicKeysBySource(user, source.loginSource, sr.SSHPublicKey) { | |||
err = models.RewriteAllPublicKeys() | |||
if isAttributeSSHPublicKeySet && asymkey_model.AddPublicKeysBySource(user, source.loginSource, sr.SSHPublicKey) { | |||
err = asymkey_model.RewriteAllPublicKeys() | |||
} | |||
if err == nil && len(source.AttributeAvatar) > 0 { |
@@ -10,7 +10,7 @@ import ( | |||
"sort" | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/db" | |||
user_model "code.gitea.io/gitea/models/user" | |||
"code.gitea.io/gitea/modules/log" | |||
@@ -68,7 +68,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { | |||
log.Warn("SyncExternalUsers: Cancelled at update of %s before completed update of users", source.loginSource.Name) | |||
// Rewrite authorized_keys file if LDAP Public SSH Key attribute is set and any key was added or removed | |||
if sshKeysNeedUpdate { | |||
err = models.RewriteAllPublicKeys() | |||
err = asymkey_model.RewriteAllPublicKeys() | |||
if err != nil { | |||
log.Error("RewriteAllPublicKeys: %v", err) | |||
} | |||
@@ -119,7 +119,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { | |||
if err == nil && isAttributeSSHPublicKeySet { | |||
log.Trace("SyncExternalUsers[%s]: Adding LDAP Public SSH Keys for user %s", source.loginSource.Name, usr.Name) | |||
if models.AddPublicKeysBySource(usr, source.loginSource, su.SSHPublicKey) { | |||
if asymkey_model.AddPublicKeysBySource(usr, source.loginSource, su.SSHPublicKey) { | |||
sshKeysNeedUpdate = true | |||
} | |||
} | |||
@@ -129,7 +129,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { | |||
} | |||
} else if updateExisting { | |||
// Synchronize SSH Public Key if that attribute is set | |||
if isAttributeSSHPublicKeySet && models.SynchronizePublicKeys(usr, source.loginSource, su.SSHPublicKey) { | |||
if isAttributeSSHPublicKeySet && asymkey_model.SynchronizePublicKeys(usr, source.loginSource, su.SSHPublicKey) { | |||
sshKeysNeedUpdate = true | |||
} | |||
@@ -171,7 +171,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { | |||
// Rewrite authorized_keys file if LDAP Public SSH Key attribute is set and any key was added or removed | |||
if sshKeysNeedUpdate { | |||
err = models.RewriteAllPublicKeys() | |||
err = asymkey_model.RewriteAllPublicKeys() | |||
if err != nil { | |||
log.Error("RewriteAllPublicKeys: %v", err) | |||
} |
@@ -9,6 +9,7 @@ import ( | |||
"time" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
user_model "code.gitea.io/gitea/models/user" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/updatechecker" | |||
@@ -67,7 +68,7 @@ func registerRewriteAllPublicKeys() { | |||
RunAtStart: false, | |||
Schedule: "@every 72h", | |||
}, func(_ context.Context, _ *user_model.User, _ Config) error { | |||
return models.RewriteAllPublicKeys() | |||
return asymkey_model.RewriteAllPublicKeys() | |||
}) | |||
} | |||
@@ -77,7 +78,7 @@ func registerRewriteAllPrincipalKeys() { | |||
RunAtStart: false, | |||
Schedule: "@every 72h", | |||
}, func(_ context.Context, _ *user_model.User, _ Config) error { | |||
return models.RewriteAllPrincipalKeys() | |||
return asymkey_model.RewriteAllPrincipalKeys() | |||
}) | |||
} | |||
@@ -27,6 +27,7 @@ import ( | |||
"code.gitea.io/gitea/modules/references" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/timeutil" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
issue_service "code.gitea.io/gitea/services/issue" | |||
) | |||
@@ -218,7 +219,7 @@ func rawMerge(pr *models.PullRequest, doer *user_model.User, mergeStyle repo_mod | |||
// Determine if we should sign | |||
signArg := "" | |||
if git.CheckGitVersionAtLeast("1.7.9") == nil { | |||
sign, keyID, signer, _ := pr.SignMerge(doer, tmpBasePath, "HEAD", trackingBranch) | |||
sign, keyID, signer, _ := asymkey_service.SignMerge(pr, doer, tmpBasePath, "HEAD", trackingBranch) | |||
if sign { | |||
signArg = "-S" + keyID | |||
if pr.BaseRepo.GetTrustModel() == repo_model.CommitterTrustModel || pr.BaseRepo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel { | |||
@@ -553,7 +554,7 @@ func IsSignedIfRequired(pr *models.PullRequest, doer *user_model.User) (bool, er | |||
return true, nil | |||
} | |||
sign, _, _, err := pr.SignMerge(doer, pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName()) | |||
sign, _, _, err := asymkey_service.SignMerge(pr, doer, pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName()) | |||
return sign, err | |||
} |
@@ -14,7 +14,6 @@ import ( | |||
"strings" | |||
"time" | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/models/db" | |||
repo_model "code.gitea.io/gitea/models/repo" | |||
"code.gitea.io/gitea/modules/git" | |||
@@ -171,7 +170,7 @@ func doArchive(r *ArchiveRequest) (*repo_model.RepoArchiver, error) { | |||
rd.Close() | |||
}() | |||
var done = make(chan error) | |||
repo, err := models.LoadArchiverRepo(archiver) | |||
repo, err := repo_model.GetRepositoryByID(archiver.RepoID) | |||
if err != nil { | |||
return nil, fmt.Errorf("archiver.LoadRepo failed: %v", err) | |||
} |
@@ -8,6 +8,7 @@ import ( | |||
"fmt" | |||
"code.gitea.io/gitea/models" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
repo_model "code.gitea.io/gitea/models/repo" | |||
user_model "code.gitea.io/gitea/models/user" | |||
"code.gitea.io/gitea/modules/git" | |||
@@ -55,7 +56,7 @@ func CountDivergingCommits(repo *repo_model.Repository, branch string) (*git.Div | |||
// GetPayloadCommitVerification returns the verification information of a commit | |||
func GetPayloadCommitVerification(commit *git.Commit) *structs.PayloadCommitVerification { | |||
verification := &structs.PayloadCommitVerification{} | |||
commitVerification := models.ParseCommitWithSignature(commit) | |||
commitVerification := asymkey_model.ParseCommitWithSignature(commit) | |||
if commit.Signature != nil { | |||
verification.Signature = commit.Signature.Signature | |||
verification.Payload = commit.Signature.Payload |
@@ -20,6 +20,7 @@ import ( | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/modules/setting" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
"code.gitea.io/gitea/services/gitdiff" | |||
) | |||
@@ -217,7 +218,7 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *user_m | |||
// Determine if we should sign | |||
if git.CheckGitVersionAtLeast("1.7.9") == nil { | |||
sign, keyID, signer, _ := models.SignCRUDAction(t.repo, author, t.basePath, "HEAD") | |||
sign, keyID, signer, _ := asymkey_service.SignCRUDAction(t.repo.RepoPath(), author, t.basePath, "HEAD") | |||
if sign { | |||
args = append(args, "-S"+keyID) | |||
if t.repo.GetTrustModel() == repo_model.CommitterTrustModel || t.repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel { |
@@ -21,6 +21,7 @@ import ( | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/structs" | |||
"code.gitea.io/gitea/modules/util" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
repo_service "code.gitea.io/gitea/services/repository" | |||
stdcharset "golang.org/x/net/html/charset" | |||
@@ -458,9 +459,9 @@ func VerifyBranchProtection(repo *repo_model.Repository, doer *user_model.User, | |||
} | |||
} | |||
if protectedBranch.RequireSignedCommits { | |||
_, _, _, err := models.SignCRUDAction(repo, doer, repo.RepoPath(), branchName) | |||
_, _, _, err := asymkey_service.SignCRUDAction(repo.RepoPath(), doer, repo.RepoPath(), branchName) | |||
if err != nil { | |||
if !models.IsErrWontSign(err) { | |||
if !asymkey_service.IsErrWontSign(err) { | |||
return err | |||
} | |||
return models.ErrUserCannotCommit{ |
@@ -31,13 +31,15 @@ func CreateRepository(doer, owner *user_model.User, opts models.CreateRepoOption | |||
} | |||
// DeleteRepository deletes a repository for a user or organization. | |||
func DeleteRepository(doer *user_model.User, repo *repo_model.Repository) error { | |||
func DeleteRepository(doer *user_model.User, repo *repo_model.Repository, notify bool) error { | |||
if err := pull_service.CloseRepoBranchesPulls(doer, repo); err != nil { | |||
log.Error("CloseRepoBranchesPulls failed: %v", err) | |||
} | |||
// If the repo itself has webhooks, we need to trigger them before deleting it... | |||
notification.NotifyDeleteRepository(doer, repo) | |||
if notify { | |||
// If the repo itself has webhooks, we need to trigger them before deleting it... | |||
notification.NotifyDeleteRepository(doer, repo) | |||
} | |||
err := models.DeleteRepository(doer, repo.OwnerID, repo.ID) | |||
return err |
@@ -14,6 +14,7 @@ import ( | |||
"code.gitea.io/gitea/models" | |||
admin_model "code.gitea.io/gitea/models/admin" | |||
asymkey_model "code.gitea.io/gitea/models/asymkey" | |||
"code.gitea.io/gitea/models/db" | |||
repo_model "code.gitea.io/gitea/models/repo" | |||
user_model "code.gitea.io/gitea/models/user" | |||
@@ -31,11 +32,11 @@ func DeleteUser(u *user_model.User) error { | |||
return fmt.Errorf("%s is an organization not a user", u.Name) | |||
} | |||
ctx, commiter, err := db.TxContext() | |||
ctx, committer, err := db.TxContext() | |||
if err != nil { | |||
return err | |||
} | |||
defer commiter.Close() | |||
defer committer.Close() | |||
// Note: A user owns any repository or belongs to any organization | |||
// cannot perform delete operation. | |||
@@ -60,14 +61,15 @@ func DeleteUser(u *user_model.User) error { | |||
return fmt.Errorf("DeleteUser: %v", err) | |||
} | |||
if err := commiter.Commit(); err != nil { | |||
if err := committer.Commit(); err != nil { | |||
return err | |||
} | |||
committer.Close() | |||
if err = models.RewriteAllPublicKeys(); err != nil { | |||
if err = asymkey_model.RewriteAllPublicKeys(); err != nil { | |||
return err | |||
} | |||
if err = models.RewriteAllPrincipalKeys(); err != nil { | |||
if err = asymkey_model.RewriteAllPrincipalKeys(); err != nil { | |||
return err | |||
} | |||
@@ -22,6 +22,7 @@ import ( | |||
repo_module "code.gitea.io/gitea/modules/repository" | |||
"code.gitea.io/gitea/modules/sync" | |||
"code.gitea.io/gitea/modules/util" | |||
asymkey_service "code.gitea.io/gitea/services/asymkey" | |||
) | |||
var ( | |||
@@ -225,7 +226,7 @@ func updateWikiPage(doer *user_model.User, repo *repo_model.Repository, oldWikiN | |||
committer := doer.NewGitSig() | |||
sign, signingKey, signer, _ := models.SignWikiCommit(repo, doer) | |||
sign, signingKey, signer, _ := asymkey_service.SignWikiCommit(repo.WikiPath(), doer) | |||
if sign { | |||
commitTreeOpts.KeyID = signingKey | |||
if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel { | |||
@@ -343,7 +344,7 @@ func DeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, wikiName | |||
committer := doer.NewGitSig() | |||
sign, signingKey, signer, _ := models.SignWikiCommit(repo, doer) | |||
sign, signingKey, signer, _ := asymkey_service.SignWikiCommit(repo.WikiPath(), doer) | |||
if sign { | |||
commitTreeOpts.KeyID = signingKey | |||
if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel { |