1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo.git synced 2025-09-30 19:22:08 +00:00
forgejo/models/migrations/v1_13/v151.go

167 lines
4.9 KiB
Go
Raw Normal View History

// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_13
import (
"errors"
"fmt"
"strings"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
)
func SetDefaultPasswordToArgon2(x *xorm.Engine) error {
switch {
case setting.Database.Type.IsMySQL():
_, err := x.Exec("ALTER TABLE `user` ALTER passwd_hash_algo SET DEFAULT 'argon2';")
return err
case setting.Database.Type.IsPostgreSQL():
_, err := x.Exec("ALTER TABLE `user` ALTER COLUMN passwd_hash_algo SET DEFAULT 'argon2';")
return err
case setting.Database.Type.IsSQLite3():
// drop through
default:
log.Fatal("Unrecognized DB")
}
tables, err := x.DBMetas()
if err != nil {
return err
}
// Now for SQLite we have to recreate the table
var table *schemas.Table
tableName := "user"
for _, table = range tables {
if table.Name == tableName {
break
}
}
if table == nil || table.Name != tableName {
type User struct {
PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'argon2'"`
}
return x.Sync(new(User))
}
column := table.GetColumn("passwd_hash_algo")
if column == nil {
type User struct {
PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'argon2'"`
}
return x.Sync(new(User))
}
tempTableName := "tmp_recreate__user"
column.Default = "'argon2'"
chore: replace xorm v1.3.9 with v1.3.9-forgejo.1, preparation for foreign key additions (#9326) Prepares for the addition of foreign keys to Forgejo tables by bringing xorm over to https://code.forgejo.org/xorm/xorm/releases/tag/v1.3.9-forgejo.1. ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [ ] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [x] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9326 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net> Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-09-19 06:30:04 +02:00
createTableSQL, _, err := x.Dialect().CreateTableSQL(table, tempTableName)
if err != nil {
return err
}
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
if _, err := sess.Exec(createTableSQL); err != nil {
log.Error("Unable to create table %s. Error: %v\n", tempTableName, err, createTableSQL)
return err
}
for _, index := range table.Indexes {
if _, err := sess.Exec(x.Dialect().CreateIndexSQL(tempTableName, index)); err != nil {
log.Error("Unable to create indexes on temporary table %s. Error: %v", tempTableName, err)
return err
}
}
newTableColumns := table.Columns()
if len(newTableColumns) == 0 {
return errors.New("no columns in new table")
}
hasID := false
for _, column := range newTableColumns {
hasID = hasID || (column.IsPrimaryKey && column.IsAutoIncrement)
}
sqlStringBuilder := &strings.Builder{}
_, _ = sqlStringBuilder.WriteString("INSERT INTO `")
_, _ = sqlStringBuilder.WriteString(tempTableName)
_, _ = sqlStringBuilder.WriteString("` (`")
_, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name)
_, _ = sqlStringBuilder.WriteString("`")
for _, column := range newTableColumns[1:] {
_, _ = sqlStringBuilder.WriteString(", `")
_, _ = sqlStringBuilder.WriteString(column.Name)
_, _ = sqlStringBuilder.WriteString("`")
}
_, _ = sqlStringBuilder.WriteString(")")
_, _ = sqlStringBuilder.WriteString(" SELECT ")
if newTableColumns[0].Default != "" {
_, _ = sqlStringBuilder.WriteString("COALESCE(`")
_, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name)
_, _ = sqlStringBuilder.WriteString("`, ")
_, _ = sqlStringBuilder.WriteString(newTableColumns[0].Default)
_, _ = sqlStringBuilder.WriteString(")")
} else {
_, _ = sqlStringBuilder.WriteString("`")
_, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name)
_, _ = sqlStringBuilder.WriteString("`")
}
for _, column := range newTableColumns[1:] {
if column.Default != "" {
_, _ = sqlStringBuilder.WriteString(", COALESCE(`")
_, _ = sqlStringBuilder.WriteString(column.Name)
_, _ = sqlStringBuilder.WriteString("`, ")
_, _ = sqlStringBuilder.WriteString(column.Default)
_, _ = sqlStringBuilder.WriteString(")")
} else {
_, _ = sqlStringBuilder.WriteString(", `")
_, _ = sqlStringBuilder.WriteString(column.Name)
_, _ = sqlStringBuilder.WriteString("`")
}
}
_, _ = sqlStringBuilder.WriteString(" FROM `")
_, _ = sqlStringBuilder.WriteString(tableName)
_, _ = sqlStringBuilder.WriteString("`")
if _, err := sess.Exec(sqlStringBuilder.String()); err != nil {
log.Error("Unable to set copy data in to temp table %s. Error: %v", tempTableName, err)
return err
}
// SQLite will drop all the constraints on the old table
if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
log.Error("Unable to drop old table %s. Error: %v", tableName, err)
return err
}
for _, index := range table.Indexes {
if _, err := sess.Exec(x.Dialect().DropIndexSQL(tempTableName, index)); err != nil {
log.Error("Unable to drop indexes on temporary table %s. Error: %v", tempTableName, err)
return err
}
}
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`", tempTableName, tableName)); err != nil {
log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err)
return err
}
for _, index := range table.Indexes {
if _, err := sess.Exec(x.Dialect().CreateIndexSQL(tableName, index)); err != nil {
log.Error("Unable to recreate indexes on table %s. Error: %v", tableName, err)
return err
}
}
return sess.Commit()
}