diff --git a/models/user/ssh_keypair.go b/models/user/ssh_keypair.go index 378b7da31c..5d55312717 100644 --- a/models/user/ssh_keypair.go +++ b/models/user/ssh_keypair.go @@ -18,16 +18,16 @@ import ( "golang.org/x/crypto/ssh" ) -// UserSSHKeypair represents an SSH keypair for repository mirroring -type UserSSHKeypair struct { +// SSHKeypair represents an SSH keypair for repository mirroring +type SSHKeypair struct { OwnerID int64 PrivateKeyEncrypted string PublicKey string Fingerprint string } -// GetUserSSHKeypairByOwner gets the SSH keypair for the given owner -func GetUserSSHKeypairByOwner(ctx context.Context, ownerID int64) (*UserSSHKeypair, error) { +// GetSSHKeypairByOwner gets the SSH keypair for the given owner +func GetSSHKeypairByOwner(ctx context.Context, ownerID int64) (*SSHKeypair, error) { settings, err := GetSettings(ctx, ownerID, []string{ UserSSHMirrorPrivPem, UserSSHMirrorPubPem, @@ -40,7 +40,7 @@ func GetUserSSHKeypairByOwner(ctx context.Context, ownerID int64) (*UserSSHKeypa return nil, util.NewNotExistErrorf("SSH keypair does not exist for owner %d", ownerID) } - keypair := &UserSSHKeypair{ + keypair := &SSHKeypair{ OwnerID: ownerID, } @@ -61,8 +61,8 @@ func GetUserSSHKeypairByOwner(ctx context.Context, ownerID int64) (*UserSSHKeypa return keypair, nil } -// CreateUserSSHKeypair creates a new SSH keypair for mirroring -func CreateUserSSHKeypair(ctx context.Context, ownerID int64) (*UserSSHKeypair, error) { +// CreateSSHKeypair creates a new SSH keypair for mirroring +func CreateSSHKeypair(ctx context.Context, ownerID int64) (*SSHKeypair, error) { publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader) if err != nil { return nil, fmt.Errorf("failed to generate Ed25519 keypair: %w", err) @@ -98,7 +98,7 @@ func CreateUserSSHKeypair(ctx context.Context, ownerID int64) (*UserSSHKeypair, return nil, err } - keypair := &UserSSHKeypair{ + keypair := &SSHKeypair{ OwnerID: ownerID, PrivateKeyEncrypted: privateKeyEncrypted, PublicKey: publicKeyStr, @@ -109,7 +109,7 @@ func CreateUserSSHKeypair(ctx context.Context, ownerID int64) (*UserSSHKeypair, } // GetDecryptedPrivateKey returns the decrypted private key -func (k *UserSSHKeypair) GetDecryptedPrivateKey() (ed25519.PrivateKey, error) { +func (k *SSHKeypair) GetDecryptedPrivateKey() (ed25519.PrivateKey, error) { decrypted, err := secret.DecryptSecret(setting.SecretKey, k.PrivateKeyEncrypted) if err != nil { return nil, fmt.Errorf("failed to decrypt private key: %w", err) @@ -118,7 +118,7 @@ func (k *UserSSHKeypair) GetDecryptedPrivateKey() (ed25519.PrivateKey, error) { } // GetPublicKeyWithComment returns the public key with a descriptive comment (namespace-fingerprint@domain) -func (k *UserSSHKeypair) GetPublicKeyWithComment(ctx context.Context) (string, error) { +func (k *SSHKeypair) GetPublicKeyWithComment(ctx context.Context) (string, error) { owner, err := GetUserByID(ctx, k.OwnerID) if err != nil { return k.PublicKey, nil @@ -138,8 +138,8 @@ func (k *UserSSHKeypair) GetPublicKeyWithComment(ctx context.Context) (string, e return strings.TrimSpace(k.PublicKey) + " " + comment, nil } -// DeleteUserSSHKeypair deletes an SSH keypair -func DeleteUserSSHKeypair(ctx context.Context, ownerID int64) error { +// DeleteSSHKeypair deletes an SSH keypair +func DeleteSSHKeypair(ctx context.Context, ownerID int64) error { return db.WithTx(ctx, func(ctx context.Context) error { if err := DeleteUserSetting(ctx, ownerID, UserSSHMirrorPrivPem); err != nil { return err @@ -151,14 +151,14 @@ func DeleteUserSSHKeypair(ctx context.Context, ownerID int64) error { }) } -// RegenerateUserSSHKeypair regenerates an SSH keypair for the given owner -func RegenerateUserSSHKeypair(ctx context.Context, ownerID int64) (*UserSSHKeypair, error) { - return db.WithTx2(ctx, func(ctx context.Context) (*UserSSHKeypair, error) { - if err := DeleteUserSSHKeypair(ctx, ownerID); err != nil { +// RegenerateSSHKeypair regenerates an SSH keypair for the given owner +func RegenerateSSHKeypair(ctx context.Context, ownerID int64) (*SSHKeypair, error) { + return db.WithTx2(ctx, func(ctx context.Context) (*SSHKeypair, error) { + if err := DeleteSSHKeypair(ctx, ownerID); err != nil { return nil, fmt.Errorf("failed to delete existing keypair: %w", err) } - newKeypair, err := CreateUserSSHKeypair(ctx, ownerID) + newKeypair, err := CreateSSHKeypair(ctx, ownerID) if err != nil { return nil, err } diff --git a/models/user/ssh_keypair_test.go b/models/user/ssh_keypair_test.go index 23beae9d46..da3da6fe9c 100644 --- a/models/user/ssh_keypair_test.go +++ b/models/user/ssh_keypair_test.go @@ -16,12 +16,12 @@ import ( "github.com/stretchr/testify/require" ) -func TestUserSSHKeypair(t *testing.T) { +func TestSSHKeypair(t *testing.T) { require.NoError(t, unittest.PrepareTestDatabase()) - t.Run("CreateUserSSHKeypair", func(t *testing.T) { + t.Run("CreateSSHKeypair", func(t *testing.T) { // Test creating a new SSH keypair for a user - keypair, err := user_model.CreateUserSSHKeypair(t.Context(), 1) + keypair, err := user_model.CreateSSHKeypair(t.Context(), 1) require.NoError(t, err) assert.NotNil(t, keypair) assert.Equal(t, int64(1), keypair.OwnerID) @@ -33,7 +33,7 @@ func TestUserSSHKeypair(t *testing.T) { assert.Contains(t, keypair.PublicKey, "ssh-ed25519") // Test creating a keypair for an organization - orgKeypair, err := user_model.CreateUserSSHKeypair(t.Context(), 2) + orgKeypair, err := user_model.CreateSSHKeypair(t.Context(), 2) require.NoError(t, err) assert.NotNil(t, orgKeypair) assert.Equal(t, int64(2), orgKeypair.OwnerID) @@ -43,20 +43,20 @@ func TestUserSSHKeypair(t *testing.T) { assert.NotEqual(t, keypair.Fingerprint, orgKeypair.Fingerprint) }) - t.Run("GetUserSSHKeypairByOwner", func(t *testing.T) { + t.Run("GetSSHKeypairByOwner", func(t *testing.T) { // Create a keypair first - created, err := user_model.CreateUserSSHKeypair(t.Context(), 3) + created, err := user_model.CreateSSHKeypair(t.Context(), 3) require.NoError(t, err) // Test retrieving the keypair - retrieved, err := user_model.GetUserSSHKeypairByOwner(t.Context(), 3) + retrieved, err := user_model.GetSSHKeypairByOwner(t.Context(), 3) require.NoError(t, err) assert.Equal(t, created.OwnerID, retrieved.OwnerID) assert.Equal(t, created.PublicKey, retrieved.PublicKey) assert.Equal(t, created.Fingerprint, retrieved.Fingerprint) // Test retrieving non-existent keypair - _, err = user_model.GetUserSSHKeypairByOwner(t.Context(), 999) + _, err = user_model.GetSSHKeypairByOwner(t.Context(), 999) assert.ErrorIs(t, err, util.ErrNotExist) }) @@ -67,7 +67,7 @@ func TestUserSSHKeypair(t *testing.T) { } // Create a keypair - keypair, err := user_model.CreateUserSSHKeypair(t.Context(), 4) + keypair, err := user_model.CreateSSHKeypair(t.Context(), 4) require.NoError(t, err) // Test decrypting the private key @@ -81,31 +81,31 @@ func TestUserSSHKeypair(t *testing.T) { assert.Len(t, publicKey, ed25519.PublicKeySize) }) - t.Run("DeleteUserSSHKeypair", func(t *testing.T) { + t.Run("DeleteSSHKeypair", func(t *testing.T) { // Create a keypair - _, err := user_model.CreateUserSSHKeypair(t.Context(), 5) + _, err := user_model.CreateSSHKeypair(t.Context(), 5) require.NoError(t, err) // Verify it exists - _, err = user_model.GetUserSSHKeypairByOwner(t.Context(), 5) + _, err = user_model.GetSSHKeypairByOwner(t.Context(), 5) require.NoError(t, err) // Delete it - err = user_model.DeleteUserSSHKeypair(t.Context(), 5) + err = user_model.DeleteSSHKeypair(t.Context(), 5) require.NoError(t, err) // Verify it's gone - _, err = user_model.GetUserSSHKeypairByOwner(t.Context(), 5) + _, err = user_model.GetSSHKeypairByOwner(t.Context(), 5) assert.ErrorIs(t, err, util.ErrNotExist) }) - t.Run("RegenerateUserSSHKeypair", func(t *testing.T) { + t.Run("RegenerateSSHKeypair", func(t *testing.T) { // Create initial keypair - original, err := user_model.CreateUserSSHKeypair(t.Context(), 6) + original, err := user_model.CreateSSHKeypair(t.Context(), 6) require.NoError(t, err) // Regenerate it - regenerated, err := user_model.RegenerateUserSSHKeypair(t.Context(), 6) + regenerated, err := user_model.RegenerateSSHKeypair(t.Context(), 6) require.NoError(t, err) // Verify it's different @@ -116,7 +116,7 @@ func TestUserSSHKeypair(t *testing.T) { }) } -func TestUserSSHKeypairConcurrency(t *testing.T) { +func TestSSHKeypairConcurrency(t *testing.T) { require.NoError(t, unittest.PrepareTestDatabase()) if setting.SecretKey == "" { @@ -131,7 +131,7 @@ func TestUserSSHKeypairConcurrency(t *testing.T) { // Start multiple goroutines creating keypairs for different owners for i := range 10 { go func(ownerID int64) { - _, err := user_model.CreateUserSSHKeypair(ctx, ownerID+100) + _, err := user_model.CreateSSHKeypair(ctx, ownerID+100) results <- err }(int64(i)) } diff --git a/modules/ssh/managed.go b/modules/ssh/managed.go index bd9a21c472..25056425e1 100644 --- a/modules/ssh/managed.go +++ b/modules/ssh/managed.go @@ -22,12 +22,12 @@ func IsSSHURL(remote string) bool { // GetOrCreateSSHKeypair gets or creates the managed SSH keypair for the given // owner (user or organization — they share the same backing storage). -func GetOrCreateSSHKeypair(ctx context.Context, ownerID int64) (*user_model.UserSSHKeypair, error) { - keypair, err := user_model.GetUserSSHKeypairByOwner(ctx, ownerID) +func GetOrCreateSSHKeypair(ctx context.Context, ownerID int64) (*user_model.SSHKeypair, error) { + keypair, err := user_model.GetSSHKeypairByOwner(ctx, ownerID) if err != nil { if db.IsErrNotExist(err) { log.Debug("Creating new SSH keypair for owner %d", ownerID) - return user_model.CreateUserSSHKeypair(ctx, ownerID) + return user_model.CreateSSHKeypair(ctx, ownerID) } return nil, fmt.Errorf("failed to get SSH keypair for owner %d: %w", ownerID, err) } @@ -35,7 +35,7 @@ func GetOrCreateSSHKeypair(ctx context.Context, ownerID int64) (*user_model.User } // GetSSHKeypairForRepository gets the managed SSH keypair for the repository's owner. -func GetSSHKeypairForRepository(ctx context.Context, repo *repo_model.Repository) (*user_model.UserSSHKeypair, error) { +func GetSSHKeypairForRepository(ctx context.Context, repo *repo_model.Repository) (*user_model.SSHKeypair, error) { return GetOrCreateSSHKeypair(ctx, repo.OwnerID) } diff --git a/routers/api/v1/org/mirror.go b/routers/api/v1/org/mirror.go index e2f48074b2..5df0f38eb1 100644 --- a/routers/api/v1/org/mirror.go +++ b/routers/api/v1/org/mirror.go @@ -82,7 +82,7 @@ func RegenerateManagedSSHKey(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" - keypair, err := user_model.RegenerateUserSSHKeypair(ctx, ctx.Org.Organization.ID) + keypair, err := user_model.RegenerateSSHKeypair(ctx, ctx.Org.Organization.ID) if err != nil { ctx.APIErrorInternal(err) return diff --git a/routers/api/v1/user/mirror.go b/routers/api/v1/user/mirror.go index fcfb6ebc3a..9d05957f04 100644 --- a/routers/api/v1/user/mirror.go +++ b/routers/api/v1/user/mirror.go @@ -66,7 +66,7 @@ func RegenerateManagedSSHKey(ctx *context.APIContext) { // fingerprint: // type: string - keypair, err := user_model.RegenerateUserSSHKeypair(ctx, ctx.Doer.ID) + keypair, err := user_model.RegenerateSSHKeypair(ctx, ctx.Doer.ID) if err != nil { ctx.APIErrorInternal(err) return diff --git a/routers/web/org/setting_ssh_keys.go b/routers/web/org/setting_ssh_keys.go index ff19d1fab9..6785fdbbdc 100644 --- a/routers/web/org/setting_ssh_keys.go +++ b/routers/web/org/setting_ssh_keys.go @@ -36,7 +36,7 @@ func SSHKeys(ctx *context.Context) { publicKeyWithComment, _ := keypair.GetPublicKeyWithComment(ctx) ctx.Data["SSHKeypair"] = struct { - *user_model.UserSSHKeypair + *user_model.SSHKeypair PublicKeyWithComment string }{keypair, publicKeyWithComment} @@ -45,7 +45,7 @@ func SSHKeys(ctx *context.Context) { // RegenerateSSHKey regenerates the SSH keypair for organization mirror operations func RegenerateSSHKey(ctx *context.Context) { - _, err := user_model.RegenerateUserSSHKeypair(ctx, ctx.Org.Organization.ID) + _, err := user_model.RegenerateSSHKeypair(ctx, ctx.Org.Organization.ID) if err != nil { ctx.ServerError("RegenerateSSHKeypairForOrg", err) return diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go index c1cf82c3ae..f902ea0067 100644 --- a/routers/web/user/setting/keys.go +++ b/routers/web/user/setting/keys.go @@ -350,10 +350,10 @@ func loadKeysData(ctx *context.Context) { // Create a struct with the public key including comment publicKeyWithComment, _ := mirrorKeypair.GetPublicKeyWithComment(ctx) mirrorKeyData := struct { - *user_model.UserSSHKeypair + *user_model.SSHKeypair PublicKeyWithComment string }{ - UserSSHKeypair: mirrorKeypair, + SSHKeypair: mirrorKeypair, PublicKeyWithComment: publicKeyWithComment, } @@ -363,9 +363,9 @@ func loadKeysData(ctx *context.Context) { } } -// RegenerateUserSSHKeypair regenerates the SSH keypair for repository mirroring -func RegenerateUserSSHKeypair(ctx *context.Context) { - _, err := user_model.RegenerateUserSSHKeypair(ctx, ctx.Doer.ID) +// RegenerateSSHKeypair regenerates the SSH keypair for repository mirroring +func RegenerateSSHKeypair(ctx *context.Context) { + _, err := user_model.RegenerateSSHKeypair(ctx, ctx.Doer.ID) if err != nil { ctx.ServerError("RegenerateSSHKeypairForUser", err) return diff --git a/routers/web/web.go b/routers/web/web.go index a81ec354bc..8d07f5d05a 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -673,7 +673,7 @@ func registerWebRoutes(m *web.Router, webAuth *AuthMiddleware) { m.Combo("/keys").Get(user_setting.Keys). Post(web.Bind(forms.AddKeyForm{}), user_setting.KeysPost) m.Post("/keys/delete", user_setting.DeleteKey) - m.Post("/keys/mirror-ssh/regenerate", user_setting.RegenerateUserSSHKeypair) + m.Post("/keys/mirror-ssh/regenerate", user_setting.RegenerateSSHKeypair) m.Group("/packages", func() { m.Get("", user_setting.Packages) m.Group("/rules", func() {