Skip to content

Commit 5994c17

Browse files
authoredDec 30, 2024
feat(patch): upgrade patch module (#7738)
* 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
1 parent 42243b1 commit 5994c17

File tree

9 files changed

+184
-35
lines changed

9 files changed

+184
-35
lines changed
 

‎cmd/common.go

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ func Init() {
1919
bootstrap.InitDB()
2020
data.InitData()
2121
bootstrap.InitIndex()
22+
bootstrap.InitUpgradePatch()
2223
}
2324

2425
func Release() {

‎internal/bootstrap/config.go

+6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ func InitConfig() {
3434
log.Fatalf("failed to create config file: %+v", err)
3535
}
3636
conf.Conf = conf.DefaultConfig()
37+
LastLaunchedVersion = conf.Version
38+
conf.Conf.LastLaunchedVersion = conf.Version
3739
if !utils.WriteJsonToFile(configPath, conf.Conf) {
3840
log.Fatalf("failed to create default config file")
3941
}
@@ -47,6 +49,10 @@ func InitConfig() {
4749
if err != nil {
4850
log.Fatalf("load config error: %+v", err)
4951
}
52+
LastLaunchedVersion = conf.Conf.LastLaunchedVersion
53+
if conf.Version != "dev" || LastLaunchedVersion == "" {
54+
conf.Conf.LastLaunchedVersion = conf.Version
55+
}
5056
// update config.json struct
5157
confBody, err := utils.Json.MarshalIndent(conf.Conf, "", " ")
5258
if err != nil {

‎internal/bootstrap/data/user.go

-35
Original file line numberDiff line numberDiff line change
@@ -64,39 +64,4 @@ func initUser() {
6464
utils.Log.Fatalf("[init user] Failed to get guest user: %v", err)
6565
}
6666
}
67-
hashPwdForOldVersion()
68-
updateAuthnForOldVersion()
69-
}
70-
71-
func hashPwdForOldVersion() {
72-
users, _, err := op.GetUsers(1, -1)
73-
if err != nil {
74-
utils.Log.Fatalf("[hash pwd for old version] failed get users: %v", err)
75-
}
76-
for i := range users {
77-
user := users[i]
78-
if user.PwdHash == "" {
79-
user.SetPassword(user.Password)
80-
user.Password = ""
81-
if err := db.UpdateUser(&user); err != nil {
82-
utils.Log.Fatalf("[hash pwd for old version] failed update user: %v", err)
83-
}
84-
}
85-
}
86-
}
87-
88-
func updateAuthnForOldVersion() {
89-
users, _, err := op.GetUsers(1, -1)
90-
if err != nil {
91-
utils.Log.Fatalf("[update authn for old version] failed get users: %v", err)
92-
}
93-
for i := range users {
94-
user := users[i]
95-
if user.Authn == "" {
96-
user.Authn = "[]"
97-
if err := db.UpdateUser(&user); err != nil {
98-
utils.Log.Fatalf("[update authn for old version] failed update user: %v", err)
99-
}
100-
}
101-
}
10267
}

‎internal/bootstrap/patch.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package bootstrap
2+
3+
import (
4+
"fmt"
5+
"github.com/alist-org/alist/v3/internal/bootstrap/patch"
6+
"github.com/alist-org/alist/v3/internal/conf"
7+
"github.com/alist-org/alist/v3/pkg/utils"
8+
)
9+
10+
var LastLaunchedVersion = ""
11+
12+
func safeCall(v string, i int, f func()) {
13+
defer func() {
14+
if r := recover(); r != nil {
15+
utils.Log.Errorf("Recovered from patch (version: %s, index: %d) panic: %v", v, i, r)
16+
}
17+
}()
18+
19+
f()
20+
}
21+
22+
func getVersion(v string) (major, minor, patchNum int, err error) {
23+
_, err = fmt.Sscanf(v, "v%d.%d.%d", &major, &minor, &patchNum)
24+
return major, minor, patchNum, err
25+
}
26+
27+
func compareVersion(majorA, minorA, patchNumA, majorB, minorB, patchNumB int) bool {
28+
if majorA != majorB {
29+
return majorA > majorB
30+
}
31+
if minorA != minorB {
32+
return minorA > minorB
33+
}
34+
if patchNumA != patchNumB {
35+
return patchNumA > patchNumB
36+
}
37+
return true
38+
}
39+
40+
func InitUpgradePatch() {
41+
if conf.Version == "dev" {
42+
return
43+
}
44+
if LastLaunchedVersion == conf.Version {
45+
return
46+
}
47+
if LastLaunchedVersion == "" {
48+
LastLaunchedVersion = "v0.0.0"
49+
}
50+
major, minor, patchNum, err := getVersion(LastLaunchedVersion)
51+
if err != nil {
52+
utils.Log.Warnf("Failed to parse last launched version %s: %v, skipping all patches and rewrite last launched version", LastLaunchedVersion, err)
53+
return
54+
}
55+
for _, vp := range patch.UpgradePatches {
56+
ma, mi, pn, err := getVersion(vp.Version)
57+
if err != nil {
58+
utils.Log.Errorf("Skip invalid version %s patches: %v", vp.Version, err)
59+
continue
60+
}
61+
if compareVersion(ma, mi, pn, major, minor, patchNum) {
62+
for i, p := range vp.Patches {
63+
safeCall(vp.Version, i, p)
64+
}
65+
}
66+
}
67+
}

‎internal/bootstrap/patch/all.go

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package patch
2+
3+
import (
4+
"github.com/alist-org/alist/v3/internal/bootstrap/patch/v3_24_0"
5+
"github.com/alist-org/alist/v3/internal/bootstrap/patch/v3_32_0"
6+
"github.com/alist-org/alist/v3/internal/bootstrap/patch/v3_41_0"
7+
)
8+
9+
type VersionPatches struct {
10+
// Version means if the system is upgraded from Version or an earlier one
11+
// to the current version, all patches in Patches will be executed.
12+
Version string
13+
Patches []func()
14+
}
15+
16+
var UpgradePatches = []VersionPatches{
17+
{
18+
Version: "v3.24.0",
19+
Patches: []func(){
20+
v3_24_0.HashPwdForOldVersion,
21+
},
22+
},
23+
{
24+
Version: "v3.32.0",
25+
Patches: []func(){
26+
v3_32_0.UpdateAuthnForOldVersion,
27+
},
28+
},
29+
{
30+
Version: "v3.41.0",
31+
Patches: []func(){
32+
v3_41_0.GrantAdminPermissions,
33+
},
34+
},
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package v3_24_0
2+
3+
import (
4+
"github.com/alist-org/alist/v3/internal/db"
5+
"github.com/alist-org/alist/v3/internal/op"
6+
"github.com/alist-org/alist/v3/pkg/utils"
7+
)
8+
9+
// HashPwdForOldVersion encode passwords using SHA256
10+
// First published: 75acbcc perf: sha256 for user's password (close #3552) by Andy Hsu
11+
func HashPwdForOldVersion() {
12+
users, _, err := op.GetUsers(1, -1)
13+
if err != nil {
14+
utils.Log.Fatalf("[hash pwd for old version] failed get users: %v", err)
15+
}
16+
for i := range users {
17+
user := users[i]
18+
if user.PwdHash == "" {
19+
user.SetPassword(user.Password)
20+
user.Password = ""
21+
if err := db.UpdateUser(&user); err != nil {
22+
utils.Log.Fatalf("[hash pwd for old version] failed update user: %v", err)
23+
}
24+
}
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package v3_32_0
2+
3+
import (
4+
"github.com/alist-org/alist/v3/internal/db"
5+
"github.com/alist-org/alist/v3/internal/op"
6+
"github.com/alist-org/alist/v3/pkg/utils"
7+
)
8+
9+
// UpdateAuthnForOldVersion updates users' authn
10+
// First published: bdfc159 fix: webauthn logspam (#6181) by itsHenry
11+
func UpdateAuthnForOldVersion() {
12+
users, _, err := op.GetUsers(1, -1)
13+
if err != nil {
14+
utils.Log.Fatalf("[update authn for old version] failed get users: %v", err)
15+
}
16+
for i := range users {
17+
user := users[i]
18+
if user.Authn == "" {
19+
user.Authn = "[]"
20+
if err := db.UpdateUser(&user); err != nil {
21+
utils.Log.Fatalf("[update authn for old version] failed update user: %v", err)
22+
}
23+
}
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package v3_41_0
2+
3+
import (
4+
"github.com/alist-org/alist/v3/internal/op"
5+
"github.com/alist-org/alist/v3/pkg/utils"
6+
)
7+
8+
// GrantAdminPermissions gives admin Permission 0(can see hidden) - 9(webdav manage)
9+
// This patch is written to help users upgrading from older version better adapt to PR AlistGo/alist#7705.
10+
func GrantAdminPermissions() {
11+
admin, err := op.GetAdmin()
12+
if err != nil {
13+
utils.Log.Errorf("Cannot grant permissions to admin: %v", err)
14+
}
15+
if (admin.Permission & 0x3FF) == 0 {
16+
admin.Permission |= 0x3FF
17+
}
18+
err = op.UpdateUser(admin)
19+
if err != nil {
20+
utils.Log.Errorf("Cannot grant permissions to admin: %v", err)
21+
}
22+
}

‎internal/conf/config.go

+2
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ type Config struct {
110110
S3 S3 `json:"s3" envPrefix:"S3_"`
111111
FTP FTP `json:"ftp" envPrefix:"FTP_"`
112112
SFTP SFTP `json:"sftp" envPrefix:"SFTP_"`
113+
LastLaunchedVersion string `json:"last_launched_version"`
113114
}
114115

115116
func DefaultConfig() *Config {
@@ -195,5 +196,6 @@ func DefaultConfig() *Config {
195196
Enable: false,
196197
Listen: ":5222",
197198
},
199+
LastLaunchedVersion: "",
198200
}
199201
}

0 commit comments

Comments
 (0)
Please sign in to comment.