feat: remove importer of v1 config (#5550)
This commit is contained in:
parent
ebc7d2303d
commit
ceb5e723f3
@ -1,40 +0,0 @@
|
|||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"github.com/filebrowser/filebrowser/v2/storage/bolt/importer"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(upgradeCmd)
|
|
||||||
|
|
||||||
upgradeCmd.Flags().String("old.database", "", "")
|
|
||||||
upgradeCmd.Flags().String("old.config", "", "")
|
|
||||||
_ = upgradeCmd.MarkFlagRequired("old.database")
|
|
||||||
}
|
|
||||||
|
|
||||||
var upgradeCmd = &cobra.Command{
|
|
||||||
Use: "upgrade",
|
|
||||||
Short: "Upgrades an old configuration",
|
|
||||||
Long: `Upgrades an old configuration. This command DOES NOT
|
|
||||||
import share links because they are incompatible with
|
|
||||||
this version.`,
|
|
||||||
Args: cobra.NoArgs,
|
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
|
||||||
flags := cmd.Flags()
|
|
||||||
oldDB, err := getString(flags, "old.database")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
oldConf, err := getString(flags, "old.config")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
db, err := getString(flags, "database")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return importer.Import(oldDB, oldConf, db)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
4
go.mod
4
go.mod
@ -16,7 +16,6 @@ require (
|
|||||||
github.com/marusama/semaphore/v2 v2.5.0
|
github.com/marusama/semaphore/v2 v2.5.0
|
||||||
github.com/mholt/archives v0.1.5
|
github.com/mholt/archives v0.1.5
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4
|
|
||||||
github.com/shirou/gopsutil/v4 v4.25.10
|
github.com/shirou/gopsutil/v4 v4.25.10
|
||||||
github.com/spf13/afero v1.15.0
|
github.com/spf13/afero v1.15.0
|
||||||
github.com/spf13/cobra v1.10.1
|
github.com/spf13/cobra v1.10.1
|
||||||
@ -24,7 +23,6 @@ require (
|
|||||||
github.com/spf13/viper v1.21.0
|
github.com/spf13/viper v1.21.0
|
||||||
github.com/stretchr/testify v1.11.1
|
github.com/stretchr/testify v1.11.1
|
||||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
|
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
|
||||||
go.etcd.io/bbolt v1.4.3
|
|
||||||
golang.org/x/crypto v0.44.0
|
golang.org/x/crypto v0.44.0
|
||||||
golang.org/x/image v0.33.0
|
golang.org/x/image v0.33.0
|
||||||
golang.org/x/text v0.31.0
|
golang.org/x/text v0.31.0
|
||||||
@ -58,6 +56,7 @@ require (
|
|||||||
github.com/mikelolasagasti/xz v1.0.1 // indirect
|
github.com/mikelolasagasti/xz v1.0.1 // indirect
|
||||||
github.com/minio/minlz v1.0.1 // indirect
|
github.com/minio/minlz v1.0.1 // indirect
|
||||||
github.com/nwaples/rardecode/v2 v2.2.0 // indirect
|
github.com/nwaples/rardecode/v2 v2.2.0 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||||
github.com/pierrec/lz4/v4 v4.1.22 // indirect
|
github.com/pierrec/lz4/v4 v4.1.22 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||||
@ -68,6 +67,7 @@ require (
|
|||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/ulikunitz/xz v0.5.15 // indirect
|
github.com/ulikunitz/xz v0.5.15 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||||
|
go.etcd.io/bbolt v1.4.3 // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||||
golang.org/x/net v0.46.0 // indirect
|
golang.org/x/net v0.46.0 // indirect
|
||||||
|
|||||||
@ -1,187 +0,0 @@
|
|||||||
package importer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/asdine/storm/v3"
|
|
||||||
"github.com/pelletier/go-toml/v2"
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
|
|
||||||
"github.com/filebrowser/filebrowser/v2/auth"
|
|
||||||
"github.com/filebrowser/filebrowser/v2/settings"
|
|
||||||
"github.com/filebrowser/filebrowser/v2/storage"
|
|
||||||
"github.com/filebrowser/filebrowser/v2/users"
|
|
||||||
)
|
|
||||||
|
|
||||||
type oldDefs struct {
|
|
||||||
Commands []string `json:"commands" yaml:"commands" toml:"commands"`
|
|
||||||
Scope string `json:"scope" yaml:"scope" toml:"scope"`
|
|
||||||
ViewMode string `json:"viewMode" yaml:"viewMode" toml:"viewMode"`
|
|
||||||
Locale string `json:"locale" yaml:"locale" toml:"locale"`
|
|
||||||
AllowCommands bool `json:"allowCommands" yaml:"allowCommands" toml:"allowCommands"`
|
|
||||||
AllowEdit bool `json:"allowEdit" yaml:"allowEdit" toml:"allowEdit"`
|
|
||||||
AllowNew bool `json:"allowNew" yaml:"allowNew" toml:"allowNew"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type oldAuth struct {
|
|
||||||
Method string `json:"method" yaml:"method" toml:"method"` // default none proxy
|
|
||||||
Header string `json:"header" yaml:"header" toml:"header"`
|
|
||||||
Command string `json:"command" yaml:"command" toml:"command"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type oldConf struct {
|
|
||||||
Port string `json:"port" yaml:"port" toml:"port"`
|
|
||||||
BaseURL string `json:"baseURL" yaml:"baseURL" toml:"baseURL"`
|
|
||||||
Log string `json:"log" yaml:"log" toml:"log"`
|
|
||||||
Address string `json:"address" yaml:"address" toml:"address"`
|
|
||||||
Defaults oldDefs `json:"defaults" yaml:"defaults" toml:"defaults"`
|
|
||||||
ReCaptcha struct {
|
|
||||||
Key string `json:"key" yaml:"key" toml:"key"`
|
|
||||||
Secret string `json:"secret" yaml:"secret" toml:"secret"`
|
|
||||||
Host string `json:"host" yaml:"host" toml:"host"`
|
|
||||||
} `json:"recaptcha" yaml:"recaptcha" toml:"recaptcha"`
|
|
||||||
Auth oldAuth `json:"auth" yaml:"auth" toml:"auth"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaults = &oldConf{
|
|
||||||
Port: "0",
|
|
||||||
Log: "stdout",
|
|
||||||
Defaults: oldDefs{
|
|
||||||
Commands: []string{"git", "svn", "hg"},
|
|
||||||
ViewMode: string(users.MosaicViewMode),
|
|
||||||
AllowCommands: true,
|
|
||||||
AllowEdit: true,
|
|
||||||
AllowNew: true,
|
|
||||||
Locale: "en",
|
|
||||||
},
|
|
||||||
Auth: oldAuth{
|
|
||||||
Method: "default",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func readConf(path string) (*oldConf, error) {
|
|
||||||
cfg := &oldConf{}
|
|
||||||
if path != "" {
|
|
||||||
ext := filepath.Ext(path)
|
|
||||||
|
|
||||||
fd, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer fd.Close()
|
|
||||||
|
|
||||||
switch ext {
|
|
||||||
case ".json":
|
|
||||||
err = json.NewDecoder(fd).Decode(cfg)
|
|
||||||
case ".toml":
|
|
||||||
err = toml.NewDecoder(fd).Decode(cfg)
|
|
||||||
case ".yaml", ".yml":
|
|
||||||
err = yaml.NewDecoder(fd).Decode(cfg)
|
|
||||||
default:
|
|
||||||
return nil, errors.New("unsupported config extension " + ext)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cfg = defaults
|
|
||||||
path, err := filepath.Abs(".")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cfg.Defaults.Scope = path
|
|
||||||
}
|
|
||||||
return cfg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func importConf(db *storm.DB, path string, sto *storage.Storage) error {
|
|
||||||
cfg, err := readConf(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
commands := map[string][]string{}
|
|
||||||
err = db.Get("config", "commands", &commands)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte{}
|
|
||||||
err = db.Get("config", "key", &key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
s := &settings.Settings{
|
|
||||||
Key: key,
|
|
||||||
Signup: false,
|
|
||||||
Defaults: settings.UserDefaults{
|
|
||||||
Scope: cfg.Defaults.Scope,
|
|
||||||
Commands: cfg.Defaults.Commands,
|
|
||||||
ViewMode: users.ViewMode(cfg.Defaults.ViewMode),
|
|
||||||
Locale: cfg.Defaults.Locale,
|
|
||||||
Perm: users.Permissions{
|
|
||||||
Admin: false,
|
|
||||||
Execute: cfg.Defaults.AllowCommands,
|
|
||||||
Create: cfg.Defaults.AllowNew,
|
|
||||||
Rename: cfg.Defaults.AllowEdit,
|
|
||||||
Modify: cfg.Defaults.AllowEdit,
|
|
||||||
Delete: cfg.Defaults.AllowEdit,
|
|
||||||
Share: true,
|
|
||||||
Download: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
server := &settings.Server{
|
|
||||||
BaseURL: cfg.BaseURL,
|
|
||||||
Port: cfg.Port,
|
|
||||||
Address: cfg.Address,
|
|
||||||
Log: cfg.Log,
|
|
||||||
}
|
|
||||||
|
|
||||||
var auther auth.Auther
|
|
||||||
switch cfg.Auth.Method {
|
|
||||||
case "proxy":
|
|
||||||
auther = &auth.ProxyAuth{Header: cfg.Auth.Header}
|
|
||||||
s.AuthMethod = auth.MethodProxyAuth
|
|
||||||
case "hook":
|
|
||||||
auther = &auth.HookAuth{Command: cfg.Auth.Command}
|
|
||||||
s.AuthMethod = auth.MethodHookAuth
|
|
||||||
case "none":
|
|
||||||
auther = &auth.NoAuth{}
|
|
||||||
s.AuthMethod = auth.MethodNoAuth
|
|
||||||
default:
|
|
||||||
auther = &auth.JSONAuth{
|
|
||||||
ReCaptcha: &auth.ReCaptcha{
|
|
||||||
Host: cfg.ReCaptcha.Host,
|
|
||||||
Key: cfg.ReCaptcha.Key,
|
|
||||||
Secret: cfg.ReCaptcha.Secret,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
s.AuthMethod = auth.MethodJSONAuth
|
|
||||||
}
|
|
||||||
|
|
||||||
err = sto.Auth.Save(auther)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = sto.Settings.Save(s)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = sto.Settings.SaveServer(server)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Configuration successfully imported.")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
package importer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/asdine/storm/v3"
|
|
||||||
|
|
||||||
"github.com/filebrowser/filebrowser/v2/storage/bolt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Import imports an old configuration to a newer database.
|
|
||||||
func Import(oldDBPath, oldConf, newDBPath string) error {
|
|
||||||
oldDB, err := storm.Open(oldDBPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer oldDB.Close()
|
|
||||||
|
|
||||||
newDB, err := storm.Open(newDBPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer newDB.Close()
|
|
||||||
|
|
||||||
sto, err := bolt.NewStorage(newDB)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = importUsers(oldDB, sto)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = importConf(oldDB, oldConf, sto)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@ -1,114 +0,0 @@
|
|||||||
package importer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/asdine/storm/v3"
|
|
||||||
bolt "go.etcd.io/bbolt"
|
|
||||||
|
|
||||||
"github.com/filebrowser/filebrowser/v2/rules"
|
|
||||||
"github.com/filebrowser/filebrowser/v2/storage"
|
|
||||||
"github.com/filebrowser/filebrowser/v2/users"
|
|
||||||
)
|
|
||||||
|
|
||||||
type oldUser struct {
|
|
||||||
ID int `storm:"id,increment"`
|
|
||||||
Admin bool `json:"admin"`
|
|
||||||
AllowCommands bool `json:"allowCommands"` // Execute commands
|
|
||||||
AllowEdit bool `json:"allowEdit"` // Edit/rename files
|
|
||||||
AllowNew bool `json:"allowNew"` // Create files and folders
|
|
||||||
AllowPublish bool `json:"allowPublish"` // Publish content (to use with static gen)
|
|
||||||
LockPassword bool `json:"lockPassword"`
|
|
||||||
Commands []string `json:"commands"`
|
|
||||||
Locale string `json:"locale"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
Rules []*rules.Rule `json:"rules"`
|
|
||||||
Scope string `json:"filesystem"`
|
|
||||||
Username string `json:"username" storm:"index,unique"`
|
|
||||||
ViewMode string `json:"viewMode"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func readOldUsers(db *storm.DB) ([]*oldUser, error) {
|
|
||||||
var oldUsers []*oldUser
|
|
||||||
err := db.Bolt.View(func(tx *bolt.Tx) error {
|
|
||||||
return tx.Bucket([]byte("User")).ForEach(func(_ []byte, v []byte) error {
|
|
||||||
if len(v) > 0 && string(v)[0] == '{' {
|
|
||||||
user := &oldUser{}
|
|
||||||
err := json.Unmarshal(v, user)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
oldUsers = append(oldUsers, user)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
return oldUsers, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertUsersToNew(old []*oldUser) ([]*users.User, error) {
|
|
||||||
list := []*users.User{}
|
|
||||||
|
|
||||||
for _, oldUser := range old {
|
|
||||||
user := &users.User{
|
|
||||||
Username: oldUser.Username,
|
|
||||||
Password: oldUser.Password,
|
|
||||||
Scope: oldUser.Scope,
|
|
||||||
Locale: oldUser.Locale,
|
|
||||||
LockPassword: oldUser.LockPassword,
|
|
||||||
ViewMode: users.ViewMode(oldUser.ViewMode),
|
|
||||||
Commands: oldUser.Commands,
|
|
||||||
Rules: []rules.Rule{},
|
|
||||||
Perm: users.Permissions{
|
|
||||||
Admin: oldUser.Admin,
|
|
||||||
Execute: oldUser.AllowCommands,
|
|
||||||
Create: oldUser.AllowNew,
|
|
||||||
Rename: oldUser.AllowEdit,
|
|
||||||
Modify: oldUser.AllowEdit,
|
|
||||||
Delete: oldUser.AllowEdit,
|
|
||||||
Share: true,
|
|
||||||
Download: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rule := range oldUser.Rules {
|
|
||||||
user.Rules = append(user.Rules, *rule)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := user.Clean("")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
list = append(list, user)
|
|
||||||
}
|
|
||||||
|
|
||||||
return list, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func importUsers(old *storm.DB, sto *storage.Storage) error {
|
|
||||||
oldUsers, err := readOldUsers(old)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
newUsers, err := convertUsersToNew(oldUsers)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, user := range newUsers {
|
|
||||||
err = sto.Users.Save(user)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("%d users successfully imported into the new DB.\n", len(newUsers))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user