aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/admin.go3
-rw-r--r--cmd/serv.go5
-rw-r--r--docs/content/doc/advanced/config-cheat-sheet.en-us.md2
-rw-r--r--integrations/api_admin_test.go6
-rw-r--r--integrations/api_keys_test.go8
-rw-r--r--integrations/api_private_serv_test.go8
-rw-r--r--models/asymkey/error.go248
-rw-r--r--models/asymkey/gpg_key.go (renamed from models/gpg_key.go)11
-rw-r--r--models/asymkey/gpg_key_add.go (renamed from models/gpg_key_add.go)2
-rw-r--r--models/asymkey/gpg_key_commit_verification.go (renamed from models/gpg_key_commit_verification.go)24
-rw-r--r--models/asymkey/gpg_key_common.go (renamed from models/gpg_key_common.go)2
-rw-r--r--models/asymkey/gpg_key_import.go (renamed from models/gpg_key_import.go)2
-rw-r--r--models/asymkey/gpg_key_test.go (renamed from models/gpg_key_test.go)2
-rw-r--r--models/asymkey/gpg_key_verify.go (renamed from models/gpg_key_verify.go)2
-rw-r--r--models/asymkey/main_test.go29
-rw-r--r--models/asymkey/ssh_key.go (renamed from models/ssh_key.go)45
-rw-r--r--models/asymkey/ssh_key_authorized_keys.go (renamed from models/ssh_key_authorized_keys.go)8
-rw-r--r--models/asymkey/ssh_key_authorized_principals.go (renamed from models/ssh_key_authorized_principals.go)2
-rw-r--r--models/asymkey/ssh_key_deploy.go (renamed from models/ssh_key_deploy.go)82
-rw-r--r--models/asymkey/ssh_key_fingerprint.go (renamed from models/ssh_key_fingerprint.go)2
-rw-r--r--models/asymkey/ssh_key_parse.go (renamed from models/ssh_key_parse.go)5
-rw-r--r--models/asymkey/ssh_key_principals.go (renamed from models/ssh_key_principals.go)4
-rw-r--r--models/asymkey/ssh_key_test.go (renamed from models/ssh_key_test.go)7
-rw-r--r--models/commit.go8
-rw-r--r--models/commit_status.go5
-rw-r--r--models/db/error.go13
-rw-r--r--models/error.go277
-rw-r--r--models/main_test.go6
-rw-r--r--models/pull_sign.go133
-rw-r--r--models/repo.go61
-rw-r--r--models/statistic.go3
-rw-r--r--models/user.go9
-rw-r--r--models/user_test.go69
-rw-r--r--modules/context/repo.go7
-rw-r--r--modules/convert/convert.go13
-rw-r--r--modules/doctor/authorizedkeys.go8
-rw-r--r--modules/gitgraph/graph_models.go9
-rw-r--r--modules/private/serv.go8
-rw-r--r--modules/repository/init.go3
-rw-r--r--modules/ssh/ssh.go10
-rw-r--r--routers/api/v1/admin/user.go8
-rw-r--r--routers/api/v1/misc/signing.go4
-rw-r--r--routers/api/v1/repo/key.go36
-rw-r--r--routers/api/v1/repo/pull.go3
-rw-r--r--routers/api/v1/repo/repo.go2
-rw-r--r--routers/api/v1/user/gpg_key.go52
-rw-r--r--routers/api/v1/user/key.go35
-rw-r--r--routers/init.go3
-rw-r--r--routers/private/hook_verification.go4
-rw-r--r--routers/private/key.go12
-rw-r--r--routers/private/serv.go23
-rw-r--r--routers/web/admin/repos.go2
-rw-r--r--routers/web/repo/commit.go7
-rw-r--r--routers/web/repo/issue.go7
-rw-r--r--routers/web/repo/setting.go29
-rw-r--r--routers/web/repo/settings_test.go5
-rw-r--r--routers/web/repo/view.go7
-rw-r--r--routers/web/user/home.go9
-rw-r--r--routers/web/user/setting/keys.go79
-rw-r--r--services/asymkey/deploy_key.go30
-rw-r--r--services/asymkey/main_test.go16
-rw-r--r--services/asymkey/sign.go (renamed from models/repo_sign.go)163
-rw-r--r--services/asymkey/ssh_key.go49
-rw-r--r--services/asymkey/ssh_key_test.go83
-rw-r--r--services/auth/source/ldap/source_authenticate.go10
-rw-r--r--services/auth/source/ldap/source_sync.go10
-rw-r--r--services/cron/tasks_extended.go5
-rw-r--r--services/pull/merge.go5
-rw-r--r--services/repository/archiver/archiver.go3
-rw-r--r--services/repository/files/commit.go3
-rw-r--r--services/repository/files/temp_repo.go3
-rw-r--r--services/repository/files/update.go5
-rw-r--r--services/repository/repository.go8
-rw-r--r--services/user/user.go12
-rw-r--r--services/wiki/wiki.go5
75 files changed, 1001 insertions, 887 deletions
diff --git a/cmd/admin.go b/cmd/admin.go
index d11b824fa1..f36e9f5de7 100644
--- a/cmd/admin.go
+++ b/cmd/admin.go
@@ -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 {
diff --git a/cmd/serv.go b/cmd/serv.go
index e34e300cbe..c3c9eff195 100644
--- a/cmd/serv.go
+++ b/cmd/serv.go
@@ -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.")
diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
index bb2eb1c8ca..e2a2687fa9 100644
--- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md
+++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
@@ -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
diff --git a/integrations/api_admin_test.go b/integrations/api_admin_test.go
index 98270ed587..b935d3eac5 100644
--- a/integrations/api_admin_test.go
+++ b/integrations/api_admin_test.go
@@ -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) {
diff --git a/integrations/api_keys_test.go b/integrations/api_keys_test.go
index 5fbd51318f..b1f455d932 100644
--- a/integrations/api_keys_test.go
+++ b/integrations/api_keys_test.go
@@ -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,
diff --git a/integrations/api_private_serv_test.go b/integrations/api_private_serv_test.go
index 388e5da00d..68308bafc5 100644
--- a/integrations/api_private_serv_test.go
+++ b/integrations/api_private_serv_test.go
@@ -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
diff --git a/models/asymkey/error.go b/models/asymkey/error.go
new file mode 100644
index 0000000000..7add553bd6
--- /dev/null
+++ b/models/asymkey/error.go
@@ -0,0 +1,248 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package asymkey
+
+import "fmt"
+
+// ErrKeyUnableVerify represents a "KeyUnableVerify" kind of error.
+type ErrKeyUnableVerify struct {
+ Result string
+}
+
+// IsErrKeyUnableVerify checks if an error is a ErrKeyUnableVerify.
+func IsErrKeyUnableVerify(err error) bool {
+ _, ok := err.(ErrKeyUnableVerify)
+ return ok
+}
+
+func (err ErrKeyUnableVerify) Error() string {
+ return fmt.Sprintf("Unable to verify key content [result: %s]", err.Result)
+}
+
+// ErrKeyNotExist represents a "KeyNotExist" kind of error.
+type ErrKeyNotExist struct {
+ ID int64
+}
+
+// IsErrKeyNotExist checks if an error is a ErrKeyNotExist.
+func IsErrKeyNotExist(err error) bool {
+ _, ok := err.(ErrKeyNotExist)
+ return ok
+}
+
+func (err ErrKeyNotExist) Error() string {
+ return fmt.Sprintf("public key does not exist [id: %d]", err.ID)
+}
+
+// ErrKeyAlreadyExist represents a "KeyAlreadyExist" kind of error.
+type ErrKeyAlreadyExist struct {
+ OwnerID int64
+ Fingerprint string
+ Content string
+}
+
+// IsErrKeyAlreadyExist checks if an error is a ErrKeyAlreadyExist.
+func IsErrKeyAlreadyExist(err error) bool {
+ _, ok := err.(ErrKeyAlreadyExist)
+ return ok
+}
+
+func (err ErrKeyAlreadyExist) Error() string {
+ return fmt.Sprintf("public key already exists [owner_id: %d, finger_print: %s, content: %s]",
+ err.OwnerID, err.Fingerprint, err.Content)
+}
+
+// ErrKeyNameAlreadyUsed represents a "KeyNameAlreadyUsed" kind of error.
+type ErrKeyNameAlreadyUsed struct {
+ OwnerID int64
+ Name string
+}
+
+// IsErrKeyNameAlreadyUsed checks if an error is a ErrKeyNameAlreadyUsed.
+func IsErrKeyNameAlreadyUsed(err error) bool {
+ _, ok := err.(ErrKeyNameAlreadyUsed)
+ return ok
+}
+
+func (err ErrKeyNameAlreadyUsed) Error() string {
+ return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name)
+}
+
+// ErrGPGNoEmailFound represents a "ErrGPGNoEmailFound" kind of error.
+type ErrGPGNoEmailFound struct {
+ FailedEmails []string
+ ID string
+}
+
+// IsErrGPGNoEmailFound checks if an error is a ErrGPGNoEmailFound.
+func IsErrGPGNoEmailFound(err error) bool {
+ _, ok := err.(ErrGPGNoEmailFound)
+ return ok
+}
+
+func (err ErrGPGNoEmailFound) Error() string {
+ return fmt.Sprintf("none of the emails attached to the GPG key could be found: %v", err.FailedEmails)
+}
+
+// ErrGPGInvalidTokenSignature represents a "ErrGPGInvalidTokenSignature" kind of error.
+type ErrGPGInvalidTokenSignature struct {
+ Wrapped error
+ ID string
+}
+
+// IsErrGPGInvalidTokenSignature checks if an error is a ErrGPGInvalidTokenSignature.
+func IsErrGPGInvalidTokenSignature(err error) bool {
+ _, ok := err.(ErrGPGInvalidTokenSignature)
+ return ok
+}
+
+func (err ErrGPGInvalidTokenSignature) Error() string {
+ return "the provided signature does not sign the token with the provided key"
+}
+
+// ErrGPGKeyParsing represents a "ErrGPGKeyParsing" kind of error.
+type ErrGPGKeyParsing struct {
+ ParseError error
+}
+
+// IsErrGPGKeyParsing checks if an error is a ErrGPGKeyParsing.
+func IsErrGPGKeyParsing(err error) bool {
+ _, ok := err.(ErrGPGKeyParsing)
+ return ok
+}
+
+func (err ErrGPGKeyParsing) Error() string {
+ return fmt.Sprintf("failed to parse gpg key %s", err.ParseError.Error())
+}
+
+// ErrGPGKeyNotExist represents a "GPGKeyNotExist" kind of error.
+type ErrGPGKeyNotExist struct {
+ ID int64
+}
+
+// IsErrGPGKeyNotExist checks if an error is a ErrGPGKeyNotExist.
+func IsErrGPGKeyNotExist(err error) bool {
+ _, ok := err.(ErrGPGKeyNotExist)
+ return ok
+}
+
+func (err ErrGPGKeyNotExist) Error() string {
+ return fmt.Sprintf("public gpg key does not exist [id: %d]", err.ID)
+}
+
+// ErrGPGKeyImportNotExist represents a "GPGKeyImportNotExist" kind of error.
+type ErrGPGKeyImportNotExist struct {
+ ID string
+}
+
+// IsErrGPGKeyImportNotExist checks if an error is a ErrGPGKeyImportNotExist.
+func IsErrGPGKeyImportNotExist(err error) bool {
+ _, ok := err.(ErrGPGKeyImportNotExist)
+ return ok
+}
+
+func (err ErrGPGKeyImportNotExist) Error() string {
+ return fmt.Sprintf("public gpg key import does not exist [id: %s]", err.ID)
+}
+
+// ErrGPGKeyIDAlreadyUsed represents a "GPGKeyIDAlreadyUsed" kind of error.
+type ErrGPGKeyIDAlreadyUsed struct {
+ KeyID string
+}
+
+// IsErrGPGKeyIDAlreadyUsed checks if an error is a ErrKeyNameAlreadyUsed.
+func IsErrGPGKeyIDAlreadyUsed(err error) bool {
+ _, ok := err.(ErrGPGKeyIDAlreadyUsed)
+ return ok
+}
+
+func (err ErrGPGKeyIDAlreadyUsed) Error() string {
+ return fmt.Sprintf("public key already exists [key_id: %s]", err.KeyID)
+}
+
+// ErrGPGKeyAccessDenied represents a "GPGKeyAccessDenied" kind of Error.
+type ErrGPGKeyAccessDenied struct {
+ UserID int64
+ KeyID int64
+}
+
+// IsErrGPGKeyAccessDenied checks if an error is a ErrGPGKeyAccessDenied.
+func IsErrGPGKeyAccessDenied(err error) bool {
+ _, ok := err.(ErrGPGKeyAccessDenied)
+ return ok
+}
+
+// Error pretty-prints an error of type ErrGPGKeyAccessDenied.
+func (err ErrGPGKeyAccessDenied) Error() string {
+ return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d]",
+ err.UserID, err.KeyID)
+}
+
+// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
+type ErrKeyAccessDenied struct {
+ UserID int64
+ KeyID int64
+ Note string
+}
+
+// IsErrKeyAccessDenied checks if an error is a ErrKeyAccessDenied.
+func IsErrKeyAccessDenied(err error) bool {
+ _, ok := err.(ErrKeyAccessDenied)
+ return ok
+}
+
+func (err ErrKeyAccessDenied) Error() string {
+ return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d, note: %s]",
+ err.UserID, err.KeyID, err.Note)
+}
+
+// ErrDeployKeyNotExist represents a "DeployKeyNotExist" kind of error.
+type ErrDeployKeyNotExist struct {
+ ID int64
+ KeyID int64
+ RepoID int64
+}
+
+// IsErrDeployKeyNotExist checks if an error is a ErrDeployKeyNotExist.
+func IsErrDeployKeyNotExist(err error) bool {
+ _, ok := err.(ErrDeployKeyNotExist)
+ return ok
+}
+
+func (err ErrDeployKeyNotExist) Error() string {
+ return fmt.Sprintf("Deploy key does not exist [id: %d, key_id: %d, repo_id: %d]", err.ID, err.KeyID, err.RepoID)
+}
+
+// ErrDeployKeyAlreadyExist represents a "DeployKeyAlreadyExist" kind of error.
+type ErrDeployKeyAlreadyExist struct {
+ KeyID int64
+ RepoID int64
+}
+
+// IsErrDeployKeyAlreadyExist checks if an error is a ErrDeployKeyAlreadyExist.
+func IsErrDeployKeyAlreadyExist(err error) bool {
+ _, ok := err.(ErrDeployKeyAlreadyExist)
+ return ok
+}
+
+func (err ErrDeployKeyAlreadyExist) Error() string {
+ return fmt.Sprintf("public key already exists [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID)
+}
+
+// ErrDeployKeyNameAlreadyUsed represents a "DeployKeyNameAlreadyUsed" kind of error.
+type ErrDeployKeyNameAlreadyUsed struct {
+ RepoID int64
+ Name string
+}
+
+// IsErrDeployKeyNameAlreadyUsed checks if an error is a ErrDeployKeyNameAlreadyUsed.
+func IsErrDeployKeyNameAlreadyUsed(err error) bool {
+ _, ok := err.(ErrDeployKeyNameAlreadyUsed)
+ return ok
+}
+
+func (err ErrDeployKeyNameAlreadyUsed) Error() string {
+ return fmt.Sprintf("public key with name already exists [repo_id: %d, name: %s]", err.RepoID, err.Name)
+}
diff --git a/models/gpg_key.go b/models/asymkey/gpg_key.go
index ce27a9237e..ced6ca37a3 100644
--- a/models/gpg_key.go
+++ b/models/asymkey/gpg_key.go
@@ -2,9 +2,10 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
+ "context"
"fmt"
"strings"
"time"
@@ -63,12 +64,8 @@ func (key *GPGKey) AfterLoad(session *xorm.Session) {
}
// ListGPGKeys returns a list of public keys belongs to given user.
-func ListGPGKeys(uid int64, listOptions db.ListOptions) ([]*GPGKey, error) {
- return listGPGKeys(db.GetEngine(db.DefaultContext), uid, listOptions)
-}
-
-func listGPGKeys(e db.Engine, uid int64, listOptions db.ListOptions) ([]*GPGKey, error) {
- sess := e.Table(&GPGKey{}).Where("owner_id=? AND primary_key_id=''", uid)
+func ListGPGKeys(ctx context.Context, uid int64, listOptions db.ListOptions) ([]*GPGKey, error) {
+ sess := db.GetEngine(ctx).Table(&GPGKey{}).Where("owner_id=? AND primary_key_id=''", uid)
if listOptions.Page != 0 {
sess = db.SetSessionPagination(sess, &listOptions)
}
diff --git a/models/gpg_key_add.go b/models/asymkey/gpg_key_add.go
index 711fc86dee..8f84bba1df 100644
--- a/models/gpg_key_add.go
+++ b/models/asymkey/gpg_key_add.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"strings"
diff --git a/models/gpg_key_commit_verification.go b/models/asymkey/gpg_key_commit_verification.go
index 48f58c07b6..5ec4e335d5 100644
--- a/models/gpg_key_commit_verification.go
+++ b/models/asymkey/gpg_key_commit_verification.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"fmt"
@@ -70,7 +70,7 @@ const (
)
// ParseCommitsWithSignature checks if signaute of commits are corresponding to users gpg keys.
-func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repository *repo_model.Repository) []*SignCommit {
+func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repoTrustModel repo_model.TrustModelType, isCodeReader func(*user_model.User) (bool, error)) []*SignCommit {
newCommits := make([]*SignCommit, 0, len(oldCommits))
keyMap := map[string]bool{}
@@ -80,7 +80,7 @@ func ParseCommitsWithSignature(oldCommits []*user_model.UserCommit, repository *
Verification: ParseCommitWithSignature(c.Commit),
}
- _ = CalculateTrustStatus(signCommit.Verification, repository, &keyMap)
+ _ = CalculateTrustStatus(signCommit.Verification, repoTrustModel, isCodeReader, &keyMap)
newCommits = append(newCommits, signCommit)
}
@@ -159,7 +159,7 @@ func ParseCommitWithSignature(c *git.Commit) *CommitVerification {
// Now try to associate the signature with the committer, if present
if committer.ID != 0 {
- keys, err := ListGPGKeys(committer.ID, db.ListOptions{})
+ keys, err := ListGPGKeys(db.DefaultContext, committer.ID, db.ListOptions{})
if err != nil { // Skipping failed to get gpg keys of user
log.Error("ListGPGKeys: %v", err)
return &CommitVerification{
@@ -448,18 +448,16 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *use
}
// CalculateTrustStatus will calculate the TrustStatus for a commit verification within a repository
-func CalculateTrustStatus(verification *CommitVerification, repository *repo_model.Repository, keyMap *map[string]bool) (err error) {
+// There are several trust models in Gitea
+func CalculateTrustStatus(verification *CommitVerification, repoTrustModel repo_model.TrustModelType, isCodeReader func(*user_model.User) (bool, error), keyMap *map[string]bool) (err error) {
if !verification.Verified {
return
}
- // There are several trust models in Gitea
- trustModel := repository.GetTrustModel()
-
// In the Committer trust model a signature is trusted if it matches the committer
// - it doesn't matter if they're a collaborator, the owner, Gitea or Github
// NB: This model is commit verification only
- if trustModel == repo_model.CommitterTrustModel {
+ if repoTrustModel == repo_model.CommitterTrustModel {
// default to "unmatched"
verification.TrustStatus = "unmatched"
@@ -482,7 +480,7 @@ func CalculateTrustStatus(verification *CommitVerification, repository *repo_mod
// However in the repo_model.CollaboratorCommitterTrustModel we cannot mark this as trusted
// unless the default key matches the email of a non-user.
- if trustModel == repo_model.CollaboratorCommitterTrustModel && (verification.CommittingUser.ID != 0 ||
+ if repoTrustModel == repo_model.CollaboratorCommitterTrustModel && (verification.CommittingUser.ID != 0 ||
verification.SigningUser.Email != verification.CommittingUser.Email) {
verification.TrustStatus = "untrusted"
}
@@ -494,11 +492,11 @@ func CalculateTrustStatus(verification *CommitVerification, repository *repo_mod
var has bool
isMember, has = (*keyMap)[verification.SigningKey.KeyID]
if !has {
- isMember, err = IsOwnerMemberCollaborator(repository, verification.SigningUser.ID)
+ isMember, err = isCodeReader(verification.SigningUser)
(*keyMap)[verification.SigningKey.KeyID] = isMember
}
} else {
- isMember, err = IsOwnerMemberCollaborator(repository, verification.SigningUser.ID)
+ isMember, err = isCodeReader(verification.SigningUser)
}
if !isMember {
@@ -508,7 +506,7 @@ func CalculateTrustStatus(verification *CommitVerification, repository *repo_mod
// This should be marked as questionable unless the signing user is a collaborator/team member etc.
verification.TrustStatus = "unmatched"
}
- } else if trustModel == repo_model.CollaboratorCommitterTrustModel && verification.CommittingUser.ID != verification.SigningUser.ID {
+ } else if repoTrustModel == repo_model.CollaboratorCommitterTrustModel && verification.CommittingUser.ID != verification.SigningUser.ID {
// The committing user and the signing user are not the same and our trustmodel states that they must match
verification.TrustStatus = "unmatched"
}
diff --git a/models/gpg_key_common.go b/models/asymkey/gpg_key_common.go
index 72803625ee..1ea510c45f 100644
--- a/models/gpg_key_common.go
+++ b/models/asymkey/gpg_key_common.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"bytes"
diff --git a/models/gpg_key_import.go b/models/asymkey/gpg_key_import.go
index 1eed929627..210c4b835b 100644
--- a/models/gpg_key_import.go
+++ b/models/asymkey/gpg_key_import.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import "code.gitea.io/gitea/models/db"
diff --git a/models/gpg_key_test.go b/models/asymkey/gpg_key_test.go
index 8f51c146aa..07bb77bdf4 100644
--- a/models/gpg_key_test.go
+++ b/models/asymkey/gpg_key_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"testing"
diff --git a/models/gpg_key_verify.go b/models/asymkey/gpg_key_verify.go
index 1824086021..152765cc3a 100644
--- a/models/gpg_key_verify.go
+++ b/models/asymkey/gpg_key_verify.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"strconv"
diff --git a/models/asymkey/main_test.go b/models/asymkey/main_test.go
new file mode 100644
index 0000000000..1c4f7752e2
--- /dev/null
+++ b/models/asymkey/main_test.go
@@ -0,0 +1,29 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package asymkey
+
+import (
+ "path/filepath"
+ "testing"
+
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/setting"
+)
+
+func init() {
+ setting.SetCustomPathAndConf("", "", "")
+ setting.LoadForTest()
+}
+
+func TestMain(m *testing.M) {
+ unittest.MainTest(m, filepath.Join("..", ".."),
+ "gpg_key.yml",
+ "public_key.yml",
+ "deploy_key.yml",
+ "gpg_key_import.yml",
+ "user.yml",
+ "email_address.yml",
+ )
+}
diff --git a/models/ssh_key.go b/models/asymkey/ssh_key.go
index 0d97096149..cc63663221 100644
--- a/models/ssh_key.go
+++ b/models/asymkey/ssh_key.go
@@ -3,9 +3,10 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
+ "context"
"fmt"
"strings"
"time"
@@ -247,13 +248,13 @@ func UpdatePublicKeyUpdated(id int64) error {
return nil
}
-// deletePublicKeys does the actual key deletion but does not update authorized_keys file.
-func deletePublicKeys(e db.Engine, keyIDs ...int64) error {
+// DeletePublicKeys does the actual key deletion but does not update authorized_keys file.
+func DeletePublicKeys(ctx context.Context, keyIDs ...int64) error {
if len(keyIDs) == 0 {
return nil
}
- _, err := e.In("id", keyIDs).Delete(new(PublicKey))
+ _, err := db.GetEngine(ctx).In("id", keyIDs).Delete(new(PublicKey))
return err
}
@@ -325,40 +326,6 @@ func PublicKeyIsExternallyManaged(id int64) (bool, error) {
return false, nil
}
-// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
-func DeletePublicKey(doer *user_model.User, id int64) (err error) {
- key, err := GetPublicKeyByID(id)
- if err != nil {
- return err
- }
-
- // Check if user has access to delete this key.
- if !doer.IsAdmin && doer.ID != key.OwnerID {
- return ErrKeyAccessDenied{doer.ID, key.ID, "public"}
- }
-
- ctx, committer, err := db.TxContext()
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if err = deletePublicKeys(db.GetEngine(ctx), id); err != nil {
- return err
- }
-
- if err = committer.Commit(); err != nil {
- return err
- }
- committer.Close()
-
- if key.Type == KeyTypePrincipal {
- return RewriteAllPrincipalKeys()
- }
-
- return RewriteAllPublicKeys()
-}
-
// deleteKeysMarkedForDeletion returns true if ssh keys needs update
func deleteKeysMarkedForDeletion(keys []string) (bool, error) {
// Start session
@@ -377,7 +344,7 @@ func deleteKeysMarkedForDeletion(keys []string) (bool, error) {
log.Error("SearchPublicKeyByContent: %v", err)
continue
}
- if err = deletePublicKeys(sess, key.ID); err != nil {
+ if err = DeletePublicKeys(ctx, key.ID); err != nil {
log.Error("deletePublicKeys: %v", err)
continue
}
diff --git a/models/ssh_key_authorized_keys.go b/models/asymkey/ssh_key_authorized_keys.go
index 7843390ffc..dd058f5d11 100644
--- a/models/ssh_key_authorized_keys.go
+++ b/models/asymkey/ssh_key_authorized_keys.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"bufio"
@@ -118,10 +118,6 @@ func appendAuthorizedKeysToFile(keys ...*PublicKey) error {
// Note: db.GetEngine(db.DefaultContext).Iterate does not get latest data after insert/delete, so we have to call this function
// outside any session scope independently.
func RewriteAllPublicKeys() error {
- return rewriteAllPublicKeys(db.GetEngine(db.DefaultContext))
-}
-
-func rewriteAllPublicKeys(e db.Engine) error {
// Don't rewrite key if internal server
if setting.SSH.StartBuiltinServer || !setting.SSH.CreateAuthorizedKeysFile {
return nil
@@ -169,7 +165,7 @@ func rewriteAllPublicKeys(e db.Engine) error {
}
}
- if err := regeneratePublicKeys(e, t); err != nil {
+ if err := RegeneratePublicKeys(t); err != nil {
return err
}
diff --git a/models/ssh_key_authorized_principals.go b/models/asymkey/ssh_key_authorized_principals.go
index c053b4b6d5..a8c48c50aa 100644
--- a/models/ssh_key_authorized_principals.go
+++ b/models/asymkey/ssh_key_authorized_principals.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"bufio"
diff --git a/models/ssh_key_deploy.go b/models/asymkey/ssh_key_deploy.go
index 672974afb3..fc6324792a 100644
--- a/models/ssh_key_deploy.go
+++ b/models/asymkey/ssh_key_deploy.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"context"
@@ -11,8 +11,6 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/builder"
@@ -169,13 +167,9 @@ func AddDeployKey(repoID int64, name, content string, readOnly bool) (*DeployKey
}
// GetDeployKeyByID returns deploy key by given ID.
-func GetDeployKeyByID(id int64) (*DeployKey, error) {
- return getDeployKeyByID(db.GetEngine(db.DefaultContext), id)
-}
-
-func getDeployKeyByID(e db.Engine, id int64) (*DeployKey, error) {
+func GetDeployKeyByID(ctx context.Context, id int64) (*DeployKey, error) {
key := new(DeployKey)
- has, err := e.ID(id).Get(key)
+ has, err := db.GetEngine(ctx).ID(id).Get(key)
if err != nil {
return nil, err
} else if !has {
@@ -215,68 +209,6 @@ func UpdateDeployKey(key *DeployKey) error {
return err
}
-// DeleteDeployKey deletes deploy key from its repository authorized_keys file if needed.
-func DeleteDeployKey(doer *user_model.User, id int64) error {
- ctx, committer, err := db.TxContext()
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if err := deleteDeployKey(ctx, doer, id); err != nil {
- return err
- }
- return committer.Commit()
-}
-
-func deleteDeployKey(ctx context.Context, doer *user_model.User, id int64) error {
- sess := db.GetEngine(ctx)
- key, err := getDeployKeyByID(sess, id)
- if err != nil {
- if IsErrDeployKeyNotExist(err) {
- return nil
- }
- return fmt.Errorf("GetDeployKeyByID: %v", err)
- }
-
- // Check if user has access to delete this key.
- if !doer.IsAdmin {
- repo, err := repo_model.GetRepositoryByIDCtx(ctx, key.RepoID)
- if err != nil {
- return fmt.Errorf("repo_model.GetRepositoryByID: %v", err)
- }
- has, err := isUserRepoAdmin(sess, repo, doer)
- if err != nil {
- return fmt.Errorf("GetUserRepoPermission: %v", err)
- } else if !has {
- return ErrKeyAccessDenied{doer.ID, key.ID, "deploy"}
- }
- }
-
- if _, err = sess.ID(key.ID).Delete(new(DeployKey)); err != nil {
- return fmt.Errorf("delete deploy key [%d]: %v", key.ID, err)
- }
-
- // Check if this is the last reference to same key content.
- has, err := sess.
- Where("key_id = ?", key.KeyID).
- Get(new(DeployKey))
- if err != nil {
- return err
- } else if !has {
- if err = deletePublicKeys(sess, key.KeyID); err != nil {
- return err
- }
-
- // after deleted the public keys, should rewrite the public keys file
- if err = rewriteAllPublicKeys(sess); err != nil {
- return err
- }
- }
-
- return nil
-}
-
// ListDeployKeysOptions are options for ListDeployKeys
type ListDeployKeysOptions struct {
db.ListOptions
@@ -300,12 +232,8 @@ func (opt ListDeployKeysOptions) toCond() builder.Cond {
}
// ListDeployKeys returns a list of deploy keys matching the provided arguments.
-func ListDeployKeys(opts *ListDeployKeysOptions) ([]*DeployKey, error) {
- return listDeployKeys(db.GetEngine(db.DefaultContext), opts)
-}
-
-func listDeployKeys(e db.Engine, opts *ListDeployKeysOptions) ([]*DeployKey, error) {
- sess := e.Where(opts.toCond())
+func ListDeployKeys(ctx context.Context, opts *ListDeployKeysOptions) ([]*DeployKey, error) {
+ sess := db.GetEngine(ctx).Where(opts.toCond())
if opts.Page != 0 {
sess = db.SetSessionPagination(sess, opts)
diff --git a/models/ssh_key_fingerprint.go b/models/asymkey/ssh_key_fingerprint.go
index 85296c961c..437f283bfa 100644
--- a/models/ssh_key_fingerprint.go
+++ b/models/asymkey/ssh_key_fingerprint.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"errors"
diff --git a/models/ssh_key_parse.go b/models/asymkey/ssh_key_parse.go
index 748c66da7d..734bd4ccab 100644
--- a/models/ssh_key_parse.go
+++ b/models/asymkey/ssh_key_parse.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"crypto/rsa"
@@ -18,6 +18,7 @@ import (
"strconv"
"strings"
+ "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting"
@@ -157,7 +158,7 @@ func parseKeyString(content string) (string, error) {
// It returns the actual public key line on success.
func CheckPublicKeyString(content string) (_ string, err error) {
if setting.SSH.Disabled {
- return "", ErrSSHDisabled{}
+ return "", db.ErrSSHDisabled{}
}
content, err = parseKeyString(content)
diff --git a/models/ssh_key_principals.go b/models/asymkey/ssh_key_principals.go
index 9a17a56f1a..19fc6644cb 100644
--- a/models/ssh_key_principals.go
+++ b/models/asymkey/ssh_key_principals.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"errors"
@@ -76,7 +76,7 @@ func addPrincipalKey(e db.Engine, key *PublicKey) (err error) {
// CheckPrincipalKeyString strips spaces and returns an error if the given principal contains newlines
func CheckPrincipalKeyString(user *user_model.User, content string) (_ string, err error) {
if setting.SSH.Disabled {
- return "", ErrSSHDisabled{}
+ return "", db.ErrSSHDisabled{}
}
content = strings.TrimSpace(content)
diff --git a/models/ssh_key_test.go b/models/asymkey/ssh_key_test.go
index b52a36bdbd..62c07c6035 100644
--- a/models/ssh_key_test.go
+++ b/models/asymkey/ssh_key_test.go
@@ -3,7 +3,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package asymkey
import (
"strings"
@@ -14,11 +14,6 @@ import (
"github.com/stretchr/testify/assert"
)
-func init() {
- setting.SetCustomPathAndConf("", "", "")
- setting.LoadForTest()
-}
-
func Test_SSHParsePublicKey(t *testing.T) {
testCases := []struct {
name string
diff --git a/models/commit.go b/models/commit.go
index 8de71da1b3..5df6964a1d 100644
--- a/models/commit.go
+++ b/models/commit.go
@@ -5,6 +5,7 @@
package models
import (
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
@@ -13,9 +14,12 @@ import (
// ConvertFromGitCommit converts git commits into SignCommitWithStatuses
func ConvertFromGitCommit(commits []*git.Commit, repo *repo_model.Repository) []*SignCommitWithStatuses {
return ParseCommitsWithStatus(
- ParseCommitsWithSignature(
+ asymkey_model.ParseCommitsWithSignature(
user_model.ValidateCommitsWithEmails(commits),
- repo,
+ repo.GetTrustModel(),
+ func(user *user_model.User) (bool, error) {
+ return IsUserRepoAdmin(repo, user)
+ },
),
repo,
)
diff --git a/models/commit_status.go b/models/commit_status.go
index e0942d2028..93b6f93f96 100644
--- a/models/commit_status.go
+++ b/models/commit_status.go
@@ -12,6 +12,7 @@ import (
"strings"
"time"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
@@ -328,11 +329,11 @@ func NewCommitStatus(opts NewCommitStatusOptions) error {
type SignCommitWithStatuses struct {
Status *CommitStatus
Statuses []*CommitStatus
- *SignCommit
+ *asymkey_model.SignCommit
}
// ParseCommitsWithStatus checks commits latest statuses and calculates its worst status state
-func ParseCommitsWithStatus(oldCommits []*SignCommit, repo *repo_model.Repository) []*SignCommitWithStatuses {
+func ParseCommitsWithStatus(oldCommits []*asymkey_model.SignCommit, repo *repo_model.Repository) []*SignCommitWithStatuses {
newCommits := make([]*SignCommitWithStatuses, 0, len(oldCommits))
for _, c := range oldCommits {
diff --git a/models/db/error.go b/models/db/error.go
index adaeedcc09..f20cc9b4cb 100644
--- a/models/db/error.go
+++ b/models/db/error.go
@@ -29,3 +29,16 @@ func ErrCancelledf(format string, args ...interface{}) error {
fmt.Sprintf(format, args...),
}
}
+
+// ErrSSHDisabled represents an "SSH disabled" error.
+type ErrSSHDisabled struct{}
+
+// IsErrSSHDisabled checks if an error is a ErrSSHDisabled.
+func IsErrSSHDisabled(err error) bool {
+ _, ok := err.(ErrSSHDisabled)
+ return ok
+}
+
+func (err ErrSSHDisabled) Error() string {
+ return "SSH is disabled"
+}
diff --git a/models/error.go b/models/error.go
index 20ed7f90e1..54556fd787 100644
--- a/models/error.go
+++ b/models/error.go
@@ -28,19 +28,6 @@ func (err ErrNotExist) Error() string {
return fmt.Sprintf("record does not exist [id: %d]", err.ID)
}
-// ErrSSHDisabled represents an "SSH disabled" error.
-type ErrSSHDisabled struct{}
-
-// IsErrSSHDisabled checks if an error is a ErrSSHDisabled.
-func IsErrSSHDisabled(err error) bool {
- _, ok := err.(ErrSSHDisabled)
- return ok
-}
-
-func (err ErrSSHDisabled) Error() string {
- return "SSH is disabled"
-}
-
// ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
type ErrUserOwnRepos struct {
UID int64
@@ -151,254 +138,6 @@ func (err ErrWikiInvalidFileName) Error() string {
return fmt.Sprintf("Invalid wiki filename: %s", err.FileName)
}
-// __________ ___. .__ .__ ____ __.
-// \______ \__ _\_ |__ | | |__| ____ | |/ _|____ ___.__.
-// | ___/ | \ __ \| | | |/ ___\ | <_/ __ < | |
-// | | | | / \_\ \ |_| \ \___ | | \ ___/\___ |
-// |____| |____/|___ /____/__|\___ > |____|__ \___ > ____|
-// \/ \/ \/ \/\/
-
-// ErrKeyUnableVerify represents a "KeyUnableVerify" kind of error.
-type ErrKeyUnableVerify struct {
- Result string
-}
-
-// IsErrKeyUnableVerify checks if an error is a ErrKeyUnableVerify.
-func IsErrKeyUnableVerify(err error) bool {
- _, ok := err.(ErrKeyUnableVerify)
- return ok
-}
-
-func (err ErrKeyUnableVerify) Error() string {
- return fmt.Sprintf("Unable to verify key content [result: %s]", err.Result)
-}
-
-// ErrKeyNotExist represents a "KeyNotExist" kind of error.
-type ErrKeyNotExist struct {
- ID int64
-}
-
-// IsErrKeyNotExist checks if an error is a ErrKeyNotExist.
-func IsErrKeyNotExist(err error) bool {
- _, ok := err.(ErrKeyNotExist)
- return ok
-}
-
-func (err ErrKeyNotExist) Error() string {
- return fmt.Sprintf("public key does not exist [id: %d]", err.ID)
-}
-
-// ErrKeyAlreadyExist represents a "KeyAlreadyExist" kind of error.
-type ErrKeyAlreadyExist struct {
- OwnerID int64
- Fingerprint string
- Content string
-}
-
-// IsErrKeyAlreadyExist checks if an error is a ErrKeyAlreadyExist.
-func IsErrKeyAlreadyExist(err error) bool {
- _, ok := err.(ErrKeyAlreadyExist)
- return ok
-}
-
-func (err ErrKeyAlreadyExist) Error() string {
- return fmt.Sprintf("public key already exists [owner_id: %d, finger_print: %s, content: %s]",
- err.OwnerID, err.Fingerprint, err.Content)
-}
-
-// ErrKeyNameAlreadyUsed represents a "KeyNameAlreadyUsed" kind of error.
-type ErrKeyNameAlreadyUsed struct {
- OwnerID int64
- Name string
-}
-
-// IsErrKeyNameAlreadyUsed checks if an error is a ErrKeyNameAlreadyUsed.
-func IsErrKeyNameAlreadyUsed(err error) bool {
- _, ok := err.(ErrKeyNameAlreadyUsed)
- return ok
-}
-
-func (err ErrKeyNameAlreadyUsed) Error() string {
- return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name)
-}
-
-// ErrGPGNoEmailFound represents a "ErrGPGNoEmailFound" kind of error.
-type ErrGPGNoEmailFound struct {
- FailedEmails []string
- ID string
-}
-
-// IsErrGPGNoEmailFound checks if an error is a ErrGPGNoEmailFound.
-func IsErrGPGNoEmailFound(err error) bool {
- _, ok := err.(ErrGPGNoEmailFound)
- return ok
-}
-
-func (err ErrGPGNoEmailFound) Error() string {
- return fmt.Sprintf("none of the emails attached to the GPG key could be found: %v", err.FailedEmails)
-}
-
-// ErrGPGInvalidTokenSignature represents a "ErrGPGInvalidTokenSignature" kind of error.
-type ErrGPGInvalidTokenSignature struct {
- Wrapped error
- ID string
-}
-
-// IsErrGPGInvalidTokenSignature checks if an error is a ErrGPGInvalidTokenSignature.
-func IsErrGPGInvalidTokenSignature(err error) bool {
- _, ok := err.(ErrGPGInvalidTokenSignature)
- return ok
-}
-
-func (err ErrGPGInvalidTokenSignature) Error() string {
- return "the provided signature does not sign the token with the provided key"
-}
-
-// ErrGPGKeyParsing represents a "ErrGPGKeyParsing" kind of error.
-type ErrGPGKeyParsing struct {
- ParseError error
-}
-
-// IsErrGPGKeyParsing checks if an error is a ErrGPGKeyParsing.
-func IsErrGPGKeyParsing(err error) bool {
- _, ok := err.(ErrGPGKeyParsing)
- return ok
-}
-
-func (err ErrGPGKeyParsing) Error() string {
- return fmt.Sprintf("failed to parse gpg key %s", err.ParseError.Error())
-}
-
-// ErrGPGKeyNotExist represents a "GPGKeyNotExist" kind of error.
-type ErrGPGKeyNotExist struct {
- ID int64
-}
-
-// IsErrGPGKeyNotExist checks if an error is a ErrGPGKeyNotExist.
-func IsErrGPGKeyNotExist(err error) bool {
- _, ok := err.(ErrGPGKeyNotExist)
- return ok
-}
-
-func (err ErrGPGKeyNotExist) Error() string {
- return fmt.Sprintf("public gpg key does not exist [id: %d]", err.ID)
-}
-
-// ErrGPGKeyImportNotExist represents a "GPGKeyImportNotExist" kind of error.
-type ErrGPGKeyImportNotExist struct {
- ID string
-}
-
-// IsErrGPGKeyImportNotExist checks if an error is a ErrGPGKeyImportNotExist.
-func IsErrGPGKeyImportNotExist(err error) bool {
- _, ok := err.(ErrGPGKeyImportNotExist)
- return ok
-}
-
-func (err ErrGPGKeyImportNotExist) Error() string {
- return fmt.Sprintf("public gpg key import does not exist [id: %s]", err.ID)
-}
-
-// ErrGPGKeyIDAlreadyUsed represents a "GPGKeyIDAlreadyUsed" kind of error.
-type ErrGPGKeyIDAlreadyUsed struct {
- KeyID string
-}
-
-// IsErrGPGKeyIDAlreadyUsed checks if an error is a ErrKeyNameAlreadyUsed.
-func IsErrGPGKeyIDAlreadyUsed(err error) bool {
- _, ok := err.(ErrGPGKeyIDAlreadyUsed)
- return ok
-}
-
-func (err ErrGPGKeyIDAlreadyUsed) Error() string {
- return fmt.Sprintf("public key already exists [key_id: %s]", err.KeyID)
-}
-
-// ErrGPGKeyAccessDenied represents a "GPGKeyAccessDenied" kind of Error.
-type ErrGPGKeyAccessDenied struct {
- UserID int64
- KeyID int64
-}
-
-// IsErrGPGKeyAccessDenied checks if an error is a ErrGPGKeyAccessDenied.
-func IsErrGPGKeyAccessDenied(err error) bool {
- _, ok := err.(ErrGPGKeyAccessDenied)
- return ok
-}
-
-// Error pretty-prints an error of type ErrGPGKeyAccessDenied.
-func (err ErrGPGKeyAccessDenied) Error() string {
- return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d]",
- err.UserID, err.KeyID)
-}
-
-// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
-type ErrKeyAccessDenied struct {
- UserID int64
- KeyID int64
- Note string
-}
-
-// IsErrKeyAccessDenied checks if an error is a ErrKeyAccessDenied.
-func IsErrKeyAccessDenied(err error) bool {
- _, ok := err.(ErrKeyAccessDenied)
- return ok
-}
-
-func (err ErrKeyAccessDenied) Error() string {
- return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d, note: %s]",
- err.UserID, err.KeyID, err.Note)
-}
-
-// ErrDeployKeyNotExist represents a "DeployKeyNotExist" kind of error.
-type ErrDeployKeyNotExist struct {
- ID int64
- KeyID int64
- RepoID int64
-}
-
-// IsErrDeployKeyNotExist checks if an error is a ErrDeployKeyNotExist.
-func IsErrDeployKeyNotExist(err error) bool {
- _, ok := err.(ErrDeployKeyNotExist)
- return ok
-}
-
-func (err ErrDeployKeyNotExist) Error() string {
- return fmt.Sprintf("Deploy key does not exist [id: %d, key_id: %d, repo_id: %d]", err.ID, err.KeyID, err.RepoID)
-}
-
-// ErrDeployKeyAlreadyExist represents a "DeployKeyAlreadyExist" kind of error.
-type ErrDeployKeyAlreadyExist struct {
- KeyID int64
- RepoID int64
-}
-
-// IsErrDeployKeyAlreadyExist checks if an error is a ErrDeployKeyAlreadyExist.
-func IsErrDeployKeyAlreadyExist(err error) bool {
- _, ok := err.(ErrDeployKeyAlreadyExist)
- return ok
-}
-
-func (err ErrDeployKeyAlreadyExist) Error() string {
- return fmt.Sprintf("public key already exists [key_id: %d, repo_id: %d]", err.KeyID, err.RepoID)
-}
-
-// ErrDeployKeyNameAlreadyUsed represents a "DeployKeyNameAlreadyUsed" kind of error.
-type ErrDeployKeyNameAlreadyUsed struct {
- RepoID int64
- Name string
-}
-
-// IsErrDeployKeyNameAlreadyUsed checks if an error is a ErrDeployKeyNameAlreadyUsed.
-func IsErrDeployKeyNameAlreadyUsed(err error) bool {
- _, ok := err.(ErrDeployKeyNameAlreadyUsed)
- return ok
-}
-
-func (err ErrDeployKeyNameAlreadyUsed) Error() string {
- return fmt.Sprintf("public key with name already exists [repo_id: %d, name: %s]", err.RepoID, err.Name)
-}
-
// _____ ___________ __
// / _ \ ____ ____ ____ ______ _____\__ ___/___ | | __ ____ ____
// / /_\ \_/ ___\/ ___\/ __ \ / ___// ___/ | | / _ \| |/ // __ \ / \
@@ -878,22 +617,6 @@ func (err ErrUserDoesNotHaveAccessToRepo) Error() string {
return fmt.Sprintf("user doesn't have access to repo [user_id: %d, repo_name: %s]", err.UserID, err.RepoName)
}
-// ErrWontSign explains the first reason why a commit would not be signed
-// There may be other reasons - this is just the first reason found
-type ErrWontSign struct {
- Reason signingMode
-}
-
-func (e *ErrWontSign) Error() string {
- return fmt.Sprintf("wont sign: %s", e.Reason)
-}
-
-// IsErrWontSign checks if an error is a ErrWontSign
-func IsErrWontSign(err error) bool {
- _, ok := err.(*ErrWontSign)
- return ok
-}
-
// __________ .__
// \______ \____________ ____ ____ | |__
// | | _/\_ __ \__ \ / \_/ ___\| | \
diff --git a/models/main_test.go b/models/main_test.go
index 20107eab1e..8d5291a8aa 100644
--- a/models/main_test.go
+++ b/models/main_test.go
@@ -10,10 +10,16 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
+func init() {
+ setting.SetCustomPathAndConf("", "", "")
+ setting.LoadForTest()
+}
+
// TestFixturesAreConsistent assert that test fixtures are consistent
func TestFixturesAreConsistent(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
diff --git a/models/pull_sign.go b/models/pull_sign.go
deleted file mode 100644
index 269e8e06d2..0000000000
--- a/models/pull_sign.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package models
-
-import (
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/login"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
-)
-
-// SignMerge determines if we should sign a PR merge commit to the base repository
-func (pr *PullRequest) SignMerge(u *user_model.User, tmpBasePath, baseCommit, headCommit string) (bool, string, *git.Signature, error) {
- if err := pr.LoadBaseRepo(); err != nil {
- log.Error("Unable to get Base Repo for pull request")
- return false, "", nil, err
- }
- repo := pr.BaseRepo
-
- signingKey, signer := SigningKey(repo.RepoPath())
- if signingKey == "" {
- return false, "", nil, &ErrWontSign{noKey}
- }
- rules := signingModeFromStrings(setting.Repository.Signing.Merges)
-
- var gitRepo *git.Repository
- var err error
-
-Loop:
- for _, rule := range rules {
- switch rule {
- case never:
- return false, "", nil, &ErrWontSign{never}
- case always:
- break Loop
- case pubkey:
- keys, err := ListGPGKeys(u.ID, db.ListOptions{})
- if err != nil {
- return false, "", nil, err
- }
- if len(keys) == 0 {
- return false, "", nil, &ErrWontSign{pubkey}
- }
- case twofa:
- twofaModel, err := login.GetTwoFactorByUID(u.ID)
- if err != nil && !login.IsErrTwoFactorNotEnrolled(err) {
- return false, "", nil, err
- }
- if twofaModel == nil {
- return false, "", nil, &ErrWontSign{twofa}
- }
- case approved:
- protectedBranch, err := GetProtectedBranchBy(repo.ID, pr.BaseBranch)
- if err != nil {
- return false, "", nil, err
- }
- if protectedBranch == nil {
- return false, "", nil, &ErrWontSign{approved}
- }
- if protectedBranch.GetGrantedApprovalsCount(pr) < 1 {
- return false, "", nil, &ErrWontSign{approved}
- }
- case baseSigned:
- if gitRepo == nil {
- gitRepo, err = git.OpenRepository(tmpBasePath)
- if err != nil {
- return false, "", nil, err
- }
- defer gitRepo.Close()
- }
- commit, err := gitRepo.GetCommit(baseCommit)
- if err != nil {
- return false, "", nil, err
- }
- verification := ParseCommitWithSignature(commit)
- if !verification.Verified {
- return false, "", nil, &ErrWontSign{baseSigned}
- }
- case headSigned:
- if gitRepo == nil {
- gitRepo, err = git.OpenRepository(tmpBasePath)
- if err != nil {
- return false, "", nil, err
- }
- defer gitRepo.Close()
- }
- commit, err := gitRepo.GetCommit(headCommit)
- if err != nil {
- return false, "", nil, err
- }
- verification := ParseCommitWithSignature(commit)
- if !verification.Verified {
- return false, "", nil, &ErrWontSign{headSigned}
- }
- case commitsSigned:
- if gitRepo == nil {
- gitRepo, err = git.OpenRepository(tmpBasePath)
- if err != nil {
- return false, "", nil, err
- }
- defer gitRepo.Close()
- }
- commit, err := gitRepo.GetCommit(headCommit)
- if err != nil {
- return false, "", nil, err
- }
- verification := ParseCommitWithSignature(commit)
- if !verification.Verified {
- return false, "", nil, &ErrWontSign{commitsSigned}
- }
- // need to work out merge-base
- mergeBaseCommit, _, err := gitRepo.GetMergeBase("", baseCommit, headCommit)
- if err != nil {
- return false, "", nil, err
- }
- commitList, err := commit.CommitsBeforeUntil(mergeBaseCommit)
- if err != nil {
- return false, "", nil, err
- }
- for _, commit := range commitList {
- verification := ParseCommitWithSignature(commit)
- if !verification.Verified {
- return false, "", nil, &ErrWontSign{commitsSigned}
- }
- }
- }
- }
- return true, signingKey, signer, nil
-}
diff --git a/models/repo.go b/models/repo.go
index 6bdc4c20d2..adc62c9528 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -20,6 +20,7 @@ import (
_ "image/jpeg" // Needed for jpeg support
admin_model "code.gitea.io/gitea/models/admin"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
@@ -856,12 +857,13 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
}
// Delete Deploy Keys
- deployKeys, err := listDeployKeys(sess, &ListDeployKeysOptions{RepoID: repoID})
+ deployKeys, err := asymkey_model.ListDeployKeys(ctx, &asymkey_model.ListDeployKeysOptions{RepoID: repoID})
if err != nil {
return fmt.Errorf("listDeployKeys: %v", err)
}
+ var needRewriteKeysFile = len(deployKeys) > 0
for _, dKey := range deployKeys {
- if err := deleteDeployKey(ctx, doer, dKey.ID); err != nil {
+ if err := DeleteDeployKey(ctx, doer, dKey.ID); err != nil {
return fmt.Errorf("deleteDeployKeys: %v", err)
}
}
@@ -1049,6 +1051,12 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
committer.Close()
+ if needRewriteKeysFile {
+ if err := asymkey_model.RewriteAllPublicKeys(); err != nil {
+ log.Error("RewriteAllPublicKeys failed: %v", err)
+ }
+ }
+
// We should always delete the files after the database transaction succeed. If
// we delete the file but the database rollback, the repository will be broken.
@@ -1407,3 +1415,52 @@ func LinkedRepository(a *repo_model.Attachment) (*repo_model.Repository, unit.Ty
}
return nil, -1, nil
}
+
+// DeleteDeployKey delete deploy keys
+func DeleteDeployKey(ctx context.Context, doer *user_model.User, id int64) error {
+ key, err := asymkey_model.GetDeployKeyByID(ctx, id)
+ if err != nil {
+ if asymkey_model.IsErrDeployKeyNotExist(err) {
+ return nil
+ }
+ return fmt.Errorf("GetDeployKeyByID: %v", err)
+ }
+
+ sess := db.GetEngine(ctx)
+
+ // Check if user has access to delete this key.
+ if !doer.IsAdmin {
+ repo, err := repo_model.GetRepositoryByIDCtx(ctx, key.RepoID)
+ if err != nil {
+ return fmt.Errorf("GetRepositoryByID: %v", err)
+ }
+ has, err := isUserRepoAdmin(sess, repo, doer)
+ if err != nil {
+ return fmt.Errorf("GetUserRepoPermission: %v", err)
+ } else if !has {
+ return asymkey_model.ErrKeyAccessDenied{
+ UserID: doer.ID,
+ KeyID: key.ID,
+ Note: "deploy",
+ }
+ }
+ }
+
+ if _, err = sess.ID(key.ID).Delete(new(asymkey_model.DeployKey)); err != nil {
+ return fmt.Errorf("delete deploy key [%d]: %v", key.ID, err)
+ }
+
+ // Check if this is the last reference to same key content.
+ has, err := sess.
+ Where("key_id = ?", key.KeyID).
+ Get(new(asymkey_model.DeployKey))
+ if err != nil {
+ return err
+ } else if !has {
+ if err = asymkey_model.DeletePublicKeys(ctx, key.KeyID); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/models/statistic.go b/models/statistic.go
index 055f312c11..175815081f 100644
--- a/models/statistic.go
+++ b/models/statistic.go
@@ -5,6 +5,7 @@
package models
import (
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/login"
repo_model "code.gitea.io/gitea/models/repo"
@@ -47,7 +48,7 @@ func GetStatistic() (stats Statistic) {
e := db.GetEngine(db.DefaultContext)
stats.Counter.User = user_model.CountUsers()
stats.Counter.Org = CountOrganizations()
- stats.Counter.PublicKey, _ = e.Count(new(PublicKey))
+ stats.Counter.PublicKey, _ = e.Count(new(asymkey_model.PublicKey))
stats.Counter.Repo = repo_model.CountRepositories(true)
stats.Counter.Watch, _ = e.Count(new(Watch))
stats.Counter.Star, _ = e.Count(new(Star))
diff --git a/models/user.go b/models/user.go
index 1427833e21..2a727dd124 100644
--- a/models/user.go
+++ b/models/user.go
@@ -12,6 +12,7 @@ import (
_ "image/jpeg" // Needed for jpeg support
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
@@ -234,23 +235,23 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {
}
// ***** START: PublicKey *****
- if _, err = e.Delete(&PublicKey{OwnerID: u.ID}); err != nil {
+ if _, err = e.Delete(&asymkey_model.PublicKey{OwnerID: u.ID}); err != nil {
return fmt.Errorf("deletePublicKeys: %v", err)
}
// ***** END: PublicKey *****
// ***** START: GPGPublicKey *****
- keys, err := listGPGKeys(e, u.ID, db.ListOptions{})
+ keys, err := asymkey_model.ListGPGKeys(ctx, u.ID, db.ListOptions{})
if err != nil {
return fmt.Errorf("ListGPGKeys: %v", err)
}
// Delete GPGKeyImport(s).
for _, key := range keys {
- if _, err = e.Delete(&GPGKeyImport{KeyID: key.KeyID}); err != nil {
+ if _, err = e.Delete(&asymkey_model.GPGKeyImport{KeyID: key.KeyID}); err != nil {
return fmt.Errorf("deleteGPGKeyImports: %v", err)
}
}
- if _, err = e.Delete(&GPGKey{OwnerID: u.ID}); err != nil {
+ if _, err = e.Delete(&asymkey_model.GPGKey{OwnerID: u.ID}); err != nil {
return fmt.Errorf("deleteGPGKeys: %v", err)
}
// ***** END: GPGPublicKey *****
diff --git a/models/user_test.go b/models/user_test.go
index d3c7718d69..4749a3af73 100644
--- a/models/user_test.go
+++ b/models/user_test.go
@@ -8,7 +8,6 @@ import (
"fmt"
"testing"
- "code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -121,71 +120,3 @@ func TestGetOrgRepositoryIDs(t *testing.T) {
// User 5's team has no access to any repo
assert.Len(t, accessibleRepos, 0)
}
-
-func TestAddLdapSSHPublicKeys(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
-
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- s := &login.Source{ID: 1}
-
- testCases := []struct {
- keyString string
- number int
- keyContents []string
- }{
- {
- keyString: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n",
- number: 1,
- keyContents: []string{
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
- },
- },
- {
- keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment
-ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`,
- number: 2,
- keyContents: []string{
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
- "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=",
- },
- },
- {
- keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment
-# comment asmdna,ndp
-ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`,
- number: 2,
- keyContents: []string{
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
- "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=",
- },
- },
- {
- keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment
-382488320jasdj1lasmva/vasodifipi4193-fksma.cm
-ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`,
- number: 2,
- keyContents: []string{
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
- "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=",
- },
- },
- }
-
- for i, kase := range testCases {
- s.ID = int64(i) + 20
- AddPublicKeysBySource(user, s, []string{kase.keyString})
- keys, err := ListPublicKeysBySource(user.ID, s.ID)
- assert.NoError(t, err)
- if err != nil {
- continue
- }
- assert.Len(t, keys, kase.number)
-
- for _, key := range keys {
- assert.Contains(t, kase.keyContents, key.Content)
- }
- for _, key := range keys {
- DeletePublicKey(user, key.ID)
- }
- }
-}
diff --git a/modules/context/repo.go b/modules/context/repo.go
index 694c483bd4..1725cb724d 100644
--- a/modules/context/repo.go
+++ b/modules/context/repo.go
@@ -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"
diff --git a/modules/convert/convert.go b/modules/convert/convert.go
index eda9f23cd6..1c78c35cda 100644
--- a/modules/convert/convert.go
+++ b/modules/convert/convert.go
@@ -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,
diff --git a/modules/doctor/authorizedkeys.go b/modules/doctor/authorizedkeys.go
index d9bc70bb77..1a9b60e248 100644
--- a/modules/doctor/authorizedkeys.go
+++ b/modules/doctor/authorizedkeys.go
@@ -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)
diff --git a/modules/gitgraph/graph_models.go b/modules/gitgraph/graph_models.go
index e7280e2adc..4cfa96816a 100644
--- a/modules/gitgraph/graph_models.go
+++ b/modules/gitgraph/graph_models.go
@@ -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
diff --git a/modules/private/serv.go b/modules/private/serv.go
index 4f5b19c597..a7a56df7b3 100644
--- a/modules/private/serv.go
+++ b/modules/private/serv.go
@@ -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()
diff --git a/modules/repository/init.go b/modules/repository/init.go
index cfee1a3215..08c5aac1b8 100644
--- a/modules/repository/init.go
+++ b/modules/repository/init.go
@@ -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)
diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go
index 5f19dd4a5c..a3756fd2af 100644
--- a/modules/ssh/ssh.go
+++ b/modules/ssh/ssh.go
@@ -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())
diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go
index b93c628072..44358b4bef 100644
--- a/routers/api/v1/admin/user.go
+++ b/routers/api/v1/admin/user.go
@@ -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)
diff --git a/routers/api/v1/misc/signing.go b/routers/api/v1/misc/signing.go
index 3c3391bfe7..e2833173a3 100644
--- a/routers/api/v1/misc/signing.go
+++ b/routers/api/v1/misc/signing.go
@@ -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
diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go
index 03ebcb8f72..669cc7c51c 100644
--- a/routers/api/v1/repo/key.go
+++ b/routers/api/v1/repo/key.go
@@ -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)
diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go
index 3e37da24ec..e593819dac 100644
--- a/routers/api/v1/repo/pull.go
+++ b/routers/api/v1/repo/pull.go
@@ -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
}
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 4486e33fe8..62f9c37244 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -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
}
diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go
index 9066268bba..b0f9f1feb3 100644
--- a/routers/api/v1/user/gpg_key.go
+++ b/routers/api/v1/user/gpg_key.go
@@ -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)
diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go
index 32291264bc..e8cc2035e5 100644
--- a/routers/api/v1/user/key.go
+++ b/routers/api/v1/user/key.go
@@ -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)
diff --git a/routers/init.go b/routers/init.go
index 2143ab476b..804dfd6533 100644
--- a/routers/init.go
+++ b/routers/init.go
@@ -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)
diff --git a/routers/private/hook_verification.go b/routers/private/hook_verification.go
index 8c7492ea68..1b44550cff 100644
--- a/routers/private/hook_verification.go
+++ b/routers/private/hook_verification.go
@@ -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{
diff --git a/routers/private/key.go b/routers/private/key.go
index 4f518e41f0..30fde73c8a 100644
--- a/routers/private/key.go
+++ b/routers/private/key.go
@@ -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(),
diff --git a/routers/private/serv.go b/routers/private/serv.go
index f28d5a7450..e5ebc5aa92 100644
--- a/routers/private/serv.go
+++ b/routers/private/serv.go
@@ -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,
diff --git a/routers/web/admin/repos.go b/routers/web/admin/repos.go
index 7db8b4d337..7e3ec96fce 100644
--- a/routers/web/admin/repos.go
+++ b/routers/web/admin/repos.go
@@ -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
}
diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go
index 5bc9f9eae9..0a51e43cf7 100644
--- a/routers/web/repo/commit.go
+++ b/routers/web/repo/commit.go
@@ -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
}
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index a5eecd0c33..f03a8dfbc2 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -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)
diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go
index 68b53f2e90..bb118a9035 100644
--- a/routers/web/repo/setting.go
+++ b/routers/web/repo/setting.go
@@ -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"))
diff --git a/routers/web/repo/settings_test.go b/routers/web/repo/settings_test.go
index fe6e9b52ba..5b62e1ed16 100644
--- a/routers/web/repo/settings_test.go
+++ b/routers/web/repo/settings_test.go
@@ -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,
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index bc8396ab79..9e0f670cf9 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -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
}
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index d3883571ed..bad621f91f 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -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
}
diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go
index 22a0fe4741..ec55462149 100644
--- a/routers/web/user/setting/keys.go
+++ b/routers/web/user/setting/keys.go
@@ -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
diff --git a/services/asymkey/deploy_key.go b/services/asymkey/deploy_key.go
new file mode 100644
index 0000000000..aa0925ab13
--- /dev/null
+++ b/services/asymkey/deploy_key.go
@@ -0,0 +1,30 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package asymkey
+
+import (
+ "code.gitea.io/gitea/models"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+)
+
+// DeleteDeployKey deletes deploy key from its repository authorized_keys file if needed.
+func DeleteDeployKey(doer *user_model.User, id int64) error {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+
+ if err := models.DeleteDeployKey(ctx, doer, id); err != nil {
+ return err
+ }
+ if err := committer.Commit(); err != nil {
+ return err
+ }
+
+ return asymkey_model.RewriteAllPublicKeys()
+}
diff --git a/services/asymkey/main_test.go b/services/asymkey/main_test.go
new file mode 100644
index 0000000000..a891a10cf6
--- /dev/null
+++ b/services/asymkey/main_test.go
@@ -0,0 +1,16 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package asymkey
+
+import (
+ "path/filepath"
+ "testing"
+
+ "code.gitea.io/gitea/models/unittest"
+)
+
+func TestMain(m *testing.M) {
+ unittest.MainTest(m, filepath.Join("..", ".."))
+}
diff --git a/models/repo_sign.go b/services/asymkey/sign.go
index 1c736a62da..4ccc581803 100644
--- a/models/repo_sign.go
+++ b/services/asymkey/sign.go
@@ -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
+}
diff --git a/services/asymkey/ssh_key.go b/services/asymkey/ssh_key.go
new file mode 100644
index 0000000000..1f6b93eb24
--- /dev/null
+++ b/services/asymkey/ssh_key.go
@@ -0,0 +1,49 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package asymkey
+
+import (
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/db"
+ user_model "code.gitea.io/gitea/models/user"
+)
+
+// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
+func DeletePublicKey(doer *user_model.User, id int64) (err error) {
+ key, err := asymkey_model.GetPublicKeyByID(id)
+ if err != nil {
+ return err
+ }
+
+ // Check if user has access to delete this key.
+ if !doer.IsAdmin && doer.ID != key.OwnerID {
+ return asymkey_model.ErrKeyAccessDenied{
+ UserID: doer.ID,
+ KeyID: key.ID,
+ Note: "public",
+ }
+ }
+
+ ctx, committer, err := db.TxContext()
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+
+ if err = asymkey_model.DeletePublicKeys(ctx, id); err != nil {
+ return err
+ }
+
+ if err = committer.Commit(); err != nil {
+ return err
+ }
+ committer.Close()
+
+ if key.Type == asymkey_model.KeyTypePrincipal {
+ return asymkey_model.RewriteAllPrincipalKeys()
+ }
+
+ return asymkey_model.RewriteAllPublicKeys()
+}
diff --git a/services/asymkey/ssh_key_test.go b/services/asymkey/ssh_key_test.go
new file mode 100644
index 0000000000..0ce235f7f6
--- /dev/null
+++ b/services/asymkey/ssh_key_test.go
@@ -0,0 +1,83 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package asymkey
+
+import (
+ "testing"
+
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
+ "code.gitea.io/gitea/models/login"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAddLdapSSHPublicKeys(t *testing.T) {
+ assert.NoError(t, unittest.PrepareTestDatabase())
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ s := &login.Source{ID: 1}
+
+ testCases := []struct {
+ keyString string
+ number int
+ keyContents []string
+ }{
+ {
+ keyString: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n",
+ number: 1,
+ keyContents: []string{
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
+ },
+ },
+ {
+ keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment
+ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`,
+ number: 2,
+ keyContents: []string{
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
+ "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=",
+ },
+ },
+ {
+ keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment
+# comment asmdna,ndp
+ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`,
+ number: 2,
+ keyContents: []string{
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
+ "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=",
+ },
+ },
+ {
+ keyString: `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment
+382488320jasdj1lasmva/vasodifipi4193-fksma.cm
+ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment`,
+ number: 2,
+ keyContents: []string{
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=",
+ "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag=",
+ },
+ },
+ }
+
+ for i, kase := range testCases {
+ s.ID = int64(i) + 20
+ asymkey_model.AddPublicKeysBySource(user, s, []string{kase.keyString})
+ keys, err := asymkey_model.ListPublicKeysBySource(user.ID, s.ID)
+ assert.NoError(t, err)
+ if err != nil {
+ continue
+ }
+ assert.Len(t, keys, kase.number)
+
+ for _, key := range keys {
+ assert.Contains(t, kase.keyContents, key.Content)
+ }
+ for _, key := range keys {
+ DeletePublicKey(user, key.ID)
+ }
+ }
+}
diff --git a/services/auth/source/ldap/source_authenticate.go b/services/auth/source/ldap/source_authenticate.go
index 9bb07d244f..9938525c0e 100644
--- a/services/auth/source/ldap/source_authenticate.go
+++ b/services/auth/source/ldap/source_authenticate.go
@@ -8,7 +8,7 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/login"
user_model "code.gitea.io/gitea/models/user"
@@ -59,8 +59,8 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str
}
if user != nil {
- if isAttributeSSHPublicKeySet && models.SynchronizePublicKeys(user, source.loginSource, sr.SSHPublicKey) {
- return user, models.RewriteAllPublicKeys()
+ if isAttributeSSHPublicKeySet && asymkey_model.SynchronizePublicKeys(user, source.loginSource, sr.SSHPublicKey) {
+ return user, asymkey_model.RewriteAllPublicKeys()
}
return user, nil
@@ -95,8 +95,8 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str
mailer.SendRegisterNotifyMail(user)
- if isAttributeSSHPublicKeySet && models.AddPublicKeysBySource(user, source.loginSource, sr.SSHPublicKey) {
- err = models.RewriteAllPublicKeys()
+ if isAttributeSSHPublicKeySet && asymkey_model.AddPublicKeysBySource(user, source.loginSource, sr.SSHPublicKey) {
+ err = asymkey_model.RewriteAllPublicKeys()
}
if err == nil && len(source.AttributeAvatar) > 0 {
diff --git a/services/auth/source/ldap/source_sync.go b/services/auth/source/ldap/source_sync.go
index 9c504476c0..fb15b2f046 100644
--- a/services/auth/source/ldap/source_sync.go
+++ b/services/auth/source/ldap/source_sync.go
@@ -10,7 +10,7 @@ import (
"sort"
"strings"
- "code.gitea.io/gitea/models"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
@@ -68,7 +68,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
log.Warn("SyncExternalUsers: Cancelled at update of %s before completed update of users", source.loginSource.Name)
// Rewrite authorized_keys file if LDAP Public SSH Key attribute is set and any key was added or removed
if sshKeysNeedUpdate {
- err = models.RewriteAllPublicKeys()
+ err = asymkey_model.RewriteAllPublicKeys()
if err != nil {
log.Error("RewriteAllPublicKeys: %v", err)
}
@@ -119,7 +119,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
if err == nil && isAttributeSSHPublicKeySet {
log.Trace("SyncExternalUsers[%s]: Adding LDAP Public SSH Keys for user %s", source.loginSource.Name, usr.Name)
- if models.AddPublicKeysBySource(usr, source.loginSource, su.SSHPublicKey) {
+ if asymkey_model.AddPublicKeysBySource(usr, source.loginSource, su.SSHPublicKey) {
sshKeysNeedUpdate = true
}
}
@@ -129,7 +129,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
}
} else if updateExisting {
// Synchronize SSH Public Key if that attribute is set
- if isAttributeSSHPublicKeySet && models.SynchronizePublicKeys(usr, source.loginSource, su.SSHPublicKey) {
+ if isAttributeSSHPublicKeySet && asymkey_model.SynchronizePublicKeys(usr, source.loginSource, su.SSHPublicKey) {
sshKeysNeedUpdate = true
}
@@ -171,7 +171,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
// Rewrite authorized_keys file if LDAP Public SSH Key attribute is set and any key was added or removed
if sshKeysNeedUpdate {
- err = models.RewriteAllPublicKeys()
+ err = asymkey_model.RewriteAllPublicKeys()
if err != nil {
log.Error("RewriteAllPublicKeys: %v", err)
}
diff --git a/services/cron/tasks_extended.go b/services/cron/tasks_extended.go
index bc6add090b..90b391474f 100644
--- a/services/cron/tasks_extended.go
+++ b/services/cron/tasks_extended.go
@@ -9,6 +9,7 @@ import (
"time"
"code.gitea.io/gitea/models"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/updatechecker"
@@ -67,7 +68,7 @@ func registerRewriteAllPublicKeys() {
RunAtStart: false,
Schedule: "@every 72h",
}, func(_ context.Context, _ *user_model.User, _ Config) error {
- return models.RewriteAllPublicKeys()
+ return asymkey_model.RewriteAllPublicKeys()
})
}
@@ -77,7 +78,7 @@ func registerRewriteAllPrincipalKeys() {
RunAtStart: false,
Schedule: "@every 72h",
}, func(_ context.Context, _ *user_model.User, _ Config) error {
- return models.RewriteAllPrincipalKeys()
+ return asymkey_model.RewriteAllPrincipalKeys()
})
}
diff --git a/services/pull/merge.go b/services/pull/merge.go
index 49050d6bee..ab1f43a50a 100644
--- a/services/pull/merge.go
+++ b/services/pull/merge.go
@@ -27,6 +27,7 @@ import (
"code.gitea.io/gitea/modules/references"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
issue_service "code.gitea.io/gitea/services/issue"
)
@@ -218,7 +219,7 @@ func rawMerge(pr *models.PullRequest, doer *user_model.User, mergeStyle repo_mod
// Determine if we should sign
signArg := ""
if git.CheckGitVersionAtLeast("1.7.9") == nil {
- sign, keyID, signer, _ := pr.SignMerge(doer, tmpBasePath, "HEAD", trackingBranch)
+ sign, keyID, signer, _ := asymkey_service.SignMerge(pr, doer, tmpBasePath, "HEAD", trackingBranch)
if sign {
signArg = "-S" + keyID
if pr.BaseRepo.GetTrustModel() == repo_model.CommitterTrustModel || pr.BaseRepo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
@@ -553,7 +554,7 @@ func IsSignedIfRequired(pr *models.PullRequest, doer *user_model.User) (bool, er
return true, nil
}
- sign, _, _, err := pr.SignMerge(doer, pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName())
+ sign, _, _, err := asymkey_service.SignMerge(pr, doer, pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName())
return sign, err
}
diff --git a/services/repository/archiver/archiver.go b/services/repository/archiver/archiver.go
index 7e886d79cb..fb40c3383d 100644
--- a/services/repository/archiver/archiver.go
+++ b/services/repository/archiver/archiver.go
@@ -14,7 +14,6 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
@@ -171,7 +170,7 @@ func doArchive(r *ArchiveRequest) (*repo_model.RepoArchiver, error) {
rd.Close()
}()
var done = make(chan error)
- repo, err := models.LoadArchiverRepo(archiver)
+ repo, err := repo_model.GetRepositoryByID(archiver.RepoID)
if err != nil {
return nil, fmt.Errorf("archiver.LoadRepo failed: %v", err)
}
diff --git a/services/repository/files/commit.go b/services/repository/files/commit.go
index 6bff1bb97f..4e391ff343 100644
--- a/services/repository/files/commit.go
+++ b/services/repository/files/commit.go
@@ -8,6 +8,7 @@ import (
"fmt"
"code.gitea.io/gitea/models"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
@@ -55,7 +56,7 @@ func CountDivergingCommits(repo *repo_model.Repository, branch string) (*git.Div
// GetPayloadCommitVerification returns the verification information of a commit
func GetPayloadCommitVerification(commit *git.Commit) *structs.PayloadCommitVerification {
verification := &structs.PayloadCommitVerification{}
- commitVerification := models.ParseCommitWithSignature(commit)
+ commitVerification := asymkey_model.ParseCommitWithSignature(commit)
if commit.Signature != nil {
verification.Signature = commit.Signature.Signature
verification.Payload = commit.Signature.Payload
diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go
index 815aa2c69f..52879dd3b0 100644
--- a/services/repository/files/temp_repo.go
+++ b/services/repository/files/temp_repo.go
@@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
"code.gitea.io/gitea/services/gitdiff"
)
@@ -217,7 +218,7 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *user_m
// Determine if we should sign
if git.CheckGitVersionAtLeast("1.7.9") == nil {
- sign, keyID, signer, _ := models.SignCRUDAction(t.repo, author, t.basePath, "HEAD")
+ sign, keyID, signer, _ := asymkey_service.SignCRUDAction(t.repo.RepoPath(), author, t.basePath, "HEAD")
if sign {
args = append(args, "-S"+keyID)
if t.repo.GetTrustModel() == repo_model.CommitterTrustModel || t.repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
diff --git a/services/repository/files/update.go b/services/repository/files/update.go
index 9a069acbfc..4bafa62cc1 100644
--- a/services/repository/files/update.go
+++ b/services/repository/files/update.go
@@ -21,6 +21,7 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
repo_service "code.gitea.io/gitea/services/repository"
stdcharset "golang.org/x/net/html/charset"
@@ -458,9 +459,9 @@ func VerifyBranchProtection(repo *repo_model.Repository, doer *user_model.User,
}
}
if protectedBranch.RequireSignedCommits {
- _, _, _, err := models.SignCRUDAction(repo, doer, repo.RepoPath(), branchName)
+ _, _, _, err := asymkey_service.SignCRUDAction(repo.RepoPath(), doer, repo.RepoPath(), branchName)
if err != nil {
- if !models.IsErrWontSign(err) {
+ if !asymkey_service.IsErrWontSign(err) {
return err
}
return models.ErrUserCannotCommit{
diff --git a/services/repository/repository.go b/services/repository/repository.go
index 0b97148f66..17fab57e19 100644
--- a/services/repository/repository.go
+++ b/services/repository/repository.go
@@ -31,13 +31,15 @@ func CreateRepository(doer, owner *user_model.User, opts models.CreateRepoOption
}
// DeleteRepository deletes a repository for a user or organization.
-func DeleteRepository(doer *user_model.User, repo *repo_model.Repository) error {
+func DeleteRepository(doer *user_model.User, repo *repo_model.Repository, notify bool) error {
if err := pull_service.CloseRepoBranchesPulls(doer, repo); err != nil {
log.Error("CloseRepoBranchesPulls failed: %v", err)
}
- // If the repo itself has webhooks, we need to trigger them before deleting it...
- notification.NotifyDeleteRepository(doer, repo)
+ if notify {
+ // If the repo itself has webhooks, we need to trigger them before deleting it...
+ notification.NotifyDeleteRepository(doer, repo)
+ }
err := models.DeleteRepository(doer, repo.OwnerID, repo.ID)
return err
diff --git a/services/user/user.go b/services/user/user.go
index 72052f4ec9..21f1a74f62 100644
--- a/services/user/user.go
+++ b/services/user/user.go
@@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/models"
admin_model "code.gitea.io/gitea/models/admin"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
@@ -31,11 +32,11 @@ func DeleteUser(u *user_model.User) error {
return fmt.Errorf("%s is an organization not a user", u.Name)
}
- ctx, commiter, err := db.TxContext()
+ ctx, committer, err := db.TxContext()
if err != nil {
return err
}
- defer commiter.Close()
+ defer committer.Close()
// Note: A user owns any repository or belongs to any organization
// cannot perform delete operation.
@@ -60,14 +61,15 @@ func DeleteUser(u *user_model.User) error {
return fmt.Errorf("DeleteUser: %v", err)
}
- if err := commiter.Commit(); err != nil {
+ if err := committer.Commit(); err != nil {
return err
}
+ committer.Close()
- if err = models.RewriteAllPublicKeys(); err != nil {
+ if err = asymkey_model.RewriteAllPublicKeys(); err != nil {
return err
}
- if err = models.RewriteAllPrincipalKeys(); err != nil {
+ if err = asymkey_model.RewriteAllPrincipalKeys(); err != nil {
return err
}
diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go
index 18e9b26d81..aa683dd44f 100644
--- a/services/wiki/wiki.go
+++ b/services/wiki/wiki.go
@@ -22,6 +22,7 @@ import (
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/sync"
"code.gitea.io/gitea/modules/util"
+ asymkey_service "code.gitea.io/gitea/services/asymkey"
)
var (
@@ -225,7 +226,7 @@ func updateWikiPage(doer *user_model.User, repo *repo_model.Repository, oldWikiN
committer := doer.NewGitSig()
- sign, signingKey, signer, _ := models.SignWikiCommit(repo, doer)
+ sign, signingKey, signer, _ := asymkey_service.SignWikiCommit(repo.WikiPath(), doer)
if sign {
commitTreeOpts.KeyID = signingKey
if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
@@ -343,7 +344,7 @@ func DeleteWikiPage(doer *user_model.User, repo *repo_model.Repository, wikiName
committer := doer.NewGitSig()
- sign, signingKey, signer, _ := models.SignWikiCommit(repo, doer)
+ sign, signingKey, signer, _ := asymkey_service.SignWikiCommit(repo.WikiPath(), doer)
if sign {
commitTreeOpts.KeyID = signingKey
if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {