mirror of
https://github.com/go-gitea/gitea
synced 2025-07-23 02:38:35 +00:00
Split migrations folder (#21549)
There are too many files in `models/migrations` folder so that I split them into sub folders.
This commit is contained in:
15
models/migrations/v1_17/main_test.go
Normal file
15
models/migrations/v1_17/main_test.go
Normal file
@@ -0,0 +1,15 @@
|
||||
// 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
base.MainTest(m)
|
||||
}
|
26
models/migrations/v1_17/v211.go
Normal file
26
models/migrations/v1_17/v211.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func CreateForeignReferenceTable(x *xorm.Engine) error {
|
||||
type ForeignReference struct {
|
||||
// RepoID is the first column in all indices. now we only need 2 indices: (repo, local) and (repo, foreign, type)
|
||||
RepoID int64 `xorm:"UNIQUE(repo_foreign_type) INDEX(repo_local)" `
|
||||
LocalIndex int64 `xorm:"INDEX(repo_local)"` // the resource key inside Gitea, it can be IssueIndex, or some model ID.
|
||||
ForeignIndex string `xorm:"INDEX UNIQUE(repo_foreign_type)"`
|
||||
Type string `xorm:"VARCHAR(16) INDEX UNIQUE(repo_foreign_type)"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(ForeignReference)); err != nil {
|
||||
return fmt.Errorf("Sync2: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
94
models/migrations/v1_17/v212.go
Normal file
94
models/migrations/v1_17/v212.go
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddPackageTables(x *xorm.Engine) error {
|
||||
type Package struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
OwnerID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
Type string `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
Name string `xorm:"NOT NULL"`
|
||||
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
SemverCompatible bool `xorm:"NOT NULL DEFAULT false"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(Package)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type PackageVersion struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
PackageID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
CreatorID int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
Version string `xorm:"NOT NULL"`
|
||||
LowerVersion string `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"`
|
||||
IsInternal bool `xorm:"INDEX NOT NULL DEFAULT false"`
|
||||
MetadataJSON string `xorm:"metadata_json TEXT"`
|
||||
DownloadCount int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(PackageVersion)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type PackageProperty struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RefType int64 `xorm:"INDEX NOT NULL"`
|
||||
RefID int64 `xorm:"INDEX NOT NULL"`
|
||||
Name string `xorm:"INDEX NOT NULL"`
|
||||
Value string `xorm:"TEXT NOT NULL"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(PackageProperty)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type PackageFile struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
VersionID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
BlobID int64 `xorm:"INDEX NOT NULL"`
|
||||
Name string `xorm:"NOT NULL"`
|
||||
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
CompositeKey string `xorm:"UNIQUE(s) INDEX"`
|
||||
IsLead bool `xorm:"NOT NULL DEFAULT false"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(PackageFile)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type PackageBlob struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Size int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
HashMD5 string `xorm:"hash_md5 char(32) UNIQUE(md5) INDEX NOT NULL"`
|
||||
HashSHA1 string `xorm:"hash_sha1 char(40) UNIQUE(sha1) INDEX NOT NULL"`
|
||||
HashSHA256 string `xorm:"hash_sha256 char(64) UNIQUE(sha256) INDEX NOT NULL"`
|
||||
HashSHA512 string `xorm:"hash_sha512 char(128) UNIQUE(sha512) INDEX NOT NULL"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"`
|
||||
}
|
||||
|
||||
if err := x.Sync2(new(PackageBlob)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type PackageBlobUpload struct {
|
||||
ID string `xorm:"pk"`
|
||||
BytesReceived int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
HashStateBytes []byte `xorm:"BLOB"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"updated INDEX NOT NULL"`
|
||||
}
|
||||
|
||||
return x.Sync2(new(PackageBlobUpload))
|
||||
}
|
18
models/migrations/v1_17/v213.go
Normal file
18
models/migrations/v1_17/v213.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddAllowMaintainerEdit(x *xorm.Engine) error {
|
||||
// PullRequest represents relation between pull request and repositories.
|
||||
type PullRequest struct {
|
||||
AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`
|
||||
}
|
||||
|
||||
return x.Sync2(new(PullRequest))
|
||||
}
|
23
models/migrations/v1_17/v214.go
Normal file
23
models/migrations/v1_17/v214.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddAutoMergeTable(x *xorm.Engine) error {
|
||||
type MergeStyle string
|
||||
type PullAutoMerge struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
PullID int64 `xorm:"UNIQUE"`
|
||||
DoerID int64 `xorm:"NOT NULL"`
|
||||
MergeStyle MergeStyle `xorm:"varchar(30)"`
|
||||
Message string `xorm:"LONGTEXT"`
|
||||
CreatedUnix int64 `xorm:"created"`
|
||||
}
|
||||
|
||||
return x.Sync2(&PullAutoMerge{})
|
||||
}
|
25
models/migrations/v1_17/v215.go
Normal file
25
models/migrations/v1_17/v215.go
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/models/pull"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddReviewViewedFiles(x *xorm.Engine) error {
|
||||
type ReviewState struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
|
||||
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"`
|
||||
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"`
|
||||
UpdatedFiles map[string]pull.ViewedState `xorm:"NOT NULL LONGTEXT JSON"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
|
||||
}
|
||||
|
||||
return x.Sync2(new(ReviewState))
|
||||
}
|
8
models/migrations/v1_17/v216.go
Normal file
8
models/migrations/v1_17/v216.go
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
// This migration added non-ideal indices to the action table which on larger datasets slowed things down
|
||||
// it has been superceded by v218.go
|
26
models/migrations/v1_17/v217.go
Normal file
26
models/migrations/v1_17/v217.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AlterHookTaskTextFieldsToLongText(x *xorm.Engine) error {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if setting.Database.UseMySQL {
|
||||
if _, err := sess.Exec("ALTER TABLE `hook_task` CHANGE `payload_content` `payload_content` LONGTEXT, CHANGE `request_content` `request_content` LONGTEXT, change `response_content` `response_content` LONGTEXT"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
53
models/migrations/v1_17/v218.go
Normal file
53
models/migrations/v1_17/v218.go
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
type improveActionTableIndicesAction struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
UserID int64 // Receiver user id.
|
||||
OpType int
|
||||
ActUserID int64 // Action user id.
|
||||
RepoID int64
|
||||
CommentID int64 `xorm:"INDEX"`
|
||||
IsDeleted bool `xorm:"NOT NULL DEFAULT false"`
|
||||
RefName string
|
||||
IsPrivate bool `xorm:"NOT NULL DEFAULT false"`
|
||||
Content string `xorm:"TEXT"`
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created"`
|
||||
}
|
||||
|
||||
// TableName sets the name of this table
|
||||
func (*improveActionTableIndicesAction) TableName() string {
|
||||
return "action"
|
||||
}
|
||||
|
||||
// TableIndices implements xorm's TableIndices interface
|
||||
func (*improveActionTableIndicesAction) TableIndices() []*schemas.Index {
|
||||
repoIndex := schemas.NewIndex("r_u_d", schemas.IndexType)
|
||||
repoIndex.AddColumn("repo_id", "user_id", "is_deleted")
|
||||
|
||||
actUserIndex := schemas.NewIndex("au_r_c_u_d", schemas.IndexType)
|
||||
actUserIndex.AddColumn("act_user_id", "repo_id", "created_unix", "user_id", "is_deleted")
|
||||
indices := []*schemas.Index{actUserIndex, repoIndex}
|
||||
if setting.Database.UsePostgreSQL {
|
||||
cudIndex := schemas.NewIndex("c_u_d", schemas.IndexType)
|
||||
cudIndex.AddColumn("created_unix", "user_id", "is_deleted")
|
||||
indices = append(indices, cudIndex)
|
||||
}
|
||||
|
||||
return indices
|
||||
}
|
||||
|
||||
func ImproveActionTableIndices(x *xorm.Engine) error {
|
||||
return x.Sync2(&improveActionTableIndicesAction{})
|
||||
}
|
31
models/migrations/v1_17/v219.go
Normal file
31
models/migrations/v1_17/v219.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddSyncOnCommitColForPushMirror(x *xorm.Engine) error {
|
||||
type PushMirror struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
Repo *repo.Repository `xorm:"-"`
|
||||
RemoteName string
|
||||
|
||||
SyncOnCommit bool `xorm:"NOT NULL DEFAULT true"`
|
||||
Interval time.Duration
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"created"`
|
||||
LastUpdateUnix timeutil.TimeStamp `xorm:"INDEX last_update"`
|
||||
LastError string `xorm:"text"`
|
||||
}
|
||||
|
||||
return x.Sync2(new(PushMirror))
|
||||
}
|
28
models/migrations/v1_17/v220.go
Normal file
28
models/migrations/v1_17/v220.go
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
packages_model "code.gitea.io/gitea/models/packages"
|
||||
container_module "code.gitea.io/gitea/modules/packages/container"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
func AddContainerRepositoryProperty(x *xorm.Engine) (err error) {
|
||||
switch x.Dialect().URI().DBType {
|
||||
case schemas.SQLITE:
|
||||
_, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name || '/' || p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
|
||||
packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
|
||||
case schemas.MSSQL:
|
||||
_, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name + '/' + p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
|
||||
packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
|
||||
default:
|
||||
_, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, CONCAT(u.lower_name, '/', p.lower_name) FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
|
||||
packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
|
||||
}
|
||||
return err
|
||||
}
|
75
models/migrations/v1_17/v221.go
Normal file
75
models/migrations/v1_17/v221.go
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"encoding/base32"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func StoreWebauthnCredentialIDAsBytes(x *xorm.Engine) error {
|
||||
// Create webauthnCredential table
|
||||
type webauthnCredential struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Name string
|
||||
LowerName string `xorm:"unique(s)"`
|
||||
UserID int64 `xorm:"INDEX unique(s)"`
|
||||
CredentialID string `xorm:"INDEX VARCHAR(410)"`
|
||||
// Note the lack of INDEX here - these will be created once the column is renamed in v223.go
|
||||
CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022
|
||||
PublicKey []byte
|
||||
AttestationType string
|
||||
AAGUID []byte
|
||||
SignCount uint32 `xorm:"BIGINT"`
|
||||
CloneWarning bool
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
if err := x.Sync2(&webauthnCredential{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var start int
|
||||
creds := make([]*webauthnCredential, 0, 50)
|
||||
for {
|
||||
err := x.Select("id, credential_id").OrderBy("id").Limit(50, start).Find(&creds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = func() error {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return fmt.Errorf("unable to allow start session. Error: %w", err)
|
||||
}
|
||||
for _, cred := range creds {
|
||||
cred.CredentialIDBytes, err = base32.HexEncoding.DecodeString(cred.CredentialID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse credential id %s for credential[%d]: %w", cred.CredentialID, cred.ID, err)
|
||||
}
|
||||
count, err := sess.ID(cred.ID).Cols("credential_id_bytes").Update(cred)
|
||||
if count != 1 || err != nil {
|
||||
return fmt.Errorf("unable to update credential id bytes for credential[%d]: %d,%w", cred.ID, count, err)
|
||||
}
|
||||
}
|
||||
return sess.Commit()
|
||||
}()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(creds) < 50 {
|
||||
break
|
||||
}
|
||||
start += 50
|
||||
creds = creds[:0]
|
||||
}
|
||||
return nil
|
||||
}
|
67
models/migrations/v1_17/v221_test.go
Normal file
67
models/migrations/v1_17/v221_test.go
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"encoding/base32"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_StoreWebauthnCredentialIDAsBytes(t *testing.T) {
|
||||
// Create webauthnCredential table
|
||||
type WebauthnCredential struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Name string
|
||||
LowerName string `xorm:"unique(s)"`
|
||||
UserID int64 `xorm:"INDEX unique(s)"`
|
||||
CredentialID string `xorm:"INDEX VARCHAR(410)"`
|
||||
PublicKey []byte
|
||||
AttestationType string
|
||||
AAGUID []byte
|
||||
SignCount uint32 `xorm:"BIGINT"`
|
||||
CloneWarning bool
|
||||
}
|
||||
|
||||
type ExpectedWebauthnCredential struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
CredentialID string // CredentialID is at most 1023 bytes as per spec released 20 July 2022
|
||||
}
|
||||
|
||||
type ConvertedWebauthnCredential struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022
|
||||
}
|
||||
|
||||
// Prepare and load the testing database
|
||||
x, deferable := base.PrepareTestEnv(t, 0, new(WebauthnCredential), new(ExpectedWebauthnCredential))
|
||||
defer deferable()
|
||||
if x == nil || t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
if err := StoreWebauthnCredentialIDAsBytes(x); err != nil {
|
||||
assert.NoError(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
expected := []ExpectedWebauthnCredential{}
|
||||
if err := x.Table("expected_webauthn_credential").Asc("id").Find(&expected); !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
|
||||
got := []ConvertedWebauthnCredential{}
|
||||
if err := x.Table("webauthn_credential").Select("id, credential_id_bytes").Asc("id").Find(&got); !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
|
||||
for i, e := range expected {
|
||||
credIDBytes, _ := base32.HexEncoding.DecodeString(e.CredentialID)
|
||||
assert.Equal(t, credIDBytes, got[i].CredentialIDBytes)
|
||||
}
|
||||
}
|
65
models/migrations/v1_17/v222.go
Normal file
65
models/migrations/v1_17/v222.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func DropOldCredentialIDColumn(x *xorm.Engine) error {
|
||||
// This migration maybe rerun so that we should check if it has been run
|
||||
credentialIDExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !credentialIDExist {
|
||||
// Column is already non-extant
|
||||
return nil
|
||||
}
|
||||
credentialIDBytesExists, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id_bytes")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !credentialIDBytesExists {
|
||||
// looks like 221 hasn't properly run
|
||||
return fmt.Errorf("webauthn_credential does not have a credential_id_bytes column... it is not safe to run this migration")
|
||||
}
|
||||
|
||||
// Create webauthnCredential table
|
||||
type webauthnCredential struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Name string
|
||||
LowerName string `xorm:"unique(s)"`
|
||||
UserID int64 `xorm:"INDEX unique(s)"`
|
||||
CredentialID string `xorm:"INDEX VARCHAR(410)"`
|
||||
// Note the lack of the INDEX on CredentialIDBytes - we will add this in v223.go
|
||||
CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022
|
||||
PublicKey []byte
|
||||
AttestationType string
|
||||
AAGUID []byte
|
||||
SignCount uint32 `xorm:"BIGINT"`
|
||||
CloneWarning bool
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
if err := x.Sync2(&webauthnCredential{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Drop the old credential ID
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
if err := base.DropTableColumns(sess, "webauthn_credential", "credential_id"); err != nil {
|
||||
return fmt.Errorf("unable to drop old credentialID column: %w", err)
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
104
models/migrations/v1_17/v223.go
Normal file
104
models/migrations/v1_17/v223.go
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright 2022 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 v1_17 // nolint
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models/migrations/base"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func RenameCredentialIDBytes(x *xorm.Engine) error {
|
||||
// This migration maybe rerun so that we should check if it has been run
|
||||
credentialIDExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if credentialIDExist {
|
||||
credentialIDBytesExists, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id_bytes")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !credentialIDBytesExists {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
err = func() error {
|
||||
// webauthnCredential table
|
||||
type webauthnCredential struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Name string
|
||||
LowerName string `xorm:"unique(s)"`
|
||||
UserID int64 `xorm:"INDEX unique(s)"`
|
||||
// Note the lack of INDEX here
|
||||
CredentialIDBytes []byte `xorm:"VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022
|
||||
PublicKey []byte
|
||||
AttestationType string
|
||||
AAGUID []byte
|
||||
SignCount uint32 `xorm:"BIGINT"`
|
||||
CloneWarning bool
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := sess.Sync2(new(webauthnCredential)); err != nil {
|
||||
return fmt.Errorf("error on Sync2: %w", err)
|
||||
}
|
||||
|
||||
if credentialIDExist {
|
||||
// if both errors and message exist, drop message at first
|
||||
if err := base.DropTableColumns(sess, "webauthn_credential", "credential_id"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case setting.Database.UseMySQL:
|
||||
if _, err := sess.Exec("ALTER TABLE `webauthn_credential` CHANGE credential_id_bytes credential_id VARBINARY(1024)"); err != nil {
|
||||
return err
|
||||
}
|
||||
case setting.Database.UseMSSQL:
|
||||
if _, err := sess.Exec("sp_rename 'webauthn_credential.credential_id_bytes', 'credential_id', 'COLUMN'"); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
if _, err := sess.Exec("ALTER TABLE `webauthn_credential` RENAME COLUMN credential_id_bytes TO credential_id"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return sess.Commit()
|
||||
}()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create webauthnCredential table
|
||||
type webauthnCredential struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Name string
|
||||
LowerName string `xorm:"unique(s)"`
|
||||
UserID int64 `xorm:"INDEX unique(s)"`
|
||||
CredentialID []byte `xorm:"INDEX VARBINARY(1024)"` // CredentialID is at most 1023 bytes as per spec released 20 July 2022
|
||||
PublicKey []byte
|
||||
AttestationType string
|
||||
AAGUID []byte
|
||||
SignCount uint32 `xorm:"BIGINT"`
|
||||
CloneWarning bool
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
}
|
||||
return x.Sync2(&webauthnCredential{})
|
||||
}
|
Reference in New Issue
Block a user