From b391bb649013080bf346483a980bc3cc993e7f83 Mon Sep 17 00:00:00 2001 From: kolaente Date: Mon, 20 Jan 2020 20:16:24 +0100 Subject: [PATCH] Add migration status --- pkg/cmd/cmd.go | 5 ++ pkg/modules/migration/db.go | 49 +++++++++++++++++++ pkg/modules/migration/handler/handler.go | 30 ++++++++++++ pkg/modules/migration/migration_status.go | 49 +++++++++++++++++++ pkg/modules/migration/migrator.go | 3 ++ .../migration/wunderlist/wunderlist.go | 5 ++ 6 files changed, 141 insertions(+) create mode 100644 pkg/modules/migration/db.go create mode 100644 pkg/modules/migration/migration_status.go diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 0e791fa1d..62d70f8ad 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -23,6 +23,7 @@ import ( "code.vikunja.io/api/pkg/mail" "code.vikunja.io/api/pkg/migration" "code.vikunja.io/api/pkg/models" + migrator "code.vikunja.io/api/pkg/modules/migration" "code.vikunja.io/api/pkg/red" "fmt" "github.com/spf13/cobra" @@ -79,6 +80,10 @@ func initialize() { if err != nil { log.Fatal(err.Error()) } + err = migrator.InitDB() + if err != nil { + log.Fatal(err.Error()) + } // Initialize the files handler files.InitFileHandler() diff --git a/pkg/modules/migration/db.go b/pkg/modules/migration/db.go new file mode 100644 index 000000000..814ef6771 --- /dev/null +++ b/pkg/modules/migration/db.go @@ -0,0 +1,49 @@ +// Vikunja is a todo-list application to facilitate your life. +// Copyright 2018-2020 Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package migration + +import ( + "code.vikunja.io/api/pkg/config" + "code.vikunja.io/api/pkg/db" + "code.vikunja.io/api/pkg/log" + "github.com/go-xorm/xorm" +) + +var x *xorm.Engine + +// InitDB sets up the database connection to use in this module +func InitDB() (err error) { + x, err = db.CreateDBEngine() + if err != nil { + log.Criticalf("Could not connect to db: %v", err.Error()) + return + } + + // Cache + if config.CacheEnabled.GetBool() && config.CacheType.GetString() == "redis" { + db.RegisterTableStructsForCache(GetTables()) + } + + return nil +} + +// GetTables returns all structs which are also a table. +func GetTables() []interface{} { + return []interface{}{ + &Status{}, + } +} diff --git a/pkg/modules/migration/handler/handler.go b/pkg/modules/migration/handler/handler.go index 4efef3adb..0bb47881d 100644 --- a/pkg/modules/migration/handler/handler.go +++ b/pkg/modules/migration/handler/handler.go @@ -34,6 +34,14 @@ type AuthURL struct { URL string `json:"url"` } +// RegisterRoutes registers all routes for migration +func (mw *MigrationWeb) RegisterRoutes(g echo.Group) { + ms := mw.MigrationStruct() + g.GET("/"+ms.Name()+"/auth", mw.AuthURL) + g.GET("/"+ms.Name()+"/status", mw.Status) + g.POST("/"+ms.Name()+"/migrate", mw.Migrate) +} + // AuthURL is the web handler to get the auth url func (mw *MigrationWeb) AuthURL(c echo.Context) error { ms := mw.MigrationStruct() @@ -62,5 +70,27 @@ func (mw *MigrationWeb) Migrate(c echo.Context) error { return handler.HandleHTTPError(err, c) } + err = migration.SetMigrationStatus(ms, user) + if err != nil { + return handler.HandleHTTPError(err, c) + } + return c.JSON(http.StatusOK, models.Message{Message: "Everything was migrated successfully."}) } + +// Status returns whether or not a user has already done this migration +func (mw *MigrationWeb) Status(c echo.Context) error { + ms := mw.MigrationStruct() + + user, err := models.GetCurrentUser(c) + if err != nil { + return handler.HandleHTTPError(err, c) + } + + status, err := migration.GetMigrationStatus(ms, user) + if err != nil { + return handler.HandleHTTPError(err, c) + } + + return c.JSON(http.StatusOK, status) +} diff --git a/pkg/modules/migration/migration_status.go b/pkg/modules/migration/migration_status.go new file mode 100644 index 000000000..cfce103b7 --- /dev/null +++ b/pkg/modules/migration/migration_status.go @@ -0,0 +1,49 @@ +// Vikunja is a todo-list application to facilitate your life. +// Copyright 2018-2020 Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package migration + +import "code.vikunja.io/api/pkg/models" + +// Status represents this migration status +type Status struct { + ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"` + UserID int64 `xorm:"int(11) not null" json:"user_id"` + MigratorName string `xorm:"varchar(255)" json:"migrator_name"` + CreatedUnix int64 `xorm:"created not null"` +} + +// TableName holds the table name for the migration status table +func (s *Status) TableName() string { + return "migration_status" +} + +// SetMigrationStatus sets the migration status for a user +func SetMigrationStatus(m Migrator, u *models.User) (err error) { + status := &Status{ + UserID: u.ID, + MigratorName: m.Name(), + } + _, err = x.Insert(status) + return +} + +// GetMigrationStatus returns the migration status for a migration and a user +func GetMigrationStatus(m Migrator, u *models.User) (status *Status, err error) { + status = &Status{} + _, err = x.Where("user_id = ? and migrator_name = ?", u.ID, m.Name()).Desc("id").Get(status) + return +} diff --git a/pkg/modules/migration/migrator.go b/pkg/modules/migration/migrator.go index bac7dd716..8ea27391a 100644 --- a/pkg/modules/migration/migrator.go +++ b/pkg/modules/migration/migrator.go @@ -28,4 +28,7 @@ type Migrator interface { // The use case for this are Oauth flows, where the server token should remain hidden and not // known to the frontend. AuthURL() string + // Name holds the name of the migration. + // This is used to show the name to users and to keep track of users who already migrated. + Name() string } diff --git a/pkg/modules/migration/wunderlist/wunderlist.go b/pkg/modules/migration/wunderlist/wunderlist.go index 3bdbce3d5..255753f34 100644 --- a/pkg/modules/migration/wunderlist/wunderlist.go +++ b/pkg/modules/migration/wunderlist/wunderlist.go @@ -480,3 +480,8 @@ func (w *Migration) AuthURL() string { config.MigrationWunderlistRedirectURL.GetString() + "&state=" + utils.MakeRandomString(32) } + +// Name is used to get the name of the wunderlist migration +func (w *Migration) Name() string { + return "wunderlist" +}