Skip to content

Commit

Permalink
feat(patch): upgrade patch module (#7738)
Browse files Browse the repository at this point in the history
* feat(patch): upgrade patch module

* chore(patch): add docs

* fix(patch): skip and rewrite invalid last launched version

* fix(patch): turn two functions into patches
  • Loading branch information
KirCute authored Dec 30, 2024
1 parent 42243b1 commit 5994c17
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 35 deletions.
1 change: 1 addition & 0 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func Init() {
bootstrap.InitDB()
data.InitData()
bootstrap.InitIndex()
bootstrap.InitUpgradePatch()
}

func Release() {
Expand Down
6 changes: 6 additions & 0 deletions internal/bootstrap/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ func InitConfig() {
log.Fatalf("failed to create config file: %+v", err)
}
conf.Conf = conf.DefaultConfig()
LastLaunchedVersion = conf.Version
conf.Conf.LastLaunchedVersion = conf.Version
if !utils.WriteJsonToFile(configPath, conf.Conf) {
log.Fatalf("failed to create default config file")
}
Expand All @@ -47,6 +49,10 @@ func InitConfig() {
if err != nil {
log.Fatalf("load config error: %+v", err)
}
LastLaunchedVersion = conf.Conf.LastLaunchedVersion
if conf.Version != "dev" || LastLaunchedVersion == "" {
conf.Conf.LastLaunchedVersion = conf.Version
}
// update config.json struct
confBody, err := utils.Json.MarshalIndent(conf.Conf, "", " ")
if err != nil {
Expand Down
35 changes: 0 additions & 35 deletions internal/bootstrap/data/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,39 +64,4 @@ func initUser() {
utils.Log.Fatalf("[init user] Failed to get guest user: %v", err)
}
}
hashPwdForOldVersion()
updateAuthnForOldVersion()
}

func hashPwdForOldVersion() {
users, _, err := op.GetUsers(1, -1)
if err != nil {
utils.Log.Fatalf("[hash pwd for old version] failed get users: %v", err)
}
for i := range users {
user := users[i]
if user.PwdHash == "" {
user.SetPassword(user.Password)
user.Password = ""
if err := db.UpdateUser(&user); err != nil {
utils.Log.Fatalf("[hash pwd for old version] failed update user: %v", err)
}
}
}
}

func updateAuthnForOldVersion() {
users, _, err := op.GetUsers(1, -1)
if err != nil {
utils.Log.Fatalf("[update authn for old version] failed get users: %v", err)
}
for i := range users {
user := users[i]
if user.Authn == "" {
user.Authn = "[]"
if err := db.UpdateUser(&user); err != nil {
utils.Log.Fatalf("[update authn for old version] failed update user: %v", err)
}
}
}
}
67 changes: 67 additions & 0 deletions internal/bootstrap/patch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package bootstrap

import (
"fmt"
"github.com/alist-org/alist/v3/internal/bootstrap/patch"
"github.com/alist-org/alist/v3/internal/conf"
"github.com/alist-org/alist/v3/pkg/utils"
)

var LastLaunchedVersion = ""

func safeCall(v string, i int, f func()) {
defer func() {
if r := recover(); r != nil {
utils.Log.Errorf("Recovered from patch (version: %s, index: %d) panic: %v", v, i, r)
}
}()

f()
}

func getVersion(v string) (major, minor, patchNum int, err error) {
_, err = fmt.Sscanf(v, "v%d.%d.%d", &major, &minor, &patchNum)
return major, minor, patchNum, err
}

func compareVersion(majorA, minorA, patchNumA, majorB, minorB, patchNumB int) bool {
if majorA != majorB {
return majorA > majorB
}
if minorA != minorB {
return minorA > minorB
}
if patchNumA != patchNumB {
return patchNumA > patchNumB
}
return true
}

func InitUpgradePatch() {
if conf.Version == "dev" {
return
}
if LastLaunchedVersion == conf.Version {
return
}
if LastLaunchedVersion == "" {
LastLaunchedVersion = "v0.0.0"
}
major, minor, patchNum, err := getVersion(LastLaunchedVersion)
if err != nil {
utils.Log.Warnf("Failed to parse last launched version %s: %v, skipping all patches and rewrite last launched version", LastLaunchedVersion, err)
return
}
for _, vp := range patch.UpgradePatches {
ma, mi, pn, err := getVersion(vp.Version)
if err != nil {
utils.Log.Errorf("Skip invalid version %s patches: %v", vp.Version, err)
continue
}
if compareVersion(ma, mi, pn, major, minor, patchNum) {
for i, p := range vp.Patches {
safeCall(vp.Version, i, p)
}
}
}
}
35 changes: 35 additions & 0 deletions internal/bootstrap/patch/all.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package patch

import (
"github.com/alist-org/alist/v3/internal/bootstrap/patch/v3_24_0"
"github.com/alist-org/alist/v3/internal/bootstrap/patch/v3_32_0"
"github.com/alist-org/alist/v3/internal/bootstrap/patch/v3_41_0"
)

type VersionPatches struct {
// Version means if the system is upgraded from Version or an earlier one
// to the current version, all patches in Patches will be executed.
Version string
Patches []func()
}

var UpgradePatches = []VersionPatches{
{
Version: "v3.24.0",
Patches: []func(){
v3_24_0.HashPwdForOldVersion,
},
},
{
Version: "v3.32.0",
Patches: []func(){
v3_32_0.UpdateAuthnForOldVersion,
},
},
{
Version: "v3.41.0",
Patches: []func(){
v3_41_0.GrantAdminPermissions,
},
},
}
26 changes: 26 additions & 0 deletions internal/bootstrap/patch/v3_24_0/hash_password.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package v3_24_0

import (
"github.com/alist-org/alist/v3/internal/db"
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/pkg/utils"
)

// HashPwdForOldVersion encode passwords using SHA256
// First published: 75acbcc perf: sha256 for user's password (close #3552) by Andy Hsu
func HashPwdForOldVersion() {
users, _, err := op.GetUsers(1, -1)
if err != nil {
utils.Log.Fatalf("[hash pwd for old version] failed get users: %v", err)
}
for i := range users {
user := users[i]
if user.PwdHash == "" {
user.SetPassword(user.Password)
user.Password = ""
if err := db.UpdateUser(&user); err != nil {
utils.Log.Fatalf("[hash pwd for old version] failed update user: %v", err)
}
}
}
}
25 changes: 25 additions & 0 deletions internal/bootstrap/patch/v3_32_0/update_authn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package v3_32_0

import (
"github.com/alist-org/alist/v3/internal/db"
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/pkg/utils"
)

// UpdateAuthnForOldVersion updates users' authn
// First published: bdfc159 fix: webauthn logspam (#6181) by itsHenry
func UpdateAuthnForOldVersion() {
users, _, err := op.GetUsers(1, -1)
if err != nil {
utils.Log.Fatalf("[update authn for old version] failed get users: %v", err)
}
for i := range users {
user := users[i]
if user.Authn == "" {
user.Authn = "[]"
if err := db.UpdateUser(&user); err != nil {
utils.Log.Fatalf("[update authn for old version] failed update user: %v", err)
}
}
}
}
22 changes: 22 additions & 0 deletions internal/bootstrap/patch/v3_41_0/grant_permission.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package v3_41_0

import (
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/pkg/utils"
)

// GrantAdminPermissions gives admin Permission 0(can see hidden) - 9(webdav manage)
// This patch is written to help users upgrading from older version better adapt to PR AlistGo/alist#7705.
func GrantAdminPermissions() {
admin, err := op.GetAdmin()
if err != nil {
utils.Log.Errorf("Cannot grant permissions to admin: %v", err)
}
if (admin.Permission & 0x3FF) == 0 {
admin.Permission |= 0x3FF
}
err = op.UpdateUser(admin)
if err != nil {
utils.Log.Errorf("Cannot grant permissions to admin: %v", err)
}
}
2 changes: 2 additions & 0 deletions internal/conf/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ type Config struct {
S3 S3 `json:"s3" envPrefix:"S3_"`
FTP FTP `json:"ftp" envPrefix:"FTP_"`
SFTP SFTP `json:"sftp" envPrefix:"SFTP_"`
LastLaunchedVersion string `json:"last_launched_version"`
}

func DefaultConfig() *Config {
Expand Down Expand Up @@ -195,5 +196,6 @@ func DefaultConfig() *Config {
Enable: false,
Listen: ":5222",
},
LastLaunchedVersion: "",
}
}

0 comments on commit 5994c17

Please sign in to comment.