From 7e099340246028a3637baf0dc688e94ea5417b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E9=BB=84=E6=9E=97?= Date: Thu, 14 Sep 2023 23:29:42 +0800 Subject: [PATCH] change config from ini to toml (processing) --- cmd/frps-panel/cmd.go | 244 ++++++---------------------- cmd/frps-panel/config.go | 31 ---- config/frps-panel.toml | 18 -- config/frps-tokens.toml | 18 ++ go.mod | 3 +- pkg/server/controller/authorizer.go | 14 +- pkg/server/controller/controller.go | 186 +++++++-------------- pkg/server/controller/handler.go | 12 +- pkg/server/controller/register.go | 10 +- pkg/server/controller/variables.go | 42 +++-- pkg/server/server.go | 2 +- 11 files changed, 168 insertions(+), 412 deletions(-) delete mode 100644 cmd/frps-panel/config.go create mode 100644 config/frps-tokens.toml diff --git a/cmd/frps-panel/cmd.go b/cmd/frps-panel/cmd.go index 8929df2..9de7cc0 100644 --- a/cmd/frps-panel/cmd.go +++ b/cmd/frps-panel/cmd.go @@ -1,13 +1,10 @@ package main import ( - "errors" "frps-panel/pkg/server" "frps-panel/pkg/server/controller" - "github.com/pelletier/go-toml/v2" + "github.com/BurntSushi/toml" "github.com/spf13/cobra" - "gopkg.in/ini.v1" - "io/fs" "log" "os" "path/filepath" @@ -23,7 +20,7 @@ var ( func init() { rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frps-panel") - rootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "./frps-panel.ini", "config file of frps-panel") + rootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "./frps-panel.toml", "config file of frps-panel") } var rootCmd = &cobra.Command{ @@ -41,7 +38,10 @@ var rootCmd = &cobra.Command{ } rootDir := filepath.Dir(executable) - config, tls, err := ParseConfigFile(configFile) + configDir := filepath.Dir(configFile) + tokensFile := filepath.Join(configDir, "frps-tokens.toml") + + config, tls, err := parseConfigFile(configFile, tokensFile) if err != nil { log.Printf("fail to start frps-panel : %v", err) return err @@ -69,211 +69,59 @@ func Execute() { } } -func ParseConfigFile(file string) (controller.HandleController, server.TLS, error) { - - var config Config - readFile, _ := os.ReadFile("/Volumes/Working/Works/Git Sources/frps-panel/config/frps-panel.toml") - _ = toml.Unmarshal(readFile, &config) - log.Printf("%v", config) - f, err := os.Create("/Volumes/Working/Works/Git Sources/frps-panel/config/frps-panel-new.toml") +func parseConfigFile(configFile, tokensFile string) (controller.HandleController, server.TLS, error) { + var config controller.Config + _, err := toml.DecodeFile(configFile, &config) if err != nil { - log.Fatal(err) - } - if err := toml.NewEncoder(f).Encode(config); err != nil { - // failed to encode - log.Fatal(err) - } - if err := f.Close(); err != nil { - // failed to close the file - log.Fatal(err) - + log.Fatalf("decode config file %v error: %v", configFile, err) } - common := controller.CommonInfo{} - users := make(map[string]controller.TokenInfo) - ports := make(map[string][]string) - domains := make(map[string][]string) - subdomains := make(map[string][]string) + _, err = toml.DecodeFile(tokensFile, &config) + if err != nil { + log.Fatalf("decode token file %v error: %v", tokensFile, err) + } + + config.Common.DashboardTls = strings.HasPrefix("https://", strings.ToLower(config.Common.DashboardAddr)) + + //f, err := os.Create("/Volumes/Work/Git Sources/frps-panel/config/frps-panel-new.toml") + //if err != nil { + // log.Fatal(err) + //} + //if err := toml.NewEncoder(f).Encode(config); err != nil { + // // failed to encode + // log.Fatal(err) + //} + //if err := f.Close(); err != nil { + // // failed to close the file + // log.Fatal(err) + //} + tls := server.TLS{ - Enable: false, + Enable: config.Common.TlsMode, Protocol: "HTTP", } - iniFile, err := ini.LoadSources(ini.LoadOptions{ - Insensitive: false, - InsensitiveSections: false, - InsensitiveKeys: false, - IgnoreInlineComment: true, - AllowBooleanKeys: true, - }, file) - if err != nil { - var pathError *fs.PathError - if errors.As(err, &pathError) { - log.Printf("token file %s not found", file) - } else { - log.Printf("fail to parse token file %s : %v", file, err) - } - return controller.HandleController{ - CommonInfo: common, - Tokens: nil, - Ports: nil, - Domains: nil, - Subdomains: nil, - IniFile: iniFile, - }, tls, err - } - - commonSection, err := iniFile.GetSection("common") - if err != nil { - log.Printf("fail to get [common] section from file %s : %v", file, err) - return controller.HandleController{ - CommonInfo: common, - Tokens: nil, - Ports: nil, - Domains: nil, - Subdomains: nil, - IniFile: iniFile, - }, tls, err - } - common.PluginAddr = commonSection.Key("plugin_addr").MustString("0.0.0.0") - common.PluginPort = commonSection.Key("plugin_port").MustInt(7200) - common.User = commonSection.Key("admin_user").Value() - common.Pwd = commonSection.Key("admin_pwd").Value() - common.KeepTime = commonSection.Key("admin_keep_time").MustInt(0) - common.DashboardAddr = commonSection.Key("dashboard_addr").MustString("127.0.0.1") - common.DashboardPort = commonSection.Key("dashboard_port").MustInt(7500) - common.DashboardUser = commonSection.Key("dashboard_user").Value() - common.DashboardPwd = commonSection.Key("dashboard_pwd").Value() - common.DashboardTLS = strings.HasPrefix(strings.ToLower(common.DashboardAddr), "https://") - - if common.KeepTime < 0 { - common.KeepTime = 0 - } - - tls.Enable = commonSection.Key("tls_mode").MustBool(false) - tls.Cert = commonSection.Key("tls_cert_file").MustString("") - tls.Key = commonSection.Key("tls_key_file").MustString("") if tls.Enable { tls.Protocol = "HTTPS" - } - if tls.Enable && (strings.TrimSpace(tls.Cert) == "" || strings.TrimSpace(tls.Key) == "") { - tls.Enable = false - tls.Protocol = "HTTP" - log.Printf("fail to enable tls: tls cert or key not exist, use http as default.") - } - portsSection, err := iniFile.GetSection("ports") - if err != nil { - log.Printf("fail to get [ports] section from file %s : %v", file, err) - return controller.HandleController{ - CommonInfo: common, - Tokens: nil, - Ports: nil, - Domains: nil, - Subdomains: nil, - IniFile: iniFile, - }, tls, err - } - for _, key := range portsSection.Keys() { - user := key.Name() - value := key.Value() - port := strings.Split(controller.TrimAllSpaceReg.ReplaceAllString(value, ""), ",") - ports[user] = port - } - - domainsSection, err := iniFile.GetSection("domains") - if err != nil { - log.Printf("fail to get [domains] section from file %s : %v", file, err) - return controller.HandleController{ - CommonInfo: common, - Tokens: nil, - Ports: nil, - Domains: nil, - Subdomains: nil, - IniFile: iniFile, - }, tls, err - } - for _, key := range domainsSection.Keys() { - user := key.Name() - value := key.Value() - domain := strings.Split(controller.TrimAllSpaceReg.ReplaceAllString(value, ""), ",") - domains[user] = domain - } - - subdomainsSection, err := iniFile.GetSection("subdomains") - if err != nil { - log.Printf("fail to get [subdomains] section from file %s : %v", file, err) - return controller.HandleController{ - CommonInfo: common, - Tokens: nil, - Ports: nil, - Domains: nil, - Subdomains: nil, - IniFile: iniFile, - }, tls, err - } - for _, key := range subdomainsSection.Keys() { - user := key.Name() - value := key.Value() - subdomain := strings.Split(controller.TrimAllSpaceReg.ReplaceAllString(value, ""), ",") - subdomains[user] = subdomain - } - - usersSection, err := iniFile.GetSection("users") - if err != nil { - log.Printf("fail to get [users] section from file %s : %v", file, err) - return controller.HandleController{ - CommonInfo: common, - Tokens: nil, - Ports: nil, - Domains: nil, - Subdomains: nil, - IniFile: iniFile, - }, tls, err - } - - disabledSection, err := iniFile.GetSection("disabled") - if err != nil { - log.Printf("fail to get [disabled] section from file %s : %v", file, err) - return controller.HandleController{ - CommonInfo: common, - Tokens: nil, - Ports: nil, - Domains: nil, - Subdomains: nil, - IniFile: iniFile, - }, tls, err - } - - keys := usersSection.Keys() - for _, key := range keys { - comment, found := strings.CutPrefix(key.Comment, ";") - if !found { - comment, found = strings.CutPrefix(comment, "#") + if strings.TrimSpace(tls.Cert) == "" || strings.TrimSpace(tls.Key) == "" { + tls.Enable = false + tls.Protocol = "HTTP" + log.Printf("fail to enable tls: tls cert or key not exist, use http as default.") } - token := controller.TokenInfo{ - User: key.Name(), - Token: key.Value(), - Comment: comment, - Ports: strings.Join(ports[key.Name()], ","), - Domains: strings.Join(domains[key.Name()], ","), - Subdomains: strings.Join(subdomains[key.Name()], ","), - Status: !(disabledSection.HasKey(key.Name()) && disabledSection.Key(key.Name()).Value() == "disable"), - } - users[token.User] = token } + + tokens := make(map[string]controller.TokenInfo) + + for _, token := range config.Tokens { + tokens[token.User] = token + } + return controller.HandleController{ - CommonInfo: common, - Tokens: users, - Ports: ports, - Domains: domains, - Subdomains: subdomains, - ConfigFile: configFile, - IniFile: iniFile, + CommonInfo: config.Common, + Tokens: tokens, Version: version, + ConfigFile: configFile, + TokensFile: tokensFile, }, tls, nil } - -func decode() { - -} diff --git a/cmd/frps-panel/config.go b/cmd/frps-panel/config.go deleted file mode 100644 index 8bc02b5..0000000 --- a/cmd/frps-panel/config.go +++ /dev/null @@ -1,31 +0,0 @@ -package main - -type Config struct { - Common CommonInfo - Tokens []TokenInfo -} - -type CommonInfo struct { - PluginAddr string `toml:"plugin_addr" commented:"true"` - PluginPort int `toml:"plugin_port"` - AdminUser string `toml:"admin_user"` - AdminPwd string `toml:"admin_pwd"` - AdminKeepTime int `toml:"admin_keep_time"` - TlsMode bool `toml:"tls_mode"` - TlsCertFile string `toml:"tls_cert_file"` - TlsKeyFile string `toml:"tls_key_file"` - DashboardAddr string `toml:"dashboard_addr"` - DashboardPort int `toml:"dashboard_port"` - DashboardUser string `toml:"dashboard_user"` - DashboardPwd string `toml:"dashboard_pwd"` -} - -type TokenInfo struct { - User string `toml:"user" json:"user" form:"user"` - Token string `toml:"token" json:"token" form:"token"` - Comment string `toml:"comment" json:"comment" form:"comment"` - Ports []any `toml:"ports" json:"ports" from:"ports"` - Domains []string `toml:"domains" json:"domains" from:"domains"` - Subdomains []string `toml:"subdomains" json:"subdomains" from:"subdomains"` - Status bool `toml:"status" json:"status" form:"status"` -} diff --git a/config/frps-panel.toml b/config/frps-panel.toml index 01b72c0..1871aec 100644 --- a/config/frps-panel.toml +++ b/config/frps-panel.toml @@ -19,21 +19,3 @@ dashboard_port = 7500 dashboard_user = "admin" dashboard_pwd = "admin" -# token info -[[tokens]] -user = "user1" -token = "token1" -comment = "张三" -ports = [1, 2, 3, "10-100"] -domains = ["aaa.com", "bbb.com"] -subdomains = ["a.com", "b.com"] -status = true - -[[tokens]] -user = "user2" -token = "token2" -comment = "李四" -ports = [11, 22, 33, "110-200"] -domains = ["ccc.com", "ddd.com"] -subdomains = ["c.com", "d.com"] -status = true diff --git a/config/frps-tokens.toml b/config/frps-tokens.toml new file mode 100644 index 0000000..c050bb9 --- /dev/null +++ b/config/frps-tokens.toml @@ -0,0 +1,18 @@ +# token info +[[tokens]] +user = "user1" +token = "token1" +comment = "张三" +ports = ["1", "2", "3", "10-100"] +domains = ["aaa.com", "bbb.com"] +subdomains = ["a.com", "b.com"] +status = true + +[[tokens]] +user = "user2" +token = "token2" +comment = "李四" +ports = ["11", "22", "33", "110-200"] +domains = ["ccc.com", "ddd.com"] +subdomains = ["c.com", "d.com"] +status = true diff --git a/go.mod b/go.mod index 333c359..b8c2660 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,11 @@ module frps-panel go 1.21 require ( + github.com/BurntSushi/toml v1.0.0 github.com/fatedier/frp v0.34.1 github.com/gin-contrib/i18n v1.0.0 github.com/gin-contrib/sessions v0.0.5 github.com/gin-gonic/gin v1.9.1 - github.com/pelletier/go-toml/v2 v2.0.9 github.com/spf13/cobra v0.0.3 golang.org/x/text v0.11.0 gopkg.in/ini.v1 v1.67.0 @@ -36,6 +36,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/nicksnyder/go-i18n/v2 v2.2.1 // indirect + github.com/pelletier/go-toml/v2 v2.0.9 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect diff --git a/pkg/server/controller/authorizer.go b/pkg/server/controller/authorizer.go index e400dc3..75a98ee 100644 --- a/pkg/server/controller/authorizer.go +++ b/pkg/server/controller/authorizer.go @@ -12,7 +12,7 @@ import ( func (c *HandleController) BasicAuth() gin.HandlerFunc { return func(context *gin.Context) { - if strings.TrimSpace(c.CommonInfo.User) == "" || strings.TrimSpace(c.CommonInfo.Pwd) == "" { + if strings.TrimSpace(c.CommonInfo.AdminUser) == "" || strings.TrimSpace(c.CommonInfo.AdminPwd) == "" { if context.Request.RequestURI == LoginUrl { context.Redirect(http.StatusTemporaryRedirect, LoginSuccessUrl) } @@ -23,19 +23,19 @@ func (c *HandleController) BasicAuth() gin.HandlerFunc { auth := session.Get(AuthName) if auth != nil { - if c.CommonInfo.KeepTime > 0 { + if c.CommonInfo.AdminKeepTime > 0 { cookie, _ := context.Request.Cookie(SessionName) if cookie != nil { //important thx https://blog.csdn.net/zhanghongxia8285/article/details/107321838/ - cookie.Expires = time.Now().Add(time.Second * time.Duration(c.CommonInfo.KeepTime)) + cookie.Expires = time.Now().Add(time.Second * time.Duration(c.CommonInfo.AdminKeepTime)) http.SetCookie(context.Writer, cookie) } } username, password, _ := parseBasicAuth(fmt.Sprintf("%v", auth)) - usernameMatch := username == c.CommonInfo.User - passwordMatch := password == c.CommonInfo.Pwd + usernameMatch := username == c.CommonInfo.AdminUser + passwordMatch := password == c.CommonInfo.AdminPwd if usernameMatch && passwordMatch { context.Next() @@ -54,14 +54,14 @@ func (c *HandleController) BasicAuth() gin.HandlerFunc { } func (c *HandleController) LoginAuth(username, password string, context *gin.Context) bool { - if strings.TrimSpace(c.CommonInfo.User) == "" || strings.TrimSpace(c.CommonInfo.Pwd) == "" { + if strings.TrimSpace(c.CommonInfo.AdminUser) == "" || strings.TrimSpace(c.CommonInfo.AdminPwd) == "" { return true } session := sessions.Default(context) sessionAuth := session.Get(AuthName) - internalAuth := encodeBasicAuth(c.CommonInfo.User, c.CommonInfo.Pwd) + internalAuth := encodeBasicAuth(c.CommonInfo.AdminUser, c.CommonInfo.AdminPwd) if sessionAuth == internalAuth { return true diff --git a/pkg/server/controller/controller.go b/pkg/server/controller/controller.go index 77b8db5..ed15d5e 100644 --- a/pkg/server/controller/controller.go +++ b/pkg/server/controller/controller.go @@ -5,12 +5,14 @@ import ( "encoding/json" "errors" "fmt" + "github.com/BurntSushi/toml" plugin "github.com/fatedier/frp/pkg/plugin/server" ginI18n "github.com/gin-contrib/i18n" "github.com/gin-gonic/gin" "io" "log" "net/http" + "os" "sort" "strconv" "strings" @@ -121,7 +123,7 @@ func (c *HandleController) MakeIndexFunc() func(context *gin.Context) { return func(context *gin.Context) { context.HTML(http.StatusOK, "index.html", gin.H{ "version": c.Version, - "showExit": strings.TrimSpace(c.CommonInfo.User) != "" && strings.TrimSpace(c.CommonInfo.Pwd) != "", + "showExit": strings.TrimSpace(c.CommonInfo.AdminUser) != "" && strings.TrimSpace(c.CommonInfo.AdminPwd) != "", "FrpsPanel": ginI18n.MustGetMessage(context, "Frps Panel"), "User": ginI18n.MustGetMessage(context, "User"), "Token": ginI18n.MustGetMessage(context, "Token"), @@ -352,36 +354,18 @@ func (c *HandleController) MakeAddTokenFunc() func(context *gin.Context) { context.JSON(http.StatusOK, &response) return } - replaceSpaceToken := TrimAllSpaceReg.ReplaceAllString(info.Token, "") - info.Token = replaceSpaceToken - c.Tokens[info.User] = info - usersSection, _ := c.IniFile.GetSection("users") - key, err := usersSection.NewKey(info.User, info.Token) - key.Comment = info.Comment - - replaceSpacePorts := TrimAllSpaceReg.ReplaceAllString(info.Ports, "") - if len(replaceSpacePorts) != 0 { - portsSection, _ := c.IniFile.GetSection("ports") - key, err = portsSection.NewKey(info.User, replaceSpacePorts) - key.Comment = fmt.Sprintf("user %s allowed ports", info.User) + tokenFile, err := os.Create(c.TokensFile) + if err != nil { + log.Printf("error to crate file %v: %v", c.TokensFile, err) + } + if err = toml.NewEncoder(tokenFile).Encode(c.Tokens); err != nil { + log.Printf("error to encode tokens: %v", err) + } + if err = tokenFile.Close(); err != nil { + log.Printf("error to close file %v: %v", c.TokensFile, err) } - replaceSpaceDomains := TrimAllSpaceReg.ReplaceAllString(info.Domains, "") - if len(replaceSpaceDomains) != 0 { - domainsSection, _ := c.IniFile.GetSection("domains") - key, err = domainsSection.NewKey(info.User, replaceSpaceDomains) - key.Comment = fmt.Sprintf("user %s allowed domains", info.User) - } - - replaceSpaceSubdomains := TrimAllSpaceReg.ReplaceAllString(info.Subdomains, "") - if len(replaceSpaceSubdomains) != 0 { - subdomainsSection, _ := c.IniFile.GetSection("subdomains") - key, err = subdomainsSection.NewKey(info.User, replaceSpaceSubdomains) - key.Comment = fmt.Sprintf("user %s allowed subdomains", info.User) - } - - err = c.IniFile.SaveTo(c.ConfigFile) if err != nil { log.Printf("add failed, error : %v", err) response.Success = false @@ -414,13 +398,7 @@ func (c *HandleController) MakeUpdateTokensFunc() func(context *gin.Context) { } after := update.After - before := update.Before - - usersSection, _ := c.IniFile.GetSection("users") - key, err := usersSection.GetKey(before.User) - comment := TrimBreakLineReg.ReplaceAllString(after.Comment, "") - after.Comment = comment - key.Comment = comment + _ = update.Before if !TokenFormatReg.MatchString(after.Token) { log.Printf("update failed, token format error") @@ -430,58 +408,20 @@ func (c *HandleController) MakeUpdateTokensFunc() func(context *gin.Context) { context.JSON(http.StatusOK, &response) return } - replaceSpaceToken := TrimAllSpaceReg.ReplaceAllString(after.Token, "") - after.Token = replaceSpaceToken - key.SetValue(replaceSpaceToken) - - if before.Ports != after.Ports { - portsSection, _ := c.IniFile.GetSection("ports") - replaceSpacePorts := TrimAllSpaceReg.ReplaceAllString(after.Ports, "") - after.Ports = replaceSpacePorts - ports := strings.Split(replaceSpacePorts, ",") - if len(replaceSpacePorts) != 0 { - key, err = portsSection.NewKey(after.User, replaceSpacePorts) - key.Comment = fmt.Sprintf("user %s allowed ports", after.User) - c.Ports[after.User] = ports - } else { - portsSection.DeleteKey(after.User) - delete(c.Ports, after.User) - } - } - - if before.Domains != after.Domains { - domainsSection, _ := c.IniFile.GetSection("domains") - replaceSpaceDomains := TrimAllSpaceReg.ReplaceAllString(after.Domains, "") - after.Domains = replaceSpaceDomains - domains := strings.Split(replaceSpaceDomains, ",") - if len(replaceSpaceDomains) != 0 { - key, err = domainsSection.NewKey(after.User, replaceSpaceDomains) - key.Comment = fmt.Sprintf("user %s allowed domains", after.User) - c.Domains[after.User] = domains - } else { - domainsSection.DeleteKey(after.User) - delete(c.Domains, after.User) - } - } - - if before.Subdomains != after.Subdomains { - subdomainsSection, _ := c.IniFile.GetSection("subdomains") - replaceSpaceSubdomains := TrimAllSpaceReg.ReplaceAllString(after.Subdomains, "") - after.Subdomains = replaceSpaceSubdomains - subdomains := strings.Split(replaceSpaceSubdomains, ",") - if len(replaceSpaceSubdomains) != 0 { - key, err = subdomainsSection.NewKey(after.User, replaceSpaceSubdomains) - key.Comment = fmt.Sprintf("user %s allowed subdomains", after.User) - c.Subdomains[after.User] = subdomains - } else { - subdomainsSection.DeleteKey(after.User) - delete(c.Subdomains, after.User) - } - } c.Tokens[after.User] = after - err = c.IniFile.SaveTo(c.ConfigFile) + tokenFile, err := os.Create(c.TokensFile) + if err != nil { + log.Printf("error to crate file %v: %v", c.TokensFile, err) + } + if err = toml.NewEncoder(tokenFile).Encode(c.Tokens); err != nil { + log.Printf("error to encode tokens: %v", err) + } + if err = tokenFile.Close(); err != nil { + log.Printf("error to close file %v: %v", c.TokensFile, err) + } + if err != nil { log.Printf("user update failed, error : %v", err) response.Success = false @@ -513,36 +453,26 @@ func (c *HandleController) MakeRemoveTokensFunc() func(context *gin.Context) { return } - usersSection, _ := c.IniFile.GetSection("users") for _, user := range remove.Users { delete(c.Tokens, user.User) - usersSection.DeleteKey(user.User) } - portsSection, _ := c.IniFile.GetSection("ports") - for _, user := range remove.Users { - delete(c.Ports, user.User) - portsSection.DeleteKey(user.User) - } - - domainsSection, _ := c.IniFile.GetSection("domains") - for _, user := range remove.Users { - delete(c.Domains, user.User) - domainsSection.DeleteKey(user.User) - } - - subdomainsSection, _ := c.IniFile.GetSection("subdomains") - for _, user := range remove.Users { - delete(c.Subdomains, user.User) - subdomainsSection.DeleteKey(user.User) - } - - err = c.IniFile.SaveTo(c.ConfigFile) + tokenFile, err := os.Create(c.TokensFile) if err != nil { - log.Printf("user remove failed, error : %v", err) + log.Printf("error to crate file %v: %v", c.TokensFile, err) + } + if err = toml.NewEncoder(tokenFile).Encode(c.Tokens); err != nil { + log.Printf("error to encode tokens: %v", err) + } + if err = tokenFile.Close(); err != nil { + log.Printf("error to close file %v: %v", c.TokensFile, err) + } + + if err != nil { + log.Printf("user update failed, error : %v", err) response.Success = false response.Code = SaveError - response.Message = "user remove failed" + response.Message = "user update failed" context.JSON(http.StatusOK, &response) return } @@ -569,25 +499,22 @@ func (c *HandleController) MakeDisableTokensFunc() func(context *gin.Context) { return } - section, _ := c.IniFile.GetSection("disabled") for _, user := range disable.Users { - section.DeleteKey(user.User) token := c.Tokens[user.User] token.Status = false - c.Tokens[user.User] = token - key, err := section.NewKey(user.User, "disable") - if err != nil { - log.Printf("disable failed, error : %v", err) - response.Success = false - response.Code = SaveError - response.Message = "disable failed" - context.JSON(http.StatusOK, &response) - return - } - key.Comment = fmt.Sprintf("disable user '%s'", user.User) } - err = c.IniFile.SaveTo(c.ConfigFile) + tokenFile, err := os.Create(c.TokensFile) + if err != nil { + log.Printf("error to crate file %v: %v", c.TokensFile, err) + } + if err = toml.NewEncoder(tokenFile).Encode(c.Tokens); err != nil { + log.Printf("error to encode tokens: %v", err) + } + if err = tokenFile.Close(); err != nil { + log.Printf("error to close file %v: %v", c.TokensFile, err) + } + if err != nil { log.Printf("disable failed, error : %v", err) response.Success = false @@ -619,15 +546,22 @@ func (c *HandleController) MakeEnableTokensFunc() func(context *gin.Context) { return } - section, _ := c.IniFile.GetSection("disabled") for _, user := range enable.Users { - section.DeleteKey(user.User) token := c.Tokens[user.User] token.Status = true - c.Tokens[user.User] = token } - err = c.IniFile.SaveTo(c.ConfigFile) + tokenFile, err := os.Create(c.TokensFile) + if err != nil { + log.Printf("error to crate file %v: %v", c.TokensFile, err) + } + if err = toml.NewEncoder(tokenFile).Encode(c.Tokens); err != nil { + log.Printf("error to encode tokens: %v", err) + } + if err = tokenFile.Close(); err != nil { + log.Printf("error to close file %v: %v", c.TokensFile, err) + } + if err != nil { log.Printf("enable failed, error : %v", err) response.Success = false @@ -646,7 +580,7 @@ func (c *HandleController) MakeProxyFunc() func(context *gin.Context) { var client *http.Client var protocol string - if c.CommonInfo.DashboardTLS { + if c.CommonInfo.DashboardTls { client = &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ diff --git a/pkg/server/controller/handler.go b/pkg/server/controller/handler.go index 9e207fe..735d500 100644 --- a/pkg/server/controller/handler.go +++ b/pkg/server/controller/handler.go @@ -92,8 +92,8 @@ func (c *HandleController) JudgePort(content *plugin.NewProxyContent) plugin.Res portAllowed := true if proxyType == "tcp" || proxyType == "udp" { portAllowed = false - if _, exist := c.Ports[user]; exist { - for _, port := range c.Ports[user] { + if token, exist := c.Tokens[user]; exist { + for _, port := range token.Ports { if strings.Contains(port, "-") { allowedRanges := strings.Split(port, "-") if len(allowedRanges) != 2 { @@ -139,9 +139,9 @@ func (c *HandleController) JudgePort(content *plugin.NewProxyContent) plugin.Res domainAllowed := true if proxyType == "http" || proxyType == "https" || proxyType == "tcpmux" { if portAllowed { - if _, exist := c.Domains[user]; exist { + if token, exist := c.Tokens[user]; exist { for _, userDomain := range userDomains { - if StringIndexOf(userDomain, c.Domains[user]) == -1 { + if StringIndexOf(userDomain, token.Domains) == -1 { domainAllowed = false break } @@ -158,8 +158,8 @@ func (c *HandleController) JudgePort(content *plugin.NewProxyContent) plugin.Res if proxyType == "http" || proxyType == "https" { subdomainAllowed = false if portAllowed && domainAllowed { - if _, exist := c.Subdomains[user]; exist { - for _, subdomain := range c.Subdomains[user] { + if token, exist := c.Tokens[user]; exist { + for _, subdomain := range token.Subdomains { if subdomain == userSubdomain { subdomainAllowed = true break diff --git a/pkg/server/controller/register.go b/pkg/server/controller/register.go index bfffb09..893b577 100644 --- a/pkg/server/controller/register.go +++ b/pkg/server/controller/register.go @@ -2,7 +2,6 @@ package controller import ( "github.com/gin-gonic/gin" - "gopkg.in/ini.v1" "os" "path/filepath" ) @@ -10,12 +9,9 @@ import ( type HandleController struct { CommonInfo CommonInfo Tokens map[string]TokenInfo - Ports map[string][]string - Domains map[string][]string - Subdomains map[string][]string - ConfigFile string - IniFile *ini.File Version string + ConfigFile string + TokensFile string } func NewHandleController(config *HandleController) *HandleController { @@ -39,7 +35,7 @@ func (c *HandleController) Register(rootDir string, engine *gin.Engine) { engine.GET(LogoutUrl, c.MakeLogoutFunc()) var group *gin.RouterGroup - if len(c.CommonInfo.User) != 0 { + if len(c.CommonInfo.AdminUser) != 0 { //group = engine.Group("/", gin.BasicAuthForRealm(gin.Accounts{ // c.CommonInfo.User: c.CommonInfo.Pwd, //}, "Restricted")) diff --git a/pkg/server/controller/variables.go b/pkg/server/controller/variables.go index 18eee94..2867ef2 100644 --- a/pkg/server/controller/variables.go +++ b/pkg/server/controller/variables.go @@ -37,27 +37,35 @@ type HTTPError struct { Err error } +type Config struct { + Common CommonInfo + Tokens []TokenInfo +} + type CommonInfo struct { - PluginAddr string - PluginPort int - User string - Pwd string - KeepTime int - DashboardTLS bool - DashboardAddr string - DashboardPort int - DashboardUser string - DashboardPwd string + PluginAddr string `toml:"plugin_addr"` + PluginPort int `toml:"plugin_port"` + AdminUser string `toml:"admin_user"` + AdminPwd string `toml:"admin_pwd"` + AdminKeepTime int `toml:"admin_keep_time"` + TlsMode bool `toml:"tls_mode"` + TlsCertFile string `toml:"tls_cert_file"` + TlsKeyFile string `toml:"tls_key_file"` + DashboardAddr string `toml:"dashboard_addr"` + DashboardPort int `toml:"dashboard_port"` + DashboardUser string `toml:"dashboard_user"` + DashboardPwd string `toml:"dashboard_pwd"` + DashboardTls bool } type TokenInfo struct { - User string `json:"user" form:"user"` - Token string `json:"token" form:"token"` - Comment string `json:"comment" form:"comment"` - Ports string `json:"ports" from:"ports"` - Domains string `json:"domains" from:"domains"` - Subdomains string `json:"subdomains" from:"subdomains"` - Status bool `json:"status" form:"status"` + User string `toml:"user" json:"user" form:"user"` + Token string `toml:"token" json:"token" form:"token"` + Comment string `toml:"comment" json:"comment" form:"comment"` + Ports []string `toml:"ports" json:"ports" from:"ports"` + Domains []string `toml:"domains" json:"domains" from:"domains"` + Subdomains []string `toml:"subdomains" json:"subdomains" from:"subdomains"` + Status bool `toml:"status" json:"status" form:"status"` } type TokenResponse struct { diff --git a/pkg/server/server.go b/pkg/server/server.go index b9ee940..897f466 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -179,7 +179,7 @@ func (s *Server) initHTTPServer() error { HttpOnly: false, SameSite: 4, Path: "/", - MaxAge: s.cfg.CommonInfo.KeepTime, + MaxAge: s.cfg.CommonInfo.AdminKeepTime, }) engine.Use(sessions.Sessions(controller.SessionName, authStore)) engine.Use(GinI18nLocalize(s.rootDir))