Skip to content

Commit 42dc575

Browse files
committed
feat: use env to predefine admin user #214
1 parent 13c4eb0 commit 42dc575

File tree

7 files changed

+87
-25
lines changed

7 files changed

+87
-25
lines changed

api/system/install.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ func InstallNginxUI(c *gin.Context) {
4949
if "" != json.Database {
5050
settings.ServerSettings.Database = json.Database
5151
}
52-
settings.ReflectFrom()
5352

5453
err := settings.Save()
5554
if err != nil {
@@ -72,6 +71,7 @@ func InstallNginxUI(c *gin.Context) {
7271
api.ErrHandler(c, err)
7372
return
7473
}
74+
7575
c.JSON(http.StatusOK, gin.H{
7676
"message": "ok",
7777
})

api/system/settings.go

-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ func SaveSettings(c *gin.Context) {
4040
fillSettings(&settings.OpenAISettings, &json.Openai)
4141
fillSettings(&settings.LogrotateSettings, &json.Logrotate)
4242

43-
settings.ReflectFrom()
44-
4543
err := settings.Save()
4644
if err != nil {
4745
api.ErrHandler(c, err)

internal/kernal/boot.go

+6-8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/go-co-op/gocron"
1313
"github.com/google/uuid"
1414
"mime"
15+
"os"
1516
"runtime"
1617
"time"
1718
)
@@ -41,6 +42,7 @@ func Boot() {
4142

4243
func InitAfterDatabase() {
4344
syncs := []func(){
45+
registerPredefinedUser,
4446
cert.InitRegister,
4547
InitCronJobs,
4648
analytic.RetrieveNodesStatus,
@@ -60,14 +62,11 @@ func recovery() {
6062
}
6163

6264
func InitDatabase() {
65+
logger.Debug("skip installation", os.Getenv("NGINX_UI_SKIP_INSTALLATION"))
6366

64-
// Skip installation
65-
if settings.ServerSettings.SkipInstallation && settings.ServerSettings.JwtSecret == "" {
66-
settings.ServerSettings.JwtSecret = uuid.New().String()
67-
err := settings.Save()
68-
if err != nil {
69-
logger.Error(err)
70-
}
67+
// Skip install
68+
if settings.ServerSettings.SkipInstallation {
69+
skipInstall()
7170
}
7271

7372
if "" != settings.ServerSettings.JwtSecret {
@@ -82,7 +81,6 @@ func InitNodeSecret() {
8281
if "" == settings.ServerSettings.NodeSecret {
8382
logger.Warn("NodeSecret is empty, generating...")
8483
settings.ServerSettings.NodeSecret = uuid.New().String()
85-
settings.ReflectFrom()
8684

8785
err := settings.Save()
8886
if err != nil {

internal/kernal/skip_install.go

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package kernal
2+
3+
import (
4+
"github.com/0xJacky/Nginx-UI/internal/logger"
5+
"github.com/0xJacky/Nginx-UI/model"
6+
"github.com/0xJacky/Nginx-UI/query"
7+
"github.com/0xJacky/Nginx-UI/settings"
8+
"github.com/caarlos0/env/v11"
9+
"github.com/google/uuid"
10+
"github.com/pkg/errors"
11+
"golang.org/x/crypto/bcrypt"
12+
"gorm.io/gorm"
13+
)
14+
15+
type predefinedUser struct {
16+
Name string `json:"name"`
17+
Password string `json:"password"`
18+
}
19+
20+
func skipInstall() {
21+
logger.Info("Skip installation mode enabled")
22+
23+
if settings.ServerSettings.JwtSecret == "" {
24+
settings.ServerSettings.JwtSecret = uuid.New().String()
25+
}
26+
27+
if settings.ServerSettings.NodeSecret == "" {
28+
settings.ServerSettings.NodeSecret = uuid.New().String()
29+
logger.Infof("NodeSecret: %s", settings.ServerSettings.NodeSecret)
30+
}
31+
32+
err := settings.Save()
33+
if err != nil {
34+
logger.Fatal(err)
35+
}
36+
}
37+
38+
func registerPredefinedUser() {
39+
// when skip installation mode is enabled, the predefined user will be created
40+
if !settings.ServerSettings.SkipInstallation {
41+
return
42+
}
43+
pUser := &predefinedUser{}
44+
45+
err := env.ParseWithOptions(pUser, env.Options{
46+
Prefix: "NGINX_UI_PREDEFINED_USER_",
47+
UseFieldNameByDefault: true,
48+
})
49+
50+
if err != nil {
51+
logger.Fatal(err)
52+
}
53+
54+
u := query.Auth
55+
56+
_, err = u.First()
57+
58+
// Only effect when there is no user in the database
59+
if !errors.Is(err, gorm.ErrRecordNotFound) || pUser.Name == "" || pUser.Password == "" {
60+
return
61+
}
62+
63+
// Create a new user with the predefined name and password
64+
pwd, _ := bcrypt.GenerateFromPassword([]byte(pUser.Password), bcrypt.DefaultCost)
65+
66+
err = u.Create(&model.Auth{
67+
Name: pUser.Name,
68+
Password: string(pwd),
69+
})
70+
71+
if err != nil {
72+
logger.Error(err)
73+
}
74+
}

settings/settings.go

+4-6
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,6 @@ func MapTo() {
6969
}
7070
}
7171

72-
func ReflectFrom() {
73-
for k, v := range sections {
74-
reflectFrom(k, v)
75-
}
76-
}
77-
7872
func mapTo(section string, v interface{}) {
7973
err := Conf.Section(section).MapTo(v)
8074
if err != nil {
@@ -90,6 +84,10 @@ func reflectFrom(section string, v interface{}) {
9084
}
9185

9286
func Save() (err error) {
87+
for k, v := range sections {
88+
reflectFrom(k, v)
89+
}
90+
9391
err = Conf.SaveTo(ConfPath)
9492
if err != nil {
9593
return

settings/settings_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ func TestSetup(t *testing.T) {
5252
_ = os.Setenv("NGINX_UI_LOGROTATE_CMD", "logrotate /custom/logrotate.conf")
5353
_ = os.Setenv("NGINX_UI_LOGROTATE_INTERVAL", "60")
5454

55+
ConfPath = "app.testing.ini"
5556
Setup()
5657

5758
assert.Equal(t, "8080", ServerSettings.HttpPort)
@@ -96,4 +97,5 @@ func TestSetup(t *testing.T) {
9697
assert.Equal(t, 60, LogrotateSettings.Interval)
9798

9899
os.Clearenv()
100+
_ = os.Remove("app.testing.ini")
99101
}

settings/user.go

-8
This file was deleted.

0 commit comments

Comments
 (0)