diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 176372486e..f85f672f4c 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -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 } diff --git a/models/migrations/v1_25/v322.go b/models/migrations/v1_25/v322.go index 8860721cad..64138ac6c8 100644 --- a/models/migrations/v1_25/v322.go +++ b/models/migrations/v1_25/v322.go @@ -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)) } diff --git a/models/repo/mirror_ssh_keypair.go b/models/repo/mirror_ssh_keypair.go index 4bfc83e054..7db1ffdc29 100644 --- a/models/repo/mirror_ssh_keypair.go +++ b/models/repo/mirror_ssh_keypair.go @@ -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) } diff --git a/models/repo/mirror_ssh_keypair_test.go b/models/repo/mirror_ssh_keypair_test.go index 5f540a6f74..16471ff886 100644 --- a/models/repo/mirror_ssh_keypair_test.go +++ b/models/repo/mirror_ssh_keypair_test.go @@ -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)) } diff --git a/modules/ssh/mirror.go b/modules/ssh/mirror.go index 040459f694..16bb5796b5 100644 --- a/modules/ssh/mirror.go +++ b/modules/ssh/mirror.go @@ -20,12 +20,12 @@ func IsSSHURL(url string) bool { } // GetOrCreateSSHKeypairForUser gets or creates an SSH keypair for the given user -func GetOrCreateSSHKeypairForUser(ctx context.Context, userID int64) (*repo_model.MirrorSSHKeypair, error) { - keypair, err := repo_model.GetMirrorSSHKeypairByOwner(ctx, userID) +func GetOrCreateSSHKeypairForUser(ctx context.Context, userID int64) (*repo_model.UserSSHKeypair, error) { + keypair, err := repo_model.GetUserSSHKeypairByOwner(ctx, userID) if err != nil { if db.IsErrNotExist(err) { log.Debug("Creating new SSH keypair for user %d", userID) - return repo_model.CreateMirrorSSHKeypair(ctx, userID) + return repo_model.CreateUserSSHKeypair(ctx, userID) } return nil, fmt.Errorf("failed to get SSH keypair for user %d: %w", userID, err) } @@ -33,12 +33,12 @@ func GetOrCreateSSHKeypairForUser(ctx context.Context, userID int64) (*repo_mode } // GetOrCreateSSHKeypairForOrg gets or creates an SSH keypair for the given organization -func GetOrCreateSSHKeypairForOrg(ctx context.Context, orgID int64) (*repo_model.MirrorSSHKeypair, error) { - keypair, err := repo_model.GetMirrorSSHKeypairByOwner(ctx, orgID) +func GetOrCreateSSHKeypairForOrg(ctx context.Context, orgID int64) (*repo_model.UserSSHKeypair, error) { + keypair, err := repo_model.GetUserSSHKeypairByOwner(ctx, orgID) if err != nil { if db.IsErrNotExist(err) { log.Debug("Creating new SSH keypair for organization %d", orgID) - return repo_model.CreateMirrorSSHKeypair(ctx, orgID) + return repo_model.CreateUserSSHKeypair(ctx, orgID) } return nil, fmt.Errorf("failed to get SSH keypair for organization %d: %w", orgID, err) } @@ -48,7 +48,7 @@ func GetOrCreateSSHKeypairForOrg(ctx context.Context, orgID int64) (*repo_model. // GetSSHKeypairForRepository gets the appropriate SSH keypair for a repository // If the repository belongs to an organization, it uses the org's keypair, // otherwise it uses the user's keypair -func GetSSHKeypairForRepository(ctx context.Context, repo *repo_model.Repository) (*repo_model.MirrorSSHKeypair, error) { +func GetSSHKeypairForRepository(ctx context.Context, repo *repo_model.Repository) (*repo_model.UserSSHKeypair, error) { if repo.Owner == nil { owner, err := user_model.GetUserByID(ctx, repo.OwnerID) if err != nil { @@ -65,7 +65,7 @@ func GetSSHKeypairForRepository(ctx context.Context, repo *repo_model.Repository // GetSSHKeypairForURL gets the appropriate SSH keypair for a given repository and URL // Returns nil if the URL is not an SSH URL -func GetSSHKeypairForURL(ctx context.Context, repo *repo_model.Repository, url string) (*repo_model.MirrorSSHKeypair, error) { +func GetSSHKeypairForURL(ctx context.Context, repo *repo_model.Repository, url string) (*repo_model.UserSSHKeypair, error) { if !IsSSHURL(url) { return nil, nil } diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go index a296c2434b..d5f5501722 100644 --- a/routers/web/user/setting/keys.go +++ b/routers/web/user/setting/keys.go @@ -353,10 +353,10 @@ func loadKeysData(ctx *context.Context) { // Create a struct with the public key including comment publicKeyWithComment, _ := mirrorKeypair.GetPublicKeyWithComment(ctx) mirrorKeyData := struct { - *repo_model.MirrorSSHKeypair + *repo_model.UserSSHKeypair PublicKeyWithComment string }{ - MirrorSSHKeypair: mirrorKeypair, + UserSSHKeypair: mirrorKeypair, PublicKeyWithComment: publicKeyWithComment, } @@ -366,8 +366,8 @@ func loadKeysData(ctx *context.Context) { } } -// RegenerateMirrorSSHKeyPair regenerates the SSH keypair for repository mirroring -func RegenerateMirrorSSHKeyPair(ctx *context.Context) { +// RegenerateUserSSHKeypair regenerates the SSH keypair for repository mirroring +func RegenerateUserSSHKeypair(ctx *context.Context) { _, err := mirror_service.RegenerateSSHKeypairForUser(ctx, ctx.Doer.ID) if err != nil { ctx.ServerError("RegenerateSSHKeypairForUser", err) diff --git a/routers/web/web.go b/routers/web/web.go index 26562eba53..8fb0fc02ee 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -641,7 +641,7 @@ func registerWebRoutes(m *web.Router) { 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.RegenerateMirrorSSHKeyPair) + m.Post("/keys/mirror-ssh/regenerate", user_setting.RegenerateUserSSHKeypair) m.Group("/packages", func() { m.Get("", user_setting.Packages) m.Group("/rules", func() { diff --git a/services/mirror/ssh_keypair.go b/services/mirror/ssh_keypair.go index 91acd7ced8..00bd26fc0d 100644 --- a/services/mirror/ssh_keypair.go +++ b/services/mirror/ssh_keypair.go @@ -12,32 +12,32 @@ import ( ) // GetOrCreateSSHKeypairForUser gets or creates an SSH keypair for the given user -func GetOrCreateSSHKeypairForUser(ctx context.Context, userID int64) (*repo_model.MirrorSSHKeypair, error) { +func GetOrCreateSSHKeypairForUser(ctx context.Context, userID int64) (*repo_model.UserSSHKeypair, error) { return ssh_module.GetOrCreateSSHKeypairForUser(ctx, userID) } // GetOrCreateSSHKeypairForOrg gets or creates an SSH keypair for the given organization -func GetOrCreateSSHKeypairForOrg(ctx context.Context, orgID int64) (*repo_model.MirrorSSHKeypair, error) { +func GetOrCreateSSHKeypairForOrg(ctx context.Context, orgID int64) (*repo_model.UserSSHKeypair, error) { return ssh_module.GetOrCreateSSHKeypairForOrg(ctx, orgID) } // GetSSHKeypairForRepository gets the appropriate SSH keypair for a repository // If the repository belongs to an organization, it uses the org's keypair, // otherwise it uses the user's keypair -func GetSSHKeypairForRepository(ctx context.Context, repo *repo_model.Repository) (*repo_model.MirrorSSHKeypair, error) { +func GetSSHKeypairForRepository(ctx context.Context, repo *repo_model.Repository) (*repo_model.UserSSHKeypair, error) { return ssh_module.GetSSHKeypairForRepository(ctx, repo) } // RegenerateSSHKeypairForUser regenerates the SSH keypair for a user -func RegenerateSSHKeypairForUser(ctx context.Context, userID int64) (*repo_model.MirrorSSHKeypair, error) { +func RegenerateSSHKeypairForUser(ctx context.Context, userID int64) (*repo_model.UserSSHKeypair, error) { log.Info("Regenerating SSH keypair for user %d", userID) - return repo_model.RegenerateMirrorSSHKeypair(ctx, userID) + return repo_model.RegenerateUserSSHKeypair(ctx, userID) } // RegenerateSSHKeypairForOrg regenerates the SSH keypair for an organization -func RegenerateSSHKeypairForOrg(ctx context.Context, orgID int64) (*repo_model.MirrorSSHKeypair, error) { +func RegenerateSSHKeypairForOrg(ctx context.Context, orgID int64) (*repo_model.UserSSHKeypair, error) { log.Info("Regenerating SSH keypair for organization %d", orgID) - return repo_model.RegenerateMirrorSSHKeypair(ctx, orgID) + return repo_model.RegenerateUserSSHKeypair(ctx, orgID) } // IsSSHURL checks if a URL is an SSH URL @@ -47,6 +47,6 @@ func IsSSHURL(url string) bool { // GetSSHKeypairForURL gets the appropriate SSH keypair for a given repository and URL // Returns nil if the URL is not an SSH URL -func GetSSHKeypairForURL(ctx context.Context, repo *repo_model.Repository, url string) (*repo_model.MirrorSSHKeypair, error) { +func GetSSHKeypairForURL(ctx context.Context, repo *repo_model.Repository, url string) (*repo_model.UserSSHKeypair, error) { return ssh_module.GetSSHKeypairForURL(ctx, repo, url) }