diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2022-08-25 10:31:57 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-25 10:31:57 +0800 |
commit | 1d8543e7db58d7c4973758e47f005c4d8bd7d7a3 (patch) | |
tree | b60c99e2dfd69ccb998f8a0829d98d7cadcf0d6b /models/admin | |
parent | 4a4bfafa238bf48851f8c11fa3701bd42b912475 (diff) | |
download | gitea-1d8543e7db58d7c4973758e47f005c4d8bd7d7a3.tar.gz gitea-1d8543e7db58d7c4973758e47f005c4d8bd7d7a3.zip |
Move some files into models' sub packages (#20262)
* Move some files into models' sub packages
* Move functions
* merge main branch
* Fix check
* fix check
* Fix some tests
* Fix lint
* Fix lint
* Revert lint changes
* Fix error comments
* Fix lint
Co-authored-by: 6543 <6543@obermui.de>
Diffstat (limited to 'models/admin')
-rw-r--r-- | models/admin/main_test.go | 7 | ||||
-rw-r--r-- | models/admin/notice_test.go | 73 | ||||
-rw-r--r-- | models/admin/task.go | 264 |
3 files changed, 306 insertions, 38 deletions
diff --git a/models/admin/main_test.go b/models/admin/main_test.go index 693b70fbf7..23277fe37c 100644 --- a/models/admin/main_test.go +++ b/models/admin/main_test.go @@ -2,18 +2,21 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package admin +package admin_test import ( "path/filepath" "testing" "code.gitea.io/gitea/models/unittest" + + _ "code.gitea.io/gitea/models" + _ "code.gitea.io/gitea/models/activities" + _ "code.gitea.io/gitea/models/perm/access" ) func TestMain(m *testing.M) { unittest.MainTest(m, &unittest.TestOptions{ GiteaRootPath: filepath.Join("..", ".."), - FixtureFiles: []string{"notice.yml"}, }) } diff --git a/models/admin/notice_test.go b/models/admin/notice_test.go index b4613db8e7..f3767392d1 100644 --- a/models/admin/notice_test.go +++ b/models/admin/notice_test.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package admin +package admin_test import ( "testing" + "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" @@ -14,8 +15,8 @@ import ( ) func TestNotice_TrStr(t *testing.T) { - notice := &Notice{ - Type: NoticeRepository, + notice := &admin.Notice{ + Type: admin.NoticeRepository, Description: "test description", } assert.Equal(t, "admin.notices.type_1", notice.TrStr()) @@ -24,24 +25,24 @@ func TestNotice_TrStr(t *testing.T) { func TestCreateNotice(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - noticeBean := &Notice{ - Type: NoticeRepository, + noticeBean := &admin.Notice{ + Type: admin.NoticeRepository, Description: "test description", } unittest.AssertNotExistsBean(t, noticeBean) - assert.NoError(t, CreateNotice(db.DefaultContext, noticeBean.Type, noticeBean.Description)) + assert.NoError(t, admin.CreateNotice(db.DefaultContext, noticeBean.Type, noticeBean.Description)) unittest.AssertExistsAndLoadBean(t, noticeBean) } func TestCreateRepositoryNotice(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - noticeBean := &Notice{ - Type: NoticeRepository, + noticeBean := &admin.Notice{ + Type: admin.NoticeRepository, Description: "test description", } unittest.AssertNotExistsBean(t, noticeBean) - assert.NoError(t, CreateRepositoryNotice(noticeBean.Description)) + assert.NoError(t, admin.CreateRepositoryNotice(noticeBean.Description)) unittest.AssertExistsAndLoadBean(t, noticeBean) } @@ -49,20 +50,20 @@ func TestCreateRepositoryNotice(t *testing.T) { func TestCountNotices(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.Equal(t, int64(3), CountNotices()) + assert.Equal(t, int64(3), admin.CountNotices()) } func TestNotices(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - notices, err := Notices(1, 2) + notices, err := admin.Notices(1, 2) assert.NoError(t, err) if assert.Len(t, notices, 2) { assert.Equal(t, int64(3), notices[0].ID) assert.Equal(t, int64(2), notices[1].ID) } - notices, err = Notices(2, 2) + notices, err = admin.Notices(2, 2) assert.NoError(t, err) if assert.Len(t, notices, 1) { assert.Equal(t, int64(1), notices[0].ID) @@ -72,45 +73,45 @@ func TestNotices(t *testing.T) { func TestDeleteNotice(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) - assert.NoError(t, DeleteNotice(3)) - unittest.AssertNotExistsBean(t, &Notice{ID: 3}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) + assert.NoError(t, admin.DeleteNotice(3)) + unittest.AssertNotExistsBean(t, &admin.Notice{ID: 3}) } func TestDeleteNotices(t *testing.T) { // delete a non-empty range assert.NoError(t, unittest.PrepareTestDatabase()) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) - assert.NoError(t, DeleteNotices(1, 2)) - unittest.AssertNotExistsBean(t, &Notice{ID: 1}) - unittest.AssertNotExistsBean(t, &Notice{ID: 2}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) + assert.NoError(t, admin.DeleteNotices(1, 2)) + unittest.AssertNotExistsBean(t, &admin.Notice{ID: 1}) + unittest.AssertNotExistsBean(t, &admin.Notice{ID: 2}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) } func TestDeleteNotices2(t *testing.T) { // delete an empty range assert.NoError(t, unittest.PrepareTestDatabase()) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) - assert.NoError(t, DeleteNotices(3, 2)) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) + assert.NoError(t, admin.DeleteNotices(3, 2)) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) } func TestDeleteNoticesByIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) - assert.NoError(t, DeleteNoticesByIDs([]int64{1, 3})) - unittest.AssertNotExistsBean(t, &Notice{ID: 1}) - unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) - unittest.AssertNotExistsBean(t, &Notice{ID: 3}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) + assert.NoError(t, admin.DeleteNoticesByIDs([]int64{1, 3})) + unittest.AssertNotExistsBean(t, &admin.Notice{ID: 1}) + unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) + unittest.AssertNotExistsBean(t, &admin.Notice{ID: 3}) } diff --git a/models/admin/task.go b/models/admin/task.go new file mode 100644 index 0000000000..07eb61decc --- /dev/null +++ b/models/admin/task.go @@ -0,0 +1,264 @@ +// Copyright 2019 Gitea. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package admin + +import ( + "context" + "fmt" + + "code.gitea.io/gitea/models/db" + repo_model "code.gitea.io/gitea/models/repo" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/json" + "code.gitea.io/gitea/modules/migration" + "code.gitea.io/gitea/modules/secret" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" + + "xorm.io/builder" +) + +// Task represents a task +type Task struct { + ID int64 + DoerID int64 `xorm:"index"` // operator + Doer *user_model.User `xorm:"-"` + OwnerID int64 `xorm:"index"` // repo owner id, when creating, the repoID maybe zero + Owner *user_model.User `xorm:"-"` + RepoID int64 `xorm:"index"` + Repo *repo_model.Repository `xorm:"-"` + Type structs.TaskType + Status structs.TaskStatus `xorm:"index"` + StartTime timeutil.TimeStamp + EndTime timeutil.TimeStamp + PayloadContent string `xorm:"TEXT"` + Message string `xorm:"TEXT"` // if task failed, saved the error reason + Created timeutil.TimeStamp `xorm:"created"` +} + +func init() { + db.RegisterModel(new(Task)) +} + +// TranslatableMessage represents JSON struct that can be translated with a Locale +type TranslatableMessage struct { + Format string + Args []interface{} `json:"omitempty"` +} + +// LoadRepo loads repository of the task +func (task *Task) LoadRepo() error { + return task.loadRepo(db.DefaultContext) +} + +func (task *Task) loadRepo(ctx context.Context) error { + if task.Repo != nil { + return nil + } + var repo repo_model.Repository + has, err := db.GetEngine(ctx).ID(task.RepoID).Get(&repo) + if err != nil { + return err + } else if !has { + return repo_model.ErrRepoNotExist{ + ID: task.RepoID, + } + } + task.Repo = &repo + return nil +} + +// LoadDoer loads do user +func (task *Task) LoadDoer() error { + if task.Doer != nil { + return nil + } + + var doer user_model.User + has, err := db.GetEngine(db.DefaultContext).ID(task.DoerID).Get(&doer) + if err != nil { + return err + } else if !has { + return user_model.ErrUserNotExist{ + UID: task.DoerID, + } + } + task.Doer = &doer + + return nil +} + +// LoadOwner loads owner user +func (task *Task) LoadOwner() error { + if task.Owner != nil { + return nil + } + + var owner user_model.User + has, err := db.GetEngine(db.DefaultContext).ID(task.OwnerID).Get(&owner) + if err != nil { + return err + } else if !has { + return user_model.ErrUserNotExist{ + UID: task.OwnerID, + } + } + task.Owner = &owner + + return nil +} + +// UpdateCols updates some columns +func (task *Task) UpdateCols(cols ...string) error { + _, err := db.GetEngine(db.DefaultContext).ID(task.ID).Cols(cols...).Update(task) + return err +} + +// MigrateConfig returns task config when migrate repository +func (task *Task) MigrateConfig() (*migration.MigrateOptions, error) { + if task.Type == structs.TaskTypeMigrateRepo { + var opts migration.MigrateOptions + err := json.Unmarshal([]byte(task.PayloadContent), &opts) + if err != nil { + return nil, err + } + + // decrypt credentials + if opts.CloneAddrEncrypted != "" { + if opts.CloneAddr, err = secret.DecryptSecret(setting.SecretKey, opts.CloneAddrEncrypted); err != nil { + return nil, err + } + } + if opts.AuthPasswordEncrypted != "" { + if opts.AuthPassword, err = secret.DecryptSecret(setting.SecretKey, opts.AuthPasswordEncrypted); err != nil { + return nil, err + } + } + if opts.AuthTokenEncrypted != "" { + if opts.AuthToken, err = secret.DecryptSecret(setting.SecretKey, opts.AuthTokenEncrypted); err != nil { + return nil, err + } + } + + return &opts, nil + } + return nil, fmt.Errorf("Task type is %s, not Migrate Repo", task.Type.Name()) +} + +// ErrTaskDoesNotExist represents a "TaskDoesNotExist" kind of error. +type ErrTaskDoesNotExist struct { + ID int64 + RepoID int64 + Type structs.TaskType +} + +// IsErrTaskDoesNotExist checks if an error is a ErrTaskDoesNotExist. +func IsErrTaskDoesNotExist(err error) bool { + _, ok := err.(ErrTaskDoesNotExist) + return ok +} + +func (err ErrTaskDoesNotExist) Error() string { + return fmt.Sprintf("task does not exist [id: %d, repo_id: %d, type: %d]", + err.ID, err.RepoID, err.Type) +} + +// GetMigratingTask returns the migrating task by repo's id +func GetMigratingTask(repoID int64) (*Task, error) { + task := Task{ + RepoID: repoID, + Type: structs.TaskTypeMigrateRepo, + } + has, err := db.GetEngine(db.DefaultContext).Get(&task) + if err != nil { + return nil, err + } else if !has { + return nil, ErrTaskDoesNotExist{0, repoID, task.Type} + } + return &task, nil +} + +// HasFinishedMigratingTask returns if a finished migration task exists for the repo. +func HasFinishedMigratingTask(repoID int64) (bool, error) { + return db.GetEngine(db.DefaultContext). + Where("repo_id=? AND type=? AND status=?", repoID, structs.TaskTypeMigrateRepo, structs.TaskStatusFinished). + Table("task"). + Exist() +} + +// GetMigratingTaskByID returns the migrating task by repo's id +func GetMigratingTaskByID(id, doerID int64) (*Task, *migration.MigrateOptions, error) { + task := Task{ + ID: id, + DoerID: doerID, + Type: structs.TaskTypeMigrateRepo, + } + has, err := db.GetEngine(db.DefaultContext).Get(&task) + if err != nil { + return nil, nil, err + } else if !has { + return nil, nil, ErrTaskDoesNotExist{id, 0, task.Type} + } + + var opts migration.MigrateOptions + if err := json.Unmarshal([]byte(task.PayloadContent), &opts); err != nil { + return nil, nil, err + } + return &task, &opts, nil +} + +// FindTaskOptions find all tasks +type FindTaskOptions struct { + Status int +} + +// ToConds generates conditions for database operation. +func (opts FindTaskOptions) ToConds() builder.Cond { + cond := builder.NewCond() + if opts.Status >= 0 { + cond = cond.And(builder.Eq{"status": opts.Status}) + } + return cond +} + +// FindTasks find all tasks +func FindTasks(opts FindTaskOptions) ([]*Task, error) { + tasks := make([]*Task, 0, 10) + err := db.GetEngine(db.DefaultContext).Where(opts.ToConds()).Find(&tasks) + return tasks, err +} + +// CreateTask creates a task on database +func CreateTask(task *Task) error { + return db.Insert(db.DefaultContext, task) +} + +// FinishMigrateTask updates database when migrate task finished +func FinishMigrateTask(task *Task) error { + task.Status = structs.TaskStatusFinished + task.EndTime = timeutil.TimeStampNow() + + // delete credentials when we're done, they're a liability. + conf, err := task.MigrateConfig() + if err != nil { + return err + } + conf.AuthPassword = "" + conf.AuthToken = "" + conf.CloneAddr = util.SanitizeCredentialURLs(conf.CloneAddr) + conf.AuthPasswordEncrypted = "" + conf.AuthTokenEncrypted = "" + conf.CloneAddrEncrypted = "" + confBytes, err := json.Marshal(conf) + if err != nil { + return err + } + task.PayloadContent = string(confBytes) + + _, err = db.GetEngine(db.DefaultContext).ID(task.ID).Cols("status", "end_time", "payload_content").Update(task) + return err +} |