update to UserSSHKeypair per feedback

This commit is contained in:
techknowlogick
2025-08-08 12:20:39 -04:00
parent cee2ca0a7f
commit f97acdc60f
8 changed files with 65 additions and 60 deletions
+5
View File
@@ -24,6 +24,7 @@ import (
"code.gitea.io/gitea/models/migrations/v1_22"
"code.gitea.io/gitea/models/migrations/v1_23"
"code.gitea.io/gitea/models/migrations/v1_24"
"code.gitea.io/gitea/models/migrations/v1_25"
"code.gitea.io/gitea/models/migrations/v1_6"
"code.gitea.io/gitea/models/migrations/v1_7"
"code.gitea.io/gitea/models/migrations/v1_8"
@@ -382,6 +383,10 @@ func prepareMigrationTasks() []*migration {
newMigration(318, "Add anonymous_access_mode for repo_unit", v1_24.AddRepoUnitAnonymousAccessMode),
newMigration(319, "Add ExclusiveOrder to Label table", v1_24.AddExclusiveOrderColumnToLabelTable),
newMigration(320, "Migrate two_factor_policy to login_source table", v1_24.MigrateSkipTwoFactor),
// Gitea 1.24.0 ends at migration ID number 320 (database version 321)
newMigration(321, "Use LONGTEXT for some columns and fix review_state.updated_files column", v1_25.UseLongTextInSomeColumnsAndFixBugs),
newMigration(322, "Add Mirror SSH keypair table", v1_25.AddUserSSHKeypairTable),
}
return preparedMigrations
}
+3 -3
View File
@@ -9,8 +9,8 @@ import (
"xorm.io/xorm"
)
func AddMirrorSSHKeypairTable(x *xorm.Engine) error {
type MirrorSSHKeypair struct {
func AddUserSSHKeypairTable(x *xorm.Engine) error {
type UserSSHKeypair struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"INDEX NOT NULL"`
PrivateKeyEncrypted string `xorm:"TEXT NOT NULL"`
@@ -20,5 +20,5 @@ func AddMirrorSSHKeypairTable(x *xorm.Engine) error {
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
}
return x.Sync(new(MirrorSSHKeypair))
return x.Sync(new(UserSSHKeypair))
}
+17 -17
View File
@@ -22,8 +22,8 @@ import (
"golang.org/x/crypto/ssh"
)
// MirrorSSHKeypair represents an SSH keypair for repository mirroring
type MirrorSSHKeypair struct {
// UserSSHKeypair represents an SSH keypair for repository mirroring
type UserSSHKeypair struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"INDEX NOT NULL"`
PrivateKeyEncrypted string `xorm:"TEXT NOT NULL"`
@@ -34,12 +34,12 @@ type MirrorSSHKeypair struct {
}
func init() {
db.RegisterModel(new(MirrorSSHKeypair))
db.RegisterModel(new(UserSSHKeypair))
}
// GetMirrorSSHKeypairByOwner gets the most recent SSH keypair for the given owner
func GetMirrorSSHKeypairByOwner(ctx context.Context, ownerID int64) (*MirrorSSHKeypair, error) {
keypair := &MirrorSSHKeypair{}
// GetUserSSHKeypairByOwner gets the most recent SSH keypair for the given owner
func GetUserSSHKeypairByOwner(ctx context.Context, ownerID int64) (*UserSSHKeypair, error) {
keypair := &UserSSHKeypair{}
has, err := db.GetEngine(ctx).Where("owner_id = ?", ownerID).
Desc("created_unix").Get(keypair)
if err != nil {
@@ -51,8 +51,8 @@ func GetMirrorSSHKeypairByOwner(ctx context.Context, ownerID int64) (*MirrorSSHK
return keypair, nil
}
// CreateMirrorSSHKeypair creates a new SSH keypair for mirroring
func CreateMirrorSSHKeypair(ctx context.Context, ownerID int64) (*MirrorSSHKeypair, error) {
// CreateUserSSHKeypair creates a new SSH keypair for mirroring
func CreateUserSSHKeypair(ctx context.Context, ownerID int64) (*UserSSHKeypair, error) {
publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, fmt.Errorf("failed to generate Ed25519 keypair: %w", err)
@@ -73,7 +73,7 @@ func CreateMirrorSSHKeypair(ctx context.Context, ownerID int64) (*MirrorSSHKeypa
return nil, fmt.Errorf("failed to encrypt private key: %w", err)
}
keypair := &MirrorSSHKeypair{
keypair := &UserSSHKeypair{
OwnerID: ownerID,
PrivateKeyEncrypted: privateKeyEncrypted,
PublicKey: publicKeyStr,
@@ -84,7 +84,7 @@ func CreateMirrorSSHKeypair(ctx context.Context, ownerID int64) (*MirrorSSHKeypa
}
// GetDecryptedPrivateKey returns the decrypted private key
func (k *MirrorSSHKeypair) GetDecryptedPrivateKey() (ed25519.PrivateKey, error) {
func (k *UserSSHKeypair) 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)
@@ -93,7 +93,7 @@ func (k *MirrorSSHKeypair) GetDecryptedPrivateKey() (ed25519.PrivateKey, error)
}
// GetPublicKeyWithComment returns the public key with a descriptive comment (namespace-fingerprint@domain)
func (k *MirrorSSHKeypair) GetPublicKeyWithComment(ctx context.Context) (string, error) {
func (k *UserSSHKeypair) GetPublicKeyWithComment(ctx context.Context) (string, error) {
owner, err := user_model.GetUserByID(ctx, k.OwnerID)
if err != nil {
return k.PublicKey, nil
@@ -113,14 +113,14 @@ func (k *MirrorSSHKeypair) GetPublicKeyWithComment(ctx context.Context) (string,
return strings.TrimSpace(k.PublicKey) + " " + comment, nil
}
// DeleteMirrorSSHKeypair deletes an SSH keypair
func DeleteMirrorSSHKeypair(ctx context.Context, ownerID int64) error {
_, err := db.GetEngine(ctx).Where("owner_id = ?", ownerID).Delete(&MirrorSSHKeypair{})
// DeleteUserSSHKeypair deletes an SSH keypair
func DeleteUserSSHKeypair(ctx context.Context, ownerID int64) error {
_, err := db.GetEngine(ctx).Where("owner_id = ?", ownerID).Delete(&UserSSHKeypair{})
return err
}
// RegenerateMirrorSSHKeypair regenerates an SSH keypair for the given owner
func RegenerateMirrorSSHKeypair(ctx context.Context, ownerID int64) (*MirrorSSHKeypair, error) {
// RegenerateUserSSHKeypair regenerates an SSH keypair for the given owner
func RegenerateUserSSHKeypair(ctx context.Context, ownerID int64) (*UserSSHKeypair, error) {
// TODO: This creates a new one old ones will be garbage collected later, as the user may accidentally regenerate
return CreateMirrorSSHKeypair(ctx, ownerID)
return CreateUserSSHKeypair(ctx, ownerID)
}
+19 -19
View File
@@ -17,12 +17,12 @@ import (
"github.com/stretchr/testify/require"
)
func TestMirrorSSHKeypair(t *testing.T) {
func TestUserSSHKeypair(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
t.Run("CreateMirrorSSHKeypair", func(t *testing.T) {
t.Run("CreateUserSSHKeypair", func(t *testing.T) {
// Test creating a new SSH keypair for a user
keypair, err := repo_model.CreateMirrorSSHKeypair(db.DefaultContext, 1)
keypair, err := repo_model.CreateUserSSHKeypair(db.DefaultContext, 1)
require.NoError(t, err)
assert.NotNil(t, keypair)
assert.Equal(t, int64(1), keypair.OwnerID)
@@ -36,7 +36,7 @@ func TestMirrorSSHKeypair(t *testing.T) {
assert.Contains(t, keypair.PublicKey, "ssh-ed25519")
// Test creating a keypair for an organization
orgKeypair, err := repo_model.CreateMirrorSSHKeypair(db.DefaultContext, 2)
orgKeypair, err := repo_model.CreateUserSSHKeypair(db.DefaultContext, 2)
require.NoError(t, err)
assert.NotNil(t, orgKeypair)
assert.Equal(t, int64(2), orgKeypair.OwnerID)
@@ -46,20 +46,20 @@ func TestMirrorSSHKeypair(t *testing.T) {
assert.NotEqual(t, keypair.Fingerprint, orgKeypair.Fingerprint)
})
t.Run("GetMirrorSSHKeypairByOwner", func(t *testing.T) {
t.Run("GetUserSSHKeypairByOwner", func(t *testing.T) {
// Create a keypair first
created, err := repo_model.CreateMirrorSSHKeypair(db.DefaultContext, 3)
created, err := repo_model.CreateUserSSHKeypair(db.DefaultContext, 3)
require.NoError(t, err)
// Test retrieving the keypair
retrieved, err := repo_model.GetMirrorSSHKeypairByOwner(db.DefaultContext, 3)
retrieved, err := repo_model.GetUserSSHKeypairByOwner(db.DefaultContext, 3)
require.NoError(t, err)
assert.Equal(t, created.ID, retrieved.ID)
assert.Equal(t, created.PublicKey, retrieved.PublicKey)
assert.Equal(t, created.Fingerprint, retrieved.Fingerprint)
// Test retrieving non-existent keypair
_, err = repo_model.GetMirrorSSHKeypairByOwner(db.DefaultContext, 999)
_, err = repo_model.GetUserSSHKeypairByOwner(db.DefaultContext, 999)
assert.ErrorIs(t, err, util.ErrNotExist)
})
@@ -70,7 +70,7 @@ func TestMirrorSSHKeypair(t *testing.T) {
}
// Create a keypair
keypair, err := repo_model.CreateMirrorSSHKeypair(db.DefaultContext, 4)
keypair, err := repo_model.CreateUserSSHKeypair(db.DefaultContext, 4)
require.NoError(t, err)
// Test decrypting the private key
@@ -84,31 +84,31 @@ func TestMirrorSSHKeypair(t *testing.T) {
assert.Len(t, publicKey, ed25519.PublicKeySize)
})
t.Run("DeleteMirrorSSHKeypair", func(t *testing.T) {
t.Run("DeleteUserSSHKeypair", func(t *testing.T) {
// Create a keypair
_, err := repo_model.CreateMirrorSSHKeypair(db.DefaultContext, 5)
_, err := repo_model.CreateUserSSHKeypair(db.DefaultContext, 5)
require.NoError(t, err)
// Verify it exists
_, err = repo_model.GetMirrorSSHKeypairByOwner(db.DefaultContext, 5)
_, err = repo_model.GetUserSSHKeypairByOwner(db.DefaultContext, 5)
require.NoError(t, err)
// Delete it
err = repo_model.DeleteMirrorSSHKeypair(db.DefaultContext, 5)
err = repo_model.DeleteUserSSHKeypair(db.DefaultContext, 5)
require.NoError(t, err)
// Verify it's gone
_, err = repo_model.GetMirrorSSHKeypairByOwner(db.DefaultContext, 5)
_, err = repo_model.GetUserSSHKeypairByOwner(db.DefaultContext, 5)
assert.ErrorIs(t, err, util.ErrNotExist)
})
t.Run("RegenerateMirrorSSHKeypair", func(t *testing.T) {
t.Run("RegenerateUserSSHKeypair", func(t *testing.T) {
// Create initial keypair
original, err := repo_model.CreateMirrorSSHKeypair(db.DefaultContext, 6)
original, err := repo_model.CreateUserSSHKeypair(db.DefaultContext, 6)
require.NoError(t, err)
// Regenerate it
regenerated, err := repo_model.RegenerateMirrorSSHKeypair(db.DefaultContext, 6)
regenerated, err := repo_model.RegenerateUserSSHKeypair(db.DefaultContext, 6)
require.NoError(t, err)
// Verify it's different
@@ -119,7 +119,7 @@ func TestMirrorSSHKeypair(t *testing.T) {
})
}
func TestMirrorSSHKeypairConcurrency(t *testing.T) {
func TestUserSSHKeypairConcurrency(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
if setting.SecretKey == "" {
@@ -134,7 +134,7 @@ func TestMirrorSSHKeypairConcurrency(t *testing.T) {
// Start multiple goroutines creating keypairs for different owners
for i := range 10 {
go func(ownerID int64) {
_, err := repo_model.CreateMirrorSSHKeypair(ctx, ownerID+100)
_, err := repo_model.CreateUserSSHKeypair(ctx, ownerID+100)
results <- err
}(int64(i))
}