forked from vikunja/vikunja
188 lines
6.3 KiB
Go
188 lines
6.3 KiB
Go
// Vikunja is a to-do list application to facilitate your life.
|
|
// Copyright 2018-present 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 Affero General Public Licensee 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 Affero General Public Licensee for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public Licensee
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package kanboard
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"encoding/base64"
|
|
"net/http"
|
|
|
|
"github.com/ybbus/jsonrpc/v2"
|
|
|
|
"code.vikunja.io/api/pkg/config"
|
|
"code.vikunja.io/api/pkg/log"
|
|
"code.vikunja.io/api/pkg/models"
|
|
"code.vikunja.io/api/pkg/modules/migration"
|
|
"code.vikunja.io/api/pkg/user"
|
|
)
|
|
|
|
// Migration represents the kanboard migration struct
|
|
type Migration struct {
|
|
Endpoint string `json:"endpoint"`
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
type kanboardBoard struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
IsActive string `json:"is_active"`
|
|
Token string `json:"token"`
|
|
LastModified string `json:"last_modified"`
|
|
IsPublic string `json:"is_public"`
|
|
IsPrivate string `json:"is_private"`
|
|
DefaultSwimlane string `json:"default_swimlane"`
|
|
ShowDefaultSwimlane string `json:"show_default_swimlane"`
|
|
Description interface{} `json:"description"`
|
|
Identifier string `json:"identifier"`
|
|
URL struct {
|
|
Board string `json:"board"`
|
|
Calendar string `json:"calendar"`
|
|
List string `json:"list"`
|
|
} `json:"url"`
|
|
}
|
|
|
|
func init() {
|
|
}
|
|
|
|
// Name is used to get the name of the kanboard migration - we're using the docs here to annotate the status route.
|
|
// @Summary Get migration status
|
|
// @Description Returns if the current user already did the migation or not. This is useful to show a confirmation message in the frontend if the user is trying to do the same migration again.
|
|
// @tags migration
|
|
// @Produce json
|
|
// @Security JWTKeyAuth
|
|
// @Success 200 {object} migration.Status "The migration status"
|
|
// @Failure 500 {object} models.Message "Internal server error"
|
|
// @Router /migration/kanboard/status [get]
|
|
func (m *Migration) Name() string {
|
|
return "kanboard"
|
|
}
|
|
|
|
// AuthURL returns the url users need to authenticate against
|
|
// @Summary Get the auth url from kanboard
|
|
// @Description Returns the auth url where the user needs to get its auth code. This code can then be used to migrate everything from kanboard to Vikunja.
|
|
// @tags migration
|
|
// @Produce json
|
|
// @Security JWTKeyAuth
|
|
// @Success 200 {object} handler.AuthURL "The auth url."
|
|
// @Failure 500 {object} models.Message "Internal server error"
|
|
// @Router /migration/kanboard/auth [get]
|
|
func (m *Migration) AuthURL() string {
|
|
return ""
|
|
}
|
|
|
|
func basicAuth(username, password string) string {
|
|
auth := username + ":" + password
|
|
return base64.StdEncoding.EncodeToString([]byte(auth))
|
|
}
|
|
|
|
func getKanboardData(endpoint string, username string, password string, allowInsecure bool) (kanboardData []kanboardBoard, err error) {
|
|
|
|
var tr *http.Transport
|
|
|
|
if allowInsecure {
|
|
tr = &http.Transport{
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
}
|
|
} else {
|
|
tr = &http.Transport{}
|
|
}
|
|
|
|
client := &http.Client{Transport: tr}
|
|
|
|
auth := make(map[string]string)
|
|
auth["Authorization"] = "Basic " + basicAuth(username, password)
|
|
|
|
opts := jsonrpc.RPCClientOpts{
|
|
HTTPClient: client,
|
|
CustomHeaders: auth,
|
|
}
|
|
|
|
rpcClient := jsonrpc.NewClientWithOpts(endpoint, &opts)
|
|
|
|
err = rpcClient.CallFor(&kanboardData, "getAllProjects")
|
|
|
|
return
|
|
}
|
|
|
|
// Converts all previously obtained data from kanboard into the vikunja format.
|
|
// `kanboardData` should contain all boards with their projects and cards respectively.
|
|
func convertKanboardDataToVikunja(kanboardData []kanboardBoard) (fullVikunjaHierachie []*models.ProjectWithTasksAndBuckets, err error) {
|
|
|
|
log.Debugf("[Kanboard Migration] ")
|
|
|
|
fullVikunjaHierachie = []*models.ProjectWithTasksAndBuckets{
|
|
{
|
|
Project: models.Project{
|
|
Title: "Imported from Kanboard",
|
|
},
|
|
ChildProjects: []*models.ProjectWithTasksAndBuckets{},
|
|
},
|
|
}
|
|
|
|
log.Debugf("[Kanboard Migration] Converting %d boards to vikunja projects", len(kanboardData))
|
|
|
|
return
|
|
}
|
|
|
|
// Migrate gets all tasks from kanboard for a user and puts them into vikunja
|
|
// @Summary Migrate all projects, tasks etc. from kanboard
|
|
// @Description Migrates all projects, tasks, notes, reminders, subtasks and files from kanboard to vikunja.
|
|
// @tags migration
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security JWTKeyAuth
|
|
// @Param migrationCode body kanboard.Migration true "The auth token previously obtained from the auth url. See the docs for /migration/kanboard/auth."
|
|
// @Success 200 {object} models.Message "A message telling you everything was migrated successfully."
|
|
// @Failure 500 {object} models.Message "Internal server error"
|
|
// @Router /migration/kanboard/migrate [post]
|
|
func (m *Migration) Migrate(u *user.User) (err error) {
|
|
log.Debugf("[Kanboard Migration] Starting migration for user %d", u.ID)
|
|
log.Debugf("[Kanboard Migration] Getting all kanboard data for user %d", u.ID)
|
|
|
|
kanboardData, err := getKanboardData(
|
|
m.Endpoint,
|
|
m.Username,
|
|
m.Password,
|
|
config.MigrationKanboardApiInsecure.GetBool(),
|
|
)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
log.Debugf("[Kanboard Migration] Got all kanboard data for user %d", u.ID)
|
|
log.Debugf("[Kanboard Migration] Start converting kanboard data for user %d", u.ID)
|
|
|
|
fullVikunjaHierachie, err := convertKanboardDataToVikunja(kanboardData)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
log.Debugf("[Kanboard Migration] Done migrating kanboard data for user %d", u.ID)
|
|
log.Debugf("[Kanboard Migration] Start inserting kanboard data for user %d", u.ID)
|
|
|
|
err = migration.InsertFromStructure(fullVikunjaHierachie, u)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
log.Debugf("[Kanboard Migration] Done inserting kanboard data for user %d", u.ID)
|
|
log.Debugf("[Kanboard Migration] Migration done for user %d", u.ID)
|
|
|
|
return nil
|
|
}
|